diff --git a/lib/graph_ql/association_resolver.rb b/lib/graph_ql/association_resolver.rb index a896a0644..142b24313 100644 --- a/lib/graph_ql/association_resolver.rb +++ b/lib/graph_ql/association_resolver.rb @@ -13,23 +13,24 @@ module GraphQL filter_forbidden_elements(requested_elements) end - def target_public_elements - target_model.respond_to?(:public_for_api) ? target_model.public_for_api : target_model.all - end - - def filter_forbidden_elements(requested_elements) - if AssociationResolver.matching_exceptions.include?(field_name) - requested_elements - elsif requested_elements.respond_to?(:each) - requested_elements.all & allowed_elements.all - else - allowed_elements.include?(requested_elements) ? requested_elements : nil - end - end - def self.matching_exceptions [:public_voter] end + private + + def target_public_elements + target_model.respond_to?(:public_for_api) ? target_model.public_for_api : target_model.all + end + + def filter_forbidden_elements(requested_elements) + if AssociationResolver.matching_exceptions.include?(field_name) + requested_elements + elsif requested_elements.respond_to?(:each) + requested_elements.all & allowed_elements.all + else + allowed_elements.include?(requested_elements) ? requested_elements : nil + end + end end end diff --git a/spec/lib/association_resolver_spec.rb b/spec/lib/association_resolver_spec.rb new file mode 100644 index 000000000..adb8a8b34 --- /dev/null +++ b/spec/lib/association_resolver_spec.rb @@ -0,0 +1,62 @@ +require 'rails_helper' + +describe GraphQL::AssociationResolver do + let(:comments_resolver) { GraphQL::AssociationResolver.new(:comments, Comment) } + let(:geozone_resolver) { GraphQL::AssociationResolver.new(:geozone, Geozone) } + let(:geozones_resolver) { GraphQL::AssociationResolver.new(:geozones, Geozone) } + + describe '#initialize' do + it 'sets allowed elements for unscoped models' do + geozone_1 = create(:geozone) + geozone_2 = create(:geozone) + + expect(geozones_resolver.allowed_elements).to match_array([geozone_1, geozone_2]) + end + + it 'sets allowed elements for scoped models' do + public_comment = create(:comment, commentable: create(:proposal)) + restricted_comment = create(:comment, commentable: create(:proposal, :hidden)) + + expect(comments_resolver.allowed_elements).to match_array([public_comment]) + end + end + + describe '#call' do + it 'resolves simple associations' do + geozone = create(:geozone) + proposal = create(:proposal, geozone: geozone) + + result = geozone_resolver.call(proposal, nil, nil) + + expect(result).to eq(geozone) + end + + it 'blocks forbidden elements when resolving simple associations' do + skip 'None of the current models allows this spec to be executed' + end + + it 'resolves paginated associations' do + proposal = create(:proposal) + comment_1 = create(:comment, commentable: proposal) + comment_2 = create(:comment, commentable: proposal) + comment_3 = create(:comment, commentable: create(:proposal)) + + result = comments_resolver.call(proposal, nil, nil) + + expect(result).to match_array([comment_1, comment_2]) + end + + it 'blocks forbidden elements when resolving paginated associations' do + proposal = create(:proposal, :hidden) + comment = create(:comment, commentable: proposal) + + result = comments_resolver.call(proposal, nil, nil) + + expect(result).to be_empty + end + + it 'permits all elements for exceptions' do + skip 'Current implementation is temporary' + end + end +end