diff options
Diffstat (limited to 'spec/graphql/resolvers')
15 files changed, 524 insertions, 157 deletions
diff --git a/spec/graphql/resolvers/alert_management/alert_resolver_spec.rb b/spec/graphql/resolvers/alert_management/alert_resolver_spec.rb index 0c1ba5aab2c..42830f0024d 100644 --- a/spec/graphql/resolvers/alert_management/alert_resolver_spec.rb +++ b/spec/graphql/resolvers/alert_management/alert_resolver_spec.rb @@ -7,8 +7,8 @@ RSpec.describe Resolvers::AlertManagement::AlertResolver do let_it_be(:current_user) { create(:user) } let_it_be(:project) { create(:project) } - let_it_be(:alert_1) { create(:alert_management_alert, :resolved, project: project, ended_at: 1.year.ago, events: 2, severity: :high) } - let_it_be(:alert_2) { create(:alert_management_alert, :ignored, project: project, events: 1, severity: :critical) } + let_it_be(:resolved_alert) { create(:alert_management_alert, :resolved, project: project, ended_at: 1.year.ago, events: 2, severity: :high) } + let_it_be(:ignored_alert) { create(:alert_management_alert, :ignored, project: project, events: 1, severity: :critical) } let_it_be(:alert_other_proj) { create(:alert_management_alert) } let(:args) { {} } @@ -24,18 +24,18 @@ RSpec.describe Resolvers::AlertManagement::AlertResolver do project.add_developer(current_user) end - it { is_expected.to contain_exactly(alert_1, alert_2) } + it { is_expected.to contain_exactly(resolved_alert, ignored_alert) } context 'finding by iid' do - let(:args) { { iid: alert_1.iid } } + let(:args) { { iid: resolved_alert.iid } } - it { is_expected.to contain_exactly(alert_1) } + it { is_expected.to contain_exactly(resolved_alert) } end context 'finding by status' do let(:args) { { status: [Types::AlertManagement::StatusEnum.values['IGNORED'].value] } } - it { is_expected.to contain_exactly(alert_2) } + it { is_expected.to contain_exactly(ignored_alert) } end describe 'sorting' do @@ -45,11 +45,11 @@ RSpec.describe Resolvers::AlertManagement::AlertResolver do let_it_be(:alert_count_3) { create(:alert_management_alert, project: project, events: 3) } it 'sorts alerts ascending' do - expect(resolve_alerts(sort: :event_count_asc)).to eq [alert_2, alert_1, alert_count_3, alert_count_6] + expect(resolve_alerts(sort: :event_count_asc)).to eq [ignored_alert, resolved_alert, alert_count_3, alert_count_6] end it 'sorts alerts descending' do - expect(resolve_alerts(sort: :event_count_desc)).to eq [alert_count_6, alert_count_3, alert_1, alert_2] + expect(resolve_alerts(sort: :event_count_desc)).to eq [alert_count_6, alert_count_3, resolved_alert, ignored_alert] 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 new file mode 100644 index 00000000000..e23a37b3d69 --- /dev/null +++ b/spec/graphql/resolvers/board_list_issues_resolver_spec.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Resolvers::BoardListIssuesResolver do + include GraphqlHelpers + + let_it_be(:user) { create(:user) } + let_it_be(:unauth_user) { create(:user) } + let_it_be(:user_project) { create(:project, creator_id: user.id, namespace: user.namespace ) } + let_it_be(:group) { create(:group, :private) } + + shared_examples_for 'group and project board list issues resolver' do + let!(:board) { create(:board, resource_parent: board_parent) } + + before do + board_parent.add_developer(user) + end + + # auth is handled by the parent object + context 'when authorized' do + let!(:list) { create(:list, board: board, label: label) } + + it 'returns the issues in the correct order' do + issue1 = create(:issue, project: project, labels: [label], relative_position: 10) + issue2 = create(:issue, project: project, labels: [label], relative_position: 12) + issue3 = create(:issue, project: project, labels: [label], relative_position: 10) + + # by relative_position and then ID + issues = resolve_board_list_issues.items + + expect(issues.map(&:id)).to eq [issue3.id, issue1.id, issue2.id] + end + end + end + + describe '#resolve' do + context 'when project boards' do + let(:board_parent) { user_project } + let!(:label) { create(:label, project: project, name: 'project label') } + let(:project) { user_project } + + it_behaves_like 'group and project board list issues resolver' + end + + context 'when group boards' do + let(:board_parent) { group } + let!(:label) { create(:group_label, group: group, name: 'group label') } + let!(:project) { create(:project, :private, group: group) } + + it_behaves_like 'group and project board list issues resolver' + end + end + + def resolve_board_list_issues(args: {}, current_user: user) + resolve(described_class, obj: list, args: args, ctx: { current_user: current_user }) + end +end diff --git a/spec/graphql/resolvers/board_lists_resolver_spec.rb b/spec/graphql/resolvers/board_lists_resolver_spec.rb index f662e9a0f62..fb6a5ccb781 100644 --- a/spec/graphql/resolvers/board_lists_resolver_spec.rb +++ b/spec/graphql/resolvers/board_lists_resolver_spec.rb @@ -57,6 +57,30 @@ RSpec.describe Resolvers::BoardListsResolver do expect(lists.count).to eq 3 end end + + 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 + + expect(list).to eq [label_list] + end + + it 'returns empty result if list is not found' do + external_group = create(:group, :private) + external_board = create(:board, resource_parent: external_group ) + 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 + + 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 } + .to raise_error(Gitlab::Graphql::Errors::ArgumentError) + end + end end end diff --git a/spec/graphql/resolvers/ci_configuration/sast_resolver_spec.rb b/spec/graphql/resolvers/ci_configuration/sast_resolver_spec.rb deleted file mode 100644 index de69ad5d450..00000000000 --- a/spec/graphql/resolvers/ci_configuration/sast_resolver_spec.rb +++ /dev/null @@ -1,28 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Resolvers::CiConfiguration::SastResolver do - include GraphqlHelpers - - let_it_be(:user) { create(:user) } - let_it_be(:project) { create(:project) } - - describe '#resolve' do - subject(:sast_config) { resolve(described_class, ctx: { current_user: user }, obj: project) } - - it 'returns global variable informations related to SAST' do - expect(sast_config['global'].first['field']).to eql("SECURE_ANALYZERS_PREFIX") - expect(sast_config['global'].first['label']).to eql("Image prefix") - expect(sast_config['global'].first['type']).to eql("string") - - expect(sast_config['pipeline'].first['field']).to eql("stage") - expect(sast_config['pipeline'].first['label']).to eql("Stage") - expect(sast_config['pipeline'].first['type']).to eql("dropdown") - - expect(sast_config['analyzers'].first['name']).to eql("brakeman") - expect(sast_config['analyzers'].first['label']).to eql("Brakeman") - expect(sast_config['analyzers'].first['enabled']).to be true - end - end -end diff --git a/spec/graphql/resolvers/commit_pipelines_resolver_spec.rb b/spec/graphql/resolvers/commit_pipelines_resolver_spec.rb index 20a0cb842a4..a408981c08e 100644 --- a/spec/graphql/resolvers/commit_pipelines_resolver_spec.rb +++ b/spec/graphql/resolvers/commit_pipelines_resolver_spec.rb @@ -18,6 +18,7 @@ RSpec.describe Resolvers::CommitPipelinesResolver do status: 'success' ) end + let!(:pipeline2) do create( :ci_pipeline, @@ -27,6 +28,7 @@ RSpec.describe Resolvers::CommitPipelinesResolver do status: 'failed' ) end + let!(:pipeline3) do create( :ci_pipeline, diff --git a/spec/graphql/resolvers/group_issues_resolver_spec.rb b/spec/graphql/resolvers/group_issues_resolver_spec.rb new file mode 100644 index 00000000000..463cdca699b --- /dev/null +++ b/spec/graphql/resolvers/group_issues_resolver_spec.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Resolvers::GroupIssuesResolver do + include GraphqlHelpers + + let_it_be(:current_user) { create(:user) } + + let_it_be(:group) { create(:group) } + let_it_be(:project) { create(:project, group: group) } + let_it_be(:other_project) { create(:project, group: group) } + let_it_be(:subgroup) { create(:group, parent: group) } + let_it_be(:subproject) { create(:project, group: subgroup) } + + let_it_be(:issue1) { create(:incident, project: project, state: :opened, created_at: 3.hours.ago, updated_at: 3.hours.ago) } + let_it_be(:issue2) { create(:issue, project: project, state: :closed, title: 'foo', created_at: 1.hour.ago, updated_at: 1.hour.ago, closed_at: 1.hour.ago) } + let_it_be(:issue3) { create(:issue, project: other_project, state: :closed, title: 'foo', created_at: 1.hour.ago, updated_at: 1.hour.ago, closed_at: 1.hour.ago) } + let_it_be(:issue4) { create(:issue) } + + let_it_be(:subissue1) { create(:issue, project: subproject) } + let_it_be(:subissue2) { create(:issue, project: subproject) } + let_it_be(:subissue3) { create(:issue, project: subproject) } + + before_all do + group.add_developer(current_user) + subgroup.add_developer(current_user) + end + + describe '#resolve' do + it 'finds all group issues' do + result = resolve(described_class, obj: group, ctx: { current_user: current_user }) + + expect(result).to contain_exactly(issue1, issue2, issue3) + end + + it 'finds all group and subgroup issues' do + result = resolve(described_class, obj: group, args: { include_subgroups: true }, ctx: { current_user: current_user }) + + expect(result).to contain_exactly(issue1, issue2, issue3, subissue1, subissue2, subissue3) + end + end +end diff --git a/spec/graphql/resolvers/group_milestones_resolver_spec.rb b/spec/graphql/resolvers/group_milestones_resolver_spec.rb new file mode 100644 index 00000000000..05d0ec38192 --- /dev/null +++ b/spec/graphql/resolvers/group_milestones_resolver_spec.rb @@ -0,0 +1,123 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Resolvers::GroupMilestonesResolver do + include GraphqlHelpers + + describe '#resolve' do + let_it_be(:current_user) { create(:user) } + + def resolve_group_milestones(args = {}, context = { current_user: current_user }) + resolve(described_class, obj: group, args: args, ctx: context) + end + + let_it_be(:now) { Time.now } + let_it_be(:group) { create(:group, :private) } + + before_all do + group.add_developer(current_user) + end + + it 'calls MilestonesFinder#execute' do + expect_next_instance_of(MilestonesFinder) do |finder| + expect(finder).to receive(:execute) + end + + resolve_group_milestones + end + + context 'without parameters' do + it 'calls MilestonesFinder to retrieve all milestones' do + expect(MilestonesFinder).to receive(:new) + .with(ids: nil, group_ids: group.id, state: 'all', start_date: nil, end_date: nil) + .and_call_original + + resolve_group_milestones + end + end + + context 'with parameters' do + it 'calls MilestonesFinder with correct parameters' do + start_date = now + end_date = start_date + 1.hour + + expect(MilestonesFinder).to receive(:new) + .with(ids: nil, group_ids: group.id, state: 'closed', start_date: start_date, end_date: end_date) + .and_call_original + + resolve_group_milestones(start_date: start_date, end_date: end_date, state: 'closed') + end + end + + context 'by ids' do + it 'calls MilestonesFinder with correct parameters' do + milestone = create(:milestone, group: group) + + expect(MilestonesFinder).to receive(:new) + .with(ids: [milestone.id.to_s], group_ids: group.id, state: 'all', start_date: nil, end_date: nil) + .and_call_original + + resolve_group_milestones(ids: [milestone.to_global_id]) + end + end + + context 'by timeframe' do + context 'when start_date and end_date are present' do + context 'when start date is after end_date' do + it 'raises error' do + expect do + resolve_group_milestones(start_date: now, end_date: now - 2.days) + end.to raise_error(Gitlab::Graphql::Errors::ArgumentError, "startDate is after endDate") + end + end + end + + context 'when only start_date is present' do + it 'raises error' do + expect do + resolve_group_milestones(start_date: now) + end.to raise_error(Gitlab::Graphql::Errors::ArgumentError, /Both startDate and endDate/) + end + end + + context 'when only end_date is present' do + it 'raises error' do + expect do + resolve_group_milestones(end_date: now) + end.to raise_error(Gitlab::Graphql::Errors::ArgumentError, /Both startDate and endDate/) + end + end + end + + context 'when user cannot read milestones' do + it 'raises error' do + unauthorized_user = create(:user) + + expect do + resolve_group_milestones({}, { current_user: unauthorized_user }) + end.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable) + end + end + + context 'when including descendant milestones in a public group' do + let_it_be(:group) { create(:group, :public) } + let(:args) { { include_descendants: true } } + + it 'finds milestones only in accessible projects and groups' do + accessible_group = create(:group, :private, parent: group) + accessible_project = create(:project, group: accessible_group) + accessible_group.add_developer(current_user) + inaccessible_group = create(:group, :private, parent: group) + inaccessible_project = create(:project, :private, group: group) + milestone1 = create(:milestone, group: group) + milestone2 = create(:milestone, group: accessible_group) + milestone3 = create(:milestone, project: accessible_project) + create(:milestone, group: inaccessible_group) + create(:milestone, project: inaccessible_project) + + expect(resolve_group_milestones(args)).to match_array([milestone1, milestone2, milestone3]) + end + end + end +end diff --git a/spec/graphql/resolvers/issue_status_counts_resolver_spec.rb b/spec/graphql/resolvers/issue_status_counts_resolver_spec.rb new file mode 100644 index 00000000000..d2412db35c6 --- /dev/null +++ b/spec/graphql/resolvers/issue_status_counts_resolver_spec.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Resolvers::IssueStatusCountsResolver do + include GraphqlHelpers + + describe '#resolve' do + let_it_be(:current_user) { create(:user) } + let_it_be(:project) { create(:project) } + let_it_be(:issue) { create(:issue, project: project, state: :opened, created_at: 3.hours.ago, updated_at: 3.hours.ago) } + let_it_be(:incident) { create(:incident, project: project, state: :closed, created_at: 1.hour.ago, updated_at: 1.hour.ago, closed_at: 1.hour.ago) } + + let(:args) { {} } + + before do + project.add_developer(current_user) + end + + subject { resolve_issue_status_counts(args) } + + it { is_expected.to be_a(Gitlab::IssuablesCountForState) } + specify { expect(subject.project).to eq(project) } + + it 'returns expected results' do + result = resolve_issue_status_counts + + expect(result.all).to eq 2 + expect(result.opened).to eq 1 + expect(result.closed).to eq 1 + end + + it 'filters by search', :aggregate_failures do + result = resolve_issue_status_counts(search: issue.title) + + expect(result.all).to eq 1 + expect(result.opened).to eq 1 + expect(result.closed).to eq 0 + end + + it 'filters by issue type', :aggregate_failures do + result = resolve_issue_status_counts(issue_types: ['incident']) + + expect(result.all).to eq 1 + expect(result.opened).to eq 0 + expect(result.closed).to eq 1 + end + + # The state param is ignored in IssuableFinder#count_by_state + it 'ignores state filter', :aggregate_failures do + result = resolve_issue_status_counts(state: 'closed') + + expect(result.all).to eq 2 + expect(result.opened).to eq 1 + expect(result.closed).to eq 1 + end + + private + + def resolve_issue_status_counts(args = {}, context = { current_user: current_user }) + resolve(described_class, obj: project, args: args, ctx: context) + end + end +end diff --git a/spec/graphql/resolvers/issues_resolver_spec.rb b/spec/graphql/resolvers/issues_resolver_spec.rb index eb17e94a450..db5d009f0e7 100644 --- a/spec/graphql/resolvers/issues_resolver_spec.rb +++ b/spec/graphql/resolvers/issues_resolver_spec.rb @@ -13,7 +13,7 @@ RSpec.describe Resolvers::IssuesResolver do let_it_be(:milestone) { create(:milestone, project: project) } let_it_be(:assignee) { create(:user) } - let_it_be(:issue1) { create(:issue, project: project, state: :opened, created_at: 3.hours.ago, updated_at: 3.hours.ago, milestone: milestone) } + let_it_be(:issue1) { create(:incident, project: project, state: :opened, created_at: 3.hours.ago, updated_at: 3.hours.ago, milestone: milestone) } let_it_be(:issue2) { create(:issue, project: project, state: :closed, title: 'foo', created_at: 1.hour.ago, updated_at: 1.hour.ago, closed_at: 1.hour.ago, assignees: [assignee]) } let_it_be(:issue3) { create(:issue, project: other_project, state: :closed, title: 'foo', created_at: 1.hour.ago, updated_at: 1.hour.ago, closed_at: 1.hour.ago, assignees: [assignee]) } let_it_be(:issue4) { create(:issue) } @@ -95,6 +95,20 @@ RSpec.describe Resolvers::IssuesResolver do end end + describe 'filters by issue_type' do + it 'filters by a single type' do + expect(resolve_issues(issue_types: ['incident'])).to contain_exactly(issue1) + end + + it 'filters by more than one type' do + expect(resolve_issues(issue_types: %w(incident issue))).to contain_exactly(issue1, issue2) + end + + it 'ignores the filter if none given' do + expect(resolve_issues(issue_types: [])).to contain_exactly(issue1, issue2) + end + end + context 'when searching issues' do it 'returns correct issues' do expect(resolve_issues(search: 'foo')).to contain_exactly(issue2) diff --git a/spec/graphql/resolvers/merge_requests_resolver_spec.rb b/spec/graphql/resolvers/merge_requests_resolver_spec.rb index 0a8fd82613a..e939edae779 100644 --- a/spec/graphql/resolvers/merge_requests_resolver_spec.rb +++ b/spec/graphql/resolvers/merge_requests_resolver_spec.rb @@ -161,6 +161,24 @@ RSpec.describe Resolvers::MergeRequestsResolver do end end + context 'by merged_after and merged_before' do + before do + merge_request_1.metrics.update!(merged_at: 10.days.ago) + end + + 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]) + end + + it 'does not return anything' do + result = resolve_mr(project, merged_after: 2.days.ago) + + expect(result).to be_empty + end + end + describe 'combinations' do it 'requires all filters' do create(:merge_request, :closed, source_project: project, target_project: project, source_branch: merge_request_4.source_branch) diff --git a/spec/graphql/resolvers/milestone_resolver_spec.rb b/spec/graphql/resolvers/milestone_resolver_spec.rb deleted file mode 100644 index 36dd5ef03e2..00000000000 --- a/spec/graphql/resolvers/milestone_resolver_spec.rb +++ /dev/null @@ -1,113 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Resolvers::MilestoneResolver do - include GraphqlHelpers - - describe '#resolve' do - let_it_be(:current_user) { create(:user) } - - def resolve_group_milestones(args = {}, context = { current_user: current_user }) - resolve(described_class, obj: group, args: args, ctx: context) - end - - context 'for group milestones' do - let_it_be(:now) { Time.now } - let_it_be(:group) { create(:group, :private) } - - before do - group.add_developer(current_user) - end - - it 'calls MilestonesFinder#execute' do - expect_next_instance_of(MilestonesFinder) do |finder| - expect(finder).to receive(:execute) - end - - resolve_group_milestones - end - - context 'without parameters' do - it 'calls MilestonesFinder to retrieve all milestones' do - expect(MilestonesFinder).to receive(:new) - .with(group_ids: group.id, state: 'all', start_date: nil, end_date: nil) - .and_call_original - - resolve_group_milestones - end - end - - context 'with parameters' do - it 'calls MilestonesFinder with correct parameters' do - start_date = now - end_date = start_date + 1.hour - - expect(MilestonesFinder).to receive(:new) - .with(group_ids: group.id, state: 'closed', start_date: start_date, end_date: end_date) - .and_call_original - - resolve_group_milestones(start_date: start_date, end_date: end_date, state: 'closed') - end - end - - context 'by timeframe' do - context 'when start_date and end_date are present' do - context 'when start date is after end_date' do - it 'raises error' do - expect do - resolve_group_milestones(start_date: now, end_date: now - 2.days) - end.to raise_error(Gitlab::Graphql::Errors::ArgumentError, "startDate is after endDate") - end - end - end - - context 'when only start_date is present' do - it 'raises error' do - expect do - resolve_group_milestones(start_date: now) - end.to raise_error(Gitlab::Graphql::Errors::ArgumentError, /Both startDate and endDate/) - end - end - - context 'when only end_date is present' do - it 'raises error' do - expect do - resolve_group_milestones(end_date: now) - end.to raise_error(Gitlab::Graphql::Errors::ArgumentError, /Both startDate and endDate/) - end - end - end - - context 'when user cannot read milestones' do - it 'raises error' do - unauthorized_user = create(:user) - - expect do - resolve_group_milestones({}, { current_user: unauthorized_user }) - end.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable) - end - end - end - - context 'when including descendant milestones in a public group' do - let_it_be(:group) { create(:group, :public) } - let(:args) { { include_descendants: true } } - - it 'finds milestones only in accessible projects and groups' do - accessible_group = create(:group, :private, parent: group) - accessible_project = create(:project, group: accessible_group) - accessible_group.add_developer(current_user) - inaccessible_group = create(:group, :private, parent: group) - inaccessible_project = create(:project, :private, group: group) - milestone1 = create(:milestone, group: group) - milestone2 = create(:milestone, group: accessible_group) - milestone3 = create(:milestone, project: accessible_project) - create(:milestone, group: inaccessible_group) - create(:milestone, project: inaccessible_project) - - expect(resolve_group_milestones(args)).to match_array([milestone1, milestone2, milestone3]) - end - end - end -end diff --git a/spec/graphql/resolvers/project_milestones_resolver_spec.rb b/spec/graphql/resolvers/project_milestones_resolver_spec.rb new file mode 100644 index 00000000000..e0b250cfe7c --- /dev/null +++ b/spec/graphql/resolvers/project_milestones_resolver_spec.rb @@ -0,0 +1,117 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Resolvers::ProjectMilestonesResolver do + include GraphqlHelpers + + describe '#resolve' do + let_it_be(:project) { create(:project, :private) } + let_it_be(:current_user) { create(:user) } + + before_all do + project.add_developer(current_user) + end + + def resolve_project_milestones(args = {}, context = { current_user: current_user }) + resolve(described_class, obj: project, args: args, ctx: context) + end + + it 'calls MilestonesFinder to retrieve all milestones' do + expect(MilestonesFinder).to receive(:new) + .with(ids: nil, project_ids: project.id, state: 'all', start_date: nil, end_date: nil) + .and_call_original + + resolve_project_milestones + end + + context 'when including ancestor milestones' do + let(:parent_group) { create(:group) } + let(:group) { create(:group, parent: parent_group) } + let(:project) { create(:project, group: group) } + + before do + project.add_developer(current_user) + end + + it 'calls MilestonesFinder with correct parameters' do + expect(MilestonesFinder).to receive(:new) + .with(ids: nil, project_ids: project.id, group_ids: contain_exactly(group, parent_group), state: 'all', start_date: nil, end_date: nil) + .and_call_original + + resolve_project_milestones(include_ancestors: true) + end + end + + context 'by ids' do + it 'calls MilestonesFinder with correct parameters' do + milestone = create(:milestone, project: project) + + expect(MilestonesFinder).to receive(:new) + .with(ids: [milestone.id.to_s], project_ids: project.id, state: 'all', start_date: nil, end_date: nil) + .and_call_original + + resolve_project_milestones(ids: [milestone.to_global_id]) + end + end + + context 'by state' do + it 'calls MilestonesFinder with correct parameters' do + expect(MilestonesFinder).to receive(:new) + .with(ids: nil, project_ids: project.id, state: 'closed', start_date: nil, end_date: nil) + .and_call_original + + resolve_project_milestones(state: 'closed') + end + end + + context 'by timeframe' do + context 'when start_date and end_date are present' do + it 'calls MilestonesFinder with correct parameters' do + start_date = Time.now + end_date = Time.now + 5.days + + expect(MilestonesFinder).to receive(:new) + .with(ids: nil, project_ids: project.id, state: 'all', start_date: start_date, end_date: end_date) + .and_call_original + + resolve_project_milestones(start_date: start_date, end_date: end_date) + end + + context 'when start date is after end_date' do + it 'raises error' do + expect do + resolve_project_milestones(start_date: Time.now, end_date: Time.now - 2.days) + end.to raise_error(Gitlab::Graphql::Errors::ArgumentError, "startDate is after endDate") + end + end + end + + context 'when only start_date is present' do + it 'raises error' do + expect do + resolve_project_milestones(start_date: Time.now) + end.to raise_error(Gitlab::Graphql::Errors::ArgumentError, /Both startDate and endDate/) + end + end + + context 'when only end_date is present' do + it 'raises error' do + expect do + resolve_project_milestones(end_date: Time.now) + end.to raise_error(Gitlab::Graphql::Errors::ArgumentError, /Both startDate and endDate/) + end + end + end + + context 'when user cannot read milestones' do + it 'raises error' do + unauthorized_user = create(:user) + + expect do + resolve_project_milestones({}, { current_user: unauthorized_user }) + end.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable) + end + end + end +end diff --git a/spec/graphql/resolvers/project_pipeline_resolver_spec.rb b/spec/graphql/resolvers/project_pipeline_resolver_spec.rb index a659b3bdb6e..fada2f9193c 100644 --- a/spec/graphql/resolvers/project_pipeline_resolver_spec.rb +++ b/spec/graphql/resolvers/project_pipeline_resolver_spec.rb @@ -33,4 +33,21 @@ RSpec.describe Resolvers::ProjectPipelineResolver do it 'errors when no iid is passed' do expect { resolve_pipeline(project, {}) }.to raise_error(ArgumentError) end + + context 'when the pipeline is not a ci_config_source' do + let(:pipeline) do + config_source_value = Ci::PipelineEnums.non_ci_config_source_values.first + config_source = Ci::PipelineEnums.config_sources.key(config_source_value) + + create(:ci_pipeline, config_source: config_source, project: project) + end + + it 'resolves pipeline for the passed iid' do + result = batch_sync do + resolve_pipeline(project, { iid: pipeline.iid.to_s }) + end + + expect(result).to eq(pipeline) + end + end end diff --git a/spec/graphql/resolvers/projects/jira_projects_resolver_spec.rb b/spec/graphql/resolvers/projects/jira_projects_resolver_spec.rb index 4038bcb3e5d..840aea8b8c4 100644 --- a/spec/graphql/resolvers/projects/jira_projects_resolver_spec.rb +++ b/spec/graphql/resolvers/projects/jira_projects_resolver_spec.rb @@ -17,7 +17,7 @@ RSpec.describe Resolvers::Projects::JiraProjectsResolver do end end - context 'when project has no jira service' do + context 'when project has no Jira service' do let_it_be(:jira_service) { nil } context 'when user is a maintainer' do @@ -29,7 +29,7 @@ RSpec.describe Resolvers::Projects::JiraProjectsResolver do end end - context 'when project has jira service' do + context 'when project has Jira service' do let(:jira_service) { create(:jira_service, project: project) } context 'when user is a developer' do @@ -46,10 +46,11 @@ RSpec.describe Resolvers::Projects::JiraProjectsResolver do end context 'when Jira connection is valid' do - include_context 'jira projects request context' + include_context 'Jira projects request context' - it 'returns jira projects' do - jira_projects = resolve_jira_projects + it 'returns Jira projects', :aggregate_failures do + resolver = resolve_jira_projects + jira_projects = resolver.items project_keys = jira_projects.map(&:key) project_names = jira_projects.map(&:name) project_ids = jira_projects.map(&:id) @@ -58,6 +59,23 @@ RSpec.describe Resolvers::Projects::JiraProjectsResolver do expect(project_keys).to eq(%w(EX ABC)) expect(project_names).to eq(%w(Example Alphabetical)) expect(project_ids).to eq(%w(10000 10001)) + expect(resolver.max_page_size).to eq(2) + end + + context 'when filtering projects by name' do + it 'returns Jira projects', :aggregate_failures do + resolver = resolve_jira_projects({ name: 'ABC' }) + jira_projects = resolver.items + project_keys = jira_projects.map(&:key) + project_names = jira_projects.map(&:name) + project_ids = jira_projects.map(&:id) + + expect(jira_projects.size).to eq 1 + expect(project_keys).to eq(%w(ABC)) + expect(project_names).to eq(%w(Alphabetical)) + expect(project_ids).to eq(%w(10001)) + expect(resolver.max_page_size).to eq(1) + end end end diff --git a/spec/graphql/resolvers/todo_resolver_spec.rb b/spec/graphql/resolvers/todo_resolver_spec.rb index 0775cb8dae7..83e3140b676 100644 --- a/spec/graphql/resolvers/todo_resolver_spec.rb +++ b/spec/graphql/resolvers/todo_resolver_spec.rb @@ -99,7 +99,7 @@ RSpec.describe Resolvers::TodoResolver do end end - context 'when no user is provided' do + context 'when no target is provided' do it 'returns no todos' do todos = resolve(described_class, obj: nil, args: {}, ctx: { current_user: current_user }) @@ -107,7 +107,7 @@ RSpec.describe Resolvers::TodoResolver do end end - context 'when provided user is not current user' do + context 'when target user is not the current user' do it 'returns no todos' do other_user = create(:user) @@ -116,6 +116,16 @@ RSpec.describe Resolvers::TodoResolver do expect(todos).to be_empty end end + + context 'when request is for a todo target' do + it 'returns only the todos for the target' do + target = issue_todo_pending.target + + todos = resolve(described_class, obj: target, args: {}, ctx: { current_user: current_user }) + + expect(todos).to contain_exactly(issue_todo_pending) + end + end end def resolve_todos(args = {}, context = { current_user: current_user }) |