diff options
Diffstat (limited to 'spec/graphql/resolvers')
9 files changed, 222 insertions, 67 deletions
diff --git a/spec/graphql/resolvers/base_resolver_spec.rb b/spec/graphql/resolvers/base_resolver_spec.rb index d80a61fd318..27c62da31c3 100644 --- a/spec/graphql/resolvers/base_resolver_spec.rb +++ b/spec/graphql/resolvers/base_resolver_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Resolvers::BaseResolver do +RSpec.describe Resolvers::BaseResolver, feature_category: :api do include GraphqlHelpers let(:resolver) do diff --git a/spec/graphql/resolvers/blame_resolver_spec.rb b/spec/graphql/resolvers/blame_resolver_spec.rb new file mode 100644 index 00000000000..a3344132928 --- /dev/null +++ b/spec/graphql/resolvers/blame_resolver_spec.rb @@ -0,0 +1,81 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Resolvers::BlameResolver, feature_category: :source_code_management do + include GraphqlHelpers + + describe '#resolve' do + let_it_be(:user) { create(:user) } + let_it_be(:project) { create(:project, :repository) } + + let(:path) { 'files/ruby/popen.rb' } + let(:commit) { project.commit('master') } + let(:blob) { project.repository.blob_at(commit.id, path) } + let(:args) { { from_line: 1, to_line: 2 } } + + subject(:resolve_blame) { resolve(described_class, obj: blob, args: args, ctx: { current_user: user }) } + + context 'when unauthorized' do + it 'generates an error' do + expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do + resolve_blame + end + end + end + + context 'when authorized' do + before_all do + project.add_developer(user) + end + + context 'when feature is disabled' do + before do + stub_feature_flags(graphql_git_blame: false) + end + + it 'returns nothing' do + expect(subject).to be_nil + end + end + + shared_examples 'argument error' do + it 'raises an ArgumentError' do + expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError, + '`from_line` and `to_line` must be greater than or equal to 1') do + resolve_blame + end + end + end + + context 'when feature is enabled' do + context 'when from_line is below 1' do + let(:args) { { from_line: 0, to_line: 2 } } + + it_behaves_like 'argument error' + end + + context 'when to_line is below 1' do + let(:args) { { from_line: 1, to_line: 0 } } + + it_behaves_like 'argument error' + end + + context 'when to_line less than from_line' do + let(:args) { { from_line: 3, to_line: 1 } } + + it 'returns blame object' do + expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError, + '`to_line` must be greater than or equal to `from_line`') do + resolve_blame + end + end + end + + it 'returns blame object' do + expect(resolve_blame).to be_an_instance_of(Gitlab::Blame) + end + end + end + end +end diff --git a/spec/graphql/resolvers/branch_commit_resolver_spec.rb b/spec/graphql/resolvers/branch_commit_resolver_spec.rb index 3d5702539fa..f901306a355 100644 --- a/spec/graphql/resolvers/branch_commit_resolver_spec.rb +++ b/spec/graphql/resolvers/branch_commit_resolver_spec.rb @@ -32,7 +32,7 @@ RSpec.describe Resolvers::BranchCommitResolver do commit_a = repository.commits('master', limit: 1).last commit_b = repository.commits('spooky-stuff', limit: 1).last - commits = batch_sync(max_queries: 1) do + commits = batch_sync(max_queries: 2) do [ resolve(described_class, obj: branch), resolve(described_class, obj: repository.find_branch('spooky-stuff')) diff --git a/spec/graphql/resolvers/ci/all_jobs_resolver_spec.rb b/spec/graphql/resolvers/ci/all_jobs_resolver_spec.rb index fddc73fadfe..6b9e3a484b1 100644 --- a/spec/graphql/resolvers/ci/all_jobs_resolver_spec.rb +++ b/spec/graphql/resolvers/ci/all_jobs_resolver_spec.rb @@ -5,37 +5,114 @@ require 'spec_helper' RSpec.describe Resolvers::Ci::AllJobsResolver, feature_category: :continuous_integration do include GraphqlHelpers - let_it_be(:successful_job) { create(:ci_build, :success, name: 'Job One') } - let_it_be(:successful_job_two) { create(:ci_build, :success, name: 'Job Two') } - let_it_be(:failed_job) { create(:ci_build, :failed, name: 'Job Three') } - let_it_be(:pending_job) { create(:ci_build, :pending, name: 'Job Three') } + let_it_be(:instance_runner) { create(:ci_runner, :instance) } + let_it_be(:successful_job) { create(:ci_build, :success, name: 'successful_job') } + let_it_be(:successful_job_two) { create(:ci_build, :success, name: 'successful_job_two') } + let_it_be(:failed_job) { create(:ci_build, :failed, name: 'failed_job') } + let_it_be(:pending_job) { create(:ci_build, :pending, name: 'pending_job') } let(:args) { {} } - subject { resolve_jobs(args) } - describe '#resolve' do - context 'with admin' do - let(:current_user) { create(:admin) } + subject(:request) { resolve_jobs(args) } + + context 'when current user is an admin' do + let_it_be(:current_user) { create(:admin) } shared_examples 'executes as admin' do - context 'with statuses argument' do - let(:args) { { statuses: [Types::Ci::JobStatusEnum.coerce_isolated_input('SUCCESS')] } } + context "with argument `statuses`" do + using RSpec::Parameterized::TableSyntax + + where(:statuses, :expected_jobs) do + nil | lazy { [successful_job, successful_job_two, failed_job, pending_job] } + %w[SUCCESS] | lazy { [successful_job, successful_job_two] } + %w[SUCCESS FAILED] | lazy { [successful_job, successful_job_two, failed_job] } + %w[CANCELED] | lazy { [] } + end - it { is_expected.to contain_exactly(successful_job, successful_job_two) } + with_them do + let(:args) do + { statuses: statuses&.map { |status| Types::Ci::JobStatusEnum.coerce_isolated_input(status) } } + end + + it { is_expected.to contain_exactly(*expected_jobs) } + end end - context 'with multiple statuses' do - let(:args) do - { statuses: [Types::Ci::JobStatusEnum.coerce_isolated_input('SUCCESS'), - Types::Ci::JobStatusEnum.coerce_isolated_input('FAILED')] } + context "with argument `runner_types`" do + let_it_be(:successful_job_with_instance_runner) do + create(:ci_build, :success, name: 'successful_job_with_instance_runner', runner: instance_runner) end - it { is_expected.to contain_exactly(successful_job, successful_job_two, failed_job) } + context 'with feature flag :admin_jobs_filter_runner_type enabled' do + using RSpec::Parameterized::TableSyntax + + where(:runner_types, :expected_jobs) do + nil | lazy do + [ + successful_job, + successful_job_two, + failed_job, + pending_job, + successful_job_with_instance_runner + ] + end + %w[INSTANCE_TYPE] | lazy { [successful_job_with_instance_runner] } + %w[INSTANCE_TYPE GROUP_TYPE] | lazy { [successful_job_with_instance_runner] } + %w[PROJECT_TYPE] | lazy { [] } + end + + with_them do + let(:args) do + { + runner_types: runner_types&.map { |type| Types::Ci::RunnerTypeEnum.coerce_isolated_input(type) } + } + end + + it { is_expected.to match_array(expected_jobs) } + end + end end - context 'without statuses argument' do - it { is_expected.to contain_exactly(successful_job, successful_job_two, failed_job, pending_job) } + context "with argument combination" do + let_it_be(:successful_job_with_instance_runner) do + create( + :ci_build, + :success, + name: 'successful_job_with_instance_runner', + runner: instance_runner + ) + end + + let_it_be(:running_job_with_group_runner) do + create(:ci_build, :running, name: 'running_job_with_instance_runner', runner: create(:ci_runner, :group)) + end + + context 'with feature flag :admin_jobs_filter_runner_type enabled' do + using RSpec::Parameterized::TableSyntax + + where(:statuses, :runner_types, :expected_jobs) do + %w[SUCCESS] | %w[INSTANCE_TYPE] | lazy { [successful_job_with_instance_runner] } + %w[CANCELED] | %w[INSTANCE_TYPE] | lazy { [] } + %w[SUCCESS RUNNING] | %w[INSTANCE_TYPE GROUP_TYPE] | lazy do + [ + successful_job_with_instance_runner, + running_job_with_group_runner + ] + end + end + + with_them do + let(:args) do + { + statuses: statuses&.map { |status| Types::Ci::JobStatusEnum.coerce_isolated_input(status) }, + runner_types: runner_types&.map { |type| Types::Ci::RunnerTypeEnum.coerce_isolated_input(type) } + } + end + + it { is_expected.to contain_exactly(*expected_jobs) } + end + end end end @@ -55,7 +132,9 @@ RSpec.describe Resolvers::Ci::AllJobsResolver, feature_category: :continuous_int end context 'with unauthorized user' do - let(:current_user) { nil } + let_it_be(:unauth_user) { create(:user) } + + let(:current_user) { unauth_user } it { is_expected.to be_empty } end diff --git a/spec/graphql/resolvers/ci/group_runners_resolver_spec.rb b/spec/graphql/resolvers/ci/group_runners_resolver_spec.rb index ff343f3f43d..fedae5c86a8 100644 --- a/spec/graphql/resolvers/ci/group_runners_resolver_spec.rb +++ b/spec/graphql/resolvers/ci/group_runners_resolver_spec.rb @@ -6,7 +6,7 @@ RSpec.describe Resolvers::Ci::GroupRunnersResolver, feature_category: :runner_fl include GraphqlHelpers describe '#resolve' do - subject do + subject(:resolve_scope) do resolve(described_class, obj: obj, ctx: { current_user: user }, args: args, arg_style: :internal) end @@ -18,8 +18,10 @@ RSpec.describe Resolvers::Ci::GroupRunnersResolver, feature_category: :runner_fl # First, we can do a couple of basic real tests to verify common cases. That ensures that the code works. context 'when user cannot see runners' do - it 'returns no runners' do - expect(subject.items.to_a).to eq([]) + it 'returns Gitlab::Graphql::Errors::ResourceNotAvailable' do + expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do + resolve_scope + end end end @@ -29,14 +31,16 @@ RSpec.describe Resolvers::Ci::GroupRunnersResolver, feature_category: :runner_fl end it 'returns all the runners' do - expect(subject.items.to_a).to contain_exactly(inactive_project_runner, offline_project_runner, group_runner, subgroup_runner) + expect(resolve_scope.items.to_a).to contain_exactly( + inactive_project_runner, offline_project_runner, group_runner, subgroup_runner + ) end context 'with membership direct' do let(:args) { { membership: :direct } } it 'returns only direct runners' do - expect(subject.items.to_a).to contain_exactly(group_runner) + expect(resolve_scope.items.to_a).to contain_exactly(group_runner) end end end @@ -46,7 +50,7 @@ RSpec.describe Resolvers::Ci::GroupRunnersResolver, feature_category: :runner_fl let(:obj) { nil } it 'raises an error' do - expect { subject }.to raise_error('Expected group missing') + expect { resolve_scope }.to raise_error('Expected group missing') end end @@ -54,7 +58,7 @@ RSpec.describe Resolvers::Ci::GroupRunnersResolver, feature_category: :runner_fl let(:obj) { build(:project) } it 'raises an error' do - expect { subject }.to raise_error('Expected group missing') + expect { resolve_scope }.to raise_error('Expected group missing') end end @@ -90,7 +94,7 @@ RSpec.describe Resolvers::Ci::GroupRunnersResolver, feature_category: :runner_fl allow(::Ci::RunnersFinder).to receive(:new).with(current_user: user, params: expected_params).once.and_return(finder) allow(finder).to receive(:execute).once.and_return([:execute_return_value]) - expect(subject.items.to_a).to eq([:execute_return_value]) + expect(resolve_scope.items.to_a).to eq([:execute_return_value]) end end end diff --git a/spec/graphql/resolvers/ci/project_runners_resolver_spec.rb b/spec/graphql/resolvers/ci/project_runners_resolver_spec.rb index 83435db2ea7..55a98106baf 100644 --- a/spec/graphql/resolvers/ci/project_runners_resolver_spec.rb +++ b/spec/graphql/resolvers/ci/project_runners_resolver_spec.rb @@ -6,7 +6,7 @@ RSpec.describe Resolvers::Ci::ProjectRunnersResolver, feature_category: :runner_ include GraphqlHelpers describe '#resolve' do - subject do + subject(:resolve_scope) do resolve(described_class, obj: obj, ctx: { current_user: user }, args: args, arg_style: :internal) end @@ -17,8 +17,10 @@ RSpec.describe Resolvers::Ci::ProjectRunnersResolver, feature_category: :runner_ let(:args) { {} } context 'when user cannot see runners' do - it 'returns no runners' do - expect(subject.items.to_a).to eq([]) + it 'returns Gitlab::Graphql::Errors::ResourceNotAvailable' do + expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do + resolve_scope + end end end @@ -30,7 +32,7 @@ RSpec.describe Resolvers::Ci::ProjectRunnersResolver, feature_category: :runner_ let(:available_runners) { [inactive_project_runner, offline_project_runner, group_runner, instance_runner] } it 'returns all runners available to the project' do - expect(subject.items.to_a).to match_array(available_runners) + expect(resolve_scope.items.to_a).to match_array(available_runners) end end @@ -38,7 +40,7 @@ RSpec.describe Resolvers::Ci::ProjectRunnersResolver, feature_category: :runner_ let(:obj) { nil } it 'raises an error' do - expect { subject }.to raise_error('Expected project missing') + expect { resolve_scope }.to raise_error('Expected project missing') end end @@ -46,7 +48,7 @@ RSpec.describe Resolvers::Ci::ProjectRunnersResolver, feature_category: :runner_ let(:obj) { build(:group) } it 'raises an error' do - expect { subject }.to raise_error('Expected project missing') + expect { resolve_scope }.to raise_error('Expected project missing') end end @@ -79,7 +81,7 @@ RSpec.describe Resolvers::Ci::ProjectRunnersResolver, feature_category: :runner_ params: expected_params).once.and_return(finder) allow(finder).to receive(:execute).once.and_return([:execute_return_value]) - expect(subject.items.to_a).to eq([:execute_return_value]) + expect(resolve_scope.items.to_a).to contain_exactly(:execute_return_value) end end end diff --git a/spec/graphql/resolvers/ci/runners_resolver_spec.rb b/spec/graphql/resolvers/ci/runners_resolver_spec.rb index 02fc7d28255..35831579799 100644 --- a/spec/graphql/resolvers/ci/runners_resolver_spec.rb +++ b/spec/graphql/resolvers/ci/runners_resolver_spec.rb @@ -20,8 +20,10 @@ RSpec.describe Resolvers::Ci::RunnersResolver, feature_category: :runner_fleet d context 'when user cannot see runners' do let(:user) { build(:user) } - it 'returns no runners' do - expect(subject.items.to_a).to eq([]) + it 'returns Gitlab::Graphql::Errors::ResourceNotAvailable' do + expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do + resolve_scope + end end end @@ -30,20 +32,26 @@ RSpec.describe Resolvers::Ci::RunnersResolver, feature_category: :runner_fleet d context 'when admin mode setting is disabled', :do_not_mock_admin_mode_setting do it 'returns all the runners' do - expect(subject.items.to_a).to contain_exactly(inactive_project_runner, offline_project_runner, group_runner, subgroup_runner, instance_runner) + expect(resolve_scope.items.to_a).to contain_exactly( + inactive_project_runner, offline_project_runner, group_runner, subgroup_runner, instance_runner + ) end end context 'when admin mode setting is enabled' do context 'when in admin mode', :enable_admin_mode do it 'returns all the runners' do - expect(subject.items.to_a).to contain_exactly(inactive_project_runner, offline_project_runner, group_runner, subgroup_runner, instance_runner) + expect(resolve_scope.items.to_a).to contain_exactly( + inactive_project_runner, offline_project_runner, group_runner, subgroup_runner, instance_runner + ) end end context 'when not in admin mode' do - it 'returns no runners' do - expect(subject.items.to_a).to eq([]) + it 'returns Gitlab::Graphql::Errors::ResourceNotAvailable' do + expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do + resolve_scope + end end end end @@ -54,7 +62,7 @@ RSpec.describe Resolvers::Ci::RunnersResolver, feature_category: :runner_fleet d let(:obj) { build(:project) } it 'raises an error' do - expect { subject }.to raise_error(a_string_including('Unexpected parent type')) + expect { resolve_scope }.to raise_error(a_string_including('Unexpected parent type')) end end @@ -93,7 +101,7 @@ RSpec.describe Resolvers::Ci::RunnersResolver, feature_category: :runner_fleet d expect(::Ci::RunnersFinder).to receive(:new).with(current_user: user, params: expected_params).once.and_return(finder) allow(finder).to receive(:execute).once.and_return([:execute_return_value]) - expect(subject.items.to_a).to eq([:execute_return_value]) + expect(resolve_scope.items.to_a).to contain_exactly :execute_return_value end end @@ -116,7 +124,7 @@ RSpec.describe Resolvers::Ci::RunnersResolver, feature_category: :runner_fleet d expect(::Ci::RunnersFinder).to receive(:new).with(current_user: user, params: expected_params).once.and_return(finder) allow(finder).to receive(:execute).once.and_return([:execute_return_value]) - expect(subject.items.to_a).to eq([:execute_return_value]) + expect(resolve_scope.items.to_a).to contain_exactly :execute_return_value end end @@ -136,7 +144,7 @@ RSpec.describe Resolvers::Ci::RunnersResolver, feature_category: :runner_fleet d expect(::Ci::RunnersFinder).to receive(:new).with(current_user: user, params: expected_params).once.and_return(finder) allow(finder).to receive(:execute).once.and_return([:execute_return_value]) - expect(subject.items.to_a).to eq([:execute_return_value]) + expect(resolve_scope.items.to_a).to contain_exactly :execute_return_value end end @@ -153,7 +161,7 @@ RSpec.describe Resolvers::Ci::RunnersResolver, feature_category: :runner_fleet d expect(::Ci::RunnersFinder).to receive(:new).with(current_user: user, params: expected_params).once.and_return(finder) allow(finder).to receive(:execute).once.and_return([:execute_return_value]) - expect(subject.items.to_a).to eq([:execute_return_value]) + expect(resolve_scope.items.to_a).to contain_exactly :execute_return_value end end end diff --git a/spec/graphql/resolvers/metrics/dashboards/annotation_resolver_spec.rb b/spec/graphql/resolvers/metrics/dashboards/annotation_resolver_spec.rb index 75e0a816086..a4b957ef8e9 100644 --- a/spec/graphql/resolvers/metrics/dashboards/annotation_resolver_spec.rb +++ b/spec/graphql/resolvers/metrics/dashboards/annotation_resolver_spec.rb @@ -24,22 +24,8 @@ RSpec.describe Resolvers::Metrics::Dashboards::AnnotationResolver, feature_categ environment.project.add_developer(current_user) end - before do - stub_feature_flags(remove_monitor_metrics: false) - end - context 'with annotation records' do - context 'when metrics dashboard feature is unavailable' do - before do - stub_feature_flags(remove_monitor_metrics: true) - end - - it 'returns nothing' do - expect(resolve_annotations).to be_nil - end - end - - it 'returns [] all the time' do + it 'returns empty all the time' do expect(resolve_annotations).to be_empty end end diff --git a/spec/graphql/resolvers/work_items_resolver_spec.rb b/spec/graphql/resolvers/work_items_resolver_spec.rb index 6da62e3adb7..c856f990e7a 100644 --- a/spec/graphql/resolvers/work_items_resolver_spec.rb +++ b/spec/graphql/resolvers/work_items_resolver_spec.rb @@ -46,11 +46,6 @@ RSpec.describe Resolvers::WorkItemsResolver do expect(resolve_items).to contain_exactly(item1, item2) end - it 'filters by state' do - expect(resolve_items(state: 'opened')).to contain_exactly(item1) - expect(resolve_items(state: 'closed')).to contain_exactly(item2) - end - context 'when searching items' do it_behaves_like 'graphql query for searching issuables' do let_it_be(:parent) { project } |