summaryrefslogtreecommitdiff
path: root/spec/graphql/resolvers
diff options
context:
space:
mode:
Diffstat (limited to 'spec/graphql/resolvers')
-rw-r--r--spec/graphql/resolvers/ci/project_pipeline_counts_resolver_spec.rb63
-rw-r--r--spec/graphql/resolvers/ci/runner_jobs_resolver_spec.rb49
-rw-r--r--spec/graphql/resolvers/ci/runners_resolver_spec.rb111
-rw-r--r--spec/graphql/resolvers/clusters/agent_tokens_resolver_spec.rb8
-rw-r--r--spec/graphql/resolvers/clusters/agents_resolver_spec.rb10
-rw-r--r--spec/graphql/resolvers/merge_requests_resolver_spec.rb60
-rw-r--r--spec/graphql/resolvers/package_details_resolver_spec.rb2
-rw-r--r--spec/graphql/resolvers/package_pipelines_resolver_spec.rb7
-rw-r--r--spec/graphql/resolvers/recent_boards_resolver_spec.rb79
9 files changed, 335 insertions, 54 deletions
diff --git a/spec/graphql/resolvers/ci/project_pipeline_counts_resolver_spec.rb b/spec/graphql/resolvers/ci/project_pipeline_counts_resolver_spec.rb
new file mode 100644
index 00000000000..07b4a5509b2
--- /dev/null
+++ b/spec/graphql/resolvers/ci/project_pipeline_counts_resolver_spec.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Resolvers::Ci::ProjectPipelineCountsResolver do
+ include GraphqlHelpers
+
+ let(:current_user) { create(:user) }
+
+ let_it_be(:project) { create(:project, :private) }
+ let_it_be(:pipeline) { create(:ci_pipeline, project: project) }
+ let_it_be(:failed_pipeline) { create(:ci_pipeline, :failed, project: project) }
+ let_it_be(:success_pipeline) { create(:ci_pipeline, :success, project: project) }
+ let_it_be(:ref_pipeline) { create(:ci_pipeline, project: project, ref: 'awesome-feature') }
+ let_it_be(:sha_pipeline) { create(:ci_pipeline, :running, project: project, sha: 'deadbeef') }
+ let_it_be(:on_demand_dast_scan) { create(:ci_pipeline, :success, project: project, source: 'ondemand_dast_scan') }
+
+ before do
+ project.add_developer(current_user)
+ end
+
+ describe '#resolve' do
+ it 'counts pipelines' do
+ expect(resolve_pipeline_counts).to have_attributes(
+ all: 6,
+ finished: 3,
+ running: 1,
+ pending: 2
+ )
+ end
+
+ it 'counts by ref' do
+ expect(resolve_pipeline_counts(ref: "awesome-feature")).to have_attributes(
+ all: 1,
+ finished: 0,
+ running: 0,
+ pending: 1
+ )
+ end
+
+ it 'counts by sha' do
+ expect(resolve_pipeline_counts(sha: "deadbeef")).to have_attributes(
+ all: 1,
+ finished: 0,
+ running: 1,
+ pending: 0
+ )
+ end
+
+ it 'counts by source' do
+ expect(resolve_pipeline_counts(source: "ondemand_dast_scan")).to have_attributes(
+ all: 1,
+ finished: 1,
+ running: 0,
+ pending: 0
+ )
+ end
+ end
+
+ def resolve_pipeline_counts(args = {}, context = { current_user: current_user })
+ resolve(described_class, obj: project, args: args, ctx: context)
+ end
+end
diff --git a/spec/graphql/resolvers/ci/runner_jobs_resolver_spec.rb b/spec/graphql/resolvers/ci/runner_jobs_resolver_spec.rb
new file mode 100644
index 00000000000..53b673e255b
--- /dev/null
+++ b/spec/graphql/resolvers/ci/runner_jobs_resolver_spec.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Resolvers::Ci::RunnerJobsResolver do
+ include GraphqlHelpers
+
+ let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:pipeline) { create(:ci_pipeline, project: project) }
+ let_it_be(:irrelevant_pipeline) { create(:ci_pipeline, project: project) }
+
+ let!(:build_one) { create(:ci_build, :success, name: 'Build One', runner: runner, pipeline: pipeline) }
+ let!(:build_two) { create(:ci_build, :success, name: 'Build Two', runner: runner, pipeline: pipeline) }
+ let!(:build_three) { create(:ci_build, :failed, name: 'Build Three', runner: runner, pipeline: pipeline) }
+ let!(:irrelevant_build) { create(:ci_build, name: 'Irrelevant Build', pipeline: irrelevant_pipeline)}
+
+ let(:args) { {} }
+ let(:runner) { create(:ci_runner, :project, projects: [project]) }
+
+ subject { resolve_jobs(args) }
+
+ describe '#resolve' do
+ context 'with authorized user', :enable_admin_mode do
+ let(:current_user) { create(:user, :admin) }
+
+ context 'with statuses argument' do
+ let(:args) { { statuses: [Types::Ci::JobStatusEnum.coerce_isolated_input('SUCCESS')] } }
+
+ it { is_expected.to contain_exactly(build_one, build_two) }
+ end
+
+ context 'without statuses argument' do
+ it { is_expected.to contain_exactly(build_one, build_two, build_three) }
+ end
+ end
+
+ context 'with unauthorized user' do
+ let(:current_user) { nil }
+
+ it { is_expected.to be_nil }
+ end
+ end
+
+ private
+
+ def resolve_jobs(args = {}, context = { current_user: current_user })
+ resolve(described_class, obj: runner, args: args, ctx: context)
+ end
+end
diff --git a/spec/graphql/resolvers/ci/runners_resolver_spec.rb b/spec/graphql/resolvers/ci/runners_resolver_spec.rb
index df6490df915..9251fbf24d9 100644
--- a/spec/graphql/resolvers/ci/runners_resolver_spec.rb
+++ b/spec/graphql/resolvers/ci/runners_resolver_spec.rb
@@ -43,34 +43,99 @@ RSpec.describe Resolvers::Ci::RunnersResolver do
# 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
- {
- active: true,
- status: 'active',
- type: :instance_type,
- tag_list: ['active_runner'],
- search: 'abc',
- sort: :contacted_asc
- }
+
+ context 'with active filter' do
+ let(:args) do
+ {
+ active: true,
+ status: 'active',
+ type: :instance_type,
+ tag_list: ['active_runner'],
+ search: 'abc',
+ sort: :contacted_asc
+ }
+ end
+
+ let(:expected_params) do
+ {
+ active: true,
+ 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
+ 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])
+ end
+ end
+
+ context 'with both active and paused filter' do
+ let(:args) do
+ {
+ active: true,
+ paused: true
+ }
+ end
+
+ let(:expected_params) do
+ {
+ active: false,
+ preload: { tag_name: nil }
+ }
+ end
+
+ it 'calls RunnersFinder with expected arguments' do
+ 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])
+ end
end
- let(:expected_params) do
- {
- active: true,
- status_status: 'active',
- type_type: :instance_type,
- tag_name: ['active_runner'],
- preload: { tag_name: nil },
- search: 'abc',
- sort: 'contacted_asc'
- }
+ context 'with paused filter' do
+ let(:args) do
+ { paused: true }
+ end
+
+ let(:expected_params) do
+ {
+ active: false,
+ preload: { tag_name: nil }
+ }
+ end
+
+ it 'calls RunnersFinder with expected arguments' do
+ 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])
+ end
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])
+ context 'with neither paused or active filters' do
+ let(:args) do
+ {}
+ end
+
+ let(:expected_params) do
+ {
+ preload: { tag_name: nil }
+ }
+ end
+
+ it 'calls RunnersFinder with expected arguments' do
+ 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(subject.items.to_a).to eq([:execute_return_value])
+ end
end
end
end
diff --git a/spec/graphql/resolvers/clusters/agent_tokens_resolver_spec.rb b/spec/graphql/resolvers/clusters/agent_tokens_resolver_spec.rb
index 9b54d466681..866f4ce7b5a 100644
--- a/spec/graphql/resolvers/clusters/agent_tokens_resolver_spec.rb
+++ b/spec/graphql/resolvers/clusters/agent_tokens_resolver_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe Resolvers::Clusters::AgentTokensResolver do
describe '#resolve' do
let(:agent) { create(:cluster_agent) }
- let(:user) { create(:user, maintainer_projects: [agent.project]) }
+ let(:user) { create(:user, developer_projects: [agent.project]) }
let(:ctx) { Hash(current_user: user) }
let!(:matching_token1) { create(:cluster_agent_token, agent: agent, last_used_at: 5.days.ago) }
@@ -33,7 +33,11 @@ RSpec.describe Resolvers::Clusters::AgentTokensResolver do
end
context 'user does not have permission' do
- let(:user) { create(:user, developer_projects: [agent.project]) }
+ let(:user) { create(:user) }
+
+ before do
+ agent.project.add_reporter(user)
+ end
it { is_expected.to be_empty }
end
diff --git a/spec/graphql/resolvers/clusters/agents_resolver_spec.rb b/spec/graphql/resolvers/clusters/agents_resolver_spec.rb
index 70f40748e1d..152d7fa22c4 100644
--- a/spec/graphql/resolvers/clusters/agents_resolver_spec.rb
+++ b/spec/graphql/resolvers/clusters/agents_resolver_spec.rb
@@ -15,10 +15,14 @@ RSpec.describe Resolvers::Clusters::AgentsResolver do
describe '#resolve' do
let_it_be(:project) { create(:project) }
- let_it_be(:maintainer) { create(:user, maintainer_projects: [project]) }
- let_it_be(:developer) { create(:user, developer_projects: [project]) }
+ let_it_be(:maintainer) { create(:user, developer_projects: [project]) }
+ let_it_be(:reporter) { create(:user) }
let_it_be(:agents) { create_list(:cluster_agent, 2, project: project) }
+ before do
+ project.add_reporter(reporter)
+ end
+
let(:ctx) { { current_user: current_user } }
subject { resolve_agents }
@@ -32,7 +36,7 @@ RSpec.describe Resolvers::Clusters::AgentsResolver do
end
context 'the current user does not have access to clusters' do
- let(:current_user) { developer }
+ let(:current_user) { reporter }
it 'returns an empty result' do
expect(subject).to be_empty
diff --git a/spec/graphql/resolvers/merge_requests_resolver_spec.rb b/spec/graphql/resolvers/merge_requests_resolver_spec.rb
index 1d0eac30a23..e4eaeb9bc3c 100644
--- a/spec/graphql/resolvers/merge_requests_resolver_spec.rb
+++ b/spec/graphql/resolvers/merge_requests_resolver_spec.rb
@@ -321,7 +321,7 @@ RSpec.describe Resolvers::MergeRequestsResolver do
end
describe 'sorting' do
- let(:mrs) do
+ let_it_be(:mrs) do
[
merge_request_with_milestone, merge_request_6, merge_request_5, merge_request_4,
merge_request_3, merge_request_2, merge_request_1
@@ -363,28 +363,44 @@ RSpec.describe Resolvers::MergeRequestsResolver do
def merged_at(mr)
nils_last(mr.metrics.merged_at)
end
+ end
+
+ context 'when sorting by closed at' do
+ before do
+ merge_request_1.metrics.update!(latest_closed_at: 10.days.ago)
+ merge_request_3.metrics.update!(latest_closed_at: 5.days.ago)
+ end
+
+ it 'sorts merge requests ascending' do
+ expect(resolve_mr(project, sort: :closed_at_asc))
+ .to match_array(mrs)
+ .and be_sorted(->(mr) { [closed_at(mr), -mr.id] })
+ end
+
+ it 'sorts merge requests descending' do
+ expect(resolve_mr(project, sort: :closed_at_desc))
+ .to match_array(mrs)
+ .and be_sorted(->(mr) { [-closed_at(mr), -mr.id] })
+ end
+
+ def closed_at(mr)
+ nils_last(mr.metrics.latest_closed_at)
+ end
+ end
+
+ context 'when sorting by title' do
+ let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:mr1) { create(:merge_request, :unique_branches, title: 'foo', source_project: project) }
+ let_it_be(:mr2) { create(:merge_request, :unique_branches, title: 'bar', source_project: project) }
+ let_it_be(:mr3) { create(:merge_request, :unique_branches, title: 'baz', source_project: project) }
+ let_it_be(:mr4) { create(:merge_request, :unique_branches, title: 'Baz 2', source_project: project) }
+
+ it 'sorts issues ascending' do
+ expect(resolve_mr(project, sort: :title_asc).to_a).to eq [mr2, mr3, mr4, mr1]
+ end
- context 'when sorting by closed at' do
- before do
- merge_request_1.metrics.update!(latest_closed_at: 10.days.ago)
- merge_request_3.metrics.update!(latest_closed_at: 5.days.ago)
- end
-
- it 'sorts merge requests ascending' do
- expect(resolve_mr(project, sort: :closed_at_asc))
- .to match_array(mrs)
- .and be_sorted(->(mr) { [closed_at(mr), -mr.id] })
- end
-
- it 'sorts merge requests descending' do
- expect(resolve_mr(project, sort: :closed_at_desc))
- .to match_array(mrs)
- .and be_sorted(->(mr) { [-closed_at(mr), -mr.id] })
- end
-
- def closed_at(mr)
- nils_last(mr.metrics.latest_closed_at)
- end
+ it 'sorts issues descending' do
+ expect(resolve_mr(project, sort: :title_desc).to_a).to eq [mr1, mr4, mr3, mr2]
end
end
end
diff --git a/spec/graphql/resolvers/package_details_resolver_spec.rb b/spec/graphql/resolvers/package_details_resolver_spec.rb
index d6acb31d4e3..c8ee489a034 100644
--- a/spec/graphql/resolvers/package_details_resolver_spec.rb
+++ b/spec/graphql/resolvers/package_details_resolver_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe Resolvers::PackageDetailsResolver do
include GraphqlHelpers
let_it_be_with_reload(:project) { create(:project) }
- let_it_be(:user) { project.owner }
+ let_it_be(:user) { project.first_owner }
let_it_be(:package) { create(:composer_package, project: project) }
describe '#resolve' do
diff --git a/spec/graphql/resolvers/package_pipelines_resolver_spec.rb b/spec/graphql/resolvers/package_pipelines_resolver_spec.rb
index d48d4d8ae01..892dc641201 100644
--- a/spec/graphql/resolvers/package_pipelines_resolver_spec.rb
+++ b/spec/graphql/resolvers/package_pipelines_resolver_spec.rb
@@ -8,15 +8,16 @@ RSpec.describe Resolvers::PackagePipelinesResolver do
let_it_be_with_reload(:package) { create(:package) }
let_it_be(:pipelines) { create_list(:ci_pipeline, 3, project: package.project) }
- let(:user) { package.project.owner }
+ let(:user) { package.project.first_owner }
let(:args) { {} }
describe '#resolve' do
subject { resolve(described_class, obj: package, args: args, ctx: { current_user: user }) }
before do
- package.pipelines = pipelines
- package.save!
+ pipelines.each do |pipeline|
+ create(:package_build_info, package: package, pipeline: pipeline)
+ end
end
it { is_expected.to contain_exactly(*pipelines) }
diff --git a/spec/graphql/resolvers/recent_boards_resolver_spec.rb b/spec/graphql/resolvers/recent_boards_resolver_spec.rb
new file mode 100644
index 00000000000..1afdcd42b4f
--- /dev/null
+++ b/spec/graphql/resolvers/recent_boards_resolver_spec.rb
@@ -0,0 +1,79 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Resolvers::RecentBoardsResolver do
+ include GraphqlHelpers
+
+ let_it_be(:user) { create(:user) }
+
+ shared_examples_for 'group and project recent boards resolver' do
+ let_it_be(:board1) { create(:board, name: 'One', resource_parent: board_parent) }
+ let_it_be(:board2) { create(:board, name: 'Two', resource_parent: board_parent) }
+
+ before do
+ [board1, board2].each { |board| visit_board(board, board_parent) }
+ end
+
+ it 'calls ::Boards::VisitsFinder' do
+ expect_any_instance_of(::Boards::VisitsFinder) do |finder|
+ expect(finder).to receive(:latest)
+ end
+
+ resolve_recent_boards
+ end
+
+ it 'avoids N+1 queries' do
+ control = ActiveRecord::QueryRecorder.new { resolve_recent_boards }
+
+ board3 = create(:board, resource_parent: board_parent)
+ visit_board(board3, board_parent)
+
+ expect { resolve_recent_boards(args: {}) }.not_to exceed_query_limit(control)
+ end
+
+ it 'returns most recent visited boards' do
+ expect(resolve_recent_boards).to match_array [board2, board1]
+ end
+
+ it 'returns a set number of boards' do
+ stub_const('Board::RECENT_BOARDS_SIZE', 1)
+
+ expect(resolve_recent_boards).to match_array [board2]
+ end
+ end
+
+ describe '#resolve' do
+ context 'when there is no parent' do
+ let_it_be(:board_parent) { nil }
+
+ it 'returns none if parent is nil' do
+ expect(resolve_recent_boards).to eq(Board.none)
+ end
+ end
+
+ context 'when project boards' do
+ let_it_be(:board_parent) { create(:project, :public, creator_id: user.id, namespace: user.namespace ) }
+
+ it_behaves_like 'group and project recent boards resolver'
+ end
+
+ context 'when group boards' do
+ let_it_be(:board_parent) { create(:group) }
+
+ it_behaves_like 'group and project recent boards resolver'
+ end
+ end
+
+ def resolve_recent_boards(args: {})
+ resolve(described_class, obj: board_parent, args: args, ctx: { current_user: user })
+ end
+
+ def visit_board(board, parent)
+ if parent.is_a?(Group)
+ create(:board_group_recent_visit, group: parent, board: board, user: user)
+ else
+ create(:board_project_recent_visit, project: parent, board: board, user: user)
+ end
+ end
+end