diff --git a/config/initializers/acts_as_taggable_on.rb b/config/initializers/acts_as_taggable_on.rb index 45b6e706c..719f1271f 100644 --- a/config/initializers/acts_as_taggable_on.rb +++ b/config/initializers/acts_as_taggable_on.rb @@ -21,7 +21,7 @@ module ActsAsTaggableOn Tag.class_eval do include Graphqlable - + def increment_custom_counter_for(taggable_type) Tag.increment_counter(custom_counter_field_name_for(taggable_type), id) end @@ -45,7 +45,20 @@ module ActsAsTaggableOn end def self.public_for_api - where("kind IS NULL OR kind = 'category'") + find_by_sql(%| + SELECT * + FROM tags + WHERE (tags.kind IS NULL OR tags.kind = 'category') AND tags.id IN ( + SELECT tag_id + FROM ( + SELECT COUNT(taggings.id) AS taggings_count, tag_id + FROM ((taggings FULL OUTER JOIN proposals ON taggable_type = 'Proposal' AND taggable_id = proposals.id) FULL OUTER JOIN debates ON taggable_type = 'Debate' AND taggable_id = debates.id) + WHERE (taggable_type = 'Proposal' AND proposals.hidden_at IS NULL) OR (taggable_type = 'Debate' AND debates.hidden_at IS NULL) + GROUP BY tag_id + ) AS tag_taggings_count_relation + WHERE taggings_count > 0 + ) + |) end private diff --git a/spec/lib/acts_as_taggable_on_spec.rb b/spec/lib/acts_as_taggable_on_spec.rb index 59a469f88..d261bbad2 100644 --- a/spec/lib/acts_as_taggable_on_spec.rb +++ b/spec/lib/acts_as_taggable_on_spec.rb @@ -66,23 +66,72 @@ describe 'ActsAsTaggableOn' do end describe "public_for_api scope" do - it "returns tags whose kind is NULL" do + + it "returns tags whose kind is NULL and have at least one tagging whose taggable is not hidden" do tag = create(:tag, kind: nil) + proposal = create(:proposal) + proposal.tag_list.add(tag) + proposal.save expect(ActsAsTaggableOn::Tag.public_for_api).to include(tag) end - it "returns tags whose kind is 'category'" do + it "returns tags whose kind is 'category' and have at least one tagging whose taggable is not hidden" do tag = create(:tag, kind: 'category') + proposal = create(:proposal) + proposal.tag_list.add(tag) + proposal.save expect(ActsAsTaggableOn::Tag.public_for_api).to include(tag) end it "blocks other kinds of tags" do tag = create(:tag, kind: 'foo') + proposal = create(:proposal) + proposal.tag_list.add(tag) + proposal.save expect(ActsAsTaggableOn::Tag.public_for_api).not_to include(tag) end + + it "blocks tags that don't have at least one tagged element" do + tag = create(:tag) + + expect(ActsAsTaggableOn::Tag.public_for_api).to_not include(tag) + end + + it 'only permits tags on proposals or debates' do + tag_1 = create(:tag) + tag_2 = create(:tag) + tag_3 = create(:tag) + + proposal = create(:proposal) + spending_proposal = create(:spending_proposal) + debate = create(:debate) + + proposal.tag_list.add(tag_1) + spending_proposal.tag_list.add(tag_2) + debate.tag_list.add(tag_3) + + proposal.save + spending_proposal.save + debate.save + + expect(ActsAsTaggableOn::Tag.public_for_api).to match_array([tag_1, tag_3]) + end + + it 'blocks tags after its taggings became hidden' do + tag = create(:tag) + proposal = create(:proposal) + proposal.tag_list.add(tag) + proposal.save + + expect(ActsAsTaggableOn::Tag.public_for_api).to include(tag) + + proposal.delete + + expect(ActsAsTaggableOn::Tag.public_for_api).to be_empty + end end end diff --git a/spec/models/comment_spec.rb b/spec/models/comment_spec.rb index db68a9e4e..993710c13 100644 --- a/spec/models/comment_spec.rb +++ b/spec/models/comment_spec.rb @@ -134,7 +134,7 @@ describe Comment do end end - describe "public_for_api" do + describe "public_for_api scope" do it "returns comments" do comment = create(:comment) @@ -174,5 +174,12 @@ describe Comment do expect(Comment.public_for_api).not_to include(comment) end + + it 'does not return comments on budget investments' do + budget_investment = create(:budget_investment) + comment = create(:comment, commentable: budget_investment) + + expect(Comment.public_for_api).not_to include(comment) + end end end diff --git a/spec/models/debate_spec.rb b/spec/models/debate_spec.rb index 5272b6e7a..bae8a5f16 100644 --- a/spec/models/debate_spec.rb +++ b/spec/models/debate_spec.rb @@ -700,4 +700,16 @@ describe Debate do end end + describe 'public_for_api scope' do + it 'returns debates' do + debate = create(:debate) + expect(Debate.public_for_api).to include(debate) + end + + it 'does not return hidden debates' do + debate = create(:debate, :hidden) + expect(Debate.public_for_api).to_not include(debate) + end + end + end diff --git a/spec/models/proposal_spec.rb b/spec/models/proposal_spec.rb index 7c8d3fb41..b2bb63140 100644 --- a/spec/models/proposal_spec.rb +++ b/spec/models/proposal_spec.rb @@ -842,4 +842,16 @@ describe Proposal do end end + describe 'public_for_api scope' do + it 'returns proposals' do + proposal = create(:proposal) + expect(Proposal.public_for_api).to include(proposal) + end + + it 'does not return hidden proposals' do + proposal = create(:proposal, :hidden) + expect(Proposal.public_for_api).to_not include(proposal) + end + end + end