diff options
Diffstat (limited to 'spec/graphql/resolvers/ci')
-rw-r--r-- | spec/graphql/resolvers/ci/group_runners_resolver_spec.rb | 94 | ||||
-rw-r--r-- | spec/graphql/resolvers/ci/runners_resolver_spec.rb | 209 |
2 files changed, 141 insertions, 162 deletions
diff --git a/spec/graphql/resolvers/ci/group_runners_resolver_spec.rb b/spec/graphql/resolvers/ci/group_runners_resolver_spec.rb new file mode 100644 index 00000000000..89a2437a189 --- /dev/null +++ b/spec/graphql/resolvers/ci/group_runners_resolver_spec.rb @@ -0,0 +1,94 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Resolvers::Ci::GroupRunnersResolver do + include GraphqlHelpers + + describe '#resolve' do + subject { resolve(described_class, obj: obj, ctx: { current_user: user }, args: args) } + + include_context 'runners resolver setup' + + let(:obj) { group } + let(:args) { {} } + + # 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([]) + end + end + + context 'with user as group owner' do + before do + group.add_owner(user) + 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) + 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) + end + end + end + + # Then, we can check specific edge cases for this resolver + context 'with obj set to nil' do + let(:obj) { nil } + + it 'raises an error' do + expect { subject }.to raise_error('Expected group missing') + end + end + + context 'with obj not set to group' do + let(:obj) { build(:project) } + + it 'raises an error' do + expect { subject }.to raise_error('Expected group missing') + end + end + + # Here we have a mocked part. We assume that all possible edge cases are covered in RunnersFinder spec. So we don't need to test them twice. + # Only thing we can do is to verify that args from the resolver is correctly transformed to params of the Finder and we return the Finder's result back. + describe 'Allowed query arguments' do + let(:finder) { instance_double(::Ci::RunnersFinder) } + let(:args) do + { + status: 'active', + type: :group_type, + tag_list: ['active_runner'], + search: 'abc', + sort: :contacted_asc, + membership: :descendants + } + end + + let(:expected_params) do + { + status_status: 'active', + type_type: :group_type, + tag_name: ['active_runner'], + preload: { tag_name: nil }, + search: 'abc', + sort: 'contacted_asc', + membership: :descendants, + group: group + } + end + + it 'calls RunnersFinder with expected arguments' do + 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]) + end + end + end +end diff --git a/spec/graphql/resolvers/ci/runners_resolver_spec.rb b/spec/graphql/resolvers/ci/runners_resolver_spec.rb index 5ac15d5729f..bb8dadeca40 100644 --- a/spec/graphql/resolvers/ci/runners_resolver_spec.rb +++ b/spec/graphql/resolvers/ci/runners_resolver_spec.rb @@ -5,185 +5,70 @@ require 'spec_helper' RSpec.describe Resolvers::Ci::RunnersResolver do include GraphqlHelpers - let_it_be(:user) { create_default(:user, :admin) } - let_it_be(:group) { create(:group, :public) } - let_it_be(:project) { create(:project, :repository, :public) } - - let_it_be(:inactive_project_runner) do - create(:ci_runner, :project, projects: [project], description: 'inactive project runner', token: 'abcdef', active: false, contacted_at: 1.minute.ago, tag_list: %w(project_runner)) - end - - let_it_be(:offline_project_runner) do - create(:ci_runner, :project, projects: [project], description: 'offline project runner', token: 'defghi', contacted_at: 1.day.ago, tag_list: %w(project_runner active_runner)) - end - - let_it_be(:group_runner) { create(:ci_runner, :group, groups: [group], token: 'mnopqr', description: 'group runner', contacted_at: 1.second.ago) } - let_it_be(:instance_runner) { create(:ci_runner, :instance, description: 'shared runner', token: 'stuvxz', contacted_at: 2.minutes.ago, tag_list: %w(instance_runner active_runner)) } - describe '#resolve' do - subject { resolve(described_class, ctx: { current_user: user }, args: args).items.to_a } - - let(:args) do - {} - end - - context 'when the user cannot see runners' do - let(:user) { create(:user) } - - it 'returns no runners' do - is_expected.to be_empty - end - end - - context 'without sort' do - it 'returns all the runners' do - is_expected.to contain_exactly(inactive_project_runner, offline_project_runner, group_runner, instance_runner) - end - end - - context 'with a sort argument' do - context "set to :contacted_asc" do - let(:args) do - { sort: :contacted_asc } - end - - it { is_expected.to eq([offline_project_runner, instance_runner, inactive_project_runner, group_runner]) } - end - - context "set to :contacted_desc" do - let(:args) do - { sort: :contacted_desc } - end - - it { is_expected.to eq([offline_project_runner, instance_runner, inactive_project_runner, group_runner].reverse) } - end - - context "set to :created_at_desc" do - let(:args) do - { sort: :created_at_desc } - end + let(:obj) { nil } + let(:args) { {} } - it { is_expected.to eq([instance_runner, group_runner, offline_project_runner, inactive_project_runner]) } - end - - context "set to :created_at_asc" do - let(:args) do - { sort: :created_at_asc } - end - - it { is_expected.to eq([instance_runner, group_runner, offline_project_runner, inactive_project_runner].reverse) } - end - end + subject { resolve(described_class, obj: obj, ctx: { current_user: user }, args: args) } - context 'when type is filtered' do - let(:args) do - { type: runner_type.to_s } - end + include_context 'runners resolver setup' - context 'to instance runners' do - let(:runner_type) { :instance_type } + # 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 + let(:user) { build(:user) } - it 'returns the instance runner' do - is_expected.to contain_exactly(instance_runner) - end - end - - context 'to group runners' do - let(:runner_type) { :group_type } - - it 'returns the group runner' do - is_expected.to contain_exactly(group_runner) - end - end - - context 'to project runners' do - let(:runner_type) { :project_type } - - it 'returns the project runner' do - is_expected.to contain_exactly(inactive_project_runner, offline_project_runner) - end + it 'returns no runners' do + expect(subject.items.to_a).to eq([]) end end - context 'when status is filtered' do - let(:args) do - { status: runner_status.to_s } - end - - context 'to active runners' do - let(:runner_status) { :active } - - it 'returns the instance and group runners' do - is_expected.to contain_exactly(offline_project_runner, group_runner, instance_runner) - end - end - - context 'to offline runners' do - let(:runner_status) { :offline } + context 'when user can see runners' do + let(:obj) { nil } - it 'returns the offline project runner' do - is_expected.to contain_exactly(offline_project_runner) - 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, instance_runner) end end - context 'when tag list is filtered' do - let(:args) do - { tag_list: tag_list } - end - - context 'with "project_runner" tag' do - let(:tag_list) { ['project_runner'] } + # Then, we can check specific edge cases for this resolver + context 'with obj not set to nil' do + let(:obj) { build(:project) } - it 'returns the project_runner runners' do - is_expected.to contain_exactly(offline_project_runner, inactive_project_runner) - end - end - - context 'with "project_runner" and "active_runner" tags as comma-separated string' do - let(:tag_list) { ['project_runner,active_runner'] } - - it 'returns the offline_project_runner runner' do - is_expected.to contain_exactly(offline_project_runner) - end - end - - context 'with "active_runner" and "instance_runner" tags as array' do - let(:tag_list) { %w[instance_runner active_runner] } - - it 'returns the offline_project_runner runner' do - is_expected.to contain_exactly(instance_runner) - end + it 'raises an error' do + expect { subject }.to raise_error(a_string_including('Unexpected parent type')) end end - context 'when text is filtered' do + # Here we have a mocked part. We assume that all possible edge cases are covered in RunnersFinder spec. So we don't need to test them twice. + # Only thing we can do is to verify that args from the resolver is correctly transformed to params of the Finder and we return the Finder's result back. + describe 'Allowed query arguments' do + let(:finder) { instance_double(::Ci::RunnersFinder) } let(:args) do - { search: search_term } - end - - context 'to "project"' do - let(:search_term) { 'project' } - - it 'returns both project runners' do - is_expected.to contain_exactly(inactive_project_runner, offline_project_runner) - end - end - - context 'to "group"' do - let(:search_term) { 'group' } - - it 'returns group runner' do - is_expected.to contain_exactly(group_runner) - end - end - - context 'to "defghi"' do - let(:search_term) { 'defghi' } - - it 'returns runners containing term in token' do - is_expected.to contain_exactly(offline_project_runner) - end + { + status: 'active', + type: :instance_type, + tag_list: ['active_runner'], + search: 'abc', + sort: :contacted_asc + } + end + + let(:expected_params) do + { + status_status: 'active', + type_type: :instance_type, + tag_name: ['active_runner'], + preload: { tag_name: nil }, + search: 'abc', + sort: 'contacted_asc' + } + end + + it 'calls RunnersFinder with expected arguments' do + 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]) end end end |