diff options
Diffstat (limited to 'spec/graphql/resolvers')
14 files changed, 315 insertions, 42 deletions
diff --git a/spec/graphql/resolvers/base_resolver_spec.rb b/spec/graphql/resolvers/base_resolver_spec.rb index 8a24b69eb6f..8d2ae238bfe 100644 --- a/spec/graphql/resolvers/base_resolver_spec.rb +++ b/spec/graphql/resolvers/base_resolver_spec.rb @@ -277,8 +277,8 @@ RSpec.describe Resolvers::BaseResolver do describe '#offset_pagination' do let(:instance) { resolver_instance(resolver) } - it 'is sugar for OffsetActiveRecordRelationConnection.new' do - expect(instance.offset_pagination(User.none)).to be_a(::Gitlab::Graphql::Pagination::OffsetActiveRecordRelationConnection) + it 'is sugar for OffsetPaginatedRelation.new' do + expect(instance.offset_pagination(User.none)).to be_a(::Gitlab::Graphql::Pagination::OffsetPaginatedRelation) end end end diff --git a/spec/graphql/resolvers/board_list_issues_resolver_spec.rb b/spec/graphql/resolvers/board_list_issues_resolver_spec.rb index e7c56a526f4..5eda840854a 100644 --- a/spec/graphql/resolvers/board_list_issues_resolver_spec.rb +++ b/spec/graphql/resolvers/board_list_issues_resolver_spec.rb @@ -23,19 +23,19 @@ RSpec.describe Resolvers::BoardListIssuesResolver do it 'returns the issues in the correct order' do # by relative_position and then ID - issues = resolve_board_list_issues.items + issues = resolve_board_list_issues expect(issues.map(&:id)).to eq [issue3.id, issue1.id, issue2.id] end it 'finds only issues matching filters' do - result = resolve_board_list_issues(args: { filters: { label_name: [label.title], not: { label_name: [label2.title] } } }).items + result = resolve_board_list_issues(args: { filters: { label_name: [label.title], not: { label_name: [label2.title] } } }) expect(result).to match_array([issue1, issue3]) end it 'finds only issues matching search param' do - result = resolve_board_list_issues(args: { filters: { search: issue1.title } }).items + result = resolve_board_list_issues(args: { filters: { search: issue1.title } }) expect(result).to match_array([issue1]) end diff --git a/spec/graphql/resolvers/board_lists_resolver_spec.rb b/spec/graphql/resolvers/board_lists_resolver_spec.rb index 71ebec4dc7e..fdcebd30bb3 100644 --- a/spec/graphql/resolvers/board_lists_resolver_spec.rb +++ b/spec/graphql/resolvers/board_lists_resolver_spec.rb @@ -21,7 +21,7 @@ RSpec.describe Resolvers::BoardListsResolver do end it 'does not create the backlog list' do - lists = resolve_board_lists.items + lists = resolve_board_lists expect(lists.count).to eq 1 expect(lists[0].list_type).to eq 'closed' @@ -38,7 +38,7 @@ RSpec.describe Resolvers::BoardListsResolver do let!(:backlog_list) { create(:backlog_list, board: board) } it 'returns a list of board lists' do - lists = resolve_board_lists.items + lists = resolve_board_lists expect(lists.count).to eq 3 expect(lists.map(&:list_type)).to eq %w(backlog label closed) @@ -50,7 +50,7 @@ RSpec.describe Resolvers::BoardListsResolver do end it 'returns the complete list of board lists for this user' do - lists = resolve_board_lists.items + lists = resolve_board_lists expect(lists.count).to eq 3 end @@ -58,7 +58,7 @@ RSpec.describe Resolvers::BoardListsResolver do context 'when querying for a single list' do it 'returns specified list' do - list = resolve_board_lists(args: { id: global_id_of(label_list) }).items + list = resolve_board_lists(args: { id: global_id_of(label_list) }) expect(list).to eq [label_list] end @@ -69,13 +69,13 @@ RSpec.describe Resolvers::BoardListsResolver do external_label = create(:group_label, group: group) external_list = create(:list, board: external_board, label: external_label) - list = resolve_board_lists(args: { id: global_id_of(external_list) }).items + list = resolve_board_lists(args: { id: global_id_of(external_list) }) expect(list).to eq List.none end it 'raises an argument error if list ID is not valid' do - expect { resolve_board_lists(args: { id: 'test' }).items } + expect { resolve_board_lists(args: { id: 'test' }) } .to raise_error(Gitlab::Graphql::Errors::ArgumentError) end end diff --git a/spec/graphql/resolvers/ci/config_resolver_spec.rb b/spec/graphql/resolvers/ci/config_resolver_spec.rb index ca7ae73fef8..73e9fab9f99 100644 --- a/spec/graphql/resolvers/ci/config_resolver_spec.rb +++ b/spec/graphql/resolvers/ci/config_resolver_spec.rb @@ -36,7 +36,8 @@ RSpec.describe Resolvers::Ci::ConfigResolver do File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci_includes.yml')) end - it 'lints the ci config file' do + it 'lints the ci config file and returns the merged yaml file' do + expect(response[:merged_yaml]).to eq(content) expect(response[:status]).to eq(:valid) expect(response[:errors]).to be_empty end diff --git a/spec/graphql/resolvers/container_repositories_resolver_spec.rb b/spec/graphql/resolvers/container_repositories_resolver_spec.rb index b888d79626e..a17d2a7b0d5 100644 --- a/spec/graphql/resolvers/container_repositories_resolver_spec.rb +++ b/spec/graphql/resolvers/container_repositories_resolver_spec.rb @@ -27,6 +27,34 @@ RSpec.describe Resolvers::ContainerRepositoriesResolver do it { is_expected.to contain_exactly(named_container_repository) } end + + context 'with a sort argument' do + let_it_be(:group) { create(:group) } + let_it_be(:project) { create(:project, group: group) } + let_it_be(:sort_repository) do + create(:container_repository, name: 'bar', project: project, created_at: 1.day.ago) + end + + let_it_be(:sort_repository2) do + create(:container_repository, name: 'foo', project: project, created_at: 1.hour.ago, updated_at: 1.hour.ago) + end + + [:created_desc, :updated_asc, :name_desc].each do |order| + context "#{order}" do + let(:args) { { sort: order } } + + it { is_expected.to eq([sort_repository2, sort_repository]) } + end + end + + [:created_asc, :updated_desc, :name_asc].each do |order| + context "#{order}" do + let(:args) { { sort: order } } + + it { is_expected.to eq([sort_repository, sort_repository2]) } + end + end + end end context 'with authorized user' do diff --git a/spec/graphql/resolvers/group_labels_resolver_spec.rb b/spec/graphql/resolvers/group_labels_resolver_spec.rb new file mode 100644 index 00000000000..ed94f12502a --- /dev/null +++ b/spec/graphql/resolvers/group_labels_resolver_spec.rb @@ -0,0 +1,96 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Resolvers::GroupLabelsResolver do + include GraphqlHelpers + + using RSpec::Parameterized::TableSyntax + + let_it_be(:current_user) { create(:user) } + let_it_be(:group, reload: true) { create(:group, :private) } + let_it_be(:subgroup, reload: true) { create(:group, :private, parent: group) } + let_it_be(:sub_subgroup, reload: true) { create(:group, :private, parent: subgroup) } + let_it_be(:project, reload: true) { create(:project, :private, group: sub_subgroup) } + let_it_be(:label1) { create(:label, project: project, name: 'project feature') } + let_it_be(:label2) { create(:label, project: project, name: 'new project feature') } + let_it_be(:group_label1) { create(:group_label, group: group, name: 'group feature') } + let_it_be(:group_label2) { create(:group_label, group: group, name: 'new group feature') } + let_it_be(:subgroup_label1) { create(:group_label, group: subgroup, name: 'subgroup feature') } + let_it_be(:subgroup_label2) { create(:group_label, group: subgroup, name: 'new subgroup feature') } + let_it_be(:sub_subgroup_label1) { create(:group_label, group: sub_subgroup, name: 'sub_subgroup feature') } + let_it_be(:sub_subgroup_label2) { create(:group_label, group: sub_subgroup, name: 'new sub_subgroup feature') } + + specify do + expect(described_class).to have_nullable_graphql_type(Types::LabelType.connection_type) + end + + describe '#resolve' do + context 'with unauthorized user' do + it 'raises error' do + expect { resolve_labels(subgroup) }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable) + end + end + + context 'with authorized user' do + it 'does not raise error' do + group.add_guest(current_user) + + expect { resolve_labels(subgroup) }.not_to raise_error + end + end + + context 'without parent' do + it 'returns no labels' do + expect(resolve_labels(nil)).to eq(Label.none) + end + end + + context 'at group level' do + before_all do + group.add_developer(current_user) + end + + # because :include_ancestor_groups, :include_descendant_groups, :only_group_labels default to false + # the `nil` value would be equivalent to passing in `false` so just check for `nil` option + where(:include_ancestor_groups, :include_descendant_groups, :only_group_labels, :search_term, :test) do + nil | nil | nil | nil | -> { expect(subject).to contain_exactly(subgroup_label1, subgroup_label2) } + nil | nil | true | nil | -> { expect(subject).to contain_exactly(subgroup_label1, subgroup_label2) } + nil | true | nil | nil | -> { expect(subject).to contain_exactly(subgroup_label1, subgroup_label2, sub_subgroup_label1, sub_subgroup_label2, label1, label2) } + nil | true | true | nil | -> { expect(subject).to contain_exactly(subgroup_label1, subgroup_label2, sub_subgroup_label1, sub_subgroup_label2) } + true | nil | nil | nil | -> { expect(subject).to contain_exactly(group_label1, group_label2, subgroup_label1, subgroup_label2) } + true | nil | true | nil | -> { expect(subject).to contain_exactly(group_label1, group_label2, subgroup_label1, subgroup_label2) } + true | true | nil | nil | -> { expect(subject).to contain_exactly(group_label1, group_label2, subgroup_label1, subgroup_label2, sub_subgroup_label1, sub_subgroup_label2, label1, label2) } + true | true | true | nil | -> { expect(subject).to contain_exactly(group_label1, group_label2, subgroup_label1, subgroup_label2, sub_subgroup_label1, sub_subgroup_label2) } + + nil | nil | nil | 'new' | -> { expect(subject).to contain_exactly(subgroup_label2) } + nil | nil | true | 'new' | -> { expect(subject).to contain_exactly(subgroup_label2) } + nil | true | nil | 'new' | -> { expect(subject).to contain_exactly(subgroup_label2, sub_subgroup_label2, label2) } + nil | true | true | 'new' | -> { expect(subject).to contain_exactly(subgroup_label2, sub_subgroup_label2) } + true | nil | nil | 'new' | -> { expect(subject).to contain_exactly(group_label2, subgroup_label2) } + true | nil | true | 'new' | -> { expect(subject).to contain_exactly(group_label2, subgroup_label2) } + true | true | nil | 'new' | -> { expect(subject).to contain_exactly(group_label2, subgroup_label2, sub_subgroup_label2, label2) } + true | true | true | 'new' | -> { expect(subject).to contain_exactly(group_label2, subgroup_label2, sub_subgroup_label2) } + end + + with_them do + let(:params) do + { + include_ancestor_groups: include_ancestor_groups, + include_descendant_groups: include_descendant_groups, + only_group_labels: only_group_labels, + search_term: search_term + } + end + + subject { resolve_labels(subgroup, params) } + + it { self.instance_exec(&test) } + end + end + end + + def resolve_labels(parent, args = {}, context = { current_user: current_user }) + resolve(described_class, obj: parent, args: args, ctx: context) + end +end diff --git a/spec/graphql/resolvers/issues_resolver_spec.rb b/spec/graphql/resolvers/issues_resolver_spec.rb index 269ee9eabf9..8980f4aa19d 100644 --- a/spec/graphql/resolvers/issues_resolver_spec.rb +++ b/spec/graphql/resolvers/issues_resolver_spec.rb @@ -195,11 +195,11 @@ RSpec.describe Resolvers::IssuesResolver do let_it_be(:priority_issue4) { create(:issue, project: project) } it 'sorts issues ascending' do - expect(resolve_issues(sort: :priority_asc).items).to eq([priority_issue3, priority_issue1, priority_issue2, priority_issue4]) + expect(resolve_issues(sort: :priority_asc).to_a).to eq([priority_issue3, priority_issue1, priority_issue2, priority_issue4]) end it 'sorts issues descending' do - expect(resolve_issues(sort: :priority_desc).items).to eq([priority_issue1, priority_issue3, priority_issue2, priority_issue4]) + expect(resolve_issues(sort: :priority_desc).to_a).to eq([priority_issue1, priority_issue3, priority_issue2, priority_issue4]) end end @@ -214,11 +214,11 @@ RSpec.describe Resolvers::IssuesResolver do let_it_be(:label_issue4) { create(:issue, project: project) } it 'sorts issues ascending' do - expect(resolve_issues(sort: :label_priority_asc).items).to eq([label_issue3, label_issue1, label_issue2, label_issue4]) + expect(resolve_issues(sort: :label_priority_asc).to_a).to eq([label_issue3, label_issue1, label_issue2, label_issue4]) end it 'sorts issues descending' do - expect(resolve_issues(sort: :label_priority_desc).items).to eq([label_issue2, label_issue3, label_issue1, label_issue4]) + expect(resolve_issues(sort: :label_priority_desc).to_a).to eq([label_issue2, label_issue3, label_issue1, label_issue4]) end end @@ -231,11 +231,11 @@ RSpec.describe Resolvers::IssuesResolver do let_it_be(:milestone_issue3) { create(:issue, project: project, milestone: late_milestone) } it 'sorts issues ascending' do - expect(resolve_issues(sort: :milestone_due_asc).items).to eq([milestone_issue2, milestone_issue3, milestone_issue1]) + expect(resolve_issues(sort: :milestone_due_asc).to_a).to eq([milestone_issue2, milestone_issue3, milestone_issue1]) end it 'sorts issues descending' do - expect(resolve_issues(sort: :milestone_due_desc).items).to eq([milestone_issue3, milestone_issue2, milestone_issue1]) + expect(resolve_issues(sort: :milestone_due_desc).to_a).to eq([milestone_issue3, milestone_issue2, milestone_issue1]) end end diff --git a/spec/graphql/resolvers/labels_resolver_spec.rb b/spec/graphql/resolvers/labels_resolver_spec.rb new file mode 100644 index 00000000000..3d027a6c8d5 --- /dev/null +++ b/spec/graphql/resolvers/labels_resolver_spec.rb @@ -0,0 +1,96 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Resolvers::LabelsResolver do + include GraphqlHelpers + + using RSpec::Parameterized::TableSyntax + + let_it_be(:current_user) { create(:user) } + let_it_be(:group, reload: true) { create(:group, :private) } + let_it_be(:subgroup, reload: true) { create(:group, :private, parent: group) } + let_it_be(:sub_subgroup, reload: true) { create(:group, :private, parent: subgroup) } + let_it_be(:project, reload: true) { create(:project, :private, group: subgroup) } + let_it_be(:label1) { create(:label, project: project, name: 'project feature') } + let_it_be(:label2) { create(:label, project: project, name: 'new project feature') } + let_it_be(:group_label1) { create(:group_label, group: group, name: 'group feature') } + let_it_be(:group_label2) { create(:group_label, group: group, name: 'new group feature') } + let_it_be(:subgroup_label1) { create(:group_label, group: subgroup, name: 'subgroup feature') } + let_it_be(:subgroup_label2) { create(:group_label, group: subgroup, name: 'new subgroup feature') } + let_it_be(:sub_subgroup_label1) { create(:group_label, group: sub_subgroup, name: 'sub_subgroup feature') } + let_it_be(:sub_subgroup_label2) { create(:group_label, group: sub_subgroup, name: 'new sub_subgroup feature') } + + specify do + expect(described_class).to have_nullable_graphql_type(Types::LabelType.connection_type) + end + + describe '#resolve' do + context 'with unauthorized user' do + it 'returns no labels' do + expect { resolve_labels(project) }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable) + end + end + + context 'with authorized user' do + it 'returns no labels' do + group.add_guest(current_user) + + expect { resolve_labels(project) }.not_to raise_error + end + end + + context 'without parent' do + it 'returns no labels' do + expect(resolve_labels(nil)).to eq(Label.none) + end + end + + context 'at project level' do + before_all do + group.add_developer(current_user) + end + + # because :include_ancestor_groups, :include_descendant_groups, :only_group_labels default to false + # the `nil` value would be equivalent to passing in `false` so just check for `nil` option + where(:include_ancestor_groups, :include_descendant_groups, :only_group_labels, :search_term, :test) do + nil | nil | nil | nil | -> { expect(subject).to contain_exactly(label1, label2, subgroup_label1, subgroup_label2) } + nil | nil | true | nil | -> { expect(subject).to contain_exactly(label1, label2, subgroup_label1, subgroup_label2) } + nil | true | nil | nil | -> { expect(subject).to contain_exactly(label1, label2, subgroup_label1, subgroup_label2, sub_subgroup_label1, sub_subgroup_label2) } + nil | true | true | nil | -> { expect(subject).to contain_exactly(label1, label2, subgroup_label1, subgroup_label2, sub_subgroup_label1, sub_subgroup_label2) } + true | nil | nil | nil | -> { expect(subject).to contain_exactly(label1, label2, group_label1, group_label2, subgroup_label1, subgroup_label2) } + true | nil | true | nil | -> { expect(subject).to contain_exactly(label1, label2, group_label1, group_label2, subgroup_label1, subgroup_label2) } + true | true | nil | nil | -> { expect(subject).to contain_exactly(label1, label2, group_label1, group_label2, subgroup_label1, subgroup_label2, sub_subgroup_label1, sub_subgroup_label2) } + true | true | true | nil | -> { expect(subject).to contain_exactly(label1, label2, group_label1, group_label2, subgroup_label1, subgroup_label2, sub_subgroup_label1, sub_subgroup_label2) } + + nil | nil | nil | 'new' | -> { expect(subject).to contain_exactly(label2, subgroup_label2) } + nil | nil | true | 'new' | -> { expect(subject).to contain_exactly(label2, subgroup_label2) } + nil | true | nil | 'new' | -> { expect(subject).to contain_exactly(label2, subgroup_label2, sub_subgroup_label2) } + nil | true | true | 'new' | -> { expect(subject).to contain_exactly(label2, subgroup_label2, sub_subgroup_label2) } + true | nil | nil | 'new' | -> { expect(subject).to contain_exactly(label2, group_label2, subgroup_label2) } + true | nil | true | 'new' | -> { expect(subject).to contain_exactly(label2, group_label2, subgroup_label2) } + true | true | nil | 'new' | -> { expect(subject).to contain_exactly(label2, group_label2, subgroup_label2, sub_subgroup_label2) } + true | true | true | 'new' | -> { expect(subject).to contain_exactly(label2, group_label2, subgroup_label2, sub_subgroup_label2) } + end + + with_them do + let(:params) do + { + include_ancestor_groups: include_ancestor_groups, + include_descendant_groups: include_descendant_groups, + only_group_labels: only_group_labels, + search_term: search_term + } + end + + subject { resolve_labels(project, params) } + + it { self.instance_exec(&test) } + end + end + end + + def resolve_labels(parent, args = {}, context = { current_user: current_user }) + resolve(described_class, obj: parent, args: args, ctx: context) + end +end diff --git a/spec/graphql/resolvers/merge_requests_resolver_spec.rb b/spec/graphql/resolvers/merge_requests_resolver_spec.rb index 50b9243efa5..c5c368fc88f 100644 --- a/spec/graphql/resolvers/merge_requests_resolver_spec.rb +++ b/spec/graphql/resolvers/merge_requests_resolver_spec.rb @@ -4,6 +4,7 @@ require 'spec_helper' RSpec.describe Resolvers::MergeRequestsResolver do include GraphqlHelpers + include SortingHelper let_it_be(:project) { create(:project, :repository) } let_it_be(:milestone) { create(:milestone, project: project) } @@ -30,6 +31,16 @@ RSpec.describe Resolvers::MergeRequestsResolver do end describe '#resolve' do + # One for the initial auth, then MRs, and the load of project and project_feature (for further auth): + # SELECT MAX("project_authorizations"."access_level") AS maximum_access_level, + # "project_authorizations"."user_id" AS project_authorizations_user_id + # FROM "project_authorizations" + # WHERE "project_authorizations"."project_id" = 2 AND "project_authorizations"."user_id" = 2 + # GROUP BY "project_authorizations"."user_id" + # SELECT "merge_requests".* FROM "merge_requests" WHERE "merge_requests"."target_project_id" = 2 + # AND "merge_requests"."iid" = 1 ORDER BY "merge_requests"."id" DESC + # SELECT "projects".* FROM "projects" WHERE "projects"."id" = 2 + # SELECT "project_features".* FROM "project_features" WHERE "project_features"."project_id" = 2 let(:queries_per_project) { 3 } context 'no arguments' do @@ -72,15 +83,17 @@ RSpec.describe Resolvers::MergeRequestsResolver do expect(result).to contain_exactly(merge_request_1, merge_request_2, merge_request_3) end - it 'can batch-resolve merge requests from different projects' do + it 'can batch-resolve merge requests from different projects', :request_store, :use_clean_rails_memory_store_caching do # 2 queries for project_authorizations, and 2 for merge_requests - result = batch_sync(max_queries: queries_per_project * 2) do - resolve_mr(project, iids: [iid_1]) + - resolve_mr(project, iids: [iid_2]) + - resolve_mr(other_project, iids: [other_iid]) + results = batch_sync(max_queries: queries_per_project * 2) do + a = resolve_mr(project, iids: [iid_1]) + b = resolve_mr(project, iids: [iid_2]) + c = resolve_mr(other_project, iids: [other_iid]) + + [a, b, c].flat_map(&:to_a) end - expect(result).to contain_exactly(merge_request_1, merge_request_2, other_merge_request) + expect(results).to contain_exactly(merge_request_1, merge_request_2, other_merge_request) end it 'resolves an unknown iid to be empty' do @@ -134,9 +147,9 @@ RSpec.describe Resolvers::MergeRequestsResolver do it 'takes more than one argument' do mrs = [merge_request_3, merge_request_4] branches = mrs.map(&:target_branch) - result = resolve_mr(project, target_branches: branches ) + result = resolve_mr(project, target_branches: branches) - expect(result.compact).to match_array(mrs) + expect(result).to match_array(mrs) end end @@ -173,7 +186,7 @@ RSpec.describe Resolvers::MergeRequestsResolver do it 'returns merge requests merged between the given period' do result = resolve_mr(project, merged_after: 20.days.ago, merged_before: 5.days.ago) - expect(result).to eq([merge_request_1]) + expect(result).to contain_exactly(merge_request_1) end it 'does not return anything' do @@ -187,7 +200,7 @@ RSpec.describe Resolvers::MergeRequestsResolver do it 'filters merge requests by milestone title' do result = resolve_mr(project, milestone_title: milestone.title) - expect(result).to eq([merge_request_with_milestone]) + expect(result).to contain_exactly(merge_request_with_milestone) end it 'does not find anything' do @@ -203,18 +216,29 @@ RSpec.describe Resolvers::MergeRequestsResolver do result = resolve_mr(project, source_branches: [merge_request_4.source_branch], state: 'locked') - expect(result.compact).to contain_exactly(merge_request_4) + expect(result).to contain_exactly(merge_request_4) end end describe 'sorting' do + let(:mrs) do + [ + merge_request_with_milestone, merge_request_6, merge_request_5, merge_request_4, + merge_request_3, merge_request_2, merge_request_1 + ] + end + context 'when sorting by created' do it 'sorts merge requests ascending' do - expect(resolve_mr(project, sort: 'created_asc')).to eq [merge_request_1, merge_request_2, merge_request_3, merge_request_4, merge_request_5, merge_request_6, merge_request_with_milestone] + expect(resolve_mr(project, sort: 'created_asc')) + .to match_array(mrs) + .and be_sorted(:created_at, :asc) end it 'sorts merge requests descending' do - expect(resolve_mr(project, sort: 'created_desc')).to eq [merge_request_with_milestone, merge_request_6, merge_request_5, merge_request_4, merge_request_3, merge_request_2, merge_request_1] + expect(resolve_mr(project, sort: 'created_desc')) + .to match_array(mrs) + .and be_sorted(:created_at, :desc) end end @@ -225,11 +249,19 @@ RSpec.describe Resolvers::MergeRequestsResolver do end it 'sorts merge requests ascending' do - expect(resolve_mr(project, sort: :merged_at_asc)).to eq [merge_request_1, merge_request_3, merge_request_with_milestone, merge_request_6, merge_request_5, merge_request_4, merge_request_2] + expect(resolve_mr(project, sort: :merged_at_asc)) + .to match_array(mrs) + .and be_sorted(->(mr) { [merged_at(mr), -mr.id] }) end it 'sorts merge requests descending' do - expect(resolve_mr(project, sort: :merged_at_desc)).to eq [merge_request_3, merge_request_1, merge_request_with_milestone, merge_request_6, merge_request_5, merge_request_4, merge_request_2] + expect(resolve_mr(project, sort: :merged_at_desc)) + .to match_array(mrs) + .and be_sorted(->(mr) { [-merged_at(mr), -mr.id] }) + end + + def merged_at(mr) + nils_last(mr.metrics.merged_at) end context 'when label filter is given and the optimized_issuable_label_filter feature flag is off' do diff --git a/spec/graphql/resolvers/package_details_resolver_spec.rb b/spec/graphql/resolvers/package_details_resolver_spec.rb index 825b2aed40a..1bdc069b3bb 100644 --- a/spec/graphql/resolvers/package_details_resolver_spec.rb +++ b/spec/graphql/resolvers/package_details_resolver_spec.rb @@ -4,6 +4,7 @@ require 'spec_helper' RSpec.describe Resolvers::PackageDetailsResolver do include GraphqlHelpers + include ::Gitlab::Graphql::Laziness let_it_be_with_reload(:project) { create(:project) } let_it_be(:user) { project.owner } @@ -11,10 +12,10 @@ RSpec.describe Resolvers::PackageDetailsResolver do describe '#resolve' do let(:args) do - { id: package.to_global_id.to_s } + { id: global_id_of(package) } end - subject { resolve(described_class, ctx: { current_user: user }, args: args).sync } + subject { force(resolve(described_class, ctx: { current_user: user }, args: args)) } it { is_expected.to eq(package) } end diff --git a/spec/graphql/resolvers/packages_resolver_spec.rb b/spec/graphql/resolvers/packages_resolver_spec.rb index 9aec2c7e036..bc0588daf7f 100644 --- a/spec/graphql/resolvers/packages_resolver_spec.rb +++ b/spec/graphql/resolvers/packages_resolver_spec.rb @@ -6,7 +6,7 @@ RSpec.describe Resolvers::PackagesResolver do include GraphqlHelpers let_it_be(:user) { create(:user) } - let_it_be(:project) { create(:project) } + let_it_be(:project) { create(:project, :public) } let_it_be(:package) { create(:package, project: project) } describe '#resolve' do diff --git a/spec/graphql/resolvers/release_milestones_resolver_spec.rb b/spec/graphql/resolvers/release_milestones_resolver_spec.rb index 5f66cba859d..f05069998d0 100644 --- a/spec/graphql/resolvers/release_milestones_resolver_spec.rb +++ b/spec/graphql/resolvers/release_milestones_resolver_spec.rb @@ -6,18 +6,19 @@ RSpec.describe Resolvers::ReleaseMilestonesResolver do include GraphqlHelpers let_it_be(:release) { create(:release, :with_milestones, milestones_count: 2) } + let_it_be(:current_user) { create(:user, developer_projects: [release.project]) } let(:resolved) do - resolve(described_class, obj: release) + resolve(described_class, obj: release, ctx: { current_user: current_user }) end describe '#resolve' do - it "returns an OffsetActiveRecordRelationConnection" do - expect(resolved).to be_a(::Gitlab::Graphql::Pagination::OffsetActiveRecordRelationConnection) + it "uses offset-pagination" do + expect(resolved).to be_a(::Gitlab::Graphql::Pagination::OffsetPaginatedRelation) end it "includes the release's milestones in the returned OffsetActiveRecordRelationConnection" do - expect(resolved.items).to eq(release.milestones.order_by_dates_and_title) + expect(resolved.to_a).to eq(release.milestones.order_by_dates_and_title) end end end diff --git a/spec/graphql/resolvers/release_resolver_spec.rb b/spec/graphql/resolvers/release_resolver_spec.rb index 04765fc68e9..782c9604f15 100644 --- a/spec/graphql/resolvers/release_resolver_spec.rb +++ b/spec/graphql/resolvers/release_resolver_spec.rb @@ -36,7 +36,7 @@ RSpec.describe Resolvers::ReleaseResolver do let(:args) { {} } it 'raises an error' do - expect { resolve_release }.to raise_error(ArgumentError, "missing keyword: :tag_name") + expect { resolve_release }.to raise_error(ArgumentError) end end end diff --git a/spec/graphql/resolvers/terraform/states_resolver_spec.rb b/spec/graphql/resolvers/terraform/states_resolver_spec.rb index 64b515528cd..91d48cd782b 100644 --- a/spec/graphql/resolvers/terraform/states_resolver_spec.rb +++ b/spec/graphql/resolvers/terraform/states_resolver_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' RSpec.describe Resolvers::Terraform::StatesResolver do include GraphqlHelpers - it { expect(described_class.type).to eq(Types::Terraform::StateType) } + it { expect(described_class).to have_nullable_graphql_type(Types::Terraform::StateType.connection_type) } it { expect(described_class.null).to be_truthy } describe '#resolve' do @@ -31,3 +31,21 @@ RSpec.describe Resolvers::Terraform::StatesResolver do end end end + +RSpec.describe Resolvers::Terraform::StatesResolver.single do + it { expect(described_class).to be < Resolvers::Terraform::StatesResolver } + + describe 'arguments' do + subject { described_class.arguments[argument] } + + describe 'name' do + let(:argument) { 'name' } + + it do + expect(subject).to be_present + expect(subject.type.to_s).to eq('String!') + expect(subject.description).to be_present + end + end + end +end |