From a0f100d7af708f30dcb69fc5c4a35cc9295428d8 Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Mon, 10 Jul 2023 18:21:04 -0300 Subject: [PATCH 01/50] - WIP tool_groups model, migration, spec --- app/controllers/tool_groups_controller.rb | 45 ++++++++++ app/models/tool_group.rb | 7 ++ app/serializers/tool_group_serializer.rb | 11 +++ config/routes.rb | 2 + .../20230710210235_create_tool_groups.rb | 10 +++ db/schema.rb | 9 +- spec/acceptance/tool_group_spec.rb | 88 +++++++++++++++++++ spec/factories/tool_groups.rb | 6 ++ spec/models/tool_group_spec.rb | 41 +++++++++ 9 files changed, 218 insertions(+), 1 deletion(-) create mode 100644 app/controllers/tool_groups_controller.rb create mode 100644 app/models/tool_group.rb create mode 100644 app/serializers/tool_group_serializer.rb create mode 100644 db/migrate/20230710210235_create_tool_groups.rb create mode 100644 spec/acceptance/tool_group_spec.rb create mode 100644 spec/factories/tool_groups.rb create mode 100644 spec/models/tool_group_spec.rb diff --git a/app/controllers/tool_groups_controller.rb b/app/controllers/tool_groups_controller.rb new file mode 100644 index 000000000..b350e577a --- /dev/null +++ b/app/controllers/tool_groups_controller.rb @@ -0,0 +1,45 @@ +class ToolGroupsController < ApplicationController + before_action :authorize! + + def index + render json: ToolGroup.all.order(name: :asc), status: :ok + end + + def create + create_tool_group + rescue ActiveRecord::RecordInvalid + update_tool_group + end + + def show + render json: load_tool_group, status: :ok + end + + def destroy + tool_group = ToolGroup.find(params[:id]) + tool_group.destroy! + head :no_content + end + + def update + update_tool_group + end + + private + + def create_tool_group + created = ToolGroup.create!(permit_params(:name, :suggestions_weight)) + response.headers['Location'] = "tool_groups/#{created.id}" + render json: created, status: :created + end + + def update_tool_group + existing = ToolGroup.find(params[:id]) + existing.update!(permit_params(:name, :suggestions_weight)) + render json: existing, status: :accepted + end + + def load_tool_group + ToolGroup.find(params[:id]) + end +end diff --git a/app/models/tool_group.rb b/app/models/tool_group.rb new file mode 100644 index 000000000..ce0fb2da9 --- /dev/null +++ b/app/models/tool_group.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +# ToolGroup model class +class ToolGroup < ApplicationRecord + validates :name, :suggestions_weight, presence: true + validates :name, uniqueness: true +end diff --git a/app/serializers/tool_group_serializer.rb b/app/serializers/tool_group_serializer.rb new file mode 100644 index 000000000..9f3acde4e --- /dev/null +++ b/app/serializers/tool_group_serializer.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +class ToolGroupSerializer < ActiveModel::Serializer + attributes :id, :name, :suggestions_weight + + type 'tool-group' + + def type + 'tool-group' + end +end diff --git a/config/routes.rb b/config/routes.rb index 0cf7a0e69..35f59a69a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -30,6 +30,8 @@ resources :custom_manifests, only: [:create, :update, :destroy, :show] + resources :tool_groups, only: [:create, :destroy, :index, :show, :update] + patch "user/counters/:id", to: "user_counters#update" # Legacy route for GodTools Android v5.7.0-v6.0.0 patch "user/me/counters/:id", to: "user_counters#update" # Legacy route for GodTools Android v6.0.1+ get "users/:user_id/counters", to: "user_counters#index" diff --git a/db/migrate/20230710210235_create_tool_groups.rb b/db/migrate/20230710210235_create_tool_groups.rb new file mode 100644 index 000000000..ec36dfbfd --- /dev/null +++ b/db/migrate/20230710210235_create_tool_groups.rb @@ -0,0 +1,10 @@ +class CreateToolGroups < ActiveRecord::Migration[6.1] + def change + create_table :tool_groups do |t| + t.string :name + t.float :suggestions_weight + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index ac26cbbb7..349104956 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2023_03_28_180034) do +ActiveRecord::Schema.define(version: 2023_07_10_210235) do # These are extensions that must be enabled in order to support this database enable_extension "citext" @@ -222,6 +222,13 @@ t.index ["resource_id", "name"], name: "index_tips_on_resource_id_and_name", unique: true end + create_table "tool_groups", force: :cascade do |t| + t.string "name" + t.float "suggestions_weight" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + end + create_table "translated_attributes", force: :cascade do |t| t.integer "resource_id" t.string "key" diff --git a/spec/acceptance/tool_group_spec.rb b/spec/acceptance/tool_group_spec.rb new file mode 100644 index 000000000..f38768704 --- /dev/null +++ b/spec/acceptance/tool_group_spec.rb @@ -0,0 +1,88 @@ +# frozen_string_literal: true + +require 'acceptance_helper' + +resource 'ToolGroups' do + header 'Accept', 'application/vnd.api+json' + header 'Content-Type', 'application/vnd.api+json' + + let(:raw_post) { params.to_json } + let(:authorization) { AuthToken.generic_token } + + before(:each) do + %i[one two three].each do |name| + FactoryBot.create(:tool_group, name: name) + end + end + + after(:each) do + ToolGroup.delete_all + end + + post 'tool_groups' do + let(:attrs) do + { + name: 'test', + suggestions_weight: '1.0' + } + end + + requires_authorization + + it 'create tool group' do + do_request data: { type: 'tool-group', attributes: attrs } + expect(status).to eq(201) + expect(JSON.parse(response_body)['data']).not_to be_nil + end + end + + get 'tool_groups' do + requires_authorization + + it 'list groups' do + do_request + expect(status).to eq(200) + expect(JSON.parse(response_body)['data'].count).to eql 3 + end + end + + get 'tool_groups/:id' do + requires_authorization + let(:id) { ToolGroup.first.id } + + it 'get tool_group by id' do + do_request + expect(status).to eq(200) + expect(JSON.parse(response_body)['data']['attributes']['name']).to eql 'one' + end + end + + put 'tool_groups/:id' do + requires_authorization + let(:id) { ToolGroup.first.id } + let(:attrs) do + { + name: 'new name' + } + end + + it 'update tool group' do + do_request data: { type: 'tool-group', attributes: attrs } + + expect(status).to be(202) + expect(JSON.parse(response_body)['data']['attributes']['name']).to eql 'new name' + end + end + + delete 'tool_groups/:id' do + let(:id) { ToolGroup.first.id } + + requires_authorization + + it 'delete tool_group' do + do_request + + expect(status).to be(204) + end + end +end diff --git a/spec/factories/tool_groups.rb b/spec/factories/tool_groups.rb new file mode 100644 index 000000000..959128caf --- /dev/null +++ b/spec/factories/tool_groups.rb @@ -0,0 +1,6 @@ +FactoryBot.define do + factory :tool_group do + name { 'Group 1' } + suggestions_weight { 1.0 } + end +end diff --git a/spec/models/tool_group_spec.rb b/spec/models/tool_group_spec.rb new file mode 100644 index 000000000..f2950fdfe --- /dev/null +++ b/spec/models/tool_group_spec.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe ToolGroup, type: :model do + context 'create new tool-group' do + subject { ToolGroup.new(name: 'Group 1', suggestions_weight: 1.0) } + + it 'is valid with a unique name' do + expect(subject).to be_valid + end + + it 'is not valid with a duplicate name' do + FactoryBot.create(:tool_group) + attributes = { name: 'Group 1', suggestions_weight: 1.0 } + expect { described_class.create!(attributes) }.to raise_error(ActiveRecord::RecordInvalid) + expect(subject).not_to be_valid + expect(subject.errors[:name]).to include('has already been taken') + end + + it 'validates creation with valid attributes' do + attributes = { name: 'test', suggestions_weight: 1.0 } + + expect do + result = described_class.create!(attributes) + expect(result.name).to eq('test') + expect(result.suggestions_weight).to eq(1.0) + end.to change(ToolGroup, :count).by(1) + end + + it 'raises an error if the "name" attribute does not exist' do + attributes = { name: nil, suggestions_weight: 1.0 } + expect { described_class.create!(attributes) }.to raise_error(ActiveRecord::RecordInvalid) + end + + it 'raises an error if the "suggestions_weight" attribute does not exist' do + attributes = { name: 'test', suggestions_weight: nil } + expect { described_class.create!(attributes) }.to raise_error(ActiveRecord::RecordInvalid) + end + end +end From e942c34da6867ec73a355886996d761051d518ca Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Tue, 11 Jul 2023 18:22:41 -0300 Subject: [PATCH 02/50] fixed standardrb offences --- app/controllers/tool_groups_controller.rb | 2 +- app/serializers/tool_group_serializer.rb | 4 +- spec/acceptance/tool_group_spec.rb | 46 +++++++++++------------ spec/factories/tool_groups.rb | 2 +- spec/models/tool_group_spec.rb | 28 +++++++------- 5 files changed, 41 insertions(+), 41 deletions(-) diff --git a/app/controllers/tool_groups_controller.rb b/app/controllers/tool_groups_controller.rb index b350e577a..189420e3c 100644 --- a/app/controllers/tool_groups_controller.rb +++ b/app/controllers/tool_groups_controller.rb @@ -29,7 +29,7 @@ def update def create_tool_group created = ToolGroup.create!(permit_params(:name, :suggestions_weight)) - response.headers['Location'] = "tool_groups/#{created.id}" + response.headers["Location"] = "tool_groups/#{created.id}" render json: created, status: :created end diff --git a/app/serializers/tool_group_serializer.rb b/app/serializers/tool_group_serializer.rb index 9f3acde4e..257d619a7 100644 --- a/app/serializers/tool_group_serializer.rb +++ b/app/serializers/tool_group_serializer.rb @@ -3,9 +3,9 @@ class ToolGroupSerializer < ActiveModel::Serializer attributes :id, :name, :suggestions_weight - type 'tool-group' + type "tool-group" def type - 'tool-group' + "tool-group" end end diff --git a/spec/acceptance/tool_group_spec.rb b/spec/acceptance/tool_group_spec.rb index f38768704..8bb51a024 100644 --- a/spec/acceptance/tool_group_spec.rb +++ b/spec/acceptance/tool_group_spec.rb @@ -1,10 +1,10 @@ # frozen_string_literal: true -require 'acceptance_helper' +require "acceptance_helper" -resource 'ToolGroups' do - header 'Accept', 'application/vnd.api+json' - header 'Content-Type', 'application/vnd.api+json' +resource "ToolGroups" do + header "Accept", "application/vnd.api+json" + header "Content-Type", "application/vnd.api+json" let(:raw_post) { params.to_json } let(:authorization) { AuthToken.generic_token } @@ -19,67 +19,67 @@ ToolGroup.delete_all end - post 'tool_groups' do + post "tool_groups" do let(:attrs) do { - name: 'test', - suggestions_weight: '1.0' + name: "test", + suggestions_weight: "1.0" } end requires_authorization - it 'create tool group' do - do_request data: { type: 'tool-group', attributes: attrs } + it "create tool group" do + do_request data: {type: "tool-group", attributes: attrs} expect(status).to eq(201) - expect(JSON.parse(response_body)['data']).not_to be_nil + expect(JSON.parse(response_body)["data"]).not_to be_nil end end - get 'tool_groups' do + get "tool_groups" do requires_authorization - it 'list groups' do + it "list groups" do do_request expect(status).to eq(200) - expect(JSON.parse(response_body)['data'].count).to eql 3 + expect(JSON.parse(response_body)["data"].count).to eql 3 end end - get 'tool_groups/:id' do + get "tool_groups/:id" do requires_authorization let(:id) { ToolGroup.first.id } - it 'get tool_group by id' do + it "get tool_group by id" do do_request expect(status).to eq(200) - expect(JSON.parse(response_body)['data']['attributes']['name']).to eql 'one' + expect(JSON.parse(response_body)["data"]["attributes"]["name"]).to eql "one" end end - put 'tool_groups/:id' do + put "tool_groups/:id" do requires_authorization let(:id) { ToolGroup.first.id } let(:attrs) do { - name: 'new name' + name: "new name" } end - it 'update tool group' do - do_request data: { type: 'tool-group', attributes: attrs } + it "update tool group" do + do_request data: {type: "tool-group", attributes: attrs} expect(status).to be(202) - expect(JSON.parse(response_body)['data']['attributes']['name']).to eql 'new name' + expect(JSON.parse(response_body)["data"]["attributes"]["name"]).to eql "new name" end end - delete 'tool_groups/:id' do + delete "tool_groups/:id" do let(:id) { ToolGroup.first.id } requires_authorization - it 'delete tool_group' do + it "delete tool_group" do do_request expect(status).to be(204) diff --git a/spec/factories/tool_groups.rb b/spec/factories/tool_groups.rb index 959128caf..3ce505b8d 100644 --- a/spec/factories/tool_groups.rb +++ b/spec/factories/tool_groups.rb @@ -1,6 +1,6 @@ FactoryBot.define do factory :tool_group do - name { 'Group 1' } + name { "Group 1" } suggestions_weight { 1.0 } end end diff --git a/spec/models/tool_group_spec.rb b/spec/models/tool_group_spec.rb index f2950fdfe..fdbda2b1c 100644 --- a/spec/models/tool_group_spec.rb +++ b/spec/models/tool_group_spec.rb @@ -1,40 +1,40 @@ # frozen_string_literal: true -require 'rails_helper' +require "rails_helper" RSpec.describe ToolGroup, type: :model do - context 'create new tool-group' do - subject { ToolGroup.new(name: 'Group 1', suggestions_weight: 1.0) } + context "create new tool-group" do + subject { ToolGroup.new(name: "Group 1", suggestions_weight: 1.0) } - it 'is valid with a unique name' do + it "is valid with a unique name" do expect(subject).to be_valid end - it 'is not valid with a duplicate name' do + it "is not valid with a duplicate name" do FactoryBot.create(:tool_group) - attributes = { name: 'Group 1', suggestions_weight: 1.0 } + attributes = {name: "Group 1", suggestions_weight: 1.0} expect { described_class.create!(attributes) }.to raise_error(ActiveRecord::RecordInvalid) expect(subject).not_to be_valid - expect(subject.errors[:name]).to include('has already been taken') + expect(subject.errors[:name]).to include("has already been taken") end - it 'validates creation with valid attributes' do - attributes = { name: 'test', suggestions_weight: 1.0 } + it "validates creation with valid attributes" do + attributes = {name: "test", suggestions_weight: 1.0} expect do result = described_class.create!(attributes) - expect(result.name).to eq('test') + expect(result.name).to eq("test") expect(result.suggestions_weight).to eq(1.0) end.to change(ToolGroup, :count).by(1) end - it 'raises an error if the "name" attribute does not exist' do - attributes = { name: nil, suggestions_weight: 1.0 } + it "raises an error if the 'name' attribute does not exist" do + attributes = {name: nil, suggestions_weight: 1.0} expect { described_class.create!(attributes) }.to raise_error(ActiveRecord::RecordInvalid) end - it 'raises an error if the "suggestions_weight" attribute does not exist' do - attributes = { name: 'test', suggestions_weight: nil } + it "raises an error if the 'suggestions_weight' attribute does not exist" do + attributes = {name: "test", suggestions_weight: nil} expect { described_class.create!(attributes) }.to raise_error(ActiveRecord::RecordInvalid) end end From 03fc749b3ef3c78cda8399e066d675e910fcce0c Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Tue, 11 Jul 2023 18:51:20 -0300 Subject: [PATCH 03/50] deleted unnecesary method --- app/serializers/tool_group_serializer.rb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/serializers/tool_group_serializer.rb b/app/serializers/tool_group_serializer.rb index 257d619a7..7d117b85d 100644 --- a/app/serializers/tool_group_serializer.rb +++ b/app/serializers/tool_group_serializer.rb @@ -4,8 +4,4 @@ class ToolGroupSerializer < ActiveModel::Serializer attributes :id, :name, :suggestions_weight type "tool-group" - - def type - "tool-group" - end end From 493389667d2a67ac840d8f93b400592887ab4167 Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Tue, 11 Jul 2023 20:00:50 -0300 Subject: [PATCH 04/50] deleted rescue for create tool_group and return error instead --- app/controllers/tool_groups_controller.rb | 4 ++-- spec/acceptance/tool_group_spec.rb | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/app/controllers/tool_groups_controller.rb b/app/controllers/tool_groups_controller.rb index 189420e3c..e6c389a04 100644 --- a/app/controllers/tool_groups_controller.rb +++ b/app/controllers/tool_groups_controller.rb @@ -7,8 +7,8 @@ def index def create create_tool_group - rescue ActiveRecord::RecordInvalid - update_tool_group + rescue ActiveRecord::RecordInvalid => e + render json: { error: e.record.errors }, status: :unprocessable_entity end def show diff --git a/spec/acceptance/tool_group_spec.rb b/spec/acceptance/tool_group_spec.rb index 8bb51a024..25a51f34c 100644 --- a/spec/acceptance/tool_group_spec.rb +++ b/spec/acceptance/tool_group_spec.rb @@ -27,6 +27,12 @@ } end + let(:attrs_invalid) do + { + name: "test", + suggestions_weight: nil + } + end requires_authorization it "create tool group" do @@ -34,6 +40,12 @@ expect(status).to eq(201) expect(JSON.parse(response_body)["data"]).not_to be_nil end + + it "returns error message when tool group is not created" do + do_request data: {type: "tool-group", attributes: attrs_invalid} + expect(status).to eq(422) + expect(JSON.parse(response_body)["error"]).not_to be_empty + end end get "tool_groups" do From 18a26431dbd21ab59932d45bdf2c903883e1fa82 Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Tue, 11 Jul 2023 20:05:06 -0300 Subject: [PATCH 05/50] fixed standardrb offences --- app/controllers/tool_groups_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/tool_groups_controller.rb b/app/controllers/tool_groups_controller.rb index e6c389a04..e30dd3af4 100644 --- a/app/controllers/tool_groups_controller.rb +++ b/app/controllers/tool_groups_controller.rb @@ -8,7 +8,7 @@ def index def create create_tool_group rescue ActiveRecord::RecordInvalid => e - render json: { error: e.record.errors }, status: :unprocessable_entity + render json: {error: e.record.errors}, status: :unprocessable_entity end def show From c438e28acdd59b07bd2abc1aa064d60d61da6af0 Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Wed, 12 Jul 2023 12:16:59 -0300 Subject: [PATCH 06/50] fixed url path and field for tool groups feature --- app/serializers/tool_group_serializer.rb | 3 ++- config/routes.rb | 2 +- spec/acceptance/tool_group_spec.rb | 10 +++++----- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/app/serializers/tool_group_serializer.rb b/app/serializers/tool_group_serializer.rb index 7d117b85d..e8e53a0ef 100644 --- a/app/serializers/tool_group_serializer.rb +++ b/app/serializers/tool_group_serializer.rb @@ -1,7 +1,8 @@ # frozen_string_literal: true class ToolGroupSerializer < ActiveModel::Serializer - attributes :id, :name, :suggestions_weight + attributes :id, :name + attribute :suggestions_weight, key: "suggestions-weight" type "tool-group" end diff --git a/config/routes.rb b/config/routes.rb index 35f59a69a..ce667a432 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -30,7 +30,7 @@ resources :custom_manifests, only: [:create, :update, :destroy, :show] - resources :tool_groups, only: [:create, :destroy, :index, :show, :update] + resources :tool_groups, path: "tool-groups", only: [:create, :destroy, :index, :show, :update] patch "user/counters/:id", to: "user_counters#update" # Legacy route for GodTools Android v5.7.0-v6.0.0 patch "user/me/counters/:id", to: "user_counters#update" # Legacy route for GodTools Android v6.0.1+ diff --git a/spec/acceptance/tool_group_spec.rb b/spec/acceptance/tool_group_spec.rb index 25a51f34c..c31589030 100644 --- a/spec/acceptance/tool_group_spec.rb +++ b/spec/acceptance/tool_group_spec.rb @@ -19,7 +19,7 @@ ToolGroup.delete_all end - post "tool_groups" do + post "tool-groups" do let(:attrs) do { name: "test", @@ -48,7 +48,7 @@ end end - get "tool_groups" do + get "tool-groups" do requires_authorization it "list groups" do @@ -58,7 +58,7 @@ end end - get "tool_groups/:id" do + get "tool-groups/:id" do requires_authorization let(:id) { ToolGroup.first.id } @@ -69,7 +69,7 @@ end end - put "tool_groups/:id" do + put "tool-groups/:id" do requires_authorization let(:id) { ToolGroup.first.id } let(:attrs) do @@ -86,7 +86,7 @@ end end - delete "tool_groups/:id" do + delete "tool-groups/:id" do let(:id) { ToolGroup.first.id } requires_authorization From 97bf6f1cbb78ba94df621028a70a5a942eb09f13 Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Thu, 13 Jul 2023 21:42:10 -0300 Subject: [PATCH 07/50] - rule languages * migration * new spec, route, model, controller, serializer --- .../tool_group_rule_languages_controller.rb | 17 ++++++++ app/models/tool_group.rb | 2 + app/models/tool_group_rule_language.rb | 3 ++ .../tool_group_rule_language_serializer.rb | 10 +++++ app/serializers/tool_group_serializer.rb | 2 + config/routes.rb | 2 + ...233746_create_tool_group_rule_languages.rb | 11 +++++ db/schema.rb | 12 +++++- ...ol_group_rule_languages_controller_spec.rb | 40 +++++++++++++++++++ 9 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 app/controllers/tool_group_rule_languages_controller.rb create mode 100644 app/models/tool_group_rule_language.rb create mode 100644 app/serializers/tool_group_rule_language_serializer.rb create mode 100644 db/migrate/20230713233746_create_tool_group_rule_languages.rb create mode 100644 spec/acceptance/tool_group_rule_languages_controller_spec.rb diff --git a/app/controllers/tool_group_rule_languages_controller.rb b/app/controllers/tool_group_rule_languages_controller.rb new file mode 100644 index 000000000..ae6602379 --- /dev/null +++ b/app/controllers/tool_group_rule_languages_controller.rb @@ -0,0 +1,17 @@ +class ToolGroupRuleLanguagesController < ApplicationController + before_action :authorize! + + def create + create_tool_group_rule_language + rescue ActiveRecord::RecordInvalid => e + render json: {error: e.record.errors}, status: :unprocessable_entity + end + + private + + def create_tool_group_rule_language + created = ToolGroupRuleLanguage.create!(permit_params(:tool_group_id, :negative_rule, :languages => [])) + response.headers["Location"] = "tool_groups/#{created.id}" + render json: created, status: :created + end +end diff --git a/app/models/tool_group.rb b/app/models/tool_group.rb index ce0fb2da9..60a250862 100644 --- a/app/models/tool_group.rb +++ b/app/models/tool_group.rb @@ -4,4 +4,6 @@ class ToolGroup < ApplicationRecord validates :name, :suggestions_weight, presence: true validates :name, uniqueness: true + + has_many :tool_group_rule_languages end diff --git a/app/models/tool_group_rule_language.rb b/app/models/tool_group_rule_language.rb new file mode 100644 index 000000000..59d8c0198 --- /dev/null +++ b/app/models/tool_group_rule_language.rb @@ -0,0 +1,3 @@ +class ToolGroupRuleLanguage < ApplicationRecord + belongs_to :tool_group +end diff --git a/app/serializers/tool_group_rule_language_serializer.rb b/app/serializers/tool_group_rule_language_serializer.rb new file mode 100644 index 000000000..69ec7eff9 --- /dev/null +++ b/app/serializers/tool_group_rule_language_serializer.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +class ToolGroupRuleLanguageSerializer < ActiveModel::Serializer + attributes :id, :languages + attribute :negative_rule, key: "negative-rule" + + type "tool-group-rule-language" + + belongs_to :tool_group +end diff --git a/app/serializers/tool_group_serializer.rb b/app/serializers/tool_group_serializer.rb index e8e53a0ef..bf9aacd51 100644 --- a/app/serializers/tool_group_serializer.rb +++ b/app/serializers/tool_group_serializer.rb @@ -5,4 +5,6 @@ class ToolGroupSerializer < ActiveModel::Serializer attribute :suggestions_weight, key: "suggestions-weight" type "tool-group" + + has_many :tool_group_rule_languages end diff --git a/config/routes.rb b/config/routes.rb index ce667a432..9d26bedfd 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -32,6 +32,8 @@ resources :tool_groups, path: "tool-groups", only: [:create, :destroy, :index, :show, :update] + post "tool-groups/:tool_group_id/rule-languages", to: "tool_group_rule_languages#create" + patch "user/counters/:id", to: "user_counters#update" # Legacy route for GodTools Android v5.7.0-v6.0.0 patch "user/me/counters/:id", to: "user_counters#update" # Legacy route for GodTools Android v6.0.1+ get "users/:user_id/counters", to: "user_counters#index" diff --git a/db/migrate/20230713233746_create_tool_group_rule_languages.rb b/db/migrate/20230713233746_create_tool_group_rule_languages.rb new file mode 100644 index 000000000..89ceee3e0 --- /dev/null +++ b/db/migrate/20230713233746_create_tool_group_rule_languages.rb @@ -0,0 +1,11 @@ +class CreateToolGroupRuleLanguages < ActiveRecord::Migration[6.1] + def change + create_table :tool_group_rule_languages do |t| + t.references :tool_group, null: false, foreign_key: true + t.string :languages, array: true, default: [] + t.boolean :negative_rule, default: false + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 349104956..11da91465 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2023_07_10_210235) do +ActiveRecord::Schema.define(version: 2023_07_13_233746) do # These are extensions that must be enabled in order to support this database enable_extension "citext" @@ -222,6 +222,15 @@ t.index ["resource_id", "name"], name: "index_tips_on_resource_id_and_name", unique: true end + create_table "tool_group_rule_languages", force: :cascade do |t| + t.bigint "tool_group_id", null: false + t.string "languages", default: [], array: true + t.boolean "negative_rule", default: false + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["tool_group_id"], name: "index_tool_group_rule_languages_on_tool_group_id" + end + create_table "tool_groups", force: :cascade do |t| t.string "name" t.float "suggestions_weight" @@ -312,6 +321,7 @@ add_foreign_key "resources", "resources", column: "default_variant_id" add_foreign_key "resources", "resources", column: "metatool_id" add_foreign_key "resources", "systems" + add_foreign_key "tool_group_rule_languages", "tool_groups" add_foreign_key "translated_pages", "languages" add_foreign_key "translated_pages", "resources" add_foreign_key "translation_attributes", "translations" diff --git a/spec/acceptance/tool_group_rule_languages_controller_spec.rb b/spec/acceptance/tool_group_rule_languages_controller_spec.rb new file mode 100644 index 000000000..b2e3b114d --- /dev/null +++ b/spec/acceptance/tool_group_rule_languages_controller_spec.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require "acceptance_helper" + +resource "ToolGroupsRuleLanguages" do + header "Accept", "application/vnd.api+json" + header "Content-Type", "application/vnd.api+json" + + let(:raw_post) { params.to_json } + let(:authorization) { AuthToken.generic_token } + + before(:each) do + %i[one].each do |name| + FactoryBot.create(:tool_group, name: name) + end + end + + after(:each) do + ToolGroupRuleLanguage.delete_all + ToolGroup.delete_all + end + + post "tool-groups/:tool_group_id/rule-languages" do + let(:attrs) do + { + languages: ["en", "es"], + tool_group_id: ToolGroup.first.id, + negative_rule: "true" + } + end + + requires_authorization + + it "create tool group" do + do_request data: {type: "tool-group-rule-languages", attributes: attrs} + expect(status).to eq(201) + expect(JSON.parse(response_body)["data"]).not_to be_nil + end + end +end From dbd06f8a2aac2f120b830ce8b9f4df895ca48ef4 Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Fri, 14 Jul 2023 11:40:45 -0300 Subject: [PATCH 08/50] - rule languages * added patch route * added spec and controller --- .../tool_group_rule_languages_controller.rb | 10 +++++++ config/routes.rb | 5 ++-- ...ol_group_rule_languages_controller_spec.rb | 28 +++++++++++++++++-- spec/factories/tool_group_rule_languages.rb | 7 +++++ 4 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 spec/factories/tool_group_rule_languages.rb diff --git a/app/controllers/tool_group_rule_languages_controller.rb b/app/controllers/tool_group_rule_languages_controller.rb index ae6602379..9ea1a7f96 100644 --- a/app/controllers/tool_group_rule_languages_controller.rb +++ b/app/controllers/tool_group_rule_languages_controller.rb @@ -7,6 +7,10 @@ def create render json: {error: e.record.errors}, status: :unprocessable_entity end + def update + update_tool_group_rule_language + end + private def create_tool_group_rule_language @@ -14,4 +18,10 @@ def create_tool_group_rule_language response.headers["Location"] = "tool_groups/#{created.id}" render json: created, status: :created end + + def update_tool_group_rule_language + existing = ToolGroupRuleLanguage.find(params[:id]) + existing.update!(permit_params(:negative_rule, :languages => [])) + render json: existing, status: :accepted + end end diff --git a/config/routes.rb b/config/routes.rb index 9d26bedfd..599f97355 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -31,8 +31,9 @@ resources :custom_manifests, only: [:create, :update, :destroy, :show] resources :tool_groups, path: "tool-groups", only: [:create, :destroy, :index, :show, :update] - - post "tool-groups/:tool_group_id/rule-languages", to: "tool_group_rule_languages#create" + + post "tool-groups/:id/rule-languages", to: "tool_group_rule_languages#create" + patch "tool-groups/:tool_group_id/rule-languages/:id", to: "tool_group_rule_languages#update" patch "user/counters/:id", to: "user_counters#update" # Legacy route for GodTools Android v5.7.0-v6.0.0 patch "user/me/counters/:id", to: "user_counters#update" # Legacy route for GodTools Android v6.0.1+ diff --git a/spec/acceptance/tool_group_rule_languages_controller_spec.rb b/spec/acceptance/tool_group_rule_languages_controller_spec.rb index b2e3b114d..902ccf882 100644 --- a/spec/acceptance/tool_group_rule_languages_controller_spec.rb +++ b/spec/acceptance/tool_group_rule_languages_controller_spec.rb @@ -2,7 +2,7 @@ require "acceptance_helper" -resource "ToolGroupsRuleLanguages" do +resource "ToolGroupRuleLanguages" do header "Accept", "application/vnd.api+json" header "Content-Type", "application/vnd.api+json" @@ -13,6 +13,7 @@ %i[one].each do |name| FactoryBot.create(:tool_group, name: name) end + FactoryBot.create(:tool_group_rule_language, tool_group: ToolGroup.first) end after(:each) do @@ -20,7 +21,7 @@ ToolGroup.delete_all end - post "tool-groups/:tool_group_id/rule-languages" do + post "tool-groups/:id/rule-languages" do let(:attrs) do { languages: ["en", "es"], @@ -37,4 +38,27 @@ expect(JSON.parse(response_body)["data"]).not_to be_nil end end + + patch "tool-groups/:tool_group_id/rule-languages/:id" do + requires_authorization + + let(:tool_group_id) { ToolGroup.first.id } + let(:id) { ToolGroupRuleLanguage.first.id } + let(:languages) { ["fr", "es", "pt"] } + + let(:attrs) do + { + languages: languages, + negative_rule: false + } + end + + it "update tool group" do + do_request data: {type: "tool-group-rule-languages", attributes: attrs} + + expect(status).to be(202) + expect(JSON.parse(response_body)["data"]["attributes"]["languages"]).to eql languages + expect(JSON.parse(response_body)["data"]["attributes"]["negative-rule"]).to eql false + end + end end diff --git a/spec/factories/tool_group_rule_languages.rb b/spec/factories/tool_group_rule_languages.rb new file mode 100644 index 000000000..e5fd326f8 --- /dev/null +++ b/spec/factories/tool_group_rule_languages.rb @@ -0,0 +1,7 @@ +FactoryBot.define do + factory :tool_group_rule_language do + tool_group_id { 1 } + negative_rule { true } + languages { ["en"] } + end +end From 41ec9cad047f6a8a221901cf7f5a1d6329a44e9c Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Fri, 14 Jul 2023 12:15:03 -0300 Subject: [PATCH 09/50] - rule languages * added delete route * added spec and controller action --- .../tool_group_rule_languages_controller.rb | 6 ++++++ config/routes.rb | 1 + .../tool_group_rule_languages_controller_spec.rb | 16 ++++++++++++++-- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/app/controllers/tool_group_rule_languages_controller.rb b/app/controllers/tool_group_rule_languages_controller.rb index 9ea1a7f96..aee3d6398 100644 --- a/app/controllers/tool_group_rule_languages_controller.rb +++ b/app/controllers/tool_group_rule_languages_controller.rb @@ -11,6 +11,12 @@ def update update_tool_group_rule_language end + def destroy + tool_group_rule_language = ToolGroupRuleLanguage.find(params[:id]) + tool_group_rule_language.destroy! + head :no_content + end + private def create_tool_group_rule_language diff --git a/config/routes.rb b/config/routes.rb index 599f97355..d077d1e42 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -34,6 +34,7 @@ post "tool-groups/:id/rule-languages", to: "tool_group_rule_languages#create" patch "tool-groups/:tool_group_id/rule-languages/:id", to: "tool_group_rule_languages#update" + delete "tool-groups/:tool_group_id/rule-languages/:id", to: "tool_group_rule_languages#destroy" patch "user/counters/:id", to: "user_counters#update" # Legacy route for GodTools Android v5.7.0-v6.0.0 patch "user/me/counters/:id", to: "user_counters#update" # Legacy route for GodTools Android v6.0.1+ diff --git a/spec/acceptance/tool_group_rule_languages_controller_spec.rb b/spec/acceptance/tool_group_rule_languages_controller_spec.rb index 902ccf882..a0fcd8af1 100644 --- a/spec/acceptance/tool_group_rule_languages_controller_spec.rb +++ b/spec/acceptance/tool_group_rule_languages_controller_spec.rb @@ -22,6 +22,8 @@ end post "tool-groups/:id/rule-languages" do + requires_authorization + let(:attrs) do { languages: ["en", "es"], @@ -30,8 +32,6 @@ } end - requires_authorization - it "create tool group" do do_request data: {type: "tool-group-rule-languages", attributes: attrs} expect(status).to eq(201) @@ -61,4 +61,16 @@ expect(JSON.parse(response_body)["data"]["attributes"]["negative-rule"]).to eql false end end + + delete "tool-groups/:tool_group_id/rule-languages/:id" do + requires_authorization + + let(:tool_group_id) { ToolGroup.first.id } + let(:id) { ToolGroupRuleLanguage.first.id } + + it "delete tool_group rule language" do + do_request + expect(status).to be(204) + end + end end From 991093a12952657befb5c884dfcfbbfa502deec0 Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Fri, 14 Jul 2023 13:37:03 -0300 Subject: [PATCH 10/50] - moved from "tool_group_rule_languages" to "rule_languages" --- app/controllers/rule_languages_controller.rb | 33 +++++++++++++++++++ .../tool_group_rule_languages_controller.rb | 33 ------------------- app/models/rule_language.rb | 3 ++ app/models/tool_group.rb | 2 +- app/models/tool_group_rule_language.rb | 3 -- ...ializer.rb => rule_language_serializer.rb} | 4 +-- app/serializers/tool_group_serializer.rb | 2 +- config/routes.rb | 6 ++-- ...> 20230713233746_create_rule_languages.rb} | 4 +-- db/schema.rb | 20 +++++------ ...c.rb => rule_languages_controller_spec.rb} | 14 ++++---- ...up_rule_languages.rb => rule_languages.rb} | 2 +- 12 files changed, 63 insertions(+), 63 deletions(-) create mode 100644 app/controllers/rule_languages_controller.rb delete mode 100644 app/controllers/tool_group_rule_languages_controller.rb create mode 100644 app/models/rule_language.rb delete mode 100644 app/models/tool_group_rule_language.rb rename app/serializers/{tool_group_rule_language_serializer.rb => rule_language_serializer.rb} (58%) rename db/migrate/{20230713233746_create_tool_group_rule_languages.rb => 20230713233746_create_rule_languages.rb} (64%) rename spec/acceptance/{tool_group_rule_languages_controller_spec.rb => rule_languages_controller_spec.rb} (79%) rename spec/factories/{tool_group_rule_languages.rb => rule_languages.rb} (73%) diff --git a/app/controllers/rule_languages_controller.rb b/app/controllers/rule_languages_controller.rb new file mode 100644 index 000000000..531334d3e --- /dev/null +++ b/app/controllers/rule_languages_controller.rb @@ -0,0 +1,33 @@ +class RuleLanguagesController < ApplicationController + before_action :authorize! + + def create + create_rule_language + rescue ActiveRecord::RecordInvalid => e + render json: {error: e.record.errors}, status: :unprocessable_entity + end + + def update + update_rule_language + end + + def destroy + rule_language = RuleLanguage.find(params[:id]) + rule_language.destroy! + head :no_content + end + + private + + def create_rule_language + created = RuleLanguage.create!(permit_params(:tool_group_id, :negative_rule, :languages => [])) + response.headers["Location"] = "tool_groups/#{created.id}" + render json: created, status: :created + end + + def update_rule_language + existing = RuleLanguage.find(params[:id]) + existing.update!(permit_params(:negative_rule, :languages => [])) + render json: existing, status: :accepted + end +end diff --git a/app/controllers/tool_group_rule_languages_controller.rb b/app/controllers/tool_group_rule_languages_controller.rb deleted file mode 100644 index aee3d6398..000000000 --- a/app/controllers/tool_group_rule_languages_controller.rb +++ /dev/null @@ -1,33 +0,0 @@ -class ToolGroupRuleLanguagesController < ApplicationController - before_action :authorize! - - def create - create_tool_group_rule_language - rescue ActiveRecord::RecordInvalid => e - render json: {error: e.record.errors}, status: :unprocessable_entity - end - - def update - update_tool_group_rule_language - end - - def destroy - tool_group_rule_language = ToolGroupRuleLanguage.find(params[:id]) - tool_group_rule_language.destroy! - head :no_content - end - - private - - def create_tool_group_rule_language - created = ToolGroupRuleLanguage.create!(permit_params(:tool_group_id, :negative_rule, :languages => [])) - response.headers["Location"] = "tool_groups/#{created.id}" - render json: created, status: :created - end - - def update_tool_group_rule_language - existing = ToolGroupRuleLanguage.find(params[:id]) - existing.update!(permit_params(:negative_rule, :languages => [])) - render json: existing, status: :accepted - end -end diff --git a/app/models/rule_language.rb b/app/models/rule_language.rb new file mode 100644 index 000000000..cef79d79f --- /dev/null +++ b/app/models/rule_language.rb @@ -0,0 +1,3 @@ +class RuleLanguage < ApplicationRecord + belongs_to :tool_group +end diff --git a/app/models/tool_group.rb b/app/models/tool_group.rb index 60a250862..e646cfdcd 100644 --- a/app/models/tool_group.rb +++ b/app/models/tool_group.rb @@ -5,5 +5,5 @@ class ToolGroup < ApplicationRecord validates :name, :suggestions_weight, presence: true validates :name, uniqueness: true - has_many :tool_group_rule_languages + has_many :rule_languages end diff --git a/app/models/tool_group_rule_language.rb b/app/models/tool_group_rule_language.rb deleted file mode 100644 index 59d8c0198..000000000 --- a/app/models/tool_group_rule_language.rb +++ /dev/null @@ -1,3 +0,0 @@ -class ToolGroupRuleLanguage < ApplicationRecord - belongs_to :tool_group -end diff --git a/app/serializers/tool_group_rule_language_serializer.rb b/app/serializers/rule_language_serializer.rb similarity index 58% rename from app/serializers/tool_group_rule_language_serializer.rb rename to app/serializers/rule_language_serializer.rb index 69ec7eff9..742acec27 100644 --- a/app/serializers/tool_group_rule_language_serializer.rb +++ b/app/serializers/rule_language_serializer.rb @@ -1,10 +1,10 @@ # frozen_string_literal: true -class ToolGroupRuleLanguageSerializer < ActiveModel::Serializer +class RuleLanguageSerializer < ActiveModel::Serializer attributes :id, :languages attribute :negative_rule, key: "negative-rule" - type "tool-group-rule-language" + type "rule-language" belongs_to :tool_group end diff --git a/app/serializers/tool_group_serializer.rb b/app/serializers/tool_group_serializer.rb index bf9aacd51..b6b1c81a4 100644 --- a/app/serializers/tool_group_serializer.rb +++ b/app/serializers/tool_group_serializer.rb @@ -6,5 +6,5 @@ class ToolGroupSerializer < ActiveModel::Serializer type "tool-group" - has_many :tool_group_rule_languages + has_many :rule_languages end diff --git a/config/routes.rb b/config/routes.rb index d077d1e42..635651667 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -32,9 +32,9 @@ resources :tool_groups, path: "tool-groups", only: [:create, :destroy, :index, :show, :update] - post "tool-groups/:id/rule-languages", to: "tool_group_rule_languages#create" - patch "tool-groups/:tool_group_id/rule-languages/:id", to: "tool_group_rule_languages#update" - delete "tool-groups/:tool_group_id/rule-languages/:id", to: "tool_group_rule_languages#destroy" + post "tool-groups/:id/rule-languages", to: "rule_languages#create" + patch "tool-groups/:tool_group_id/rule-languages/:id", to: "rule_languages#update" + delete "tool-groups/:tool_group_id/rule-languages/:id", to: "rule_languages#destroy" patch "user/counters/:id", to: "user_counters#update" # Legacy route for GodTools Android v5.7.0-v6.0.0 patch "user/me/counters/:id", to: "user_counters#update" # Legacy route for GodTools Android v6.0.1+ diff --git a/db/migrate/20230713233746_create_tool_group_rule_languages.rb b/db/migrate/20230713233746_create_rule_languages.rb similarity index 64% rename from db/migrate/20230713233746_create_tool_group_rule_languages.rb rename to db/migrate/20230713233746_create_rule_languages.rb index 89ceee3e0..bced23532 100644 --- a/db/migrate/20230713233746_create_tool_group_rule_languages.rb +++ b/db/migrate/20230713233746_create_rule_languages.rb @@ -1,6 +1,6 @@ -class CreateToolGroupRuleLanguages < ActiveRecord::Migration[6.1] +class CreateRuleLanguages < ActiveRecord::Migration[6.1] def change - create_table :tool_group_rule_languages do |t| + create_table :rule_languages do |t| t.references :tool_group, null: false, foreign_key: true t.string :languages, array: true, default: [] t.boolean :negative_rule, default: false diff --git a/db/schema.rb b/db/schema.rb index 11da91465..b1ac3ee61 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -208,6 +208,15 @@ t.index ["system_id"], name: "index_resources_on_system_id" end + create_table "rule_languages", force: :cascade do |t| + t.bigint "tool_group_id", null: false + t.string "languages", default: [], array: true + t.boolean "negative_rule", default: false + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["tool_group_id"], name: "index_rule_languages_on_tool_group_id" + end + create_table "systems", id: :serial, force: :cascade do |t| t.string "name", null: false t.index ["name"], name: "index_systems_on_name", unique: true @@ -222,15 +231,6 @@ t.index ["resource_id", "name"], name: "index_tips_on_resource_id_and_name", unique: true end - create_table "tool_group_rule_languages", force: :cascade do |t| - t.bigint "tool_group_id", null: false - t.string "languages", default: [], array: true - t.boolean "negative_rule", default: false - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false - t.index ["tool_group_id"], name: "index_tool_group_rule_languages_on_tool_group_id" - end - create_table "tool_groups", force: :cascade do |t| t.string "name" t.float "suggestions_weight" @@ -321,7 +321,7 @@ add_foreign_key "resources", "resources", column: "default_variant_id" add_foreign_key "resources", "resources", column: "metatool_id" add_foreign_key "resources", "systems" - add_foreign_key "tool_group_rule_languages", "tool_groups" + add_foreign_key "rule_languages", "tool_groups" add_foreign_key "translated_pages", "languages" add_foreign_key "translated_pages", "resources" add_foreign_key "translation_attributes", "translations" diff --git a/spec/acceptance/tool_group_rule_languages_controller_spec.rb b/spec/acceptance/rule_languages_controller_spec.rb similarity index 79% rename from spec/acceptance/tool_group_rule_languages_controller_spec.rb rename to spec/acceptance/rule_languages_controller_spec.rb index a0fcd8af1..8cdf0a536 100644 --- a/spec/acceptance/tool_group_rule_languages_controller_spec.rb +++ b/spec/acceptance/rule_languages_controller_spec.rb @@ -2,7 +2,7 @@ require "acceptance_helper" -resource "ToolGroupRuleLanguages" do +resource "RuleLanguages" do header "Accept", "application/vnd.api+json" header "Content-Type", "application/vnd.api+json" @@ -13,11 +13,11 @@ %i[one].each do |name| FactoryBot.create(:tool_group, name: name) end - FactoryBot.create(:tool_group_rule_language, tool_group: ToolGroup.first) + FactoryBot.create(:rule_language, tool_group: ToolGroup.first) end after(:each) do - ToolGroupRuleLanguage.delete_all + RuleLanguage.delete_all ToolGroup.delete_all end @@ -33,7 +33,7 @@ end it "create tool group" do - do_request data: {type: "tool-group-rule-languages", attributes: attrs} + do_request data: {type: "rule-languages", attributes: attrs} expect(status).to eq(201) expect(JSON.parse(response_body)["data"]).not_to be_nil end @@ -43,7 +43,7 @@ requires_authorization let(:tool_group_id) { ToolGroup.first.id } - let(:id) { ToolGroupRuleLanguage.first.id } + let(:id) { RuleLanguage.first.id } let(:languages) { ["fr", "es", "pt"] } let(:attrs) do @@ -54,7 +54,7 @@ end it "update tool group" do - do_request data: {type: "tool-group-rule-languages", attributes: attrs} + do_request data: {type: "rule-languages", attributes: attrs} expect(status).to be(202) expect(JSON.parse(response_body)["data"]["attributes"]["languages"]).to eql languages @@ -66,7 +66,7 @@ requires_authorization let(:tool_group_id) { ToolGroup.first.id } - let(:id) { ToolGroupRuleLanguage.first.id } + let(:id) { RuleLanguage.first.id } it "delete tool_group rule language" do do_request diff --git a/spec/factories/tool_group_rule_languages.rb b/spec/factories/rule_languages.rb similarity index 73% rename from spec/factories/tool_group_rule_languages.rb rename to spec/factories/rule_languages.rb index e5fd326f8..32ac47e9a 100644 --- a/spec/factories/tool_group_rule_languages.rb +++ b/spec/factories/rule_languages.rb @@ -1,5 +1,5 @@ FactoryBot.define do - factory :tool_group_rule_language do + factory :rule_language do tool_group_id { 1 } negative_rule { true } languages { ["en"] } From a9979d6a52ae873ec006d3d54520f6eb079e08f0 Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Fri, 14 Jul 2023 15:55:34 -0300 Subject: [PATCH 11/50] fixed to the right type 'tool-group-rule-language' --- app/serializers/rule_language_serializer.rb | 2 +- spec/acceptance/rule_languages_controller_spec.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/serializers/rule_language_serializer.rb b/app/serializers/rule_language_serializer.rb index 742acec27..aab432422 100644 --- a/app/serializers/rule_language_serializer.rb +++ b/app/serializers/rule_language_serializer.rb @@ -4,7 +4,7 @@ class RuleLanguageSerializer < ActiveModel::Serializer attributes :id, :languages attribute :negative_rule, key: "negative-rule" - type "rule-language" + type "tool-group-rule-language" belongs_to :tool_group end diff --git a/spec/acceptance/rule_languages_controller_spec.rb b/spec/acceptance/rule_languages_controller_spec.rb index 8cdf0a536..7c6de7e80 100644 --- a/spec/acceptance/rule_languages_controller_spec.rb +++ b/spec/acceptance/rule_languages_controller_spec.rb @@ -33,7 +33,7 @@ end it "create tool group" do - do_request data: {type: "rule-languages", attributes: attrs} + do_request data: {type: "tool-group-rule-languages", attributes: attrs} expect(status).to eq(201) expect(JSON.parse(response_body)["data"]).not_to be_nil end @@ -54,7 +54,7 @@ end it "update tool group" do - do_request data: {type: "rule-languages", attributes: attrs} + do_request data: {type: "tool-group-rule-languages", attributes: attrs} expect(status).to be(202) expect(JSON.parse(response_body)["data"]["attributes"]["languages"]).to eql languages From 9cb1449098e822af225c381fe17530198b4a6008 Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Fri, 14 Jul 2023 16:36:23 -0300 Subject: [PATCH 12/50] - rule countries * migration * new spec, route, model, controller, serializer --- app/controllers/rule_countries_controller.rb | 33 ++++++++ app/models/rule_country.rb | 3 + app/serializers/rule_country_serializer.rb | 10 +++ app/serializers/tool_group_serializer.rb | 1 + config/routes.rb | 8 +- .../20230714185946_create_rule_countries.rb | 11 +++ db/schema.rb | 12 ++- .../rule_countries_controller_spec.rb | 77 +++++++++++++++++++ .../rule_languages_controller_spec.rb | 6 +- spec/factories/rule_countries.rb | 7 ++ 10 files changed, 163 insertions(+), 5 deletions(-) create mode 100644 app/controllers/rule_countries_controller.rb create mode 100644 app/models/rule_country.rb create mode 100644 app/serializers/rule_country_serializer.rb create mode 100644 db/migrate/20230714185946_create_rule_countries.rb create mode 100644 spec/acceptance/rule_countries_controller_spec.rb create mode 100644 spec/factories/rule_countries.rb diff --git a/app/controllers/rule_countries_controller.rb b/app/controllers/rule_countries_controller.rb new file mode 100644 index 000000000..743c2aac1 --- /dev/null +++ b/app/controllers/rule_countries_controller.rb @@ -0,0 +1,33 @@ +class RuleCountriesController < ApplicationController + before_action :authorize! + + def create + create_rule_country + rescue ActiveRecord::RecordInvalid => e + render json: {error: e.record.errors}, status: :unprocessable_entity + end + + def update + update_rule_country + end + + def destroy + rule_country = RuleCountry.find(params[:id]) + rule_country.destroy! + head :no_content + end + + private + + def create_rule_country + created = RuleCountry.create!(permit_params(:tool_group_id, :negative_rule, :countries => [])) + response.headers["Location"] = "tool_groups/#{created.id}" + render json: created, status: :created + end + + def update_rule_country + existing = RuleCountry.find(params[:id]) + existing.update!(permit_params(:negative_rule, :countries => [])) + render json: existing, status: :accepted + end +end diff --git a/app/models/rule_country.rb b/app/models/rule_country.rb new file mode 100644 index 000000000..eb5485e4f --- /dev/null +++ b/app/models/rule_country.rb @@ -0,0 +1,3 @@ +class RuleCountry < ApplicationRecord + belongs_to :tool_group +end diff --git a/app/serializers/rule_country_serializer.rb b/app/serializers/rule_country_serializer.rb new file mode 100644 index 000000000..3014a3c1a --- /dev/null +++ b/app/serializers/rule_country_serializer.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +class RuleCountrySerializer < ActiveModel::Serializer + attributes :id, :countries + attribute :negative_rule, key: "negative-rule" + + type "tool-group-rule-country" + + belongs_to :tool_group +end diff --git a/app/serializers/tool_group_serializer.rb b/app/serializers/tool_group_serializer.rb index b6b1c81a4..9016a7d11 100644 --- a/app/serializers/tool_group_serializer.rb +++ b/app/serializers/tool_group_serializer.rb @@ -7,4 +7,5 @@ class ToolGroupSerializer < ActiveModel::Serializer type "tool-group" has_many :rule_languages + has_many :rule_countries end diff --git a/config/routes.rb b/config/routes.rb index 635651667..c189aa524 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -31,11 +31,17 @@ resources :custom_manifests, only: [:create, :update, :destroy, :show] resources :tool_groups, path: "tool-groups", only: [:create, :destroy, :index, :show, :update] - + + # Rule Languages post "tool-groups/:id/rule-languages", to: "rule_languages#create" patch "tool-groups/:tool_group_id/rule-languages/:id", to: "rule_languages#update" delete "tool-groups/:tool_group_id/rule-languages/:id", to: "rule_languages#destroy" + # Rule Countries + post "tool-groups/:id/rule-countries", to: "rule_countries#create" + patch "tool-groups/:tool_group_id/rule-countries/:id", to: "rule_countries#update" + delete "tool-groups/:tool_group_id/rule-countries/:id", to: "rule_countries#destroy" + patch "user/counters/:id", to: "user_counters#update" # Legacy route for GodTools Android v5.7.0-v6.0.0 patch "user/me/counters/:id", to: "user_counters#update" # Legacy route for GodTools Android v6.0.1+ get "users/:user_id/counters", to: "user_counters#index" diff --git a/db/migrate/20230714185946_create_rule_countries.rb b/db/migrate/20230714185946_create_rule_countries.rb new file mode 100644 index 000000000..d7c43ce58 --- /dev/null +++ b/db/migrate/20230714185946_create_rule_countries.rb @@ -0,0 +1,11 @@ +class CreateRuleCountries < ActiveRecord::Migration[6.1] + def change + create_table :rule_countries do |t| + t.references :tool_group, null: false, foreign_key: true + t.string :countries, array: true, default: [] + t.boolean :negative_rule, default: false + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index b1ac3ee61..f7540fd4b 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2023_07_13_233746) do +ActiveRecord::Schema.define(version: 2023_07_14_185946) do # These are extensions that must be enabled in order to support this database enable_extension "citext" @@ -208,6 +208,15 @@ t.index ["system_id"], name: "index_resources_on_system_id" end + create_table "rule_countries", force: :cascade do |t| + t.bigint "tool_group_id", null: false + t.string "countries", default: [], array: true + t.boolean "negative_rule", default: false + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["tool_group_id"], name: "index_rule_countries_on_tool_group_id" + end + create_table "rule_languages", force: :cascade do |t| t.bigint "tool_group_id", null: false t.string "languages", default: [], array: true @@ -321,6 +330,7 @@ add_foreign_key "resources", "resources", column: "default_variant_id" add_foreign_key "resources", "resources", column: "metatool_id" add_foreign_key "resources", "systems" + add_foreign_key "rule_countries", "tool_groups" add_foreign_key "rule_languages", "tool_groups" add_foreign_key "translated_pages", "languages" add_foreign_key "translated_pages", "resources" diff --git a/spec/acceptance/rule_countries_controller_spec.rb b/spec/acceptance/rule_countries_controller_spec.rb new file mode 100644 index 000000000..3d071f64b --- /dev/null +++ b/spec/acceptance/rule_countries_controller_spec.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true + +require "acceptance_helper" + +resource "RuleCountries" do + header "Accept", "application/vnd.api+json" + header "Content-Type", "application/vnd.api+json" + + let(:raw_post) { params.to_json } + let(:authorization) { AuthToken.generic_token } + + before(:each) do + %i[one].each do |name| + FactoryBot.create(:tool_group, name: name) + end + FactoryBot.create(:rule_country, tool_group: ToolGroup.first) + end + + after(:each) do + RuleCountry.delete_all + ToolGroup.delete_all + end + + post "tool-groups/:id/rule-countries" do + requires_authorization + + let(:attrs) do + { + countries: ["CA", "FR", "US"], + tool_group_id: ToolGroup.first.id, + negative_rule: "true" + } + end + + it "create rule country" do + do_request data: {type: "tool-group-rule-countries", attributes: attrs} + + expect(status).to eq(201) + expect(JSON.parse(response_body)["data"]).not_to be_nil + end + end + + patch "tool-groups/:tool_group_id/rule-countries/:id" do + requires_authorization + + let(:tool_group_id) { ToolGroup.first.id } + let(:id) { RuleCountry.first.id } + let(:countries) { ["FR", "AR"] } + + let(:attrs) do + { + countries: countries, + negative_rule: false + } + end + + it "update rule country" do + do_request data: {type: "tool-group-rule-countries", attributes: attrs} + + expect(status).to be(202) + expect(JSON.parse(response_body)["data"]["attributes"]["countries"]).to eql countries + expect(JSON.parse(response_body)["data"]["attributes"]["negative-rule"]).to eql false + end + end + + delete "tool-groups/:tool_group_id/rule-countries/:id" do + requires_authorization + + let(:tool_group_id) { ToolGroup.first.id } + let(:id) { RuleCountry.first.id } + + it "delete rule country" do + do_request + expect(status).to be(204) + end + end +end diff --git a/spec/acceptance/rule_languages_controller_spec.rb b/spec/acceptance/rule_languages_controller_spec.rb index 7c6de7e80..21d3de664 100644 --- a/spec/acceptance/rule_languages_controller_spec.rb +++ b/spec/acceptance/rule_languages_controller_spec.rb @@ -32,7 +32,7 @@ } end - it "create tool group" do + it "create rule language" do do_request data: {type: "tool-group-rule-languages", attributes: attrs} expect(status).to eq(201) expect(JSON.parse(response_body)["data"]).not_to be_nil @@ -53,7 +53,7 @@ } end - it "update tool group" do + it "update rule language" do do_request data: {type: "tool-group-rule-languages", attributes: attrs} expect(status).to be(202) @@ -68,7 +68,7 @@ let(:tool_group_id) { ToolGroup.first.id } let(:id) { RuleLanguage.first.id } - it "delete tool_group rule language" do + it "delete rule language" do do_request expect(status).to be(204) end diff --git a/spec/factories/rule_countries.rb b/spec/factories/rule_countries.rb new file mode 100644 index 000000000..fbb970e2e --- /dev/null +++ b/spec/factories/rule_countries.rb @@ -0,0 +1,7 @@ +FactoryBot.define do + factory :rule_country do + tool_group_id { 1 } + negative_rule { true } + countries { ["BR"] } + end +end From da4e93c3cd143bf7c540c9f3771defda04c77fcf Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Fri, 14 Jul 2023 16:55:43 -0300 Subject: [PATCH 13/50] added relationship --- app/models/tool_group.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/models/tool_group.rb b/app/models/tool_group.rb index e646cfdcd..975789f44 100644 --- a/app/models/tool_group.rb +++ b/app/models/tool_group.rb @@ -6,4 +6,5 @@ class ToolGroup < ApplicationRecord validates :name, uniqueness: true has_many :rule_languages + has_many :rule_countries end From 0cf45c77f69387b0e1083282cc1be4ab9431f7be Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Fri, 14 Jul 2023 17:18:21 -0300 Subject: [PATCH 14/50] added validations to avoid duplication of country and language rules --- app/models/rule_country.rb | 2 ++ app/models/rule_language.rb | 2 ++ 2 files changed, 4 insertions(+) diff --git a/app/models/rule_country.rb b/app/models/rule_country.rb index eb5485e4f..66e769417 100644 --- a/app/models/rule_country.rb +++ b/app/models/rule_country.rb @@ -1,3 +1,5 @@ class RuleCountry < ApplicationRecord belongs_to :tool_group + + validates :tool_group_id, uniqueness: { scope: [:countries, :negative_rule], message: "combination already exists" } end diff --git a/app/models/rule_language.rb b/app/models/rule_language.rb index cef79d79f..c73879ba2 100644 --- a/app/models/rule_language.rb +++ b/app/models/rule_language.rb @@ -1,3 +1,5 @@ class RuleLanguage < ApplicationRecord belongs_to :tool_group + + validates :tool_group_id, uniqueness: { scope: [:languages, :negative_rule], message: "combination already exists" } end From f276f7ccf03f70da384aa907680cc724a7223b0c Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Sat, 15 Jul 2023 06:46:33 -0300 Subject: [PATCH 15/50] - rule praxis * added create route * added factory, spec and controller action * added model and serializer --- app/controllers/rule_praxis_controller.rb | 17 ++++++++ app/models/rule_praxi.rb | 9 ++++ app/models/tool_group.rb | 1 + app/serializers/rule_praxi_serializer.rb | 10 +++++ app/serializers/tool_group_serializer.rb | 1 + config/routes.rb | 3 ++ .../20230714202623_create_rule_praxis.rb | 12 ++++++ db/schema.rb | 13 +++++- .../acceptance/rule_praxis_controller_spec.rb | 43 +++++++++++++++++++ spec/factories/rule_praxi.rb | 8 ++++ 10 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 app/controllers/rule_praxis_controller.rb create mode 100644 app/models/rule_praxi.rb create mode 100644 app/serializers/rule_praxi_serializer.rb create mode 100644 db/migrate/20230714202623_create_rule_praxis.rb create mode 100644 spec/acceptance/rule_praxis_controller_spec.rb create mode 100644 spec/factories/rule_praxi.rb diff --git a/app/controllers/rule_praxis_controller.rb b/app/controllers/rule_praxis_controller.rb new file mode 100644 index 000000000..5f373d07b --- /dev/null +++ b/app/controllers/rule_praxis_controller.rb @@ -0,0 +1,17 @@ +class RulePraxisController < ApplicationController + before_action :authorize! + + def create + create_rule_praxis + rescue ActiveRecord::RecordInvalid => e + render json: {error: e.record.errors}, status: :unprocessable_entity + end + + private + + def create_rule_praxis + created = RulePraxi.create!(permit_params(:tool_group_id, :negative_rule, :openness => [], :confidence => [])) + response.headers["Location"] = "tool_groups/#{created.id}" + render json: created, status: :created + end +end diff --git a/app/models/rule_praxi.rb b/app/models/rule_praxi.rb new file mode 100644 index 000000000..51bcdfab7 --- /dev/null +++ b/app/models/rule_praxi.rb @@ -0,0 +1,9 @@ +class RulePraxi < ApplicationRecord + belongs_to :tool_group + + validates :tool_group_id, uniqueness: { scope: [:openness, :confidence], message: "combination already exists" } + + # IMPLEMENT NEXT VALIDATIONS + # openness: Array (int values 1-5, can have multiple values set) + # confidence: Array (int values 1-5, can have multiple values set) +end diff --git a/app/models/tool_group.rb b/app/models/tool_group.rb index 975789f44..799ae0065 100644 --- a/app/models/tool_group.rb +++ b/app/models/tool_group.rb @@ -7,4 +7,5 @@ class ToolGroup < ApplicationRecord has_many :rule_languages has_many :rule_countries + has_many :rule_praxis end diff --git a/app/serializers/rule_praxi_serializer.rb b/app/serializers/rule_praxi_serializer.rb new file mode 100644 index 000000000..ea7c76c9e --- /dev/null +++ b/app/serializers/rule_praxi_serializer.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +class RulePraxiSerializer < ActiveModel::Serializer + attributes :id, :openness, :confidence + attribute :negative_rule, key: "negative-rule" + + type "tool-group-rule-praxis" + + belongs_to :tool_group +end diff --git a/app/serializers/tool_group_serializer.rb b/app/serializers/tool_group_serializer.rb index 9016a7d11..a0368fbff 100644 --- a/app/serializers/tool_group_serializer.rb +++ b/app/serializers/tool_group_serializer.rb @@ -8,4 +8,5 @@ class ToolGroupSerializer < ActiveModel::Serializer has_many :rule_languages has_many :rule_countries + has_many :rule_praxis end diff --git a/config/routes.rb b/config/routes.rb index c189aa524..b5f99765b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -42,6 +42,9 @@ patch "tool-groups/:tool_group_id/rule-countries/:id", to: "rule_countries#update" delete "tool-groups/:tool_group_id/rule-countries/:id", to: "rule_countries#destroy" + # Rule Praxis + post "tool-groups/:id/rule-praxis", to: "rule_praxis#create" + patch "user/counters/:id", to: "user_counters#update" # Legacy route for GodTools Android v5.7.0-v6.0.0 patch "user/me/counters/:id", to: "user_counters#update" # Legacy route for GodTools Android v6.0.1+ get "users/:user_id/counters", to: "user_counters#index" diff --git a/db/migrate/20230714202623_create_rule_praxis.rb b/db/migrate/20230714202623_create_rule_praxis.rb new file mode 100644 index 000000000..1b01c8896 --- /dev/null +++ b/db/migrate/20230714202623_create_rule_praxis.rb @@ -0,0 +1,12 @@ +class CreateRulePraxis < ActiveRecord::Migration[6.1] + def change + create_table :rule_praxis do |t| + t.references :tool_group, null: false, foreign_key: true + t.integer :openness, array: true, default: [] + t.integer :confidence, array: true, default: [] + t.boolean :negative_rule, default: false + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index f7540fd4b..66ec045d6 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2023_07_14_185946) do +ActiveRecord::Schema.define(version: 2023_07_14_202623) do # These are extensions that must be enabled in order to support this database enable_extension "citext" @@ -226,6 +226,16 @@ t.index ["tool_group_id"], name: "index_rule_languages_on_tool_group_id" end + create_table "rule_praxis", force: :cascade do |t| + t.bigint "tool_group_id", null: false + t.integer "openness", default: [], array: true + t.integer "confidence", default: [], array: true + t.boolean "negative_rule", default: false + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["tool_group_id"], name: "index_rule_praxis_on_tool_group_id" + end + create_table "systems", id: :serial, force: :cascade do |t| t.string "name", null: false t.index ["name"], name: "index_systems_on_name", unique: true @@ -332,6 +342,7 @@ add_foreign_key "resources", "systems" add_foreign_key "rule_countries", "tool_groups" add_foreign_key "rule_languages", "tool_groups" + add_foreign_key "rule_praxis", "tool_groups" add_foreign_key "translated_pages", "languages" add_foreign_key "translated_pages", "resources" add_foreign_key "translation_attributes", "translations" diff --git a/spec/acceptance/rule_praxis_controller_spec.rb b/spec/acceptance/rule_praxis_controller_spec.rb new file mode 100644 index 000000000..0b8843678 --- /dev/null +++ b/spec/acceptance/rule_praxis_controller_spec.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +require "acceptance_helper" + +resource "RulePraxis" do + header "Accept", "application/vnd.api+json" + header "Content-Type", "application/vnd.api+json" + + let(:raw_post) { params.to_json } + let(:authorization) { AuthToken.generic_token } + + before(:each) do + %i[one].each do |name| + FactoryBot.create(:tool_group, name: name) + end + FactoryBot.create(:rule_praxi, tool_group: ToolGroup.first) + end + + after(:each) do + RulePraxi.delete_all + ToolGroup.delete_all + end + + post "tool-groups/:id/rule-praxis" do + requires_authorization + + let(:attrs) do + { + tool_group_id: ToolGroup.first.id, + openness: [123, 456], + confidence: [8, 9], + negative_rule: "true" + } + end + + it "create rule praxis" do + do_request data: {type: "tool-group-rule-praxis", attributes: attrs} + + expect(status).to eq(201) + expect(JSON.parse(response_body)["data"]).not_to be_nil + end + end +end \ No newline at end of file diff --git a/spec/factories/rule_praxi.rb b/spec/factories/rule_praxi.rb new file mode 100644 index 000000000..4928f4097 --- /dev/null +++ b/spec/factories/rule_praxi.rb @@ -0,0 +1,8 @@ +FactoryBot.define do + factory :rule_praxi do + tool_group_id { 1 } + negative_rule { true } + openness { [1, 2, 3] } + confidence { [4, 5, 6] } + end +end From d485c4ef0f50de319fefcd90135a403e6562f4b0 Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Mon, 17 Jul 2023 11:43:57 -0300 Subject: [PATCH 16/50] - rule praxis * added patch route * added spec and controller --- app/controllers/rule_praxis_controller.rb | 11 ++++++++ config/routes.rb | 7 +++-- .../acceptance/rule_praxis_controller_spec.rb | 28 ++++++++++++++++++- 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/app/controllers/rule_praxis_controller.rb b/app/controllers/rule_praxis_controller.rb index 5f373d07b..029c54c1a 100644 --- a/app/controllers/rule_praxis_controller.rb +++ b/app/controllers/rule_praxis_controller.rb @@ -7,6 +7,10 @@ def create render json: {error: e.record.errors}, status: :unprocessable_entity end + def update + update_rule_praxis + end + private def create_rule_praxis @@ -14,4 +18,11 @@ def create_rule_praxis response.headers["Location"] = "tool_groups/#{created.id}" render json: created, status: :created end + + def update_rule_praxis + existing = RulePraxi.find(params[:id]) + existing.update!(permit_params(:negative_rule, :openness => [], :confidence => [])) + render json: existing, status: :accepted + end + end diff --git a/config/routes.rb b/config/routes.rb index b5f99765b..aa5f6c80a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -42,9 +42,10 @@ patch "tool-groups/:tool_group_id/rule-countries/:id", to: "rule_countries#update" delete "tool-groups/:tool_group_id/rule-countries/:id", to: "rule_countries#destroy" - # Rule Praxis - post "tool-groups/:id/rule-praxis", to: "rule_praxis#create" - + # Rule Praxis + post "tool-groups/:id/rule-praxis", to: "rule_praxis#create" + patch "tool-groups/:tool_group_id/rule-praxis/:id", to: "rule_praxis#update" + patch "user/counters/:id", to: "user_counters#update" # Legacy route for GodTools Android v5.7.0-v6.0.0 patch "user/me/counters/:id", to: "user_counters#update" # Legacy route for GodTools Android v6.0.1+ get "users/:user_id/counters", to: "user_counters#index" diff --git a/spec/acceptance/rule_praxis_controller_spec.rb b/spec/acceptance/rule_praxis_controller_spec.rb index 0b8843678..c5f707a22 100644 --- a/spec/acceptance/rule_praxis_controller_spec.rb +++ b/spec/acceptance/rule_praxis_controller_spec.rb @@ -40,4 +40,30 @@ expect(JSON.parse(response_body)["data"]).not_to be_nil end end -end \ No newline at end of file + + patch "tool-groups/:tool_group_id/rule-praxis/:id" do + requires_authorization + + let(:tool_group_id) { ToolGroup.first.id } + let(:id) { RulePraxi.first.id } + let(:openness) { [111, 222] } + let(:confidence) { [8, 9] } + + let(:attrs) do + { + openness: openness, + confidence: confidence, + negative_rule: false + } + end + + it "update rule praxis" do + do_request data: {type: "tool-group-rule-praxis", attributes: attrs} + + expect(status).to be(202) + expect(JSON.parse(response_body)["data"]["attributes"]["openness"]).to eql openness + expect(JSON.parse(response_body)["data"]["attributes"]["confidence"]).to eql confidence + expect(JSON.parse(response_body)["data"]["attributes"]["negative-rule"]).to eql false + end + end +end From 75740c81bc1fc50521cf27f34a2383b16494901d Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Mon, 17 Jul 2023 11:50:42 -0300 Subject: [PATCH 17/50] - rule praxis * added delete route * added spec and controller action --- app/controllers/rule_praxis_controller.rb | 6 ++++++ config/routes.rb | 1 + spec/acceptance/rule_praxis_controller_spec.rb | 12 ++++++++++++ 3 files changed, 19 insertions(+) diff --git a/app/controllers/rule_praxis_controller.rb b/app/controllers/rule_praxis_controller.rb index 029c54c1a..89cd25374 100644 --- a/app/controllers/rule_praxis_controller.rb +++ b/app/controllers/rule_praxis_controller.rb @@ -11,6 +11,12 @@ def update update_rule_praxis end + def destroy + rule_praxi = RulePraxi.find(params[:id]) + rule_praxi.destroy! + head :no_content + end + private def create_rule_praxis diff --git a/config/routes.rb b/config/routes.rb index aa5f6c80a..ac8f100f5 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -45,6 +45,7 @@ # Rule Praxis post "tool-groups/:id/rule-praxis", to: "rule_praxis#create" patch "tool-groups/:tool_group_id/rule-praxis/:id", to: "rule_praxis#update" + delete "tool-groups/:tool_group_id/rule-praxis/:id", to: "rule_praxis#destroy" patch "user/counters/:id", to: "user_counters#update" # Legacy route for GodTools Android v5.7.0-v6.0.0 patch "user/me/counters/:id", to: "user_counters#update" # Legacy route for GodTools Android v6.0.1+ diff --git a/spec/acceptance/rule_praxis_controller_spec.rb b/spec/acceptance/rule_praxis_controller_spec.rb index c5f707a22..6341bcb42 100644 --- a/spec/acceptance/rule_praxis_controller_spec.rb +++ b/spec/acceptance/rule_praxis_controller_spec.rb @@ -66,4 +66,16 @@ expect(JSON.parse(response_body)["data"]["attributes"]["negative-rule"]).to eql false end end + + delete "tool-groups/:tool_group_id/rule-praxis/:id" do + requires_authorization + + let(:tool_group_id) { ToolGroup.first.id } + let(:id) { RulePraxi.first.id } + + it "delete rule praxis" do + do_request + expect(status).to be(204) + end + end end From 4d4a41bc30daf1458f49bfb464d491c5b227e995 Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Mon, 17 Jul 2023 12:18:52 -0300 Subject: [PATCH 18/50] added validation for ISO-3166 alpha-2 country codes --- app/models/rule_country.rb | 12 ++++++++ .../rule_countries_controller_spec.rb | 30 +++++++++++++++---- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/app/models/rule_country.rb b/app/models/rule_country.rb index 66e769417..351655b16 100644 --- a/app/models/rule_country.rb +++ b/app/models/rule_country.rb @@ -2,4 +2,16 @@ class RuleCountry < ApplicationRecord belongs_to :tool_group validates :tool_group_id, uniqueness: { scope: [:countries, :negative_rule], message: "combination already exists" } + validate :validate_countries + + private + + def validate_countries + countries.each do |country| + unless country.match?(/\A[A-Z]{2}\z/) + errors.add(:countries, "must contain only ISO-3166 alpha-2 country codes") + break + end + end + end end diff --git a/spec/acceptance/rule_countries_controller_spec.rb b/spec/acceptance/rule_countries_controller_spec.rb index 3d071f64b..b95a3987f 100644 --- a/spec/acceptance/rule_countries_controller_spec.rb +++ b/spec/acceptance/rule_countries_controller_spec.rb @@ -24,7 +24,7 @@ post "tool-groups/:id/rule-countries" do requires_authorization - let(:attrs) do + let(:valid_attrs) do { countries: ["CA", "FR", "US"], tool_group_id: ToolGroup.first.id, @@ -32,11 +32,29 @@ } end - it "create rule country" do - do_request data: {type: "tool-group-rule-countries", attributes: attrs} - - expect(status).to eq(201) - expect(JSON.parse(response_body)["data"]).not_to be_nil + let(:invalid_attrs) do + { + countries: ["1A"], + tool_group_id: ToolGroup.first.id, + negative_rule: "true" + } + end + + context "create rule country" do + it "with valid countries values" do + do_request data: {type: "tool-group-rule-countries", attributes: valid_attrs} + + expect(status).to eq(201) + expect(JSON.parse(response_body)["data"]).not_to be_nil + end + + it "with invalid countries values" do + do_request data: {type: "tool-group-rule-countries", attributes: invalid_attrs} + + expect(status).to eq(422) + expect(JSON.parse(response_body)["data"]).to be_nil + expect(JSON.parse(response_body)["error"]["countries"][0]).to eql "must contain only ISO-3166 alpha-2 country codes" + end end end From 3d5f4aa6bb9b5aeef2b31c57ed29e76132088c9a Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Mon, 17 Jul 2023 12:33:52 -0300 Subject: [PATCH 19/50] small refactoring spec script --- spec/acceptance/rule_countries_controller_spec.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/spec/acceptance/rule_countries_controller_spec.rb b/spec/acceptance/rule_countries_controller_spec.rb index b95a3987f..835547da2 100644 --- a/spec/acceptance/rule_countries_controller_spec.rb +++ b/spec/acceptance/rule_countries_controller_spec.rb @@ -40,15 +40,17 @@ } end - context "create rule country" do - it "with valid countries values" do + context "with valid countries values" do + it "creates a rule country" do do_request data: {type: "tool-group-rule-countries", attributes: valid_attrs} expect(status).to eq(201) expect(JSON.parse(response_body)["data"]).not_to be_nil end + end - it "with invalid countries values" do + context "with invalid countries values" do + it "returns an error" do do_request data: {type: "tool-group-rule-countries", attributes: invalid_attrs} expect(status).to eq(422) From 50aa5dc2a7ba13b9a908f3b507820b23fc6ed92a Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Mon, 17 Jul 2023 13:03:15 -0300 Subject: [PATCH 20/50] fixed brakeman weakness 'Unscoped Find' --- app/controllers/rule_countries_controller.rb | 6 ++++-- app/controllers/rule_languages_controller.rb | 6 ++++-- app/controllers/rule_praxis_controller.rb | 7 ++++--- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/app/controllers/rule_countries_controller.rb b/app/controllers/rule_countries_controller.rb index 743c2aac1..3df442650 100644 --- a/app/controllers/rule_countries_controller.rb +++ b/app/controllers/rule_countries_controller.rb @@ -12,7 +12,8 @@ def update end def destroy - rule_country = RuleCountry.find(params[:id]) + tool_group = ToolGroup.find(params[:tool_group_id]) + rule_country = tool_group.rule_countries.find(params[:id]) rule_country.destroy! head :no_content end @@ -26,7 +27,8 @@ def create_rule_country end def update_rule_country - existing = RuleCountry.find(params[:id]) + tool_group = ToolGroup.find(params[:tool_group_id]) + existing = tool_group.rule_countries.find(params[:id]) existing.update!(permit_params(:negative_rule, :countries => [])) render json: existing, status: :accepted end diff --git a/app/controllers/rule_languages_controller.rb b/app/controllers/rule_languages_controller.rb index 531334d3e..f9bebb2ad 100644 --- a/app/controllers/rule_languages_controller.rb +++ b/app/controllers/rule_languages_controller.rb @@ -12,7 +12,8 @@ def update end def destroy - rule_language = RuleLanguage.find(params[:id]) + tool_group = ToolGroup.find(params[:tool_group_id]) + rule_language = tool_group.rule_languages.find(params[:id]) rule_language.destroy! head :no_content end @@ -26,7 +27,8 @@ def create_rule_language end def update_rule_language - existing = RuleLanguage.find(params[:id]) + tool_group = ToolGroup.find(params[:tool_group_id]) + existing = tool_group.rule_languages.find(params[:id]) existing.update!(permit_params(:negative_rule, :languages => [])) render json: existing, status: :accepted end diff --git a/app/controllers/rule_praxis_controller.rb b/app/controllers/rule_praxis_controller.rb index 89cd25374..b31a57da0 100644 --- a/app/controllers/rule_praxis_controller.rb +++ b/app/controllers/rule_praxis_controller.rb @@ -12,7 +12,8 @@ def update end def destroy - rule_praxi = RulePraxi.find(params[:id]) + tool_group = ToolGroup.find(params[:tool_group_id]) + rule_praxi = tool_group.rule_praxis.find(params[:id]) rule_praxi.destroy! head :no_content end @@ -26,9 +27,9 @@ def create_rule_praxis end def update_rule_praxis - existing = RulePraxi.find(params[:id]) + tool_group = ToolGroup.find(params[:tool_group_id]) + existing = tool_group.rule_praxis.find(params[:id]) existing.update!(permit_params(:negative_rule, :openness => [], :confidence => [])) render json: existing, status: :accepted end - end From 827f33343aa32ff3b5465413286e6bd60ea0cb05 Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Mon, 17 Jul 2023 13:30:37 -0300 Subject: [PATCH 21/50] fixing linting code --- app/controllers/rule_countries_controller.rb | 4 ++-- app/controllers/rule_languages_controller.rb | 4 ++-- app/controllers/rule_praxis_controller.rb | 4 ++-- app/models/rule_country.rb | 4 ++-- app/models/rule_language.rb | 2 +- app/models/rule_praxi.rb | 6 +++--- spec/acceptance/rule_countries_controller_spec.rb | 2 +- spec/acceptance/rule_languages_controller_spec.rb | 2 +- spec/acceptance/rule_praxis_controller_spec.rb | 2 +- spec/factories/rule_countries.rb | 2 +- spec/factories/rule_languages.rb | 2 +- spec/factories/rule_praxi.rb | 2 +- 12 files changed, 18 insertions(+), 18 deletions(-) diff --git a/app/controllers/rule_countries_controller.rb b/app/controllers/rule_countries_controller.rb index 3df442650..912f66475 100644 --- a/app/controllers/rule_countries_controller.rb +++ b/app/controllers/rule_countries_controller.rb @@ -21,7 +21,7 @@ def destroy private def create_rule_country - created = RuleCountry.create!(permit_params(:tool_group_id, :negative_rule, :countries => [])) + created = RuleCountry.create!(permit_params(:tool_group_id, :negative_rule, countries: [])) response.headers["Location"] = "tool_groups/#{created.id}" render json: created, status: :created end @@ -29,7 +29,7 @@ def create_rule_country def update_rule_country tool_group = ToolGroup.find(params[:tool_group_id]) existing = tool_group.rule_countries.find(params[:id]) - existing.update!(permit_params(:negative_rule, :countries => [])) + existing.update!(permit_params(:negative_rule, countries: [])) render json: existing, status: :accepted end end diff --git a/app/controllers/rule_languages_controller.rb b/app/controllers/rule_languages_controller.rb index f9bebb2ad..4211304c0 100644 --- a/app/controllers/rule_languages_controller.rb +++ b/app/controllers/rule_languages_controller.rb @@ -21,7 +21,7 @@ def destroy private def create_rule_language - created = RuleLanguage.create!(permit_params(:tool_group_id, :negative_rule, :languages => [])) + created = RuleLanguage.create!(permit_params(:tool_group_id, :negative_rule, languages: [])) response.headers["Location"] = "tool_groups/#{created.id}" render json: created, status: :created end @@ -29,7 +29,7 @@ def create_rule_language def update_rule_language tool_group = ToolGroup.find(params[:tool_group_id]) existing = tool_group.rule_languages.find(params[:id]) - existing.update!(permit_params(:negative_rule, :languages => [])) + existing.update!(permit_params(:negative_rule, languages: [])) render json: existing, status: :accepted end end diff --git a/app/controllers/rule_praxis_controller.rb b/app/controllers/rule_praxis_controller.rb index b31a57da0..380185c12 100644 --- a/app/controllers/rule_praxis_controller.rb +++ b/app/controllers/rule_praxis_controller.rb @@ -21,7 +21,7 @@ def destroy private def create_rule_praxis - created = RulePraxi.create!(permit_params(:tool_group_id, :negative_rule, :openness => [], :confidence => [])) + created = RulePraxi.create!(permit_params(:tool_group_id, :negative_rule, openness: [], confidence: [])) response.headers["Location"] = "tool_groups/#{created.id}" render json: created, status: :created end @@ -29,7 +29,7 @@ def create_rule_praxis def update_rule_praxis tool_group = ToolGroup.find(params[:tool_group_id]) existing = tool_group.rule_praxis.find(params[:id]) - existing.update!(permit_params(:negative_rule, :openness => [], :confidence => [])) + existing.update!(permit_params(:negative_rule, openness: [], confidence: [])) render json: existing, status: :accepted end end diff --git a/app/models/rule_country.rb b/app/models/rule_country.rb index 351655b16..a3f0e8007 100644 --- a/app/models/rule_country.rb +++ b/app/models/rule_country.rb @@ -1,7 +1,7 @@ class RuleCountry < ApplicationRecord belongs_to :tool_group - - validates :tool_group_id, uniqueness: { scope: [:countries, :negative_rule], message: "combination already exists" } + + validates :tool_group_id, uniqueness: {scope: [:countries, :negative_rule], message: "combination already exists"} validate :validate_countries private diff --git a/app/models/rule_language.rb b/app/models/rule_language.rb index c73879ba2..1cbeaba66 100644 --- a/app/models/rule_language.rb +++ b/app/models/rule_language.rb @@ -1,5 +1,5 @@ class RuleLanguage < ApplicationRecord belongs_to :tool_group - validates :tool_group_id, uniqueness: { scope: [:languages, :negative_rule], message: "combination already exists" } + validates :tool_group_id, uniqueness: {scope: [:languages, :negative_rule], message: "combination already exists"} end diff --git a/app/models/rule_praxi.rb b/app/models/rule_praxi.rb index 51bcdfab7..9445273fc 100644 --- a/app/models/rule_praxi.rb +++ b/app/models/rule_praxi.rb @@ -1,8 +1,8 @@ class RulePraxi < ApplicationRecord belongs_to :tool_group - - validates :tool_group_id, uniqueness: { scope: [:openness, :confidence], message: "combination already exists" } - + + validates :tool_group_id, uniqueness: {scope: [:openness, :confidence], message: "combination already exists"} + # IMPLEMENT NEXT VALIDATIONS # openness: Array (int values 1-5, can have multiple values set) # confidence: Array (int values 1-5, can have multiple values set) diff --git a/spec/acceptance/rule_countries_controller_spec.rb b/spec/acceptance/rule_countries_controller_spec.rb index 835547da2..1c394f7ba 100644 --- a/spec/acceptance/rule_countries_controller_spec.rb +++ b/spec/acceptance/rule_countries_controller_spec.rb @@ -76,7 +76,7 @@ it "update rule country" do do_request data: {type: "tool-group-rule-countries", attributes: attrs} - + expect(status).to be(202) expect(JSON.parse(response_body)["data"]["attributes"]["countries"]).to eql countries expect(JSON.parse(response_body)["data"]["attributes"]["negative-rule"]).to eql false diff --git a/spec/acceptance/rule_languages_controller_spec.rb b/spec/acceptance/rule_languages_controller_spec.rb index 21d3de664..bee5e9628 100644 --- a/spec/acceptance/rule_languages_controller_spec.rb +++ b/spec/acceptance/rule_languages_controller_spec.rb @@ -55,7 +55,7 @@ it "update rule language" do do_request data: {type: "tool-group-rule-languages", attributes: attrs} - + expect(status).to be(202) expect(JSON.parse(response_body)["data"]["attributes"]["languages"]).to eql languages expect(JSON.parse(response_body)["data"]["attributes"]["negative-rule"]).to eql false diff --git a/spec/acceptance/rule_praxis_controller_spec.rb b/spec/acceptance/rule_praxis_controller_spec.rb index 6341bcb42..ad731caa0 100644 --- a/spec/acceptance/rule_praxis_controller_spec.rb +++ b/spec/acceptance/rule_praxis_controller_spec.rb @@ -35,7 +35,7 @@ it "create rule praxis" do do_request data: {type: "tool-group-rule-praxis", attributes: attrs} - + expect(status).to eq(201) expect(JSON.parse(response_body)["data"]).not_to be_nil end diff --git a/spec/factories/rule_countries.rb b/spec/factories/rule_countries.rb index fbb970e2e..61addb331 100644 --- a/spec/factories/rule_countries.rb +++ b/spec/factories/rule_countries.rb @@ -1,7 +1,7 @@ FactoryBot.define do factory :rule_country do tool_group_id { 1 } - negative_rule { true } + negative_rule { true } countries { ["BR"] } end end diff --git a/spec/factories/rule_languages.rb b/spec/factories/rule_languages.rb index 32ac47e9a..a62a8c9de 100644 --- a/spec/factories/rule_languages.rb +++ b/spec/factories/rule_languages.rb @@ -1,7 +1,7 @@ FactoryBot.define do factory :rule_language do tool_group_id { 1 } - negative_rule { true } + negative_rule { true } languages { ["en"] } end end diff --git a/spec/factories/rule_praxi.rb b/spec/factories/rule_praxi.rb index 4928f4097..391ebb34f 100644 --- a/spec/factories/rule_praxi.rb +++ b/spec/factories/rule_praxi.rb @@ -1,7 +1,7 @@ FactoryBot.define do factory :rule_praxi do tool_group_id { 1 } - negative_rule { true } + negative_rule { true } openness { [1, 2, 3] } confidence { [4, 5, 6] } end From 948347a590a5579f81e0bd5017b0ac63b565f302 Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Mon, 17 Jul 2023 15:28:01 -0300 Subject: [PATCH 22/50] - rule praxis * test for validates not repeated openness and confidence values --- .../acceptance/rule_praxis_controller_spec.rb | 46 +++++++++++++++---- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/spec/acceptance/rule_praxis_controller_spec.rb b/spec/acceptance/rule_praxis_controller_spec.rb index ad731caa0..a5671ebc5 100644 --- a/spec/acceptance/rule_praxis_controller_spec.rb +++ b/spec/acceptance/rule_praxis_controller_spec.rb @@ -23,21 +23,51 @@ post "tool-groups/:id/rule-praxis" do requires_authorization + let(:tool_group_id) {ToolGroup.first.id} + let(:openness) {[1, 2]} + let(:confidence) {[4, 5]} - let(:attrs) do + let(:valid_attrs) do { - tool_group_id: ToolGroup.first.id, - openness: [123, 456], - confidence: [8, 9], + tool_group_id: tool_group_id, + openness: openness, + confidence: confidence, negative_rule: "true" } end - it "create rule praxis" do - do_request data: {type: "tool-group-rule-praxis", attributes: attrs} + let(:repeated_attrs) do + { + tool_group_id: tool_group_id, + openness: openness, + confidence: confidence, + negative_rule: "true" + } + end + + context "with valid openness and confidence values" do + it "create rule praxis" do + do_request data: {type: "tool-group-rule-praxis", attributes: valid_attrs} + + expect(status).to eq(201) + expect(JSON.parse(response_body)["data"]).not_to be_nil + end + end + + context "with repeated openness and confidence values" do + before do + FactoryBot.create(:rule_praxi, tool_group_id: tool_group_id, + openness: openness, + confidence: confidence) + end + + it "returns an error" do + do_request data: {type: "tool-group-rule-praxis", attributes: repeated_attrs} - expect(status).to eq(201) - expect(JSON.parse(response_body)["data"]).not_to be_nil + expect(status).to eq(422) + expect(JSON.parse(response_body)["data"]).to be_nil + expect(JSON.parse(response_body)["error"]["tool_group_id"][0]).to eql "combination already exists" + end end end From 8656d361a7e22fb92c0c1efe761305a13e3b3bd9 Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Mon, 17 Jul 2023 15:34:23 -0300 Subject: [PATCH 23/50] fixed linter --- app/models/rule_praxi.rb | 11 ++++++++--- spec/acceptance/rule_praxis_controller_spec.rb | 10 ++++------ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/app/models/rule_praxi.rb b/app/models/rule_praxi.rb index 9445273fc..e291fc213 100644 --- a/app/models/rule_praxi.rb +++ b/app/models/rule_praxi.rb @@ -2,8 +2,13 @@ class RulePraxi < ApplicationRecord belongs_to :tool_group validates :tool_group_id, uniqueness: {scope: [:openness, :confidence], message: "combination already exists"} + validate :validate_openness_or_confidence - # IMPLEMENT NEXT VALIDATIONS - # openness: Array (int values 1-5, can have multiple values set) - # confidence: Array (int values 1-5, can have multiple values set) + private + + def validate_openness_or_confidence + if openness.blank? && confidence.blank? + errors.add(:base, "Either 'openness' or 'confidence' must be present") + end + end end diff --git a/spec/acceptance/rule_praxis_controller_spec.rb b/spec/acceptance/rule_praxis_controller_spec.rb index a5671ebc5..8e1e13be0 100644 --- a/spec/acceptance/rule_praxis_controller_spec.rb +++ b/spec/acceptance/rule_praxis_controller_spec.rb @@ -23,9 +23,9 @@ post "tool-groups/:id/rule-praxis" do requires_authorization - let(:tool_group_id) {ToolGroup.first.id} - let(:openness) {[1, 2]} - let(:confidence) {[4, 5]} + let(:tool_group_id) { ToolGroup.first.id } + let(:openness) { [1, 2] } + let(:confidence) { [4, 5] } let(:valid_attrs) do { @@ -56,9 +56,7 @@ context "with repeated openness and confidence values" do before do - FactoryBot.create(:rule_praxi, tool_group_id: tool_group_id, - openness: openness, - confidence: confidence) + FactoryBot.create(:rule_praxi, tool_group_id: tool_group_id, openness: openness, confidence: confidence) end it "returns an error" do From d8d260d349284f111c2e8285cd806f9cc5515976 Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Mon, 17 Jul 2023 15:54:24 -0300 Subject: [PATCH 24/50] - rule praxis * added validation to avoid empties :openness and :confidence attributes --- app/models/rule_praxi.rb | 6 +++++- .../acceptance/rule_praxis_controller_spec.rb | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/app/models/rule_praxi.rb b/app/models/rule_praxi.rb index e291fc213..a646b8fb7 100644 --- a/app/models/rule_praxi.rb +++ b/app/models/rule_praxi.rb @@ -2,10 +2,14 @@ class RulePraxi < ApplicationRecord belongs_to :tool_group validates :tool_group_id, uniqueness: {scope: [:openness, :confidence], message: "combination already exists"} - validate :validate_openness_or_confidence + validate :validate_openness_or_confidence, if: :tool_group_id_uniqueness_passed? private + def tool_group_id_uniqueness_passed? + errors[:tool_group_id].empty? + end + def validate_openness_or_confidence if openness.blank? && confidence.blank? errors.add(:base, "Either 'openness' or 'confidence' must be present") diff --git a/spec/acceptance/rule_praxis_controller_spec.rb b/spec/acceptance/rule_praxis_controller_spec.rb index 8e1e13be0..c142ca786 100644 --- a/spec/acceptance/rule_praxis_controller_spec.rb +++ b/spec/acceptance/rule_praxis_controller_spec.rb @@ -45,6 +45,15 @@ } end + let(:empty_attrs) do + { + tool_group_id: tool_group_id, + openness: [], + confidence: [], + negative_rule: "true" + } + end + context "with valid openness and confidence values" do it "create rule praxis" do do_request data: {type: "tool-group-rule-praxis", attributes: valid_attrs} @@ -67,6 +76,16 @@ expect(JSON.parse(response_body)["error"]["tool_group_id"][0]).to eql "combination already exists" end end + + context "with empty or null openness and confidence values" do + it "returns an error" do + do_request data: {type: "tool-group-rule-praxis", attributes: empty_attrs} + + expect(status).to eq(422) + expect(JSON.parse(response_body)["data"]).to be_nil + expect(JSON.parse(response_body)["error"]["base"][0]).to eql "Either 'openness' or 'confidence' must be present" + end + end end patch "tool-groups/:tool_group_id/rule-praxis/:id" do From 8279b47e0ef1d1549de06881742e27d9f5d2b0dd Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Mon, 17 Jul 2023 16:14:33 -0300 Subject: [PATCH 25/50] - rule praxis * added validation to avoid non valid values for :openness and :confidence attributes --- app/models/rule_praxi.rb | 20 ++++++++- .../acceptance/rule_praxis_controller_spec.rb | 42 ++++++++++++++++++- spec/factories/rule_praxi.rb | 2 +- 3 files changed, 60 insertions(+), 4 deletions(-) diff --git a/app/models/rule_praxi.rb b/app/models/rule_praxi.rb index a646b8fb7..42ee713ae 100644 --- a/app/models/rule_praxi.rb +++ b/app/models/rule_praxi.rb @@ -2,7 +2,9 @@ class RulePraxi < ApplicationRecord belongs_to :tool_group validates :tool_group_id, uniqueness: {scope: [:openness, :confidence], message: "combination already exists"} - validate :validate_openness_or_confidence, if: :tool_group_id_uniqueness_passed? + + validate :validate_openness_and_confidence_values, if: :tool_group_id_uniqueness_passed? + validate :validate_openness_or_confidence #, if: :validate_openness_and_confidence_values? private @@ -15,4 +17,20 @@ def validate_openness_or_confidence errors.add(:base, "Either 'openness' or 'confidence' must be present") end end + + def validate_openness_and_confidence_values + validate_array_values(openness, "openness") + validate_array_values(confidence, "confidence") + end + + def validate_array_values(attribute_values, attribute_name) + return if attribute_values.blank? + + attribute_values.each do |value| + unless value.is_a?(Integer) && (1..5).cover?(value) + errors.add(attribute_name, "must contain integer values between 1 and 5 or an empty array") + break + end + end + end end diff --git a/spec/acceptance/rule_praxis_controller_spec.rb b/spec/acceptance/rule_praxis_controller_spec.rb index c142ca786..dbc0bfb8d 100644 --- a/spec/acceptance/rule_praxis_controller_spec.rb +++ b/spec/acceptance/rule_praxis_controller_spec.rb @@ -54,6 +54,24 @@ } end + let(:non_valid_openness_attr) do + { + tool_group_id: tool_group_id, + openness: [0], + confidence: [1, 2], + negative_rule: "true" + } + end + + let(:non_valid_confidence_attr) do + { + tool_group_id: tool_group_id, + openness: [1, 2, 3, 4, 5], + confidence: [6], + negative_rule: "true" + } + end + context "with valid openness and confidence values" do it "create rule praxis" do do_request data: {type: "tool-group-rule-praxis", attributes: valid_attrs} @@ -86,6 +104,26 @@ expect(JSON.parse(response_body)["error"]["base"][0]).to eql "Either 'openness' or 'confidence' must be present" end end + + context "with non valid openness values" do + it "returns an error" do + do_request data: {type: "tool-group-rule-praxis", attributes: non_valid_openness_attr} + + expect(status).to eq(422) + expect(JSON.parse(response_body)["data"]).to be_nil + expect(JSON.parse(response_body)["error"]["openness"][0]).to eql "must contain integer values between 1 and 5 or an empty array" + end + end + + context "with non valid confidence values" do + it "returns an error" do + do_request data: {type: "tool-group-rule-praxis", attributes: non_valid_confidence_attr} + + expect(status).to eq(422) + expect(JSON.parse(response_body)["data"]).to be_nil + expect(JSON.parse(response_body)["error"]["confidence"][0]).to eql "must contain integer values between 1 and 5 or an empty array" + end + end end patch "tool-groups/:tool_group_id/rule-praxis/:id" do @@ -93,8 +131,8 @@ let(:tool_group_id) { ToolGroup.first.id } let(:id) { RulePraxi.first.id } - let(:openness) { [111, 222] } - let(:confidence) { [8, 9] } + let(:openness) { [1, 2] } + let(:confidence) { [3, 4] } let(:attrs) do { diff --git a/spec/factories/rule_praxi.rb b/spec/factories/rule_praxi.rb index 391ebb34f..e33217595 100644 --- a/spec/factories/rule_praxi.rb +++ b/spec/factories/rule_praxi.rb @@ -3,6 +3,6 @@ tool_group_id { 1 } negative_rule { true } openness { [1, 2, 3] } - confidence { [4, 5, 6] } + confidence { [4, 5] } end end From 89fae19900d86c5d73dc4595b0ed3167e6fd4a17 Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Mon, 17 Jul 2023 16:23:18 -0300 Subject: [PATCH 26/50] only run validations in current line if previous validation already passed --- app/models/rule_praxi.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/models/rule_praxi.rb b/app/models/rule_praxi.rb index 42ee713ae..c27097821 100644 --- a/app/models/rule_praxi.rb +++ b/app/models/rule_praxi.rb @@ -4,7 +4,7 @@ class RulePraxi < ApplicationRecord validates :tool_group_id, uniqueness: {scope: [:openness, :confidence], message: "combination already exists"} validate :validate_openness_and_confidence_values, if: :tool_group_id_uniqueness_passed? - validate :validate_openness_or_confidence #, if: :validate_openness_and_confidence_values? + validate :validate_openness_or_confidence, if: :previous_validations_pass? private @@ -33,4 +33,8 @@ def validate_array_values(attribute_values, attribute_name) end end end + + def previous_validations_pass? + errors.empty? + end end From 3f07fd4e07c2df90add05ce43453f236f1160772 Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Mon, 17 Jul 2023 16:32:26 -0300 Subject: [PATCH 27/50] model rule praxis refactor --- app/models/rule_praxi.rb | 36 ++++++++++-------------------------- 1 file changed, 10 insertions(+), 26 deletions(-) diff --git a/app/models/rule_praxi.rb b/app/models/rule_praxi.rb index c27097821..f8a8d22cb 100644 --- a/app/models/rule_praxi.rb +++ b/app/models/rule_praxi.rb @@ -2,39 +2,23 @@ class RulePraxi < ApplicationRecord belongs_to :tool_group validates :tool_group_id, uniqueness: {scope: [:openness, :confidence], message: "combination already exists"} + validate :validate_openness_or_confidence, if: :no_openness_or_confidence? - validate :validate_openness_and_confidence_values, if: :tool_group_id_uniqueness_passed? - validate :validate_openness_or_confidence, if: :previous_validations_pass? + validates_each :openness, :confidence do |record, attr, value| + next if value.blank? - private - - def tool_group_id_uniqueness_passed? - errors[:tool_group_id].empty? - end - - def validate_openness_or_confidence - if openness.blank? && confidence.blank? - errors.add(:base, "Either 'openness' or 'confidence' must be present") + value.each do |v| + record.errors.add(attr, "must contain integer values between 1 and 5 or an empty array") unless v.is_a?(Integer) && (1..5).cover?(v) end end - def validate_openness_and_confidence_values - validate_array_values(openness, "openness") - validate_array_values(confidence, "confidence") - end - - def validate_array_values(attribute_values, attribute_name) - return if attribute_values.blank? + private - attribute_values.each do |value| - unless value.is_a?(Integer) && (1..5).cover?(value) - errors.add(attribute_name, "must contain integer values between 1 and 5 or an empty array") - break - end - end + def no_openness_or_confidence? + openness.blank? && confidence.blank? end - def previous_validations_pass? - errors.empty? + def validate_openness_or_confidence + errors.add(:base, "Either 'openness' or 'confidence' must be present") end end From 0ee2a267b7b03c7a9480b4f865809dddd33b5413 Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Mon, 17 Jul 2023 18:46:24 -0300 Subject: [PATCH 28/50] fixed path for rules routes and serialization of has_many relationships --- app/serializers/tool_group_serializer.rb | 18 +++++++++++++++--- config/routes.rb | 18 +++++++++--------- .../rule_countries_controller_spec.rb | 12 ++++++------ .../rule_languages_controller_spec.rb | 10 +++++----- spec/acceptance/rule_praxis_controller_spec.rb | 18 +++++++++--------- 5 files changed, 44 insertions(+), 32 deletions(-) diff --git a/app/serializers/tool_group_serializer.rb b/app/serializers/tool_group_serializer.rb index a0368fbff..4e497114b 100644 --- a/app/serializers/tool_group_serializer.rb +++ b/app/serializers/tool_group_serializer.rb @@ -6,7 +6,19 @@ class ToolGroupSerializer < ActiveModel::Serializer type "tool-group" - has_many :rule_languages - has_many :rule_countries - has_many :rule_praxis + has_many :rule_languages, key: "rules-language" + has_many :rule_countries, key: "rules-country" + has_many :rule_praxis, key: "rules-praxis" + + def custom_rule_languages + object.rule_languages + end + + def custom_rule_countries + object.rule_countries + end + + def custom_rule_praxis + object.rule_praxis + end end diff --git a/config/routes.rb b/config/routes.rb index ac8f100f5..d381e68f0 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -33,19 +33,19 @@ resources :tool_groups, path: "tool-groups", only: [:create, :destroy, :index, :show, :update] # Rule Languages - post "tool-groups/:id/rule-languages", to: "rule_languages#create" - patch "tool-groups/:tool_group_id/rule-languages/:id", to: "rule_languages#update" - delete "tool-groups/:tool_group_id/rule-languages/:id", to: "rule_languages#destroy" + resources :tool_groups, path: "tool-groups", only: [] do + resources :rule_languages, path: "rules-language", only: [:create, :destroy, :update] + end # Rule Countries - post "tool-groups/:id/rule-countries", to: "rule_countries#create" - patch "tool-groups/:tool_group_id/rule-countries/:id", to: "rule_countries#update" - delete "tool-groups/:tool_group_id/rule-countries/:id", to: "rule_countries#destroy" + resources :tool_groups, path: "tool-groups", only: [] do + resources :rule_countries, path: "rules-country", only: [:create, :destroy, :update] + end # Rule Praxis - post "tool-groups/:id/rule-praxis", to: "rule_praxis#create" - patch "tool-groups/:tool_group_id/rule-praxis/:id", to: "rule_praxis#update" - delete "tool-groups/:tool_group_id/rule-praxis/:id", to: "rule_praxis#destroy" + resources :tool_groups, path: "tool-groups", only: [] do + resources :rule_praxis, path: "rules-praxis", only: [:create, :destroy, :update] + end patch "user/counters/:id", to: "user_counters#update" # Legacy route for GodTools Android v5.7.0-v6.0.0 patch "user/me/counters/:id", to: "user_counters#update" # Legacy route for GodTools Android v6.0.1+ diff --git a/spec/acceptance/rule_countries_controller_spec.rb b/spec/acceptance/rule_countries_controller_spec.rb index 1c394f7ba..bff1f9fa5 100644 --- a/spec/acceptance/rule_countries_controller_spec.rb +++ b/spec/acceptance/rule_countries_controller_spec.rb @@ -21,7 +21,7 @@ ToolGroup.delete_all end - post "tool-groups/:id/rule-countries" do + post "tool-groups/:id/rules-country" do requires_authorization let(:valid_attrs) do @@ -42,7 +42,7 @@ context "with valid countries values" do it "creates a rule country" do - do_request data: {type: "tool-group-rule-countries", attributes: valid_attrs} + do_request data: {type: "tool-group-rules-country", attributes: valid_attrs} expect(status).to eq(201) expect(JSON.parse(response_body)["data"]).not_to be_nil @@ -51,7 +51,7 @@ context "with invalid countries values" do it "returns an error" do - do_request data: {type: "tool-group-rule-countries", attributes: invalid_attrs} + do_request data: {type: "tool-group-rules-country", attributes: invalid_attrs} expect(status).to eq(422) expect(JSON.parse(response_body)["data"]).to be_nil @@ -60,7 +60,7 @@ end end - patch "tool-groups/:tool_group_id/rule-countries/:id" do + patch "tool-groups/:tool_group_id/rules-country/:id" do requires_authorization let(:tool_group_id) { ToolGroup.first.id } @@ -75,7 +75,7 @@ end it "update rule country" do - do_request data: {type: "tool-group-rule-countries", attributes: attrs} + do_request data: {type: "tool-group-rules-country", attributes: attrs} expect(status).to be(202) expect(JSON.parse(response_body)["data"]["attributes"]["countries"]).to eql countries @@ -83,7 +83,7 @@ end end - delete "tool-groups/:tool_group_id/rule-countries/:id" do + delete "tool-groups/:tool_group_id/rules-country/:id" do requires_authorization let(:tool_group_id) { ToolGroup.first.id } diff --git a/spec/acceptance/rule_languages_controller_spec.rb b/spec/acceptance/rule_languages_controller_spec.rb index bee5e9628..66aa2b5c4 100644 --- a/spec/acceptance/rule_languages_controller_spec.rb +++ b/spec/acceptance/rule_languages_controller_spec.rb @@ -21,7 +21,7 @@ ToolGroup.delete_all end - post "tool-groups/:id/rule-languages" do + post "tool-groups/:id/rules-language" do requires_authorization let(:attrs) do @@ -33,13 +33,13 @@ end it "create rule language" do - do_request data: {type: "tool-group-rule-languages", attributes: attrs} + do_request data: {type: "tool-group-rules-language", attributes: attrs} expect(status).to eq(201) expect(JSON.parse(response_body)["data"]).not_to be_nil end end - patch "tool-groups/:tool_group_id/rule-languages/:id" do + patch "tool-groups/:tool_group_id/rules-language/:id" do requires_authorization let(:tool_group_id) { ToolGroup.first.id } @@ -54,7 +54,7 @@ end it "update rule language" do - do_request data: {type: "tool-group-rule-languages", attributes: attrs} + do_request data: {type: "tool-group-rules-language", attributes: attrs} expect(status).to be(202) expect(JSON.parse(response_body)["data"]["attributes"]["languages"]).to eql languages @@ -62,7 +62,7 @@ end end - delete "tool-groups/:tool_group_id/rule-languages/:id" do + delete "tool-groups/:tool_group_id/rules-language/:id" do requires_authorization let(:tool_group_id) { ToolGroup.first.id } diff --git a/spec/acceptance/rule_praxis_controller_spec.rb b/spec/acceptance/rule_praxis_controller_spec.rb index dbc0bfb8d..450d2ae94 100644 --- a/spec/acceptance/rule_praxis_controller_spec.rb +++ b/spec/acceptance/rule_praxis_controller_spec.rb @@ -21,7 +21,7 @@ ToolGroup.delete_all end - post "tool-groups/:id/rule-praxis" do + post "tool-groups/:id/rules-praxis" do requires_authorization let(:tool_group_id) { ToolGroup.first.id } let(:openness) { [1, 2] } @@ -74,7 +74,7 @@ context "with valid openness and confidence values" do it "create rule praxis" do - do_request data: {type: "tool-group-rule-praxis", attributes: valid_attrs} + do_request data: {type: "tool-group-rules-praxis", attributes: valid_attrs} expect(status).to eq(201) expect(JSON.parse(response_body)["data"]).not_to be_nil @@ -87,7 +87,7 @@ end it "returns an error" do - do_request data: {type: "tool-group-rule-praxis", attributes: repeated_attrs} + do_request data: {type: "tool-group-rules-praxis", attributes: repeated_attrs} expect(status).to eq(422) expect(JSON.parse(response_body)["data"]).to be_nil @@ -97,7 +97,7 @@ context "with empty or null openness and confidence values" do it "returns an error" do - do_request data: {type: "tool-group-rule-praxis", attributes: empty_attrs} + do_request data: {type: "tool-group-rules-praxis", attributes: empty_attrs} expect(status).to eq(422) expect(JSON.parse(response_body)["data"]).to be_nil @@ -107,7 +107,7 @@ context "with non valid openness values" do it "returns an error" do - do_request data: {type: "tool-group-rule-praxis", attributes: non_valid_openness_attr} + do_request data: {type: "tool-group-rules-praxis", attributes: non_valid_openness_attr} expect(status).to eq(422) expect(JSON.parse(response_body)["data"]).to be_nil @@ -117,7 +117,7 @@ context "with non valid confidence values" do it "returns an error" do - do_request data: {type: "tool-group-rule-praxis", attributes: non_valid_confidence_attr} + do_request data: {type: "tool-group-rules-praxis", attributes: non_valid_confidence_attr} expect(status).to eq(422) expect(JSON.parse(response_body)["data"]).to be_nil @@ -126,7 +126,7 @@ end end - patch "tool-groups/:tool_group_id/rule-praxis/:id" do + patch "tool-groups/:tool_group_id/rules-praxis/:id" do requires_authorization let(:tool_group_id) { ToolGroup.first.id } @@ -143,7 +143,7 @@ end it "update rule praxis" do - do_request data: {type: "tool-group-rule-praxis", attributes: attrs} + do_request data: {type: "tool-group-rules-praxis", attributes: attrs} expect(status).to be(202) expect(JSON.parse(response_body)["data"]["attributes"]["openness"]).to eql openness @@ -152,7 +152,7 @@ end end - delete "tool-groups/:tool_group_id/rule-praxis/:id" do + delete "tool-groups/:tool_group_id/rules-praxis/:id" do requires_authorization let(:tool_group_id) { ToolGroup.first.id } From 89548e97583d9333cc4416dec2c5c0c9e59da0da Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Mon, 17 Jul 2023 20:16:12 -0300 Subject: [PATCH 29/50] fixed errors to match jsonapi syntax --- app/controllers/tool_groups_controller.rb | 14 ++++++++++++-- spec/acceptance/tool_group_spec.rb | 9 ++++++--- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/app/controllers/tool_groups_controller.rb b/app/controllers/tool_groups_controller.rb index e30dd3af4..69c6dfbb2 100644 --- a/app/controllers/tool_groups_controller.rb +++ b/app/controllers/tool_groups_controller.rb @@ -2,13 +2,13 @@ class ToolGroupsController < ApplicationController before_action :authorize! def index - render json: ToolGroup.all.order(name: :asc), status: :ok + render json: tool_groups_ordered_by_name, status: :ok end def create create_tool_group rescue ActiveRecord::RecordInvalid => e - render json: {error: e.record.errors}, status: :unprocessable_entity + render json: {errors: formatted_errors(e)}, status: :unprocessable_entity end def show @@ -27,6 +27,10 @@ def update private + def tool_groups_ordered_by_name + ToolGroup.order(name: :asc) + end + def create_tool_group created = ToolGroup.create!(permit_params(:name, :suggestions_weight)) response.headers["Location"] = "tool_groups/#{created.id}" @@ -42,4 +46,10 @@ def update_tool_group def load_tool_group ToolGroup.find(params[:id]) end + + def formatted_errors(error) + error.record.errors.map do |attribute, errors| + errors.map { |error_message| {detail: "#{attribute} #{error_message}"} } + end.flatten + end end diff --git a/spec/acceptance/tool_group_spec.rb b/spec/acceptance/tool_group_spec.rb index c31589030..1b728bd30 100644 --- a/spec/acceptance/tool_group_spec.rb +++ b/spec/acceptance/tool_group_spec.rb @@ -30,9 +30,10 @@ let(:attrs_invalid) do { name: "test", - suggestions_weight: nil + suggestions_weight: "" } end + requires_authorization it "create tool group" do @@ -43,8 +44,10 @@ it "returns error message when tool group is not created" do do_request data: {type: "tool-group", attributes: attrs_invalid} - expect(status).to eq(422) - expect(JSON.parse(response_body)["error"]).not_to be_empty + + expect(status).to eq(400) + expect(JSON.parse(response_body)["errors"]).not_to be_empty + expect(JSON.parse(response_body)["errors"][0]["detail"]).to eql "Validation failed: Suggestions weight can't be blank" end end From f837e1aa781ef1a9237e7594aee654c027fae62e Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Tue, 18 Jul 2023 11:43:08 -0300 Subject: [PATCH 30/50] - Tool Group * added include and fields for show and index actions --- app/controllers/tool_groups_controller.rb | 5 +- app/models/tool_group.rb | 6 +- spec/acceptance/tool_group_spec.rb | 69 +++++++++++++++++++++-- 3 files changed, 71 insertions(+), 9 deletions(-) diff --git a/app/controllers/tool_groups_controller.rb b/app/controllers/tool_groups_controller.rb index 69c6dfbb2..87a75df3f 100644 --- a/app/controllers/tool_groups_controller.rb +++ b/app/controllers/tool_groups_controller.rb @@ -2,7 +2,7 @@ class ToolGroupsController < ApplicationController before_action :authorize! def index - render json: tool_groups_ordered_by_name, status: :ok + render json: tool_groups_ordered_by_name, include: params[:include], fields: field_params, status: :ok end def create @@ -12,7 +12,8 @@ def create end def show - render json: load_tool_group, status: :ok + include = params[:include]&.split(",") + render json: load_tool_group, include: include, fields: field_params, status: :ok end def destroy diff --git a/app/models/tool_group.rb b/app/models/tool_group.rb index 799ae0065..21fb853e8 100644 --- a/app/models/tool_group.rb +++ b/app/models/tool_group.rb @@ -5,7 +5,7 @@ class ToolGroup < ApplicationRecord validates :name, :suggestions_weight, presence: true validates :name, uniqueness: true - has_many :rule_languages - has_many :rule_countries - has_many :rule_praxis + has_many :rule_languages, dependent: :destroy + has_many :rule_countries, dependent: :destroy + has_many :rule_praxis, dependent: :destroy end diff --git a/spec/acceptance/tool_group_spec.rb b/spec/acceptance/tool_group_spec.rb index 1b728bd30..b86b21ab6 100644 --- a/spec/acceptance/tool_group_spec.rb +++ b/spec/acceptance/tool_group_spec.rb @@ -8,14 +8,24 @@ let(:raw_post) { params.to_json } let(:authorization) { AuthToken.generic_token } + let(:languages) { ["es", "en"] } + let(:countries) { ["AR", "ES"] } + let(:openness) { [1, 2, 3] } + let(:confidence) { [1, 2] } before(:each) do %i[one two three].each do |name| FactoryBot.create(:tool_group, name: name) end + FactoryBot.create(:rule_language, tool_group: ToolGroup.first, languages: languages) + FactoryBot.create(:rule_country, tool_group: ToolGroup.first, countries: countries) + FactoryBot.create(:rule_praxi, tool_group: ToolGroup.first, openness: openness, confidence: confidence) end after(:each) do + RuleCountry.delete_all + RuleLanguage.delete_all + RulePraxi.delete_all ToolGroup.delete_all end @@ -64,11 +74,56 @@ get "tool-groups/:id" do requires_authorization let(:id) { ToolGroup.first.id } + let(:include_all_rules) { "rules-language,rules-praxis,rules-country" } + let(:include_only_rules_language) { "rules-language" } + let(:include_only_rules_country) { "rules-country" } + let(:include_only_rules_praxis) { "rules-praxis" } + + context "including all rules related" do + it "get tool_group by id" do + do_request id: id, include: include_all_rules + expect(status).to eq(200) + + expect(JSON.parse(response_body)["data"]["attributes"]["name"]).to eql "one" + expect(JSON.parse(response_body)["included"][0]["attributes"]["languages"]).to eql languages + expect(JSON.parse(response_body)["included"][1]["attributes"]["countries"]).to eql countries + expect(JSON.parse(response_body)["included"][2]["attributes"]["openness"]).to eql openness + expect(JSON.parse(response_body)["included"][2]["attributes"]["confidence"]).to eql confidence + end + end - it "get tool_group by id" do - do_request - expect(status).to eq(200) - expect(JSON.parse(response_body)["data"]["attributes"]["name"]).to eql "one" + context "including only rules language" do + it "get tool_group by id" do + do_request id: id, include: include_only_rules_language + expect(status).to eq(200) + + expect(JSON.parse(response_body)["included"][0]["attributes"]["languages"]).to eql languages + expect(find_value_by_key(JSON.parse(response_body)["included"], "type", "tool-group-rule-country")).to eql nil + expect(find_value_by_key(JSON.parse(response_body)["included"], "type", "tool-group-rule-praxis")).to eql nil + end + end + + context "including only rules country" do + it "get tool_group by id" do + do_request id: id, include: include_only_rules_country + expect(status).to eq(200) + + expect(JSON.parse(response_body)["included"][0]["attributes"]["countries"]).to eql countries + expect(find_value_by_key(JSON.parse(response_body)["included"], "type", "tool-group-rule-language")).to eql nil + expect(find_value_by_key(JSON.parse(response_body)["included"], "type", "tool-group-rule-praxis")).to eql nil + end + end + + context "including only rules praxis" do + it "get tool_group by id" do + do_request id: id, include: include_only_rules_praxis + expect(status).to eq(200) + + expect(JSON.parse(response_body)["included"][0]["attributes"]["openness"]).to eql openness + expect(JSON.parse(response_body)["included"][0]["attributes"]["confidence"]).to eql confidence + expect(find_value_by_key(JSON.parse(response_body)["included"], "type", "tool-group-rule-language")).to eql nil + expect(find_value_by_key(JSON.parse(response_body)["included"], "type", "tool-group-rule-country")).to eql nil + end end end @@ -100,4 +155,10 @@ expect(status).to be(204) end end + + private + + def find_value_by_key(json_array, key_to_find, value_to_find) + value_to_find if json_array.any? { |json_element| json_element[key_to_find] == value_to_find } + end end From 24434853d1949eaddef3db88fbe8b80eee6a0a22 Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Tue, 18 Jul 2023 15:59:13 -0300 Subject: [PATCH 31/50] added more specs for include on index action --- app/controllers/tool_groups_controller.rb | 30 +++++- spec/acceptance/tool_group_spec.rb | 123 ++++++++++++++++++---- 2 files changed, 133 insertions(+), 20 deletions(-) diff --git a/app/controllers/tool_groups_controller.rb b/app/controllers/tool_groups_controller.rb index 87a75df3f..ea09c84a7 100644 --- a/app/controllers/tool_groups_controller.rb +++ b/app/controllers/tool_groups_controller.rb @@ -2,7 +2,13 @@ class ToolGroupsController < ApplicationController before_action :authorize! def index - render json: tool_groups_ordered_by_name, include: params[:include], fields: field_params, status: :ok + include = {} + fields = {} + + include = params[:include]&.split(",") if params[:include] + fields = get_fields(params[:fields]) if params[:fields] + + render json: tool_groups_ordered_by_name, include: include, fields: fields, status: :ok end def create @@ -53,4 +59,26 @@ def formatted_errors(error) errors.map { |error_message| {detail: "#{attribute} #{error_message}"} } end.flatten end + + def get_fields(fields) + array = fields&.split('&') || [fields] + + result = {} + json_hash = {} + + array.each do |item| + match = item.match(/\Afields\[(.+)\]=(.+)\z/) + if match + key = match[1] + value = match[2] + result[key] = value + end + end + + result.each do |key, value| + json_hash[key] = value.include?(',') ? value.split(',') : [value] + end + + json_hash + end end diff --git a/spec/acceptance/tool_group_spec.rb b/spec/acceptance/tool_group_spec.rb index b86b21ab6..e2bffc5d3 100644 --- a/spec/acceptance/tool_group_spec.rb +++ b/spec/acceptance/tool_group_spec.rb @@ -64,10 +64,91 @@ get "tool-groups" do requires_authorization - it "list groups" do - do_request - expect(status).to eq(200) - expect(JSON.parse(response_body)["data"].count).to eql 3 + let(:include_all_rules) { "rules-language,rules-praxis,rules-country" } + let(:include_only_rules_language) { "rules-language" } + let(:include_only_rules_country) { "rules-country" } + let(:include_only_rules_praxis) { "rules-praxis" } + + let(:all_fields) { "fields[tool-group-rule-language]=languages&fields[tool-group-rule-country]=countries&fields[tool-group-rule-praxis]=openness,confidence" } + let(:field_openness_only) { "fields[tool-group-rule-praxis]=openness" } + let(:field_confidence_only) { "fields[tool-group-rule-praxis]=confidence" } + + context "including all rules related and all fields" do + it "list groups" do + do_request include: include_all_rules, fields: all_fields + + included = JSON.parse(response_body)["included"] + expect(status).to eq(200) + expect(JSON.parse(response_body)["data"].count).to eql 3 + expect(included.count).to eql 3 + + expect(included[0]["attributes"]["languages"]).to eql languages + expect(included[1]["attributes"]["countries"]).to eql countries + + expect(included[2]["attributes"]["openness"]).to eql openness + expect(included[2]["attributes"]["confidence"]).to eql confidence + expect(included[2]["attributes"].key?("openness")).to eql true + expect(included[2]["attributes"].key?("confidence")).to eql true + end + end + + context "including for praxis only field openness" do + it "list groups" do + do_request include: include_only_rules_praxis, fields: field_openness_only + expect(status).to eq(200) + + included = JSON.parse(response_body)["included"] + expect(included[0]["attributes"].key?("openness")).to eql true + expect(included[0]["attributes"].key?("confidence")).to eql false + end + end + + context "including for praxis only field confidence" do + it "list groups" do + do_request include: include_only_rules_praxis, fields: field_confidence_only + expect(status).to eq(200) + + included = JSON.parse(response_body)["included"] + expect(included[0]["attributes"].key?("openness")).to eql false + expect(included[0]["attributes"].key?("confidence")).to eql true + end + end + + context "including only rules language" do + it "list groups" do + do_request include: include_only_rules_language + expect(status).to eq(200) + + included = JSON.parse(response_body)["included"] + expect(included[0]["attributes"]["languages"]).to eql languages + expect(return_rules_included?(included, "type", "tool-group-rule-country")).to eql nil + expect(return_rules_included?(included, "type", "tool-group-rule-praxis")).to eql nil + end + end + + context "including only rules country" do + it "list groups" do + do_request include: include_only_rules_country + expect(status).to eq(200) + + included = JSON.parse(response_body)["included"] + expect(included[0]["attributes"]["countries"]).to eql countries + expect(return_rules_included?(included, "type", "tool-group-rule-language")).to eql nil + expect(return_rules_included?(included, "type", "tool-group-rule-praxis")).to eql nil + end + end + + context "including only rules praxis" do + it "list groups" do + do_request include: include_only_rules_praxis + expect(status).to eq(200) + + included = JSON.parse(response_body)["included"] + expect(included[0]["attributes"]["openness"]).to eql openness + expect(included[0]["attributes"]["confidence"]).to eql confidence + expect(return_rules_included?(included, "type", "tool-group-rule-language")).to eql nil + expect(return_rules_included?(included, "type", "tool-group-rule-country")).to eql nil + end end end @@ -84,11 +165,12 @@ do_request id: id, include: include_all_rules expect(status).to eq(200) + included = JSON.parse(response_body)["included"] expect(JSON.parse(response_body)["data"]["attributes"]["name"]).to eql "one" - expect(JSON.parse(response_body)["included"][0]["attributes"]["languages"]).to eql languages - expect(JSON.parse(response_body)["included"][1]["attributes"]["countries"]).to eql countries - expect(JSON.parse(response_body)["included"][2]["attributes"]["openness"]).to eql openness - expect(JSON.parse(response_body)["included"][2]["attributes"]["confidence"]).to eql confidence + expect(included[0]["attributes"]["languages"]).to eql languages + expect(included[1]["attributes"]["countries"]).to eql countries + expect(included[2]["attributes"]["openness"]).to eql openness + expect(included[2]["attributes"]["confidence"]).to eql confidence end end @@ -97,9 +179,10 @@ do_request id: id, include: include_only_rules_language expect(status).to eq(200) - expect(JSON.parse(response_body)["included"][0]["attributes"]["languages"]).to eql languages - expect(find_value_by_key(JSON.parse(response_body)["included"], "type", "tool-group-rule-country")).to eql nil - expect(find_value_by_key(JSON.parse(response_body)["included"], "type", "tool-group-rule-praxis")).to eql nil + included = JSON.parse(response_body)["included"] + expect(included[0]["attributes"]["languages"]).to eql languages + expect(return_rules_included?(included, "type", "tool-group-rule-country")).to eql nil + expect(return_rules_included?(included, "type", "tool-group-rule-praxis")).to eql nil end end @@ -108,9 +191,10 @@ do_request id: id, include: include_only_rules_country expect(status).to eq(200) - expect(JSON.parse(response_body)["included"][0]["attributes"]["countries"]).to eql countries - expect(find_value_by_key(JSON.parse(response_body)["included"], "type", "tool-group-rule-language")).to eql nil - expect(find_value_by_key(JSON.parse(response_body)["included"], "type", "tool-group-rule-praxis")).to eql nil + included = JSON.parse(response_body)["included"] + expect(included[0]["attributes"]["countries"]).to eql countries + expect(return_rules_included?(included, "type", "tool-group-rule-language")).to eql nil + expect(return_rules_included?(included, "type", "tool-group-rule-praxis")).to eql nil end end @@ -119,10 +203,11 @@ do_request id: id, include: include_only_rules_praxis expect(status).to eq(200) - expect(JSON.parse(response_body)["included"][0]["attributes"]["openness"]).to eql openness - expect(JSON.parse(response_body)["included"][0]["attributes"]["confidence"]).to eql confidence - expect(find_value_by_key(JSON.parse(response_body)["included"], "type", "tool-group-rule-language")).to eql nil - expect(find_value_by_key(JSON.parse(response_body)["included"], "type", "tool-group-rule-country")).to eql nil + included = JSON.parse(response_body)["included"] + expect(included[0]["attributes"]["openness"]).to eql openness + expect(included[0]["attributes"]["confidence"]).to eql confidence + expect(return_rules_included?(included, "type", "tool-group-rule-language")).to eql nil + expect(return_rules_included?(included, "type", "tool-group-rule-country")).to eql nil end end end @@ -158,7 +243,7 @@ private - def find_value_by_key(json_array, key_to_find, value_to_find) + def return_rules_included?(json_array, key_to_find, value_to_find) value_to_find if json_array.any? { |json_element| json_element[key_to_find] == value_to_find } end end From 80575bfca4dcba2a5f26b48c44b6055ffa594b1c Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Tue, 18 Jul 2023 20:23:42 -0300 Subject: [PATCH 32/50] fixed specs params --- app/controllers/tool_groups_controller.rb | 24 ++++++----------------- spec/acceptance/tool_group_spec.rb | 11 ++++------- 2 files changed, 10 insertions(+), 25 deletions(-) diff --git a/app/controllers/tool_groups_controller.rb b/app/controllers/tool_groups_controller.rb index ea09c84a7..53ced02ab 100644 --- a/app/controllers/tool_groups_controller.rb +++ b/app/controllers/tool_groups_controller.rb @@ -61,24 +61,12 @@ def formatted_errors(error) end def get_fields(fields) - array = fields&.split('&') || [fields] + hash_result = {} + filter_fields = {} - result = {} - json_hash = {} - - array.each do |item| - match = item.match(/\Afields\[(.+)\]=(.+)\z/) - if match - key = match[1] - value = match[2] - result[key] = value - end - end - - result.each do |key, value| - json_hash[key] = value.include?(',') ? value.split(',') : [value] - end - - json_hash + array = fields.each do |key, value| filter_fields[key] = value&.split(",") ? value&.split(",") : [value] end + array.each { |key, value| hash_result[key] = value&.include?(',') ? value.split(',') : [value] } + + hash_result end end diff --git a/spec/acceptance/tool_group_spec.rb b/spec/acceptance/tool_group_spec.rb index e2bffc5d3..aae248327 100644 --- a/spec/acceptance/tool_group_spec.rb +++ b/spec/acceptance/tool_group_spec.rb @@ -69,13 +69,9 @@ let(:include_only_rules_country) { "rules-country" } let(:include_only_rules_praxis) { "rules-praxis" } - let(:all_fields) { "fields[tool-group-rule-language]=languages&fields[tool-group-rule-country]=countries&fields[tool-group-rule-praxis]=openness,confidence" } - let(:field_openness_only) { "fields[tool-group-rule-praxis]=openness" } - let(:field_confidence_only) { "fields[tool-group-rule-praxis]=confidence" } - context "including all rules related and all fields" do it "list groups" do - do_request include: include_all_rules, fields: all_fields + do_request include: include_all_rules included = JSON.parse(response_body)["included"] expect(status).to eq(200) @@ -94,7 +90,7 @@ context "including for praxis only field openness" do it "list groups" do - do_request include: include_only_rules_praxis, fields: field_openness_only + do_request include: include_only_rules_praxis, "fields[tool-group-rule-praxis]": "openness" expect(status).to eq(200) included = JSON.parse(response_body)["included"] @@ -105,7 +101,8 @@ context "including for praxis only field confidence" do it "list groups" do - do_request include: include_only_rules_praxis, fields: field_confidence_only + do_request include: include_only_rules_praxis, "fields[tool-group-rule-praxis]": "confidence" + expect(status).to eq(200) included = JSON.parse(response_body)["included"] From 3df22523be7bd94a86558a114930ad833c6e87c8 Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Tue, 18 Jul 2023 20:29:37 -0300 Subject: [PATCH 33/50] fixed lint warnings --- app/controllers/tool_groups_controller.rb | 6 +++--- spec/acceptance/tool_group_spec.rb | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/controllers/tool_groups_controller.rb b/app/controllers/tool_groups_controller.rb index 53ced02ab..551c1f97b 100644 --- a/app/controllers/tool_groups_controller.rb +++ b/app/controllers/tool_groups_controller.rb @@ -64,9 +64,9 @@ def get_fields(fields) hash_result = {} filter_fields = {} - array = fields.each do |key, value| filter_fields[key] = value&.split(",") ? value&.split(",") : [value] end - array.each { |key, value| hash_result[key] = value&.include?(',') ? value.split(',') : [value] } - + array = fields.each { |key, value| filter_fields[key] = value&.split(",") || [value] } + array.each { |key, value| hash_result[key] = value&.include?(",") ? value.split(",") : [value] } + hash_result end end diff --git a/spec/acceptance/tool_group_spec.rb b/spec/acceptance/tool_group_spec.rb index aae248327..c2c595a21 100644 --- a/spec/acceptance/tool_group_spec.rb +++ b/spec/acceptance/tool_group_spec.rb @@ -94,8 +94,8 @@ expect(status).to eq(200) included = JSON.parse(response_body)["included"] - expect(included[0]["attributes"].key?("openness")).to eql true - expect(included[0]["attributes"].key?("confidence")).to eql false + expect(included[0]["attributes"].key?("openness")).to eql true + expect(included[0]["attributes"].key?("confidence")).to eql false end end From d438174eb3709d15d626b8fd9c46a7370ff2717a Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Tue, 18 Jul 2023 20:53:20 -0300 Subject: [PATCH 34/50] code not needed --- app/controllers/tool_groups_controller.rb | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/app/controllers/tool_groups_controller.rb b/app/controllers/tool_groups_controller.rb index 551c1f97b..d016637ad 100644 --- a/app/controllers/tool_groups_controller.rb +++ b/app/controllers/tool_groups_controller.rb @@ -2,13 +2,10 @@ class ToolGroupsController < ApplicationController before_action :authorize! def index - include = {} fields = {} - - include = params[:include]&.split(",") if params[:include] fields = get_fields(params[:fields]) if params[:fields] - render json: tool_groups_ordered_by_name, include: include, fields: fields, status: :ok + render json: tool_groups_ordered_by_name, include: params[:include], fields: fields, status: :ok end def create @@ -18,8 +15,7 @@ def create end def show - include = params[:include]&.split(",") - render json: load_tool_group, include: include, fields: field_params, status: :ok + render json: load_tool_group, include: params[:include], fields: field_params, status: :ok end def destroy From efdfa160aaf1cb80d53474cfcd5c2430edca9e51 Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Tue, 18 Jul 2023 21:07:15 -0300 Subject: [PATCH 35/50] more code not needed --- app/controllers/tool_groups_controller.rb | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/app/controllers/tool_groups_controller.rb b/app/controllers/tool_groups_controller.rb index d016637ad..70710da4a 100644 --- a/app/controllers/tool_groups_controller.rb +++ b/app/controllers/tool_groups_controller.rb @@ -2,10 +2,7 @@ class ToolGroupsController < ApplicationController before_action :authorize! def index - fields = {} - fields = get_fields(params[:fields]) if params[:fields] - - render json: tool_groups_ordered_by_name, include: params[:include], fields: fields, status: :ok + render json: tool_groups_ordered_by_name, include: params[:include], fields: field_params, status: :ok end def create @@ -55,14 +52,4 @@ def formatted_errors(error) errors.map { |error_message| {detail: "#{attribute} #{error_message}"} } end.flatten end - - def get_fields(fields) - hash_result = {} - filter_fields = {} - - array = fields.each { |key, value| filter_fields[key] = value&.split(",") || [value] } - array.each { |key, value| hash_result[key] = value&.include?(",") ? value.split(",") : [value] } - - hash_result - end end From 29d865fc6ef898fbd5c5db90c29c93ef1d476870 Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Wed, 19 Jul 2023 12:53:18 -0300 Subject: [PATCH 36/50] added transformation params to get consistency on tool_groups attribute as 'suggestions-weight' --- app/controllers/tool_groups_controller.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/controllers/tool_groups_controller.rb b/app/controllers/tool_groups_controller.rb index 70710da4a..d3b33eb74 100644 --- a/app/controllers/tool_groups_controller.rb +++ b/app/controllers/tool_groups_controller.rb @@ -1,5 +1,6 @@ class ToolGroupsController < ApplicationController before_action :authorize! + before_action :transform_params, only: [:create, :update] def index render json: tool_groups_ordered_by_name, include: params[:include], fields: field_params, status: :ok @@ -27,6 +28,10 @@ def update private + def transform_params + params.deep_transform_keys!{ |key| key.tr('-', '_') } + end + def tool_groups_ordered_by_name ToolGroup.order(name: :asc) end From 435a5ba6a8e60fc53daeffd6652d2943a6fdd0bd Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Wed, 19 Jul 2023 13:07:38 -0300 Subject: [PATCH 37/50] - movded tranformation params method to application controller - fixed lint --- app/controllers/application_controller.rb | 4 ++++ app/controllers/tool_groups_controller.rb | 6 +----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 650ca0ddc..0027db86c 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -119,4 +119,8 @@ def initialize(code, message) errors.add(code, message) end end + + def convert_hyphen_to_dash + params.deep_transform_keys! { |key| key.tr("-", "_") } + end end diff --git a/app/controllers/tool_groups_controller.rb b/app/controllers/tool_groups_controller.rb index d3b33eb74..505a84b5f 100644 --- a/app/controllers/tool_groups_controller.rb +++ b/app/controllers/tool_groups_controller.rb @@ -1,6 +1,6 @@ class ToolGroupsController < ApplicationController before_action :authorize! - before_action :transform_params, only: [:create, :update] + before_action :convert_hyphen_to_dash, only: [:create, :update] def index render json: tool_groups_ordered_by_name, include: params[:include], fields: field_params, status: :ok @@ -28,10 +28,6 @@ def update private - def transform_params - params.deep_transform_keys!{ |key| key.tr('-', '_') } - end - def tool_groups_ordered_by_name ToolGroup.order(name: :asc) end From 91c8761195594cbb3e97004e8cf1178001725195 Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Wed, 19 Jul 2023 18:28:27 -0300 Subject: [PATCH 38/50] - renamed from table from "rule_praxis" to "rule_praxes" to follow RoR inflection pattern - changes in route, controller, model name and its relationships, serializers, specs --- ...raxis_controller.rb => rule_praxes_controller.rb} | 10 +++++----- app/models/{rule_praxi.rb => rule_praxis.rb} | 4 +++- app/models/tool_group.rb | 2 +- ...praxi_serializer.rb => rule_praxis_serializer.rb} | 2 +- app/serializers/tool_group_serializer.rb | 4 ++-- config/routes.rb | 2 +- ...230719201411_rename_rule_praxis_to_rule_praxes.rb | 5 +++++ db/schema.rb | 8 ++++---- ...roller_spec.rb => rule_praxes_controller_spec.rb} | 12 ++++++------ spec/acceptance/tool_group_spec.rb | 4 ++-- spec/factories/{rule_praxi.rb => rule_praxis.rb} | 2 +- 11 files changed, 31 insertions(+), 24 deletions(-) rename app/controllers/{rule_praxis_controller.rb => rule_praxes_controller.rb} (69%) rename app/models/{rule_praxi.rb => rule_praxis.rb} (90%) rename app/serializers/{rule_praxi_serializer.rb => rule_praxis_serializer.rb} (77%) create mode 100644 db/migrate/20230719201411_rename_rule_praxis_to_rule_praxes.rb rename spec/acceptance/{rule_praxis_controller_spec.rb => rule_praxes_controller_spec.rb} (93%) rename spec/factories/{rule_praxi.rb => rule_praxis.rb} (83%) diff --git a/app/controllers/rule_praxis_controller.rb b/app/controllers/rule_praxes_controller.rb similarity index 69% rename from app/controllers/rule_praxis_controller.rb rename to app/controllers/rule_praxes_controller.rb index 380185c12..0b03263ce 100644 --- a/app/controllers/rule_praxis_controller.rb +++ b/app/controllers/rule_praxes_controller.rb @@ -1,4 +1,4 @@ -class RulePraxisController < ApplicationController +class RulePraxesController < ApplicationController before_action :authorize! def create @@ -13,22 +13,22 @@ def update def destroy tool_group = ToolGroup.find(params[:tool_group_id]) - rule_praxi = tool_group.rule_praxis.find(params[:id]) - rule_praxi.destroy! + rule_praxes = tool_group.rule_praxes.find(params[:id]) + rule_praxes.destroy! head :no_content end private def create_rule_praxis - created = RulePraxi.create!(permit_params(:tool_group_id, :negative_rule, openness: [], confidence: [])) + created = RulePraxis.create!(permit_params(:tool_group_id, :negative_rule, openness: [], confidence: [])) response.headers["Location"] = "tool_groups/#{created.id}" render json: created, status: :created end def update_rule_praxis tool_group = ToolGroup.find(params[:tool_group_id]) - existing = tool_group.rule_praxis.find(params[:id]) + existing = tool_group.rule_praxes.find(params[:id]) existing.update!(permit_params(:negative_rule, openness: [], confidence: [])) render json: existing, status: :accepted end diff --git a/app/models/rule_praxi.rb b/app/models/rule_praxis.rb similarity index 90% rename from app/models/rule_praxi.rb rename to app/models/rule_praxis.rb index f8a8d22cb..f9ca4cadf 100644 --- a/app/models/rule_praxi.rb +++ b/app/models/rule_praxis.rb @@ -1,4 +1,6 @@ -class RulePraxi < ApplicationRecord +class RulePraxis < ApplicationRecord + self.table_name = "rule_praxes" + belongs_to :tool_group validates :tool_group_id, uniqueness: {scope: [:openness, :confidence], message: "combination already exists"} diff --git a/app/models/tool_group.rb b/app/models/tool_group.rb index 21fb853e8..de829308c 100644 --- a/app/models/tool_group.rb +++ b/app/models/tool_group.rb @@ -7,5 +7,5 @@ class ToolGroup < ApplicationRecord has_many :rule_languages, dependent: :destroy has_many :rule_countries, dependent: :destroy - has_many :rule_praxis, dependent: :destroy + has_many :rule_praxes, class_name: "RulePraxis", dependent: :destroy end diff --git a/app/serializers/rule_praxi_serializer.rb b/app/serializers/rule_praxis_serializer.rb similarity index 77% rename from app/serializers/rule_praxi_serializer.rb rename to app/serializers/rule_praxis_serializer.rb index ea7c76c9e..3e16636f7 100644 --- a/app/serializers/rule_praxi_serializer.rb +++ b/app/serializers/rule_praxis_serializer.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class RulePraxiSerializer < ActiveModel::Serializer +class RulePraxisSerializer < ActiveModel::Serializer attributes :id, :openness, :confidence attribute :negative_rule, key: "negative-rule" diff --git a/app/serializers/tool_group_serializer.rb b/app/serializers/tool_group_serializer.rb index 4e497114b..bcd10ddeb 100644 --- a/app/serializers/tool_group_serializer.rb +++ b/app/serializers/tool_group_serializer.rb @@ -8,7 +8,7 @@ class ToolGroupSerializer < ActiveModel::Serializer has_many :rule_languages, key: "rules-language" has_many :rule_countries, key: "rules-country" - has_many :rule_praxis, key: "rules-praxis" + has_many :rule_praxes, key: "rules-praxis" def custom_rule_languages object.rule_languages @@ -19,6 +19,6 @@ def custom_rule_countries end def custom_rule_praxis - object.rule_praxis + object.rule_praxes end end diff --git a/config/routes.rb b/config/routes.rb index d381e68f0..e1a090888 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -44,7 +44,7 @@ # Rule Praxis resources :tool_groups, path: "tool-groups", only: [] do - resources :rule_praxis, path: "rules-praxis", only: [:create, :destroy, :update] + resources :rule_praxes, path: "rules-praxis", only: [:create, :destroy, :update] end patch "user/counters/:id", to: "user_counters#update" # Legacy route for GodTools Android v5.7.0-v6.0.0 diff --git a/db/migrate/20230719201411_rename_rule_praxis_to_rule_praxes.rb b/db/migrate/20230719201411_rename_rule_praxis_to_rule_praxes.rb new file mode 100644 index 000000000..9d74eb7db --- /dev/null +++ b/db/migrate/20230719201411_rename_rule_praxis_to_rule_praxes.rb @@ -0,0 +1,5 @@ +class RenameRulePraxisToRulePraxes < ActiveRecord::Migration[6.1] + def change + rename_table :rule_praxis, :rule_praxes + end +end diff --git a/db/schema.rb b/db/schema.rb index 66ec045d6..54a24f040 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2023_07_14_202623) do +ActiveRecord::Schema.define(version: 2023_07_19_201411) do # These are extensions that must be enabled in order to support this database enable_extension "citext" @@ -226,14 +226,14 @@ t.index ["tool_group_id"], name: "index_rule_languages_on_tool_group_id" end - create_table "rule_praxis", force: :cascade do |t| + create_table "rule_praxes", force: :cascade do |t| t.bigint "tool_group_id", null: false t.integer "openness", default: [], array: true t.integer "confidence", default: [], array: true t.boolean "negative_rule", default: false t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false - t.index ["tool_group_id"], name: "index_rule_praxis_on_tool_group_id" + t.index ["tool_group_id"], name: "index_rule_praxes_on_tool_group_id" end create_table "systems", id: :serial, force: :cascade do |t| @@ -342,7 +342,7 @@ add_foreign_key "resources", "systems" add_foreign_key "rule_countries", "tool_groups" add_foreign_key "rule_languages", "tool_groups" - add_foreign_key "rule_praxis", "tool_groups" + add_foreign_key "rule_praxes", "tool_groups" add_foreign_key "translated_pages", "languages" add_foreign_key "translated_pages", "resources" add_foreign_key "translation_attributes", "translations" diff --git a/spec/acceptance/rule_praxis_controller_spec.rb b/spec/acceptance/rule_praxes_controller_spec.rb similarity index 93% rename from spec/acceptance/rule_praxis_controller_spec.rb rename to spec/acceptance/rule_praxes_controller_spec.rb index 450d2ae94..bad825d16 100644 --- a/spec/acceptance/rule_praxis_controller_spec.rb +++ b/spec/acceptance/rule_praxes_controller_spec.rb @@ -2,7 +2,7 @@ require "acceptance_helper" -resource "RulePraxis" do +resource "RulePraxes" do header "Accept", "application/vnd.api+json" header "Content-Type", "application/vnd.api+json" @@ -13,11 +13,11 @@ %i[one].each do |name| FactoryBot.create(:tool_group, name: name) end - FactoryBot.create(:rule_praxi, tool_group: ToolGroup.first) + FactoryBot.create(:rule_praxis, tool_group: ToolGroup.first) end after(:each) do - RulePraxi.delete_all + RulePraxis.delete_all ToolGroup.delete_all end @@ -83,7 +83,7 @@ context "with repeated openness and confidence values" do before do - FactoryBot.create(:rule_praxi, tool_group_id: tool_group_id, openness: openness, confidence: confidence) + FactoryBot.create(:rule_praxis, tool_group_id: tool_group_id, openness: openness, confidence: confidence) end it "returns an error" do @@ -130,7 +130,7 @@ requires_authorization let(:tool_group_id) { ToolGroup.first.id } - let(:id) { RulePraxi.first.id } + let(:id) { RulePraxis.first.id } let(:openness) { [1, 2] } let(:confidence) { [3, 4] } @@ -156,7 +156,7 @@ requires_authorization let(:tool_group_id) { ToolGroup.first.id } - let(:id) { RulePraxi.first.id } + let(:id) { RulePraxis.first.id } it "delete rule praxis" do do_request diff --git a/spec/acceptance/tool_group_spec.rb b/spec/acceptance/tool_group_spec.rb index c2c595a21..01daf564f 100644 --- a/spec/acceptance/tool_group_spec.rb +++ b/spec/acceptance/tool_group_spec.rb @@ -19,13 +19,13 @@ end FactoryBot.create(:rule_language, tool_group: ToolGroup.first, languages: languages) FactoryBot.create(:rule_country, tool_group: ToolGroup.first, countries: countries) - FactoryBot.create(:rule_praxi, tool_group: ToolGroup.first, openness: openness, confidence: confidence) + FactoryBot.create(:rule_praxis, tool_group: ToolGroup.first, openness: openness, confidence: confidence) end after(:each) do RuleCountry.delete_all RuleLanguage.delete_all - RulePraxi.delete_all + RulePraxis.delete_all ToolGroup.delete_all end diff --git a/spec/factories/rule_praxi.rb b/spec/factories/rule_praxis.rb similarity index 83% rename from spec/factories/rule_praxi.rb rename to spec/factories/rule_praxis.rb index e33217595..a00326b4c 100644 --- a/spec/factories/rule_praxi.rb +++ b/spec/factories/rule_praxis.rb @@ -1,5 +1,5 @@ FactoryBot.define do - factory :rule_praxi do + factory :rule_praxis do tool_group_id { 1 } negative_rule { true } openness { [1, 2, 3] } From 4085ef353f87ad34a001710efc243040a14083f3 Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Thu, 20 Jul 2023 12:40:14 -0300 Subject: [PATCH 39/50] - ResourceToolGroup * migration, model, serializer, specs --- app/controllers/tool_groups_controller.rb | 8 +++++++ app/models/resource.rb | 3 +++ app/models/resource_tool_group.rb | 7 ++++++ app/models/tool_group.rb | 2 ++ app/serializers/resource_serializer.rb | 2 ++ .../resource_tool_group_serializer.rb | 11 ++++++++++ app/serializers/tool_group_serializer.rb | 1 + config/routes.rb | 5 ++++- ...30719224248_create_resource_tool_groups.rb | 11 ++++++++++ db/schema.rb | 18 ++++++++++++--- spec/acceptance/tool_group_spec.rb | 22 +++++++++++++++++++ 11 files changed, 86 insertions(+), 4 deletions(-) create mode 100644 app/models/resource_tool_group.rb create mode 100644 app/serializers/resource_tool_group_serializer.rb create mode 100644 db/migrate/20230719224248_create_resource_tool_groups.rb diff --git a/app/controllers/tool_groups_controller.rb b/app/controllers/tool_groups_controller.rb index 505a84b5f..ad8cd84d8 100644 --- a/app/controllers/tool_groups_controller.rb +++ b/app/controllers/tool_groups_controller.rb @@ -12,6 +12,14 @@ def create render json: {errors: formatted_errors(e)}, status: :unprocessable_entity end + def create_tool + rtg = ResourceToolGroup.create!(permit_params(:tool_group_id, :resource_id, :suggestions_weight)) + byebug + tool_group = ToolGroup.find(params[:data][:attributes][:tool_group_id]) + response.headers["Location"] = "tool_groups/#{tool_group.id}" + render json: tool_group, status: :created + end + def show render json: load_tool_group, include: params[:include], fields: field_params, status: :ok end diff --git a/app/models/resource.rb b/app/models/resource.rb index 2833a7b67..a389369fc 100644 --- a/app/models/resource.rb +++ b/app/models/resource.rb @@ -12,6 +12,9 @@ class Resource < ActiveRecord::Base has_many :translated_pages has_many :translated_attributes has_many :custom_manifests + has_many :resource_tool_groups + has_many :tool_groups, through: :resource_tool_groups + belongs_to :metatool, optional: true, class_name: "Resource" belongs_to :default_variant, optional: true, class_name: "Resource" has_many :variants, class_name: "Resource", foreign_key: :metatool_id diff --git a/app/models/resource_tool_group.rb b/app/models/resource_tool_group.rb new file mode 100644 index 000000000..e7e7b94c6 --- /dev/null +++ b/app/models/resource_tool_group.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +# app/models/resource_tool_group.rb +class ResourceToolGroup < ApplicationRecord + belongs_to :resource + belongs_to :tool_group +end \ No newline at end of file diff --git a/app/models/tool_group.rb b/app/models/tool_group.rb index de829308c..c45705086 100644 --- a/app/models/tool_group.rb +++ b/app/models/tool_group.rb @@ -8,4 +8,6 @@ class ToolGroup < ApplicationRecord has_many :rule_languages, dependent: :destroy has_many :rule_countries, dependent: :destroy has_many :rule_praxes, class_name: "RulePraxis", dependent: :destroy + has_many :resource_tool_groups + has_many :resources, through: :resource_tool_groups end diff --git a/app/serializers/resource_serializer.rb b/app/serializers/resource_serializer.rb index 62bc116b5..ab5079656 100644 --- a/app/serializers/resource_serializer.rb +++ b/app/serializers/resource_serializer.rb @@ -16,6 +16,8 @@ class ResourceSerializer < ActiveModel::Serializer has_many :custom_manifests, key: "custom-manifests" has_many :variants, if: -> { object&.resource_type&.name == "metatool" } has_many :translated_attributes, key: "translated-attributes" + has_many :tool_groups, through: :resource_tool_groups + belongs_to :default_variant, key: "default-variant", if: -> { object&.resource_type&.name == "metatool" } def attributes(*args) diff --git a/app/serializers/resource_tool_group_serializer.rb b/app/serializers/resource_tool_group_serializer.rb new file mode 100644 index 000000000..05c3792ca --- /dev/null +++ b/app/serializers/resource_tool_group_serializer.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +class ResourceToolGroupSerializer < ActiveModel::Serializer + attributes :resource_id, :tool_group + attribute :suggestions_weight, key: "suggestions-weight" + + type "tool-group-tool" + + belongs_to :resource + belongs_to :tool_group +end \ No newline at end of file diff --git a/app/serializers/tool_group_serializer.rb b/app/serializers/tool_group_serializer.rb index bcd10ddeb..1f8592163 100644 --- a/app/serializers/tool_group_serializer.rb +++ b/app/serializers/tool_group_serializer.rb @@ -9,6 +9,7 @@ class ToolGroupSerializer < ActiveModel::Serializer has_many :rule_languages, key: "rules-language" has_many :rule_countries, key: "rules-country" has_many :rule_praxes, key: "rules-praxis" + has_many :resources, through: :resource_tool_groups def custom_rule_languages object.rule_languages diff --git a/config/routes.rb b/config/routes.rb index e1a090888..5b001e5ef 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -30,7 +30,10 @@ resources :custom_manifests, only: [:create, :update, :destroy, :show] - resources :tool_groups, path: "tool-groups", only: [:create, :destroy, :index, :show, :update] + resources :tool_groups, path: "tool-groups", only: [:create, :destroy, :index, :show, :update] do + # resources :resources, path: "tools", only: [:create, :destroy, :update] + post "tools", to: "tool_groups#create_tool" + end # Rule Languages resources :tool_groups, path: "tool-groups", only: [] do diff --git a/db/migrate/20230719224248_create_resource_tool_groups.rb b/db/migrate/20230719224248_create_resource_tool_groups.rb new file mode 100644 index 000000000..3da678e84 --- /dev/null +++ b/db/migrate/20230719224248_create_resource_tool_groups.rb @@ -0,0 +1,11 @@ +class CreateResourceToolGroups < ActiveRecord::Migration[6.1] + def change + create_table :resource_tool_groups do |t| + t.references :resource, null: false, foreign_key: true + t.references :tool_group, null: false, foreign_key: true + t.float :suggestions_weight + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 54a24f040..952f90258 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2023_07_19_201411) do +ActiveRecord::Schema.define(version: 2023_07_19_224248) do # These are extensions that must be enabled in order to support this database enable_extension "citext" @@ -160,8 +160,6 @@ t.string "key", null: false t.string "value", null: false t.boolean "is_translatable", default: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false t.index ["key", "resource_id", "language_id"], name: "index_language_attributes_unique", unique: true t.index ["resource_id"], name: "index_language_attributes_on_resource_id" end @@ -182,6 +180,16 @@ t.index ["resource_id"], name: "index_pages_on_resource_id" end + create_table "resource_tool_groups", force: :cascade do |t| + t.bigint "resource_id", null: false + t.bigint "tool_group_id", null: false + t.float "suggestions_weight" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["resource_id"], name: "index_resource_tool_groups_on_resource_id" + t.index ["tool_group_id"], name: "index_resource_tool_groups_on_tool_group_id" + end + create_table "resource_types", id: :serial, force: :cascade do |t| t.string "name", null: false t.string "dtd_file", null: false @@ -303,7 +311,9 @@ t.date "last_decay", default: -> { "now()" } t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false + t.string "values", default: [], array: true t.index ["user_id", "counter_name"], name: "index_user_counters_on_user_id_and_counter_name", unique: true + t.index ["values"], name: "index_user_counters_on_values", using: :gin end create_table "users", force: :cascade do |t| @@ -336,6 +346,8 @@ add_foreign_key "follow_ups", "destinations" add_foreign_key "follow_ups", "languages" add_foreign_key "pages", "resources" + add_foreign_key "resource_tool_groups", "resources" + add_foreign_key "resource_tool_groups", "tool_groups" add_foreign_key "resources", "resource_types" add_foreign_key "resources", "resources", column: "default_variant_id" add_foreign_key "resources", "resources", column: "metatool_id" diff --git a/spec/acceptance/tool_group_spec.rb b/spec/acceptance/tool_group_spec.rb index 01daf564f..56ab36041 100644 --- a/spec/acceptance/tool_group_spec.rb +++ b/spec/acceptance/tool_group_spec.rb @@ -12,6 +12,7 @@ let(:countries) { ["AR", "ES"] } let(:openness) { [1, 2, 3] } let(:confidence) { [1, 2] } + let(:metatool_resource_type) { ResourceType.find_by(name: "metatool") } before(:each) do %i[one two three].each do |name| @@ -20,12 +21,14 @@ FactoryBot.create(:rule_language, tool_group: ToolGroup.first, languages: languages) FactoryBot.create(:rule_country, tool_group: ToolGroup.first, countries: countries) FactoryBot.create(:rule_praxis, tool_group: ToolGroup.first, openness: openness, confidence: confidence) + FactoryBot.create(:resource, system_id: 1, resource_type: metatool_resource_type, name: "Resource Test One", abbreviation: "test1") end after(:each) do RuleCountry.delete_all RuleLanguage.delete_all RulePraxis.delete_all + ResourceToolGroup.delete_all ToolGroup.delete_all end @@ -61,6 +64,25 @@ end end + post "tool-groups/:tool_group_id/tools" do + let(:attrs) do + { + tool_group_id: ToolGroup.first.id, + resource_id: Resource.first.id, + suggestions_weight: "1.0" + } + end + + requires_authorization + + it "create tool group tool" do + do_request data: {type: "tool-group-tool", attributes: attrs} + byebug + expect(status).to eq(201) + expect(JSON.parse(response_body)["data"]).not_to be_nil + end + end + get "tool-groups" do requires_authorization From 9113215a9684683fafc33a321cf7065012c31a20 Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Thu, 20 Jul 2023 15:41:49 -0300 Subject: [PATCH 40/50] fixed create_rule_language --- app/controllers/rule_languages_controller.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/controllers/rule_languages_controller.rb b/app/controllers/rule_languages_controller.rb index 4211304c0..e68bddfa8 100644 --- a/app/controllers/rule_languages_controller.rb +++ b/app/controllers/rule_languages_controller.rb @@ -1,5 +1,6 @@ class RuleLanguagesController < ApplicationController before_action :authorize! + before_action :convert_hyphen_to_dash, only: [:create, :update] def create create_rule_language @@ -21,7 +22,8 @@ def destroy private def create_rule_language - created = RuleLanguage.create!(permit_params(:tool_group_id, :negative_rule, languages: [])) + tool_group = ToolGroup.find(params[:tool_group_id]) + created = tool_group.rule_languages.create!(permit_params(:tool_group_id, :negative_rule, languages: [])) response.headers["Location"] = "tool_groups/#{created.id}" render json: created, status: :created end From 29bc58832a935bac33139e81b2b7c0eddc1980bd Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Thu, 20 Jul 2023 15:49:12 -0300 Subject: [PATCH 41/50] - fixed rule languages, countries and praxes create action errors format - added update tool action, route, relationships for serializers --- app/controllers/application_controller.rb | 6 ++++ app/controllers/rule_countries_controller.rb | 5 +-- app/controllers/rule_languages_controller.rb | 2 +- app/controllers/rule_praxes_controller.rb | 5 +-- app/controllers/tool_groups_controller.rb | 15 +++++---- app/models/resource_tool_group.rb | 2 +- app/serializers/resource_serializer.rb | 2 ++ .../resource_tool_group_serializer.rb | 2 +- app/serializers/tool_group_serializer.rb | 1 + config/routes.rb | 1 + .../rule_countries_controller_spec.rb | 11 +++---- .../rule_languages_controller_spec.rb | 5 +-- .../acceptance/rule_praxes_controller_spec.rb | 31 ++++++++----------- spec/acceptance/tool_group_spec.rb | 30 ++++++++++++++++-- 14 files changed, 75 insertions(+), 43 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 0027db86c..cf5020eb5 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -123,4 +123,10 @@ def initialize(code, message) def convert_hyphen_to_dash params.deep_transform_keys! { |key| key.tr("-", "_") } end + + def formatted_errors(error) + error.record.errors.map do |attribute, errors| + errors.map { |error_message| {detail: "#{attribute} #{error_message}"} } + end.flatten + end end diff --git a/app/controllers/rule_countries_controller.rb b/app/controllers/rule_countries_controller.rb index 912f66475..12ddf44a6 100644 --- a/app/controllers/rule_countries_controller.rb +++ b/app/controllers/rule_countries_controller.rb @@ -4,7 +4,7 @@ class RuleCountriesController < ApplicationController def create create_rule_country rescue ActiveRecord::RecordInvalid => e - render json: {error: e.record.errors}, status: :unprocessable_entity + render json: {errors: formatted_errors(e)}, status: :unprocessable_entity end def update @@ -21,7 +21,8 @@ def destroy private def create_rule_country - created = RuleCountry.create!(permit_params(:tool_group_id, :negative_rule, countries: [])) + tool_group = ToolGroup.find(params[:tool_group_id]) + created = tool_group.rule_countries.create!(permit_params(:tool_group_id, :negative_rule, countries: [])) response.headers["Location"] = "tool_groups/#{created.id}" render json: created, status: :created end diff --git a/app/controllers/rule_languages_controller.rb b/app/controllers/rule_languages_controller.rb index e68bddfa8..38253a558 100644 --- a/app/controllers/rule_languages_controller.rb +++ b/app/controllers/rule_languages_controller.rb @@ -5,7 +5,7 @@ class RuleLanguagesController < ApplicationController def create create_rule_language rescue ActiveRecord::RecordInvalid => e - render json: {error: e.record.errors}, status: :unprocessable_entity + render json: {errors: formatted_errors(e)}, status: :unprocessable_entity end def update diff --git a/app/controllers/rule_praxes_controller.rb b/app/controllers/rule_praxes_controller.rb index 0b03263ce..7619ee859 100644 --- a/app/controllers/rule_praxes_controller.rb +++ b/app/controllers/rule_praxes_controller.rb @@ -4,7 +4,7 @@ class RulePraxesController < ApplicationController def create create_rule_praxis rescue ActiveRecord::RecordInvalid => e - render json: {error: e.record.errors}, status: :unprocessable_entity + render json: {errors: formatted_errors(e)}, status: :unprocessable_entity end def update @@ -21,7 +21,8 @@ def destroy private def create_rule_praxis - created = RulePraxis.create!(permit_params(:tool_group_id, :negative_rule, openness: [], confidence: [])) + tool_group = ToolGroup.find(params[:tool_group_id]) + created = tool_group.rule_praxes.create!(permit_params(:tool_group_id, :negative_rule, openness: [], confidence: [])) response.headers["Location"] = "tool_groups/#{created.id}" render json: created, status: :created end diff --git a/app/controllers/tool_groups_controller.rb b/app/controllers/tool_groups_controller.rb index ad8cd84d8..746bf2a42 100644 --- a/app/controllers/tool_groups_controller.rb +++ b/app/controllers/tool_groups_controller.rb @@ -13,13 +13,18 @@ def create end def create_tool - rtg = ResourceToolGroup.create!(permit_params(:tool_group_id, :resource_id, :suggestions_weight)) - byebug + ResourceToolGroup.create!(permit_params(:tool_group_id, :resource_id, :suggestions_weight)) tool_group = ToolGroup.find(params[:data][:attributes][:tool_group_id]) response.headers["Location"] = "tool_groups/#{tool_group.id}" render json: tool_group, status: :created end + def update_tool + existing = ResourceToolGroup.find(params[:id]) + existing.update!(permit_params(:tool_group_id, :resource_id, :suggestions_weight)) + render json: existing, status: :accepted + end + def show render json: load_tool_group, include: params[:include], fields: field_params, status: :ok end @@ -55,10 +60,4 @@ def update_tool_group def load_tool_group ToolGroup.find(params[:id]) end - - def formatted_errors(error) - error.record.errors.map do |attribute, errors| - errors.map { |error_message| {detail: "#{attribute} #{error_message}"} } - end.flatten - end end diff --git a/app/models/resource_tool_group.rb b/app/models/resource_tool_group.rb index e7e7b94c6..73836236d 100644 --- a/app/models/resource_tool_group.rb +++ b/app/models/resource_tool_group.rb @@ -4,4 +4,4 @@ class ResourceToolGroup < ApplicationRecord belongs_to :resource belongs_to :tool_group -end \ No newline at end of file +end diff --git a/app/serializers/resource_serializer.rb b/app/serializers/resource_serializer.rb index ab5079656..4d173074e 100644 --- a/app/serializers/resource_serializer.rb +++ b/app/serializers/resource_serializer.rb @@ -16,6 +16,8 @@ class ResourceSerializer < ActiveModel::Serializer has_many :custom_manifests, key: "custom-manifests" has_many :variants, if: -> { object&.resource_type&.name == "metatool" } has_many :translated_attributes, key: "translated-attributes" + + has_many :resource_tool_groups has_many :tool_groups, through: :resource_tool_groups belongs_to :default_variant, key: "default-variant", if: -> { object&.resource_type&.name == "metatool" } diff --git a/app/serializers/resource_tool_group_serializer.rb b/app/serializers/resource_tool_group_serializer.rb index 05c3792ca..64ef6eaf1 100644 --- a/app/serializers/resource_tool_group_serializer.rb +++ b/app/serializers/resource_tool_group_serializer.rb @@ -8,4 +8,4 @@ class ResourceToolGroupSerializer < ActiveModel::Serializer belongs_to :resource belongs_to :tool_group -end \ No newline at end of file +end diff --git a/app/serializers/tool_group_serializer.rb b/app/serializers/tool_group_serializer.rb index 1f8592163..9e90ed840 100644 --- a/app/serializers/tool_group_serializer.rb +++ b/app/serializers/tool_group_serializer.rb @@ -9,6 +9,7 @@ class ToolGroupSerializer < ActiveModel::Serializer has_many :rule_languages, key: "rules-language" has_many :rule_countries, key: "rules-country" has_many :rule_praxes, key: "rules-praxis" + has_many :resource_tool_groups has_many :resources, through: :resource_tool_groups def custom_rule_languages diff --git a/config/routes.rb b/config/routes.rb index 5b001e5ef..079b8f3e6 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -33,6 +33,7 @@ resources :tool_groups, path: "tool-groups", only: [:create, :destroy, :index, :show, :update] do # resources :resources, path: "tools", only: [:create, :destroy, :update] post "tools", to: "tool_groups#create_tool" + put "tools/:id", to: "tool_groups#update_tool" end # Rule Languages diff --git a/spec/acceptance/rule_countries_controller_spec.rb b/spec/acceptance/rule_countries_controller_spec.rb index bff1f9fa5..e14973458 100644 --- a/spec/acceptance/rule_countries_controller_spec.rb +++ b/spec/acceptance/rule_countries_controller_spec.rb @@ -6,6 +6,7 @@ header "Accept", "application/vnd.api+json" header "Content-Type", "application/vnd.api+json" + let(:tool_group_id) { ToolGroup.first.id } let(:raw_post) { params.to_json } let(:authorization) { AuthToken.generic_token } @@ -27,7 +28,6 @@ let(:valid_attrs) do { countries: ["CA", "FR", "US"], - tool_group_id: ToolGroup.first.id, negative_rule: "true" } end @@ -35,14 +35,13 @@ let(:invalid_attrs) do { countries: ["1A"], - tool_group_id: ToolGroup.first.id, negative_rule: "true" } end context "with valid countries values" do it "creates a rule country" do - do_request data: {type: "tool-group-rules-country", attributes: valid_attrs} + do_request tool_group_id: tool_group_id, data: {type: "tool-group-rules-country", attributes: valid_attrs} expect(status).to eq(201) expect(JSON.parse(response_body)["data"]).not_to be_nil @@ -51,11 +50,11 @@ context "with invalid countries values" do it "returns an error" do - do_request data: {type: "tool-group-rules-country", attributes: invalid_attrs} + do_request tool_group_id: tool_group_id, data: {type: "tool-group-rules-country", attributes: invalid_attrs} - expect(status).to eq(422) + expect(status).to eq(400) expect(JSON.parse(response_body)["data"]).to be_nil - expect(JSON.parse(response_body)["error"]["countries"][0]).to eql "must contain only ISO-3166 alpha-2 country codes" + expect(JSON.parse(response_body)["errors"][0]["detail"]).to eql "Validation failed: Countries must contain only ISO-3166 alpha-2 country codes" end end end diff --git a/spec/acceptance/rule_languages_controller_spec.rb b/spec/acceptance/rule_languages_controller_spec.rb index 66aa2b5c4..16d5ee25b 100644 --- a/spec/acceptance/rule_languages_controller_spec.rb +++ b/spec/acceptance/rule_languages_controller_spec.rb @@ -24,16 +24,17 @@ post "tool-groups/:id/rules-language" do requires_authorization + let(:tool_group_id) { ToolGroup.first.id } + let(:attrs) do { languages: ["en", "es"], - tool_group_id: ToolGroup.first.id, negative_rule: "true" } end it "create rule language" do - do_request data: {type: "tool-group-rules-language", attributes: attrs} + do_request tool_group_id: tool_group_id, data: {type: "tool-group-rules-language", attributes: attrs} expect(status).to eq(201) expect(JSON.parse(response_body)["data"]).not_to be_nil end diff --git a/spec/acceptance/rule_praxes_controller_spec.rb b/spec/acceptance/rule_praxes_controller_spec.rb index bad825d16..73d842042 100644 --- a/spec/acceptance/rule_praxes_controller_spec.rb +++ b/spec/acceptance/rule_praxes_controller_spec.rb @@ -29,7 +29,6 @@ let(:valid_attrs) do { - tool_group_id: tool_group_id, openness: openness, confidence: confidence, negative_rule: "true" @@ -38,7 +37,6 @@ let(:repeated_attrs) do { - tool_group_id: tool_group_id, openness: openness, confidence: confidence, negative_rule: "true" @@ -47,7 +45,6 @@ let(:empty_attrs) do { - tool_group_id: tool_group_id, openness: [], confidence: [], negative_rule: "true" @@ -56,7 +53,6 @@ let(:non_valid_openness_attr) do { - tool_group_id: tool_group_id, openness: [0], confidence: [1, 2], negative_rule: "true" @@ -65,7 +61,6 @@ let(:non_valid_confidence_attr) do { - tool_group_id: tool_group_id, openness: [1, 2, 3, 4, 5], confidence: [6], negative_rule: "true" @@ -74,7 +69,7 @@ context "with valid openness and confidence values" do it "create rule praxis" do - do_request data: {type: "tool-group-rules-praxis", attributes: valid_attrs} + do_request tool_group_id: tool_group_id, data: {type: "tool-group-rules-praxis", attributes: valid_attrs} expect(status).to eq(201) expect(JSON.parse(response_body)["data"]).not_to be_nil @@ -87,41 +82,41 @@ end it "returns an error" do - do_request data: {type: "tool-group-rules-praxis", attributes: repeated_attrs} + do_request tool_group_id: tool_group_id, data: {type: "tool-group-rules-praxis", attributes: repeated_attrs} - expect(status).to eq(422) + expect(status).to eq(400) expect(JSON.parse(response_body)["data"]).to be_nil - expect(JSON.parse(response_body)["error"]["tool_group_id"][0]).to eql "combination already exists" + expect(JSON.parse(response_body)["errors"][0]["detail"]).to eql "Validation failed: Tool group combination already exists" end end context "with empty or null openness and confidence values" do it "returns an error" do - do_request data: {type: "tool-group-rules-praxis", attributes: empty_attrs} + do_request tool_group_id: tool_group_id, data: {type: "tool-group-rules-praxis", attributes: empty_attrs} - expect(status).to eq(422) + expect(status).to eq(400) expect(JSON.parse(response_body)["data"]).to be_nil - expect(JSON.parse(response_body)["error"]["base"][0]).to eql "Either 'openness' or 'confidence' must be present" + expect(JSON.parse(response_body)["errors"][0]["detail"]).to eql "Validation failed: Either 'openness' or 'confidence' must be present" end end context "with non valid openness values" do it "returns an error" do - do_request data: {type: "tool-group-rules-praxis", attributes: non_valid_openness_attr} + do_request tool_group_id: tool_group_id, data: {type: "tool-group-rules-praxis", attributes: non_valid_openness_attr} - expect(status).to eq(422) + expect(status).to eq(400) expect(JSON.parse(response_body)["data"]).to be_nil - expect(JSON.parse(response_body)["error"]["openness"][0]).to eql "must contain integer values between 1 and 5 or an empty array" + expect(JSON.parse(response_body)["errors"][0]["detail"]).to eql "Validation failed: Openness must contain integer values between 1 and 5 or an empty array" end end context "with non valid confidence values" do it "returns an error" do - do_request data: {type: "tool-group-rules-praxis", attributes: non_valid_confidence_attr} + do_request tool_group_id: tool_group_id, data: {type: "tool-group-rules-praxis", attributes: non_valid_confidence_attr} - expect(status).to eq(422) + expect(status).to eq(400) expect(JSON.parse(response_body)["data"]).to be_nil - expect(JSON.parse(response_body)["error"]["confidence"][0]).to eql "must contain integer values between 1 and 5 or an empty array" + expect(JSON.parse(response_body)["errors"][0]["detail"]).to eql "Validation failed: Confidence must contain integer values between 1 and 5 or an empty array" end end end diff --git a/spec/acceptance/tool_group_spec.rb b/spec/acceptance/tool_group_spec.rb index 56ab36041..8beeb8682 100644 --- a/spec/acceptance/tool_group_spec.rb +++ b/spec/acceptance/tool_group_spec.rb @@ -13,6 +13,7 @@ let(:openness) { [1, 2, 3] } let(:confidence) { [1, 2] } let(:metatool_resource_type) { ResourceType.find_by(name: "metatool") } + let(:resource) { FactoryBot.create(:resource, system_id: 1, resource_type: metatool_resource_type, name: "Resource Test One", abbreviation: "test1") } before(:each) do %i[one two three].each do |name| @@ -21,7 +22,7 @@ FactoryBot.create(:rule_language, tool_group: ToolGroup.first, languages: languages) FactoryBot.create(:rule_country, tool_group: ToolGroup.first, countries: countries) FactoryBot.create(:rule_praxis, tool_group: ToolGroup.first, openness: openness, confidence: confidence) - FactoryBot.create(:resource, system_id: 1, resource_type: metatool_resource_type, name: "Resource Test One", abbreviation: "test1") + resource end after(:each) do @@ -77,12 +78,37 @@ it "create tool group tool" do do_request data: {type: "tool-group-tool", attributes: attrs} - byebug expect(status).to eq(201) expect(JSON.parse(response_body)["data"]).not_to be_nil end end + put "tool-groups/:tool_group_id/tools/:id" do + requires_authorization + let(:tool_group_first) { ToolGroup.first } + let(:tool_group_last) { ToolGroup.last } + let(:suggestions_weight) { 0.5 } + let(:resource) { Resource.first } + + let(:id) { ResourceToolGroup.create(resource_id: resource.id, tool_group_id: tool_group_first.id, suggestions_weight: "1.0").id } + + let(:attrs) do + { + suggestions_weight: suggestions_weight, + tool_group_id: tool_group_last.id + } + end + + it "update tool group tool" do + do_request id: id, data: {type: "tool-group-tool", attributes: attrs} + + expect(status).to eq(202) + expect(JSON.parse(response_body)["data"]).not_to be_nil + expect(JSON.parse(response_body)["data"]["attributes"]["suggestions-weight"]).to eql suggestions_weight + expect(JSON.parse(response_body)["data"]["attributes"]["tool-group"]["id"]).to eql tool_group_last.id + end + end + get "tool-groups" do requires_authorization From 1edf6e195f8991e20bd1b99d49dbc4bd80edf55a Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Thu, 20 Jul 2023 17:19:25 -0300 Subject: [PATCH 42/50] added delete resource tool group --- app/controllers/tool_groups_controller.rb | 6 ++++++ config/routes.rb | 1 + spec/acceptance/tool_group_spec.rb | 25 ++++++++++++++++++----- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/app/controllers/tool_groups_controller.rb b/app/controllers/tool_groups_controller.rb index 746bf2a42..d817c8479 100644 --- a/app/controllers/tool_groups_controller.rb +++ b/app/controllers/tool_groups_controller.rb @@ -25,6 +25,12 @@ def update_tool render json: existing, status: :accepted end + def delete_tool + resource_tool_group = ResourceToolGroup.find(params[:id]) + resource_tool_group.destroy! + head :no_content + end + def show render json: load_tool_group, include: params[:include], fields: field_params, status: :ok end diff --git a/config/routes.rb b/config/routes.rb index 079b8f3e6..3abc7f440 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -34,6 +34,7 @@ # resources :resources, path: "tools", only: [:create, :destroy, :update] post "tools", to: "tool_groups#create_tool" put "tools/:id", to: "tool_groups#update_tool" + delete "tools/:id", to: "tool_groups#delete_tool" end # Rule Languages diff --git a/spec/acceptance/tool_group_spec.rb b/spec/acceptance/tool_group_spec.rb index 8beeb8682..aadb5b715 100644 --- a/spec/acceptance/tool_group_spec.rb +++ b/spec/acceptance/tool_group_spec.rb @@ -14,6 +14,8 @@ let(:confidence) { [1, 2] } let(:metatool_resource_type) { ResourceType.find_by(name: "metatool") } let(:resource) { FactoryBot.create(:resource, system_id: 1, resource_type: metatool_resource_type, name: "Resource Test One", abbreviation: "test1") } + let(:tool_group_first) { ToolGroup.first } + let(:tool_group_last) { ToolGroup.last } before(:each) do %i[one two three].each do |name| @@ -85,13 +87,9 @@ put "tool-groups/:tool_group_id/tools/:id" do requires_authorization - let(:tool_group_first) { ToolGroup.first } - let(:tool_group_last) { ToolGroup.last } - let(:suggestions_weight) { 0.5 } - let(:resource) { Resource.first } + let(:suggestions_weight) { 0.5 } let(:id) { ResourceToolGroup.create(resource_id: resource.id, tool_group_id: tool_group_first.id, suggestions_weight: "1.0").id } - let(:attrs) do { suggestions_weight: suggestions_weight, @@ -109,6 +107,23 @@ end end + delete "tool-groups/:tool_group_id/tools/:id" do + let(:attrs) do + { + tool_group_id: ToolGroup.first.id + } + end + + let(:id) { ResourceToolGroup.create(resource_id: resource.id, tool_group_id: tool_group_first.id, suggestions_weight: "1.0").id } + requires_authorization + + it "delete tool_group" do + do_request id: id, data: {type: "tool-group-tool", attributes: attrs} + + expect(status).to be(204) + end + end + get "tool-groups" do requires_authorization From 141932d64ac423b847a658272491ee89f175738a Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Thu, 20 Jul 2023 19:04:15 -0300 Subject: [PATCH 43/50] - fixed create_tool action - fixed specs for create_action --- app/controllers/tool_groups_controller.rb | 11 +++++++++-- spec/acceptance/tool_group_spec.rb | 3 +-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/app/controllers/tool_groups_controller.rb b/app/controllers/tool_groups_controller.rb index d817c8479..5d57f8902 100644 --- a/app/controllers/tool_groups_controller.rb +++ b/app/controllers/tool_groups_controller.rb @@ -13,10 +13,17 @@ def create end def create_tool - ResourceToolGroup.create!(permit_params(:tool_group_id, :resource_id, :suggestions_weight)) - tool_group = ToolGroup.find(params[:data][:attributes][:tool_group_id]) + ResourceToolGroup.create!( + tool_group_id: params[:tool_group_id], + resource_id: params[:data][:attributes][:resource_id], + suggestions_weight: params[:data][:attributes][:tool_group_id] + ) + + tool_group = ToolGroup.find(params[:tool_group_id]) response.headers["Location"] = "tool_groups/#{tool_group.id}" render json: tool_group, status: :created + rescue ActiveRecord::RecordInvalid => e + render json: {errors: formatted_errors(e)}, status: :unprocessable_entity end def update_tool diff --git a/spec/acceptance/tool_group_spec.rb b/spec/acceptance/tool_group_spec.rb index aadb5b715..b8885cb1b 100644 --- a/spec/acceptance/tool_group_spec.rb +++ b/spec/acceptance/tool_group_spec.rb @@ -70,7 +70,6 @@ post "tool-groups/:tool_group_id/tools" do let(:attrs) do { - tool_group_id: ToolGroup.first.id, resource_id: Resource.first.id, suggestions_weight: "1.0" } @@ -79,7 +78,7 @@ requires_authorization it "create tool group tool" do - do_request data: {type: "tool-group-tool", attributes: attrs} + do_request tool_group_id: tool_group_first.id, data: {type: "tool-group-tool", attributes: attrs} expect(status).to eq(201) expect(JSON.parse(response_body)["data"]).not_to be_nil end From 1e6981beee7c1080cc9be00eab2d8683da3358d4 Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Thu, 20 Jul 2023 19:45:52 -0300 Subject: [PATCH 44/50] - fixed update_tool action - fixed specs for update_action --- app/controllers/tool_groups_controller.rb | 8 ++++++-- spec/acceptance/tool_group_spec.rb | 6 ++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/app/controllers/tool_groups_controller.rb b/app/controllers/tool_groups_controller.rb index 5d57f8902..169a8817d 100644 --- a/app/controllers/tool_groups_controller.rb +++ b/app/controllers/tool_groups_controller.rb @@ -16,7 +16,7 @@ def create_tool ResourceToolGroup.create!( tool_group_id: params[:tool_group_id], resource_id: params[:data][:attributes][:resource_id], - suggestions_weight: params[:data][:attributes][:tool_group_id] + suggestions_weight: params[:data][:attributes]["suggestions-weight"] ) tool_group = ToolGroup.find(params[:tool_group_id]) @@ -28,7 +28,11 @@ def create_tool def update_tool existing = ResourceToolGroup.find(params[:id]) - existing.update!(permit_params(:tool_group_id, :resource_id, :suggestions_weight)) + + existing.update!( + resource_id: params[:data][:attributes][:resource_id], + suggestions_weight: params[:data][:attributes][:suggestions_weight] + ) render json: existing, status: :accepted end diff --git a/spec/acceptance/tool_group_spec.rb b/spec/acceptance/tool_group_spec.rb index b8885cb1b..960cdab2a 100644 --- a/spec/acceptance/tool_group_spec.rb +++ b/spec/acceptance/tool_group_spec.rb @@ -92,7 +92,7 @@ let(:attrs) do { suggestions_weight: suggestions_weight, - tool_group_id: tool_group_last.id + resource_id: resource.id } end @@ -102,7 +102,7 @@ expect(status).to eq(202) expect(JSON.parse(response_body)["data"]).not_to be_nil expect(JSON.parse(response_body)["data"]["attributes"]["suggestions-weight"]).to eql suggestions_weight - expect(JSON.parse(response_body)["data"]["attributes"]["tool-group"]["id"]).to eql tool_group_last.id + expect(JSON.parse(response_body)["data"]["attributes"]["resource-id"]).to eql resource.id end end @@ -145,8 +145,6 @@ expect(included[2]["attributes"]["openness"]).to eql openness expect(included[2]["attributes"]["confidence"]).to eql confidence - expect(included[2]["attributes"].key?("openness")).to eql true - expect(included[2]["attributes"].key?("confidence")).to eql true end end From 63261036cf217ea8854dfdc19141cef1125b74b1 Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Thu, 20 Jul 2023 20:28:06 -0300 Subject: [PATCH 45/50] fixed params for tools group tools create and update --- app/controllers/tool_groups_controller.rb | 7 +++---- spec/acceptance/tool_group_spec.rb | 8 ++++---- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/app/controllers/tool_groups_controller.rb b/app/controllers/tool_groups_controller.rb index 169a8817d..0da3ee542 100644 --- a/app/controllers/tool_groups_controller.rb +++ b/app/controllers/tool_groups_controller.rb @@ -15,7 +15,7 @@ def create def create_tool ResourceToolGroup.create!( tool_group_id: params[:tool_group_id], - resource_id: params[:data][:attributes][:resource_id], + resource_id: params[:data][:attributes]["resource-id"], suggestions_weight: params[:data][:attributes]["suggestions-weight"] ) @@ -28,10 +28,9 @@ def create_tool def update_tool existing = ResourceToolGroup.find(params[:id]) - existing.update!( - resource_id: params[:data][:attributes][:resource_id], - suggestions_weight: params[:data][:attributes][:suggestions_weight] + resource_id: params[:data][:attributes]["resource-id"], + suggestions_weight: params[:data][:attributes]["suggestions-weight"] ) render json: existing, status: :accepted end diff --git a/spec/acceptance/tool_group_spec.rb b/spec/acceptance/tool_group_spec.rb index 960cdab2a..04eeb9019 100644 --- a/spec/acceptance/tool_group_spec.rb +++ b/spec/acceptance/tool_group_spec.rb @@ -70,8 +70,8 @@ post "tool-groups/:tool_group_id/tools" do let(:attrs) do { - resource_id: Resource.first.id, - suggestions_weight: "1.0" + "resource-id": Resource.first.id, + "suggestions-weight": "1.0" } end @@ -91,8 +91,8 @@ let(:id) { ResourceToolGroup.create(resource_id: resource.id, tool_group_id: tool_group_first.id, suggestions_weight: "1.0").id } let(:attrs) do { - suggestions_weight: suggestions_weight, - resource_id: resource.id + "suggestions-weight": suggestions_weight, + "resource-id": resource.id } end From fe011cff2ebd6452ae618a93931e8d0ebc04eacf Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Thu, 20 Jul 2023 21:00:37 -0300 Subject: [PATCH 46/50] - added key "resource-tool-groups" to serializer --- app/serializers/tool_group_serializer.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/serializers/tool_group_serializer.rb b/app/serializers/tool_group_serializer.rb index 9e90ed840..c7d0b1d22 100644 --- a/app/serializers/tool_group_serializer.rb +++ b/app/serializers/tool_group_serializer.rb @@ -9,7 +9,7 @@ class ToolGroupSerializer < ActiveModel::Serializer has_many :rule_languages, key: "rules-language" has_many :rule_countries, key: "rules-country" has_many :rule_praxes, key: "rules-praxis" - has_many :resource_tool_groups + has_many :resource_tool_groups, key: "resource-tool-groups" has_many :resources, through: :resource_tool_groups def custom_rule_languages From 753df6288cb15432d45f694b26ad2fde2c4e582e Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Fri, 21 Jul 2023 19:20:15 -0300 Subject: [PATCH 47/50] - Suggestions * added route, controller action and spec --- app/controllers/resources_controller.rb | 5 ++++ config/routes.rb | 2 +- spec/acceptance/resources_controller_spec.rb | 23 +++++++++++++++++++ ..._spec.rb => tool_group_controller_spec.rb} | 0 4 files changed, 29 insertions(+), 1 deletion(-) rename spec/acceptance/{tool_group_spec.rb => tool_group_controller_spec.rb} (100%) diff --git a/app/controllers/resources_controller.rb b/app/controllers/resources_controller.rb index f3ddb17d4..76fccee8c 100644 --- a/app/controllers/resources_controller.rb +++ b/app/controllers/resources_controller.rb @@ -34,6 +34,11 @@ def push_to_onesky head :no_content end + def suggestions + resources = ToolGroup.joins(:rule_countries).where("countries @> ARRAY[?]::varchar[]", params["country"]&.upcase) + render json: resources, status: :ok + end + private def cached_index_json diff --git a/config/routes.rb b/config/routes.rb index 3abc7f440..c6bda858d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -6,6 +6,7 @@ resources :systems, only: [:index, :show] resources :languages resources :resource_types, only: [:index, :show] + get "resources/suggestions", to: "resources#suggestions" resources :resources do resources :languages, controller: :resource_languages, only: [:update, :show] @@ -31,7 +32,6 @@ resources :custom_manifests, only: [:create, :update, :destroy, :show] resources :tool_groups, path: "tool-groups", only: [:create, :destroy, :index, :show, :update] do - # resources :resources, path: "tools", only: [:create, :destroy, :update] post "tools", to: "tool_groups#create_tool" put "tools/:id", to: "tool_groups#update_tool" delete "tools/:id", to: "tool_groups#delete_tool" diff --git a/spec/acceptance/resources_controller_spec.rb b/spec/acceptance/resources_controller_spec.rb index 65a3e4f83..5be762c9e 100644 --- a/spec/acceptance/resources_controller_spec.rb +++ b/spec/acceptance/resources_controller_spec.rb @@ -9,6 +9,13 @@ let(:raw_post) { params.to_json } let(:authorization) { AuthToken.generic_token } + let(:languages) { ["fr", "en"] } + let(:countries_fr) { ["FR"] } + let(:countries_gb) { ["GB"] } + let(:countries_fr_us) { ["FR", "US"] } + let(:openness) { [1, 2, 3] } + let(:confidence) { [1, 2] } + get "resources/" do it "get all resources" do do_request @@ -224,6 +231,22 @@ expect(response_body).to be_empty end end + + get "resources/suggestions" do + context "when matching country param contained in country rule" do + before(:each) do + FactoryBot.create(:tool_group, name: "one") + FactoryBot.create(:rule_country, tool_group: ToolGroup.first, countries: countries_fr_us) + end + it "returns coincidences" do + do_request languages: ["en", "es"], country: "fr", openness: "3" + + expect(status).to be(200) + expect(JSON.parse(response_body)["data"]).not_to be_nil + expect(JSON.parse(response_body)["data"].count).to eql 1 + end + end + end end private diff --git a/spec/acceptance/tool_group_spec.rb b/spec/acceptance/tool_group_controller_spec.rb similarity index 100% rename from spec/acceptance/tool_group_spec.rb rename to spec/acceptance/tool_group_controller_spec.rb From efeee116c4954e68a563e5df212b29efd41c25e8 Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Fri, 21 Jul 2023 19:48:02 -0300 Subject: [PATCH 48/50] more specs for suggestions country rule --- spec/acceptance/resources_controller_spec.rb | 25 +++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/spec/acceptance/resources_controller_spec.rb b/spec/acceptance/resources_controller_spec.rb index 5be762c9e..2110330c0 100644 --- a/spec/acceptance/resources_controller_spec.rb +++ b/spec/acceptance/resources_controller_spec.rb @@ -233,19 +233,32 @@ end get "resources/suggestions" do + before(:each) do + FactoryBot.create(:tool_group, name: "one") + FactoryBot.create(:rule_country, tool_group: ToolGroup.first, countries: countries_fr_us) + end + + # do_request languages: ["en", "es"], country: "fr", openness: "3" + context "when matching country param contained in country rule" do - before(:each) do - FactoryBot.create(:tool_group, name: "one") - FactoryBot.create(:rule_country, tool_group: ToolGroup.first, countries: countries_fr_us) - end - it "returns coincidences" do - do_request languages: ["en", "es"], country: "fr", openness: "3" + it "return coincidences" do + do_request country: "fr" expect(status).to be(200) expect(JSON.parse(response_body)["data"]).not_to be_nil expect(JSON.parse(response_body)["data"].count).to eql 1 end end + + context "when not matching country param contained in country rule" do + it "does not return coincidences" do + do_request country: "gr" + + expect(status).to be(200) + expect(JSON.parse(response_body)["data"]).not_to be_nil + expect(JSON.parse(response_body)["data"].count).to eql 0 + end + end end end From 1fa1741b913b71b7ba87b3dab279ae83a355fed8 Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Fri, 21 Jul 2023 20:34:43 -0300 Subject: [PATCH 49/50] adding more specs --- app/controllers/resources_controller.rb | 5 ++++- spec/acceptance/resources_controller_spec.rb | 14 +++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/app/controllers/resources_controller.rb b/app/controllers/resources_controller.rb index 76fccee8c..3a19840dc 100644 --- a/app/controllers/resources_controller.rb +++ b/app/controllers/resources_controller.rb @@ -35,7 +35,10 @@ def push_to_onesky end def suggestions - resources = ToolGroup.joins(:rule_countries).where("countries @> ARRAY[?]::varchar[]", params["country"]&.upcase) + resources = ToolGroup + .joins(:rule_countries) + .where("countries @> ARRAY[?]::varchar[] AND negative_rule = ?", params["country"]&.upcase, false) + render json: resources, status: :ok end diff --git a/spec/acceptance/resources_controller_spec.rb b/spec/acceptance/resources_controller_spec.rb index 2110330c0..c37f99bf4 100644 --- a/spec/acceptance/resources_controller_spec.rb +++ b/spec/acceptance/resources_controller_spec.rb @@ -240,8 +240,9 @@ # do_request languages: ["en", "es"], country: "fr", openness: "3" - context "when matching country param contained in country rule" do + context "when matching country param contained in country rule with negative rule as false" do it "return coincidences" do + RuleCountry.first.update!(negative_rule: false) do_request country: "fr" expect(status).to be(200) @@ -250,6 +251,17 @@ end end + context "when matching country param contained in country rule with negative rule as true" do + it "does not return coincidences" do + RuleCountry.first.update!(negative_rule: true) + do_request country: "fr" + + expect(status).to be(200) + expect(JSON.parse(response_body)["data"]).not_to be_nil + expect(JSON.parse(response_body)["data"].count).to eql 0 + end + end + context "when not matching country param contained in country rule" do it "does not return coincidences" do do_request country: "gr" From 6d25bd57234636477f2dfe9d2fd787c9401b02af Mon Sep 17 00:00:00 2001 From: Cesar Diaz Date: Fri, 21 Jul 2023 21:32:30 -0300 Subject: [PATCH 50/50] - added AR queries to get tool groups * if country matches and negative rule false * if country does not match and negative rule true * specs --- app/controllers/resources_controller.rb | 26 ++- app/models/tool_group.rb | 18 ++ spec/acceptance/resources_controller_spec.rb | 182 ++++++++++++++----- 3 files changed, 179 insertions(+), 47 deletions(-) diff --git a/app/controllers/resources_controller.rb b/app/controllers/resources_controller.rb index 3a19840dc..9b9763b7d 100644 --- a/app/controllers/resources_controller.rb +++ b/app/controllers/resources_controller.rb @@ -35,11 +35,27 @@ def push_to_onesky end def suggestions - resources = ToolGroup - .joins(:rule_countries) - .where("countries @> ARRAY[?]::varchar[] AND negative_rule = ?", params["country"]&.upcase, false) - - render json: resources, status: :ok + resources_1 = ToolGroup + .matching_countries__negative_rule_false(params["country"]) + .matching_languages__negative_rule_false(params["languages"]) + .joins(:rule_countries, :rule_languages) + + resources_2 = ToolGroup + .countries_not_matching__negative_rule_true(params["country"]) + .matching_languages__negative_rule_false(params["languages"]) + .joins(:rule_countries, :rule_languages) + + resources_3 = ToolGroup + .matching_countries__negative_rule_false(params["country"]) + .languages_not_matching__negative_rule_true(params["languages"]) + .joins(:rule_countries, :rule_languages) + + resources_4 = ToolGroup + .countries_not_matching__negative_rule_true(params["country"]) + .matching_languages__negative_rule_false(params["languages"]) + .joins(:rule_countries, :rule_languages) + + render json: resources_1 + resources_2 + resources_3 + resources_4, status: :ok end private diff --git a/app/models/tool_group.rb b/app/models/tool_group.rb index c45705086..cd3861939 100644 --- a/app/models/tool_group.rb +++ b/app/models/tool_group.rb @@ -10,4 +10,22 @@ class ToolGroup < ApplicationRecord has_many :rule_praxes, class_name: "RulePraxis", dependent: :destroy has_many :resource_tool_groups has_many :resources, through: :resource_tool_groups + + scope :matching_countries__negative_rule_false, lambda { |country| + where("countries @> ARRAY[?]::varchar[] AND rule_countries.negative_rule = ?", country&.upcase, false) + } + + scope :matching_languages__negative_rule_false, lambda { |language| + where("languages && ARRAY[?]::varchar[] AND rule_languages.negative_rule = ?", language, false) + } + + scope :languages_not_matching__negative_rule_true, lambda { |languages| + where("NOT ?::varchar[] <@ languages", "{#{languages.join(',')}}") + .where("rule_languages.negative_rule = ?", true) + } + + scope :countries_not_matching__negative_rule_true, lambda { |country| + where.not("countries @> ARRAY[?]::varchar[]", country&.upcase) + .where("rule_countries.negative_rule = ?", true) + } end diff --git a/spec/acceptance/resources_controller_spec.rb b/spec/acceptance/resources_controller_spec.rb index c37f99bf4..4a8ed2e6b 100644 --- a/spec/acceptance/resources_controller_spec.rb +++ b/spec/acceptance/resources_controller_spec.rb @@ -9,13 +9,152 @@ let(:raw_post) { params.to_json } let(:authorization) { AuthToken.generic_token } - let(:languages) { ["fr", "en"] } + let(:languages_fr_en) { ["fr", "en"] } + let(:languages_fr) { ["fr"] } + let(:languages_it) { ["it"] } + let(:languages_en) { ["en"] } let(:countries_fr) { ["FR"] } let(:countries_gb) { ["GB"] } let(:countries_fr_us) { ["FR", "US"] } let(:openness) { [1, 2, 3] } let(:confidence) { [1, 2] } + get "resources/suggestions" do + before(:each) do + FactoryBot.create(:tool_group, name: "one") + FactoryBot.create(:rule_country, tool_group: ToolGroup.first, countries: countries_fr_us) + FactoryBot.create(:rule_language, tool_group: ToolGroup.first, languages: languages_fr_en) + end + + # do_request languages: ["en", "es"], country: "fr", openness: "3" + + context "when matching country param contained in country rule with negative rule as false" do + before do + RuleCountry.first.update!(negative_rule: false) + RuleLanguage.first.update!(negative_rule: false) + end + + it "return coincidences" do + do_request country: "fr", languages: languages_fr + + expect(status).to be(200) + expect(JSON.parse(response_body)["data"]).not_to be_nil + expect(JSON.parse(response_body)["data"].count).to eql 1 + end + + context "plus matching languages with negative rule as false" do + it "return coincidences" do + do_request country: "fr", languages: languages_fr_en + + expect(status).to be(200) + expect(JSON.parse(response_body)["data"]).not_to be_nil + expect(JSON.parse(response_body)["data"].count).to eql 1 + end + end + + context "plus not matching languages with negative rule as false" do + before do + RuleLanguage.first.update!(languages: languages_fr_en) + end + + it "does not return coincidences" do + do_request country: "fr", languages: languages_it + + expect(status).to be(200) + expect(JSON.parse(response_body)["data"]).not_to be_nil + expect(JSON.parse(response_body)["data"].count).to eql 0 + end + end + + context "plus not matching all languages with negative rule as true" do + before do + RuleLanguage.first.update!(languages: languages_en, negative_rule: true) + end + + it "return coincidences" do + do_request country: "fr", languages: languages_fr_en + + expect(status).to be(200) + expect(JSON.parse(response_body)["data"]).not_to be_nil + expect(JSON.parse(response_body)["data"].count).to eql 1 + end + end + + context "plus not matching languages with negative rule as false" do + it "does not return coincidences" do + do_request country: "fr", languages: languages_it + + expect(status).to be(200) + expect(JSON.parse(response_body)["data"]).not_to be_nil + expect(JSON.parse(response_body)["data"].count).to eql 0 + end + end + end + + context "when matching country param contained in country rule with negative rule as true" do + before do + RuleCountry.first.update!(negative_rule: true) + end + + it "does not return coincidences" do + do_request country: "fr", languages: languages_fr_en + + expect(status).to be(200) + expect(JSON.parse(response_body)["data"]).not_to be_nil + expect(JSON.parse(response_body)["data"].count).to eql 0 + end + end + + context "when not matching country param contained in country rule with negative rule as false" do + before do + RuleCountry.first.update!(negative_rule: false) + end + + it "does not return coincidences" do + do_request country: "gb", languages: languages_fr_en + + expect(status).to be(200) + expect(JSON.parse(response_body)["data"]).not_to be_nil + expect(JSON.parse(response_body)["data"].count).to eql 0 + end + end + + context "when not matching country param contained in country rule with negative rule as true" do + before do + RuleCountry.first.update!(negative_rule: true) + RuleLanguage.first.update!(negative_rule: false) + end + + context "plus matching languages with negative rule as true" do + before do + RuleLanguage.first.update!(negative_rule: true) + end + + it "does not return coincidences" do + do_request country: "gb", languages: languages_fr_en + + expect(status).to be(200) + expect(JSON.parse(response_body)["data"]).not_to be_nil + expect(JSON.parse(response_body)["data"].count).to eql 0 + end + end + + context "plus matching languages with negative rule as false" do + before do + RuleLanguage.first.update!(negative_rule: false) + end + + it "return coincidences" do + do_request country: "gb", languages: languages_fr_en + + expect(status).to be(200) + expect(JSON.parse(response_body)["data"]).not_to be_nil + expect(JSON.parse(response_body)["data"].count).to eql 1 + end + end + end + end + get "resources/" do it "get all resources" do do_request @@ -231,47 +370,6 @@ expect(response_body).to be_empty end end - - get "resources/suggestions" do - before(:each) do - FactoryBot.create(:tool_group, name: "one") - FactoryBot.create(:rule_country, tool_group: ToolGroup.first, countries: countries_fr_us) - end - - # do_request languages: ["en", "es"], country: "fr", openness: "3" - - context "when matching country param contained in country rule with negative rule as false" do - it "return coincidences" do - RuleCountry.first.update!(negative_rule: false) - do_request country: "fr" - - expect(status).to be(200) - expect(JSON.parse(response_body)["data"]).not_to be_nil - expect(JSON.parse(response_body)["data"].count).to eql 1 - end - end - - context "when matching country param contained in country rule with negative rule as true" do - it "does not return coincidences" do - RuleCountry.first.update!(negative_rule: true) - do_request country: "fr" - - expect(status).to be(200) - expect(JSON.parse(response_body)["data"]).not_to be_nil - expect(JSON.parse(response_body)["data"].count).to eql 0 - end - end - - context "when not matching country param contained in country rule" do - it "does not return coincidences" do - do_request country: "gr" - - expect(status).to be(200) - expect(JSON.parse(response_body)["data"]).not_to be_nil - expect(JSON.parse(response_body)["data"].count).to eql 0 - end - end - end end private