diff options
Diffstat (limited to 'spec/graphql')
45 files changed, 690 insertions, 159 deletions
diff --git a/spec/graphql/graphql_triggers_spec.rb b/spec/graphql/graphql_triggers_spec.rb index a4a643582f5..a54cb8a7988 100644 --- a/spec/graphql/graphql_triggers_spec.rb +++ b/spec/graphql/graphql_triggers_spec.rb @@ -3,76 +3,89 @@ require 'spec_helper' RSpec.describe GraphqlTriggers do + let_it_be(:issuable, refind: true) { create(:work_item) } + describe '.issuable_assignees_updated' do - it 'triggers the issuableAssigneesUpdated subscription' do - assignees = create_list(:user, 2) - issue = create(:issue, assignees: assignees) + let(:assignees) { create_list(:user, 2) } + before do + issuable.update!(assignees: assignees) + end + + it 'triggers the issuableAssigneesUpdated subscription' do expect(GitlabSchema.subscriptions).to receive(:trigger).with( 'issuableAssigneesUpdated', - { issuable_id: issue.to_gid }, - issue + { issuable_id: issuable.to_gid }, + issuable ) - GraphqlTriggers.issuable_assignees_updated(issue) + GraphqlTriggers.issuable_assignees_updated(issuable) end end describe '.issuable_title_updated' do it 'triggers the issuableTitleUpdated subscription' do - work_item = create(:work_item) - expect(GitlabSchema.subscriptions).to receive(:trigger).with( 'issuableTitleUpdated', - { issuable_id: work_item.to_gid }, - work_item + { issuable_id: issuable.to_gid }, + issuable ).and_call_original - GraphqlTriggers.issuable_title_updated(work_item) + GraphqlTriggers.issuable_title_updated(issuable) end end describe '.issuable_description_updated' do it 'triggers the issuableDescriptionUpdated subscription' do - work_item = create(:work_item) - expect(GitlabSchema.subscriptions).to receive(:trigger).with( 'issuableDescriptionUpdated', - { issuable_id: work_item.to_gid }, - work_item + { issuable_id: issuable.to_gid }, + issuable ).and_call_original - GraphqlTriggers.issuable_description_updated(work_item) + GraphqlTriggers.issuable_description_updated(issuable) end end describe '.issuable_labels_updated' do - it 'triggers the issuableLabelsUpdated subscription' do - project = create(:project) - labels = create_list(:label, 3, project: project) - issue = create(:issue, labels: labels) + let(:labels) { create_list(:label, 3, project: create(:project)) } + + before do + issuable.update!(labels: labels) + end + it 'triggers the issuableLabelsUpdated subscription' do expect(GitlabSchema.subscriptions).to receive(:trigger).with( 'issuableLabelsUpdated', - { issuable_id: issue.to_gid }, - issue + { issuable_id: issuable.to_gid }, + issuable ) - GraphqlTriggers.issuable_labels_updated(issue) + GraphqlTriggers.issuable_labels_updated(issuable) end end describe '.issuable_dates_updated' do it 'triggers the issuableDatesUpdated subscription' do - work_item = create(:work_item) - expect(GitlabSchema.subscriptions).to receive(:trigger).with( 'issuableDatesUpdated', - { issuable_id: work_item.to_gid }, - work_item + { issuable_id: issuable.to_gid }, + issuable + ).and_call_original + + GraphqlTriggers.issuable_dates_updated(issuable) + end + end + + describe '.issuable_milestone_updated' do + it 'triggers the issuableMilestoneUpdated subscription' do + expect(GitlabSchema.subscriptions).to receive(:trigger).with( + 'issuableMilestoneUpdated', + { issuable_id: issuable.to_gid }, + issuable ).and_call_original - GraphqlTriggers.issuable_dates_updated(work_item) + GraphqlTriggers.issuable_milestone_updated(issuable) end end diff --git a/spec/graphql/mutations/ci/runner/bulk_delete_spec.rb b/spec/graphql/mutations/ci/runner/bulk_delete_spec.rb index f47f1b9869e..2eccfd3409f 100644 --- a/spec/graphql/mutations/ci/runner/bulk_delete_spec.rb +++ b/spec/graphql/mutations/ci/runner/bulk_delete_spec.rb @@ -6,7 +6,6 @@ RSpec.describe Mutations::Ci::Runner::BulkDelete do include GraphqlHelpers let_it_be(:admin_user) { create(:user, :admin) } - let_it_be(:user) { create(:user) } let(:current_ctx) { { current_user: user } } @@ -19,24 +18,15 @@ RSpec.describe Mutations::Ci::Runner::BulkDelete do sync(resolve(described_class, args: mutation_params, ctx: current_ctx)) end - context 'when the user cannot admin the runner' do - let(:runner) { create(:ci_runner) } - let(:mutation_params) do - { ids: [runner.to_global_id] } - end - - it 'generates an error' do - expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) { response } - end - end - context 'when user can delete runners' do + let_it_be(:group) { create(:group) } + let(:user) { admin_user } let!(:runners) do - create_list(:ci_runner, 2, :instance) + create_list(:ci_runner, 2, :group, groups: [group]) end - context 'when required arguments are missing' do + context 'when runner IDs are missing' do let(:mutation_params) { {} } context 'when admin mode is enabled', :enable_admin_mode do @@ -47,43 +37,48 @@ RSpec.describe Mutations::Ci::Runner::BulkDelete do end context 'with runners specified by id' do - let(:mutation_params) do + let!(:mutation_params) do { ids: runners.map(&:to_global_id) } end context 'when admin mode is enabled', :enable_admin_mode do it 'deletes runners', :aggregate_failures do - expect_next_instance_of( - ::Ci::Runners::BulkDeleteRunnersService, { runners: runners } - ) do |service| - expect(service).to receive(:execute).once.and_call_original - end - expect { response }.to change { Ci::Runner.count }.by(-2) expect(response[:errors]).to be_empty end + end - context 'when runner list is is above limit' do - before do - stub_const('::Ci::Runners::BulkDeleteRunnersService::RUNNER_LIMIT', 1) - end - - it 'only deletes up to the defined limit', :aggregate_failures do - expect { response }.to change { Ci::Runner.count } - .by(-::Ci::Runners::BulkDeleteRunnersService::RUNNER_LIMIT) - expect(response[:errors]).to be_empty - end + it 'ignores unknown keys from service response payload', :aggregate_failures do + expect_next_instance_of( + ::Ci::Runners::BulkDeleteRunnersService, { runners: runners, current_user: user } + ) do |service| + expect(service).to receive(:execute).once.and_return( + ServiceResponse.success( + payload: { + extra_key: 'extra_value', + deleted_count: 10, + deleted_ids: (1..10).to_a, + errors: [] + })) end + + expect(response).not_to include(extra_key: 'extra_value') end + end + end - context 'when admin mode is disabled', :aggregate_failures do - it 'returns error', :aggregate_failures do - expect do - expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do - response - end - end.not_to change { Ci::Runner.count } - end + context 'when the user cannot delete the runner' do + let(:runner) { create(:ci_runner) } + let!(:mutation_params) do + { ids: [runner.to_global_id] } + end + + context 'when user is admin and admin mode is not enabled' do + let(:user) { admin_user } + + it 'returns error', :aggregate_failures do + expect { response }.not_to change { Ci::Runner.count } + expect(response[:errors]).to match_array("User does not have permission to delete any of the runners") end end end diff --git a/spec/graphql/mutations/ci/runner/update_spec.rb b/spec/graphql/mutations/ci/runner/update_spec.rb index ee65be1e085..098b7ac6aa4 100644 --- a/spec/graphql/mutations/ci/runner/update_spec.rb +++ b/spec/graphql/mutations/ci/runner/update_spec.rb @@ -7,8 +7,10 @@ RSpec.describe Mutations::Ci::Runner::Update do let_it_be(:user) { create(:user) } let_it_be(:project1) { create(:project) } - let_it_be(:runner) do - create(:ci_runner, :project, projects: [project1], active: true, locked: false, run_untagged: true) + let_it_be(:project2) { create(:project) } + + let(:runner) do + create(:ci_runner, :project, projects: [project1, project2], active: true, locked: false, run_untagged: true) end let(:current_ctx) { { current_user: user } } @@ -79,14 +81,14 @@ RSpec.describe Mutations::Ci::Runner::Update do end context 'with associatedProjects argument' do - let_it_be(:project2) { create(:project) } + let_it_be(:project3) { create(:project) } context 'with id set to project runner' do let(:mutation_params) do { id: runner.to_global_id, description: 'updated description', - associated_projects: [project2.to_global_id.to_s] + associated_projects: [project3.to_global_id.to_s] } end @@ -96,7 +98,7 @@ RSpec.describe Mutations::Ci::Runner::Update do { runner: runner, current_user: admin_user, - project_ids: [project2.id] + project_ids: [project3.id] } ) do |service| expect(service).to receive(:execute).and_call_original @@ -110,7 +112,7 @@ RSpec.describe Mutations::Ci::Runner::Update do expect(response[:runner]).to be_an_instance_of(Ci::Runner) expect(response[:runner]).to have_attributes(expected_attributes) expect(runner.reload).to have_attributes(expected_attributes) - expect(runner.projects).to match_array([project1, project2]) + expect(runner.projects).to match_array([project1, project3]) end context 'with user not allowed to assign runner' do @@ -124,7 +126,7 @@ RSpec.describe Mutations::Ci::Runner::Update do { runner: runner, current_user: admin_user, - project_ids: [project2.id] + project_ids: [project3.id] } ) do |service| expect(service).to receive(:execute).and_call_original @@ -137,11 +139,39 @@ RSpec.describe Mutations::Ci::Runner::Update do expect(response[:errors]).to match_array(['user not allowed to assign runner']) expect(response[:runner]).to be_nil expect(runner.reload).not_to have_attributes(expected_attributes) - expect(runner.projects).to match_array([project1]) + expect(runner.projects).to match_array([project1, project2]) end end end + context 'with an empty list of projects' do + let(:mutation_params) do + { + id: runner.to_global_id, + associated_projects: [] + } + end + + it 'removes project relationships', :aggregate_failures do + expect_next_instance_of( + ::Ci::Runners::SetRunnerAssociatedProjectsService, + { + runner: runner, + current_user: admin_user, + project_ids: [] + } + ) do |service| + expect(service).to receive(:execute).and_call_original + end + + response + + expect(response[:errors]).to be_empty + expect(response[:runner]).to be_an_instance_of(Ci::Runner) + expect(runner.reload.projects).to contain_exactly(project1) + end + end + context 'with id set to instance runner' do let(:instance_runner) { create(:ci_runner, :instance) } let(:mutation_params) do diff --git a/spec/graphql/mutations/commits/create_spec.rb b/spec/graphql/mutations/commits/create_spec.rb index fd0c2c46b2e..2c452410cca 100644 --- a/spec/graphql/mutations/commits/create_spec.rb +++ b/spec/graphql/mutations/commits/create_spec.rb @@ -179,7 +179,7 @@ RSpec.describe Mutations::Commits::Create do it 'returns errors' do expect(mutated_commit).to be_nil - expect(subject[:errors].to_s).to match(/3:UserCommitFiles: empty CommitMessage/) + expect(subject[:errors].to_s).to match(/empty CommitMessage/) end end diff --git a/spec/graphql/mutations/concerns/mutations/resolves_group_spec.rb b/spec/graphql/mutations/concerns/mutations/resolves_group_spec.rb index 6bed3a752ed..3198419fb81 100644 --- a/spec/graphql/mutations/concerns/mutations/resolves_group_spec.rb +++ b/spec/graphql/mutations/concerns/mutations/resolves_group_spec.rb @@ -9,7 +9,7 @@ RSpec.describe Mutations::ResolvesGroup do end end - let(:context) { double } + let(:context) { {} } subject(:mutation) { mutation_class.new(object: nil, context: context, field: nil) } diff --git a/spec/graphql/mutations/container_repositories/destroy_spec.rb b/spec/graphql/mutations/container_repositories/destroy_spec.rb index 97da7846339..9f3ff8da80b 100644 --- a/spec/graphql/mutations/container_repositories/destroy_spec.rb +++ b/spec/graphql/mutations/container_repositories/destroy_spec.rb @@ -20,11 +20,10 @@ RSpec.describe Mutations::ContainerRepositories::Destroy do end shared_examples 'destroying the container repository' do - it 'destroys the container repistory' do + it 'marks the repository as delete_scheduled' do expect(::Packages::CreateEventService) .to receive(:new).with(nil, user, event_name: :delete_repository, scope: :container).and_call_original - expect(DeleteContainerRepositoryWorker) - .to receive(:perform_async).with(user.id, container_repository.id) + expect(DeleteContainerRepositoryWorker).not_to receive(:perform_async) expect { subject }.to change { ::Packages::Event.count }.by(1) expect(container_repository.reload.delete_scheduled?).to be true @@ -56,6 +55,23 @@ RSpec.describe Mutations::ContainerRepositories::Destroy do it_behaves_like params[:shared_examples_name] end + + context 'with container_registry_delete_repository_with_cron_worker disabled' do + before do + project.add_maintainer(user) + stub_feature_flags(container_registry_delete_repository_with_cron_worker: false) + end + + it 'enqueues a removal job' do + expect(::Packages::CreateEventService) + .to receive(:new).with(nil, user, event_name: :delete_repository, scope: :container).and_call_original + expect(DeleteContainerRepositoryWorker) + .to receive(:perform_async).with(user.id, container_repository.id) + + expect { subject }.to change { ::Packages::Event.count }.by(1) + expect(container_repository.reload.delete_scheduled?).to be true + end + end end end end diff --git a/spec/graphql/mutations/incident_management/timeline_event/create_spec.rb b/spec/graphql/mutations/incident_management/timeline_event/create_spec.rb index 9254d84b29c..aab21776a99 100644 --- a/spec/graphql/mutations/incident_management/timeline_event/create_spec.rb +++ b/spec/graphql/mutations/incident_management/timeline_event/create_spec.rb @@ -6,6 +6,9 @@ RSpec.describe Mutations::IncidentManagement::TimelineEvent::Create do let_it_be(:current_user) { create(:user) } let_it_be(:project) { create(:project) } let_it_be(:incident) { create(:incident, project: project) } + let_it_be(:timeline_event_tag) do + create(:incident_management_timeline_event_tag, project: project, name: 'Test tag 1') + end let(:args) { { note: 'note', occurred_at: Time.current } } @@ -39,6 +42,104 @@ RSpec.describe Mutations::IncidentManagement::TimelineEvent::Create do it_behaves_like 'responding with an incident timeline errors', errors: ["Occurred at can't be blank and Timeline text can't be blank"] end + + context 'when timeline event tags are passed' do + let(:args) do + { + note: 'note', + occurred_at: Time.current, + timeline_event_tag_names: [timeline_event_tag.name.to_s] + } + end + + it_behaves_like 'creating an incident timeline event' + end + + context 'when predefined tags are passed' do + let(:args) do + { + note: 'note', + occurred_at: Time.current, + timeline_event_tag_names: ['Start time'] + } + end + + it_behaves_like 'creating an incident timeline event' + + it 'creates and sets the tag on the event' do + timeline_event = resolve[:timeline_event] + + expect(timeline_event.timeline_event_tags.by_names(['Start time']).count).to eq 1 + end + end + + context 'when predefined tags exist' do + let_it_be(:end_time_tag) do + create(:incident_management_timeline_event_tag, project: project, name: 'End time') + end + + let(:args) do + { + note: 'note', + occurred_at: Time.current, + timeline_event_tag_names: ['End time'] + } + end + + it 'does not create a new tag' do + expect { resolve }.not_to change(IncidentManagement::TimelineEventTag, :count) + end + end + + context 'when same tags are tried to be assigned to same timeline event' do + let(:args) do + { + note: 'note', + occurred_at: Time.current, + timeline_event_tag_names: ['Start time', 'Start time'] + } + end + + it 'only assigns the tag once on the event' do + timeline_event = resolve[:timeline_event] + + expect(timeline_event.timeline_event_tags.by_names(['Start time']).count).to eq(1) + expect(timeline_event.timeline_event_tags.count).to eq(1) + end + end + + context 'with case-insentive tags' do + let(:args) do + { + note: 'note', + occurred_at: Time.current, + timeline_event_tag_names: ['tESt tAg 1'] + } + end + + it 'sets the tag on the event' do + timeline_event = resolve[:timeline_event] + + expect(timeline_event.timeline_event_tags.by_names(['Test tag 1']).count).to eq(1) + end + end + + context 'when non-existing tags are passed' do + let(:args) do + { + note: 'note', + occurred_at: Time.current, + timeline_event_tag_names: ['other time'] + } + end + + it_behaves_like 'responding with an incident timeline errors', + errors: ["Following tags don't exist: [\"other time\"]"] + + it 'does not create the timeline event' do + expect { resolve }.not_to change(IncidentManagement::TimelineEvent, :count) + end + end end it_behaves_like 'failing to create an incident timeline event' diff --git a/spec/graphql/mutations/incident_management/timeline_event_tag/create_spec.rb b/spec/graphql/mutations/incident_management/timeline_event_tag/create_spec.rb new file mode 100644 index 00000000000..57a32f7e4bc --- /dev/null +++ b/spec/graphql/mutations/incident_management/timeline_event_tag/create_spec.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Mutations::IncidentManagement::TimelineEventTag::Create do + let_it_be(:current_user) { create(:user) } + let_it_be_with_reload(:project) { create(:project) } + + let(:args) { { name: 'Test tag 1' } } + + before do + project.add_maintainer(current_user) + end + + specify { expect(described_class).to require_graphql_authorizations(:admin_incident_management_timeline_event_tag) } + + describe '#resolve' do + subject(:resolve) { mutation_for(project, current_user).resolve(project_path: project.full_path, **args) } + + context 'when user has permission to create timeline event tag' do + it 'adds the tag to the project' do + expect { resolve }.to change(IncidentManagement::TimelineEventTag, :count).by(1) + expect(project.incident_management_timeline_event_tags.by_names(['Test tag 1']).pluck_names) + .to match_array(['Test tag 1']) + end + end + + context 'when TimelineEventTags::CreateService responds with an error' do + let(:args) { {} } + + it 'returns errors' do + expect(resolve).to eq(timeline_event_tag: nil, errors: ["Name can't be blank and Name is invalid"]) + end + end + + context 'when user has no permissions to create tags on a project' do + before do + project.add_developer(current_user) + end + + it 'raises an error' do + expect { resolve }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable) + end + end + end + + private + + def mutation_for(project, user) + described_class.new(object: project, context: { current_user: user }, field: nil) + end +end diff --git a/spec/graphql/mutations/security/ci_configuration/base_security_analyzer_spec.rb b/spec/graphql/mutations/security/ci_configuration/base_security_analyzer_spec.rb index 668768189df..c081f9f0cd2 100644 --- a/spec/graphql/mutations/security/ci_configuration/base_security_analyzer_spec.rb +++ b/spec/graphql/mutations/security/ci_configuration/base_security_analyzer_spec.rb @@ -11,6 +11,6 @@ RSpec.describe Mutations::Security::CiConfiguration::BaseSecurityAnalyzer do project = create(:project, :public, :repository) project.add_developer(user) - expect { mutation.resolve(project_path: project.full_path ) }.to raise_error(NotImplementedError) + expect { mutation.resolve(project_path: project.full_path) }.to raise_error(NotImplementedError) end end diff --git a/spec/graphql/mutations/todos/restore_many_spec.rb b/spec/graphql/mutations/todos/restore_many_spec.rb index d43f1c8a2e9..3235be8486e 100644 --- a/spec/graphql/mutations/todos/restore_many_spec.rb +++ b/spec/graphql/mutations/todos/restore_many_spec.rb @@ -80,7 +80,7 @@ RSpec.describe Mutations::Todos::RestoreMany do end def restore_mutation(todos) - mutation.resolve(ids: todos.map { |todo| global_id_of(todo) } ) + mutation.resolve(ids: todos.map { |todo| global_id_of(todo) }) end def expect_states_were_not_changed diff --git a/spec/graphql/resolvers/board_list_issues_resolver_spec.rb b/spec/graphql/resolvers/board_list_issues_resolver_spec.rb index ab1f19abaad..d346b7aee93 100644 --- a/spec/graphql/resolvers/board_list_issues_resolver_spec.rb +++ b/spec/graphql/resolvers/board_list_issues_resolver_spec.rb @@ -7,7 +7,7 @@ RSpec.describe Resolvers::BoardListIssuesResolver do 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(: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 diff --git a/spec/graphql/resolvers/board_lists_resolver_spec.rb b/spec/graphql/resolvers/board_lists_resolver_spec.rb index 2fb7c5c4717..0f6e51ebbd0 100644 --- a/spec/graphql/resolvers/board_lists_resolver_spec.rb +++ b/spec/graphql/resolvers/board_lists_resolver_spec.rb @@ -8,7 +8,7 @@ RSpec.describe Resolvers::BoardListsResolver do let_it_be(:user) { create(:user) } let_it_be(:guest) { create(:user) } let_it_be(:unauth_user) { create(:user) } - let_it_be(:project) { create(:project, creator_id: user.id, namespace: user.namespace ) } + let_it_be(:project) { create(:project, creator_id: user.id, namespace: user.namespace) } let_it_be(:group) { create(:group, :private) } let_it_be(:project_label) { create(:label, project: project, name: 'Development') } let_it_be(:group_label) { create(:group_label, group: group, name: 'Development') } @@ -65,7 +65,7 @@ RSpec.describe Resolvers::BoardListsResolver do it 'returns empty result if list is not found' do external_group = create(:group, :private) - external_board = create(:board, resource_parent: external_group ) + 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) diff --git a/spec/graphql/resolvers/board_resolver_spec.rb b/spec/graphql/resolvers/board_resolver_spec.rb index 51a13850366..e83d2cbfd1f 100644 --- a/spec/graphql/resolvers/board_resolver_spec.rb +++ b/spec/graphql/resolvers/board_resolver_spec.rb @@ -54,7 +54,7 @@ RSpec.describe Resolvers::BoardResolver do end context 'when project boards' do - let(:board_parent) { create(:project, :public, creator_id: user.id, namespace: user.namespace ) } + let(:board_parent) { create(:project, :public, creator_id: user.id, namespace: user.namespace) } it_behaves_like 'group and project boards resolver' end diff --git a/spec/graphql/resolvers/boards_resolver_spec.rb b/spec/graphql/resolvers/boards_resolver_spec.rb index 07d0902d3ba..aa78f0db188 100644 --- a/spec/graphql/resolvers/boards_resolver_spec.rb +++ b/spec/graphql/resolvers/boards_resolver_spec.rb @@ -72,7 +72,7 @@ RSpec.describe Resolvers::BoardsResolver do end context 'when project boards' do - let(:board_parent) { create(:project, :public, creator_id: user.id, namespace: user.namespace ) } + let(:board_parent) { create(:project, :public, creator_id: user.id, namespace: user.namespace) } it_behaves_like 'group and project boards resolver' end diff --git a/spec/graphql/resolvers/container_repositories_resolver_spec.rb b/spec/graphql/resolvers/container_repositories_resolver_spec.rb index 8cbb366f873..df0a98b1536 100644 --- a/spec/graphql/resolvers/container_repositories_resolver_spec.rb +++ b/spec/graphql/resolvers/container_repositories_resolver_spec.rb @@ -43,7 +43,7 @@ RSpec.describe Resolvers::ContainerRepositoriesResolver do end [:created_desc, :updated_asc, :name_desc].each do |order| - context "#{order}" do + context order.to_s do let(:args) { { sort: order } } it { is_expected.to eq([sort_repository2, sort_repository]) } @@ -51,7 +51,7 @@ RSpec.describe Resolvers::ContainerRepositoriesResolver do end [:created_asc, :updated_desc, :name_asc].each do |order| - context "#{order}" do + context order.to_s do let(:args) { { sort: order } } it { is_expected.to eq([sort_repository, sort_repository2]) } diff --git a/spec/graphql/resolvers/group_packages_resolver_spec.rb b/spec/graphql/resolvers/group_packages_resolver_spec.rb index c600f9c9f9a..639d4d93b79 100644 --- a/spec/graphql/resolvers/group_packages_resolver_spec.rb +++ b/spec/graphql/resolvers/group_packages_resolver_spec.rb @@ -21,10 +21,10 @@ RSpec.describe 'Resolvers::GroupPackagesResolver' do describe 'project_path sorting' do let_it_be(:project2) { create(:project, :public, group: group, path: 'b') } - let_it_be(:package) { create(:package, project: project ) } - let_it_be(:package2) { create(:package, project: project2 ) } - let_it_be(:package3) { create(:package, project: project ) } - let_it_be(:package4) { create(:package, project: project2 ) } + let_it_be(:package) { create(:package, project: project) } + let_it_be(:package2) { create(:package, project: project2) } + let_it_be(:package3) { create(:package, project: project) } + let_it_be(:package4) { create(:package, project: project2) } context 'filter by package_name' do let(:args) { { sort: 'PROJECT_PATH_DESC' } } diff --git a/spec/graphql/resolvers/incident_management/timeline_event_tags_resolver_spec.rb b/spec/graphql/resolvers/incident_management/timeline_event_tags_resolver_spec.rb new file mode 100644 index 00000000000..8ab34e05e52 --- /dev/null +++ b/spec/graphql/resolvers/incident_management/timeline_event_tags_resolver_spec.rb @@ -0,0 +1,92 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Resolvers::IncidentManagement::TimelineEventTagsResolver do + include GraphqlHelpers + + let_it_be(:current_user) { create(:user) } + let_it_be(:project) { create(:project) } + let_it_be(:incident) { create(:incident, project: project) } + + let_it_be(:timeline_event) do + create(:incident_management_timeline_event, project: project, incident: incident) + end + + let_it_be(:timeline_event_with_no_tags) do + create(:incident_management_timeline_event, project: project, incident: incident) + end + + let_it_be(:timeline_event_tag) do + create(:incident_management_timeline_event_tag, project: project) + end + + let_it_be(:timeline_event_tag2) do + create(:incident_management_timeline_event_tag, project: project, name: 'Test tag 2') + end + + let_it_be(:timeline_event_tag_link) do + create(:incident_management_timeline_event_tag_link, + timeline_event: timeline_event, + timeline_event_tag: timeline_event_tag) + end + + let(:resolver) { described_class } + + subject(:resolved_timeline_event_tags) do + sync(resolve_timeline_event_tags(timeline_event, current_user: current_user).to_a) + end + + before do + project.add_guest(current_user) + end + + specify do + expect(resolver).to have_nullable_graphql_type( + Types::IncidentManagement::TimelineEventTagType.connection_type + ) + end + + it 'returns timeline event tags', :aggregate_failures do + expect(resolved_timeline_event_tags.length).to eq(1) + expect(resolved_timeline_event_tags.first).to be_a(::IncidentManagement::TimelineEventTag) + end + + context 'when timeline event is nil' do + subject(:resolved_timeline_event_tags) do + sync(resolve_timeline_event_tags(nil, current_user: current_user).to_a) + end + + it 'returns no timeline event tags' do + expect(resolved_timeline_event_tags).to be_empty + end + end + + context 'when there is no timeline event tag link' do + subject(:resolved_timeline_event_tags) do + sync(resolve_timeline_event_tags(timeline_event_with_no_tags, current_user: current_user).to_a) + end + + it 'returns no timeline event tags' do + expect(resolved_timeline_event_tags).to be_empty + end + end + + context 'when user does not have permissions' do + let(:non_member) { create(:user) } + + subject(:resolved_timeline_event_tags) do + sync(resolve_timeline_event_tags(timeline_event, current_user: non_member).to_a) + end + + it 'returns no timeline event tags' do + expect(resolved_timeline_event_tags).to be_empty + end + end + + private + + def resolve_timeline_event_tags(obj, context = { current_user: current_user }) + resolve(resolver, obj: obj, args: {}, ctx: context, arg_style: :internal_prepared) + end +end diff --git a/spec/graphql/resolvers/issues_resolver_spec.rb b/spec/graphql/resolvers/project_issues_resolver_spec.rb index a74b2a3f18c..b2796ad9b18 100644 --- a/spec/graphql/resolvers/issues_resolver_spec.rb +++ b/spec/graphql/resolvers/project_issues_resolver_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Resolvers::IssuesResolver do +RSpec.describe Resolvers::ProjectIssuesResolver do include GraphqlHelpers let_it_be(:current_user) { create(:user) } @@ -87,7 +87,7 @@ RSpec.describe Resolvers::IssuesResolver do end end - context 'negated filtering' do + context 'when using negated filters' do it 'returns issues matching the searched title after applying a negated filter' do expect(resolve_issues(milestone_title: ['past milestone'], not: { milestone_wildcard_id: wildcard_upcoming })).to contain_exactly(issue6) end @@ -252,7 +252,7 @@ RSpec.describe Resolvers::IssuesResolver do end end - context 'filtering by reaction emoji' do + context 'when filtering by reaction emoji' do let_it_be(:downvoted_issue) { create(:issue, project: project) } let_it_be(:downvote_award) { create(:award_emoji, :downvote, user: current_user, awardable: downvoted_issue) } @@ -273,7 +273,7 @@ RSpec.describe Resolvers::IssuesResolver do end end - context 'confidential issues' do + context 'when listing confidential issues' do let_it_be(:confidential_issue1) { create(:issue, project: project, confidential: true) } let_it_be(:confidential_issue2) { create(:issue, project: other_project, confidential: true) } @@ -375,13 +375,13 @@ RSpec.describe Resolvers::IssuesResolver do create(:issue_customer_relations_contact, issue: crm_issue3, contact: contact3) end - context 'contact' do + context 'when filtering by contact' do it 'returns only the issues for the contact' do expect(resolve_issues({ crm_contact_id: contact1.id })).to contain_exactly(crm_issue1) end end - context 'organization' do + context 'when filtering by organization' do it 'returns only the issues for the contact' do expect(resolve_issues({ crm_organization_id: organization.id })).to contain_exactly(crm_issue1, crm_issue2) end diff --git a/spec/graphql/resolvers/projects_resolver_spec.rb b/spec/graphql/resolvers/projects_resolver_spec.rb index 453fafb9590..77507474170 100644 --- a/spec/graphql/resolvers/projects_resolver_spec.rb +++ b/spec/graphql/resolvers/projects_resolver_spec.rb @@ -142,7 +142,7 @@ RSpec.describe Resolvers::ProjectsResolver do context 'when no sort is provided' do it 'returns projects in descending order by id' do - is_expected.to match_array((visible_projecs + named_projects).sort_by { |p| p[:id] }.reverse ) + is_expected.to match_array((visible_projecs + named_projects).sort_by { |p| p[:id] }.reverse) end end end diff --git a/spec/graphql/resolvers/recent_boards_resolver_spec.rb b/spec/graphql/resolvers/recent_boards_resolver_spec.rb index 1afdcd42b4f..059e4a538fe 100644 --- a/spec/graphql/resolvers/recent_boards_resolver_spec.rb +++ b/spec/graphql/resolvers/recent_boards_resolver_spec.rb @@ -53,7 +53,7 @@ RSpec.describe Resolvers::RecentBoardsResolver do end context 'when project boards' do - let_it_be(:board_parent) { create(:project, :public, creator_id: user.id, namespace: user.namespace ) } + 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 diff --git a/spec/graphql/resolvers/users_resolver_spec.rb b/spec/graphql/resolvers/users_resolver_spec.rb index dda15303676..2ae1b53c40f 100644 --- a/spec/graphql/resolvers/users_resolver_spec.rb +++ b/spec/graphql/resolvers/users_resolver_spec.rb @@ -23,7 +23,7 @@ RSpec.describe Resolvers::UsersResolver do context 'when both ids and usernames are passed ' do it 'generates an error' do expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError) do - resolve_users( args: { ids: [user1.to_global_id.to_s], usernames: [user1.username] } ) + resolve_users(args: { ids: [user1.to_global_id.to_s], usernames: [user1.username] }) end end end @@ -31,7 +31,7 @@ RSpec.describe Resolvers::UsersResolver do context 'when a set of IDs is passed' do it 'returns those users' do expect( - resolve_users( args: { ids: [user1.to_global_id.to_s, user2.to_global_id.to_s] } ) + resolve_users(args: { ids: [user1.to_global_id.to_s, user2.to_global_id.to_s] }) ).to contain_exactly(user1, user2) end end @@ -39,7 +39,7 @@ RSpec.describe Resolvers::UsersResolver do context 'when a set of usernames is passed' do it 'returns those users' do expect( - resolve_users( args: { usernames: [user1.username, user2.username] } ) + resolve_users(args: { usernames: [user1.username, user2.username] }) ).to contain_exactly(user1, user2) end end @@ -49,16 +49,16 @@ RSpec.describe Resolvers::UsersResolver do it 'returns only admins' do expect( - resolve_users( args: { admins: true }, ctx: { current_user: admin_user } ) + resolve_users(args: { admins: true }, ctx: { current_user: admin_user }) ).to contain_exactly(admin_user) end end context 'when a search term is passed' do it 'returns all users who match', :aggregate_failures do - expect(resolve_users( args: { search: "some" } )).to contain_exactly(user1, user2) - expect(resolve_users( args: { search: "123784" } )).to contain_exactly(user2) - expect(resolve_users( args: { search: "someperson" } )).to contain_exactly(user1) + expect(resolve_users(args: { search: "some" })).to contain_exactly(user1, user2) + expect(resolve_users(args: { search: "123784" })).to contain_exactly(user2) + expect(resolve_users(args: { search: "someperson" })).to contain_exactly(user1) end end diff --git a/spec/graphql/resolvers/work_item_resolver_spec.rb b/spec/graphql/resolvers/work_item_resolver_spec.rb index c44ed395102..dacc6ac11d8 100644 --- a/spec/graphql/resolvers/work_item_resolver_spec.rb +++ b/spec/graphql/resolvers/work_item_resolver_spec.rb @@ -27,14 +27,6 @@ RSpec.describe Resolvers::WorkItemResolver do end end end - - context 'when the work_items feature flag is disabled' do - before do - stub_feature_flags(work_items: false) - end - - it { is_expected.to be_nil } - end end private diff --git a/spec/graphql/resolvers/work_items/types_resolver_spec.rb b/spec/graphql/resolvers/work_items/types_resolver_spec.rb index 868f4566ad6..5121a105523 100644 --- a/spec/graphql/resolvers/work_items/types_resolver_spec.rb +++ b/spec/graphql/resolvers/work_items/types_resolver_spec.rb @@ -29,16 +29,6 @@ RSpec.describe Resolvers::WorkItems::TypesResolver do expect(result.to_a).to contain_exactly(WorkItems::Type.default_by_type(:task)) end end - - context 'when work_items feature flag is disabled' do - before do - stub_feature_flags(work_items: false) - end - - it 'returns nil' do - expect(result).to be_nil - end - end end describe '#resolve' do @@ -53,15 +43,5 @@ RSpec.describe Resolvers::WorkItems::TypesResolver do it_behaves_like 'a work item type resolver' end - - context 'when parent is not a group or project' do - let(:object) { 'not a project/group' } - - it 'returns nil because of feature flag check' do - result = resolve(described_class, obj: object, args: {}) - - expect(result).to be_nil - end - end end end diff --git a/spec/graphql/types/ci/pipeline_schedule_status_enum_spec.rb b/spec/graphql/types/ci/pipeline_schedule_status_enum_spec.rb index d271e72b17f..dcf37df5070 100644 --- a/spec/graphql/types/ci/pipeline_schedule_status_enum_spec.rb +++ b/spec/graphql/types/ci/pipeline_schedule_status_enum_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe Types::Ci::PipelineScheduleStatusEnum do - specify { expect(described_class.graphql_name ).to eq('PipelineScheduleStatus') } + specify { expect(described_class.graphql_name).to eq('PipelineScheduleStatus') } it 'exposes the status of a pipeline schedule' do expect(described_class.values.keys).to match_array(%w[ACTIVE INACTIVE]) diff --git a/spec/graphql/types/ci/pipeline_type_spec.rb b/spec/graphql/types/ci/pipeline_type_spec.rb index 9dee834d05f..5683b3f86c4 100644 --- a/spec/graphql/types/ci/pipeline_type_spec.rb +++ b/spec/graphql/types/ci/pipeline_type_spec.rb @@ -18,7 +18,10 @@ RSpec.describe Types::Ci::PipelineType do ] if Gitlab.ee? - expected_fields += %w[security_report_summary security_report_findings code_quality_reports dast_profile] + expected_fields += %w[ + security_report_summary security_report_findings security_report_finding + code_quality_reports dast_profile + ] end expect(described_class).to have_graphql_fields(*expected_fields) diff --git a/spec/graphql/types/commit_signature_interface_spec.rb b/spec/graphql/types/commit_signature_interface_spec.rb new file mode 100644 index 00000000000..4962131d9b5 --- /dev/null +++ b/spec/graphql/types/commit_signature_interface_spec.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe GitlabSchema.types['CommitSignature'] do + it 'exposes the expected fields' do + expect(described_class).to have_graphql_fields(:verification_status, :commit_sha, :project) + end + + describe '.resolve_type' do + it 'resolves gpg signatures' do + expect(described_class.resolve_type(build(:gpg_signature), {})).to eq( + Types::CommitSignatures::GpgSignatureType) + end + + it 'resolves x509 signatures' do + expect(described_class.resolve_type(build(:x509_commit_signature), {})).to eq( + Types::CommitSignatures::X509SignatureType) + end + + it 'raises an error when type is not known' do + expect { described_class.resolve_type(Class, {}) }.to raise_error('Unsupported commit signature type') + end + end +end diff --git a/spec/graphql/types/commit_signatures/gpg_signature_type_spec.rb b/spec/graphql/types/commit_signatures/gpg_signature_type_spec.rb new file mode 100644 index 00000000000..0b69ee169f2 --- /dev/null +++ b/spec/graphql/types/commit_signatures/gpg_signature_type_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe GitlabSchema.types['GpgSignature'] do + specify { expect(described_class.graphql_name).to eq('GpgSignature') } + + specify { expect(described_class).to require_graphql_authorizations(:download_code) } + + specify { expect(described_class).to include(Types::CommitSignatureInterface) } + + it 'contains attributes related to GPG signatures' do + expect(described_class).to have_graphql_fields( + :user, :verification_status, :commit_sha, :project, + :gpg_key_user_name, :gpg_key_user_email, :gpg_key_primary_keyid + ) + end +end diff --git a/spec/graphql/types/commit_signatures/verification_status_enum_spec.rb b/spec/graphql/types/commit_signatures/verification_status_enum_spec.rb new file mode 100644 index 00000000000..cb7ce19c9fc --- /dev/null +++ b/spec/graphql/types/commit_signatures/verification_status_enum_spec.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe GitlabSchema.types['VerificationStatus'] do + specify { expect(described_class.graphql_name).to eq('VerificationStatus') } + + it 'exposes all signature verification states' do + expect(described_class.values.keys) + .to match_array(%w[ + UNVERIFIED UNVERIFIED_KEY VERIFIED + SAME_USER_DIFFERENT_EMAIL OTHER_USER UNKNOWN_KEY + MULTIPLE_SIGNATURES + ]) + end +end diff --git a/spec/graphql/types/commit_signatures/x509_signature_type_spec.rb b/spec/graphql/types/commit_signatures/x509_signature_type_spec.rb new file mode 100644 index 00000000000..e268bd5b3b4 --- /dev/null +++ b/spec/graphql/types/commit_signatures/x509_signature_type_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe GitlabSchema.types['X509Signature'] do + specify { expect(described_class.graphql_name).to eq('X509Signature') } + + specify { expect(described_class).to require_graphql_authorizations(:download_code) } + + specify { expect(described_class).to include(Types::CommitSignatureInterface) } + + it 'contains attributes related to X.509 signatures' do + expect(described_class).to have_graphql_fields( + :user, :verification_status, :commit_sha, :project, + :x509_certificate + ) + end +end diff --git a/spec/graphql/types/commit_type_spec.rb b/spec/graphql/types/commit_type_spec.rb index fe8df15028d..561d165148b 100644 --- a/spec/graphql/types/commit_type_spec.rb +++ b/spec/graphql/types/commit_type_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' RSpec.describe GitlabSchema.types['Commit'] do specify { expect(described_class.graphql_name).to eq('Commit') } - specify { expect(described_class).to require_graphql_authorizations(:download_code) } + specify { expect(described_class).to require_graphql_authorizations(:read_code) } specify { expect(described_class).to include(Types::TodoableInterface) } @@ -13,7 +13,7 @@ RSpec.describe GitlabSchema.types['Commit'] do expect(described_class).to have_graphql_fields( :id, :sha, :short_id, :title, :full_title, :full_title_html, :description, :description_html, :message, :title_html, :authored_date, :author_name, :author_email, :author_gravatar, :author, :web_url, :web_path, - :pipelines, :signature_html + :pipelines, :signature_html, :signature ) end end diff --git a/spec/graphql/types/deployment_details_type_spec.rb b/spec/graphql/types/deployment_details_type_spec.rb index 70fdc38019e..7dc0c8f97ac 100644 --- a/spec/graphql/types/deployment_details_type_spec.rb +++ b/spec/graphql/types/deployment_details_type_spec.rb @@ -10,7 +10,7 @@ RSpec.describe GitlabSchema.types['DeploymentDetails'] do id iid ref tag tags sha created_at updated_at finished_at status commit job triggerer ] - expect(described_class).to have_graphql_fields(*expected_fields) + expect(described_class).to include_graphql_fields(*expected_fields) end specify { expect(described_class).to require_graphql_authorizations(:read_deployment) } diff --git a/spec/graphql/types/incident_management/timeline_event_tag_type_spec.rb b/spec/graphql/types/incident_management/timeline_event_tag_type_spec.rb new file mode 100644 index 00000000000..831a598ab66 --- /dev/null +++ b/spec/graphql/types/incident_management/timeline_event_tag_type_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe GitlabSchema.types['TimelineEventTagType'] do + specify { expect(described_class.graphql_name).to eq('TimelineEventTagType') } + + specify { expect(described_class).to require_graphql_authorizations(:read_incident_management_timeline_event_tag) } + + it 'exposes the expected fields' do + expected_fields = %i[ + id + name + ] + + expect(described_class).to have_graphql_fields(*expected_fields) + end +end diff --git a/spec/graphql/types/incident_management/timeline_event_type_spec.rb b/spec/graphql/types/incident_management/timeline_event_type_spec.rb index 5a6bc461f20..6805e0cdc9b 100644 --- a/spec/graphql/types/incident_management/timeline_event_type_spec.rb +++ b/spec/graphql/types/incident_management/timeline_event_type_spec.rb @@ -21,6 +21,7 @@ RSpec.describe GitlabSchema.types['TimelineEventType'] do occurred_at created_at updated_at + timeline_event_tags ] expect(described_class).to have_graphql_fields(*expected_fields) diff --git a/spec/graphql/types/issue_type_enum_spec.rb b/spec/graphql/types/issue_type_enum_spec.rb index 8f4b6f3bf74..cd1737c3ebb 100644 --- a/spec/graphql/types/issue_type_enum_spec.rb +++ b/spec/graphql/types/issue_type_enum_spec.rb @@ -5,9 +5,9 @@ require 'spec_helper' RSpec.describe Types::IssueTypeEnum do specify { expect(described_class.graphql_name).to eq('IssueType') } - it 'exposes all the existing issue type values' do + it 'exposes all the existing issue type values except key_result' do expect(described_class.values.keys).to match_array( - %w[ISSUE INCIDENT TEST_CASE REQUIREMENT TASK] + %w[ISSUE INCIDENT TEST_CASE REQUIREMENT TASK OBJECTIVE] ) end end diff --git a/spec/graphql/types/issue_type_spec.rb b/spec/graphql/types/issue_type_spec.rb index 2a0ae79b2c4..dc444f90627 100644 --- a/spec/graphql/types/issue_type_spec.rb +++ b/spec/graphql/types/issue_type_spec.rb @@ -17,7 +17,7 @@ RSpec.describe GitlabSchema.types['Issue'] do fields = %i[id iid title description state reference author assignees updated_by participants labels milestone due_date confidential hidden discussion_locked upvotes downvotes merge_requests_count user_notes_count user_discussions_count web_path web_url relative_position emails_disabled subscribed time_estimate total_time_spent human_time_estimate human_total_time_spent closed_at created_at updated_at task_completion_status - design_collection alert_management_alert severity current_user_todos moved moved_to + design_collection alert_management_alert alert_management_alerts severity current_user_todos moved moved_to closed_as_duplicate_of create_note_email timelogs project_id customer_relations_contacts escalation_status] fields.each do |field_name| diff --git a/spec/graphql/types/permission_types/ci/runner_spec.rb b/spec/graphql/types/permission_types/ci/runner_spec.rb index e5fbbb346e4..b4685794950 100644 --- a/spec/graphql/types/permission_types/ci/runner_spec.rb +++ b/spec/graphql/types/permission_types/ci/runner_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' RSpec.describe Types::PermissionTypes::Ci::Runner do it do expected_permissions = [ - :read_runner, :update_runner, :delete_runner + :read_runner, :update_runner, :delete_runner, :assign_runner ] expected_permissions.each do |permission| diff --git a/spec/graphql/types/project_type_spec.rb b/spec/graphql/types/project_type_spec.rb index b435f3ed5ff..30fabb8e9e2 100644 --- a/spec/graphql/types/project_type_spec.rb +++ b/spec/graphql/types/project_type_spec.rb @@ -36,7 +36,8 @@ RSpec.describe GitlabSchema.types['Project'] do cluster_agent cluster_agents agent_configurations ci_template timelogs merge_commit_template squash_commit_template work_item_types recent_issue_boards ci_config_path_or_default packages_cleanup_policy ci_variables - timelog_categories fork_targets branch_rules ci_config_variables pipeline_schedules + timelog_categories fork_targets branch_rules ci_config_variables pipeline_schedules languages + incident_management_timeline_event_tags ] expect(described_class).to include_graphql_fields(*expected_fields) @@ -212,8 +213,8 @@ RSpec.describe GitlabSchema.types['Project'] do it "returns the project's sast configuration for analyzer variables" do analyzer = subject.dig('data', 'project', 'sastCiConfiguration', 'analyzers', 'nodes').first - expect(analyzer['name']).to eq('bandit') - expect(analyzer['label']).to eq('Bandit') + expect(analyzer['name']).to eq('brakeman') + expect(analyzer['label']).to eq('Brakeman') expect(analyzer['enabled']).to eq(true) end @@ -290,14 +291,14 @@ RSpec.describe GitlabSchema.types['Project'] do subject { described_class.fields['issue'] } it { is_expected.to have_graphql_type(Types::IssueType) } - it { is_expected.to have_graphql_resolver(Resolvers::IssuesResolver.single) } + it { is_expected.to have_graphql_resolver(Resolvers::ProjectIssuesResolver.single) } end describe 'issues field' do subject { described_class.fields['issues'] } it { is_expected.to have_graphql_type(Types::IssueType.connection_type) } - it { is_expected.to have_graphql_resolver(Resolvers::IssuesResolver) } + it { is_expected.to have_graphql_resolver(Resolvers::ProjectIssuesResolver) } end describe 'merge_request field' do @@ -508,6 +509,12 @@ RSpec.describe GitlabSchema.types['Project'] do it { is_expected.to have_graphql_resolver(Resolvers::Ci::JobTokenScopeResolver) } end + describe 'incident_management_timeline_event_tags field' do + subject { described_class.fields['incidentManagementTimelineEventTags'] } + + it { is_expected.to have_graphql_type(Types::IncidentManagement::TimelineEventTagType) } + end + describe 'agent_configurations' do let_it_be(:project) { create(:project) } let_it_be(:user) { create(:user) } @@ -731,4 +738,114 @@ RSpec.describe GitlabSchema.types['Project'] do end end end + + describe 'timeline_event_tags' do + let_it_be(:user) { create(:user) } + let_it_be(:project) do + create(:project, + :private, + :repository, + creator_id: user.id, + namespace: user.namespace) + end + + let_it_be(:tag1) do + create(:incident_management_timeline_event_tag, + project: project, + name: 'Tag 1') + end + + let_it_be(:tag2) do + create(:incident_management_timeline_event_tag, + project: project, + name: 'Tag 2') + end + + let(:query) do + %( + query { + project(fullPath: "#{project.full_path}") { + incidentManagementTimelineEventTags { + name + id + } + } + } + ) + end + + let(:tags) do + subject.dig('data', 'project', 'incidentManagementTimelineEventTags') + end + + subject { GitlabSchema.execute(query, context: { current_user: user }).as_json } + + context 'when user has permissions to read project' do + before do + project.add_developer(user) + end + + it 'contains timeline event tags' do + expect(tags.count).to eq(2) + expect(tags.first['name']).to eq(tag1.name) + expect(tags.last['name']).to eq(tag2.name) + end + end + end + + describe 'languages' do + let_it_be(:user) { create(:user) } + let_it_be(:project) do + create(:project, + :private, + :repository, + creator_id: user.id, + namespace: user.namespace) + end + + let(:query) do + %( + query { + project(fullPath: "#{project.full_path}") { + languages { + name + share + color + } + } + } + ) + end + + let(:mock_languages) { [] } + + before do + allow_next_instance_of(::Projects::RepositoryLanguagesService) do |service| + allow(service).to receive(:execute).and_return(mock_languages) + end + end + + subject { GitlabSchema.execute(query, context: { current_user: user }).as_json } + + let(:languages) { subject.dig('data', 'project', 'languages') } + + context "when the languages haven't been detected yet" do + it 'returns an empty array' do + expect(languages).to eq([]) + end + end + + context 'when the languages were detected before' do + let(:mock_languages) do + [{ share: 66.69, name: "Ruby", color: "#701516" }, + { share: 22.98, name: "JavaScript", color: "#f1e05a" }, + { share: 7.91, name: "HTML", color: "#e34c26" }, + { share: 2.42, name: "CoffeeScript", color: "#244776" }] + end + + it 'returns the repository languages' do + expect(languages).to eq(mock_languages.map(&:stringify_keys)) + end + end + end end diff --git a/spec/graphql/types/projects/branch_rule_type_spec.rb b/spec/graphql/types/projects/branch_rule_type_spec.rb index 119ecf8a097..54ea4f6857b 100644 --- a/spec/graphql/types/projects/branch_rule_type_spec.rb +++ b/spec/graphql/types/projects/branch_rule_type_spec.rb @@ -12,12 +12,13 @@ RSpec.describe GitlabSchema.types['BranchRule'] do name isDefault branch_protection + matching_branches_count created_at updated_at ] end - specify { is_expected.to require_graphql_authorizations(:read_protected_branch) } + it { is_expected.to require_graphql_authorizations(:read_protected_branch) } - specify { is_expected.to have_graphql_fields(fields).at_least } + it { is_expected.to have_graphql_fields(fields).at_least } end diff --git a/spec/graphql/types/projects/repository_language_type_spec.rb b/spec/graphql/types/projects/repository_language_type_spec.rb new file mode 100644 index 00000000000..fd3e0ee4e90 --- /dev/null +++ b/spec/graphql/types/projects/repository_language_type_spec.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Types::Projects::RepositoryLanguageType do + specify { expect(described_class.graphql_name).to eq('RepositoryLanguage') } + + specify do + expect(described_class).to have_graphql_fields( + :name, + :share, + :color + ) + end +end diff --git a/spec/graphql/types/release_links_type_spec.rb b/spec/graphql/types/release_links_type_spec.rb index e77c4e3ddd1..5a29050a4a2 100644 --- a/spec/graphql/types/release_links_type_spec.rb +++ b/spec/graphql/types/release_links_type_spec.rb @@ -26,31 +26,31 @@ RSpec.describe GitlabSchema.types['ReleaseLinks'] do describe 'openedMergeRequestsUrl' do it 'has valid authorization' do - expect(fetch_authorizations('openedMergeRequestsUrl')).to include(:download_code) + expect(fetch_authorizations('openedMergeRequestsUrl')).to include(:read_code) end end describe 'mergedMergeRequestsUrl' do it 'has valid authorization' do - expect(fetch_authorizations('mergedMergeRequestsUrl')).to include(:download_code) + expect(fetch_authorizations('mergedMergeRequestsUrl')).to include(:read_code) end end describe 'closedMergeRequestsUrl' do it 'has valid authorization' do - expect(fetch_authorizations('closedMergeRequestsUrl')).to include(:download_code) + expect(fetch_authorizations('closedMergeRequestsUrl')).to include(:read_code) end end describe 'openedIssuesUrl' do it 'has valid authorization' do - expect(fetch_authorizations('openedIssuesUrl')).to include(:download_code) + expect(fetch_authorizations('openedIssuesUrl')).to include(:read_code) end end describe 'closedIssuesUrl' do it 'has valid authorization' do - expect(fetch_authorizations('closedIssuesUrl')).to include(:download_code) + expect(fetch_authorizations('closedIssuesUrl')).to include(:read_code) end end diff --git a/spec/graphql/types/release_source_type_spec.rb b/spec/graphql/types/release_source_type_spec.rb index 69a1ca30dbc..52f1e3a4ff5 100644 --- a/spec/graphql/types/release_source_type_spec.rb +++ b/spec/graphql/types/release_source_type_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe GitlabSchema.types['ReleaseSource'] do - it { expect(described_class).to require_graphql_authorizations(:download_code) } + it { expect(described_class).to require_graphql_authorizations(:read_code) } it 'has the expected fields' do expected_fields = %w[ diff --git a/spec/graphql/types/repository_type_spec.rb b/spec/graphql/types/repository_type_spec.rb index 5488d78b720..4ff2cbcad46 100644 --- a/spec/graphql/types/repository_type_spec.rb +++ b/spec/graphql/types/repository_type_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' RSpec.describe GitlabSchema.types['Repository'] do specify { expect(described_class.graphql_name).to eq('Repository') } - specify { expect(described_class).to require_graphql_authorizations(:download_code) } + specify { expect(described_class).to require_graphql_authorizations(:read_code) } specify { expect(described_class).to have_graphql_field(:root_ref) } diff --git a/spec/graphql/types/subscription_type_spec.rb b/spec/graphql/types/subscription_type_spec.rb index c23a14deaf3..04f0c72b06f 100644 --- a/spec/graphql/types/subscription_type_spec.rb +++ b/spec/graphql/types/subscription_type_spec.rb @@ -11,6 +11,7 @@ RSpec.describe GitlabSchema.types['Subscription'] do issuable_description_updated issuable_labels_updated issuable_dates_updated + issuable_milestone_updated merge_request_reviewers_updated merge_request_merge_status_updated ] diff --git a/spec/graphql/types/x509_certificate_type_spec.rb b/spec/graphql/types/x509_certificate_type_spec.rb new file mode 100644 index 00000000000..e59d1f83b28 --- /dev/null +++ b/spec/graphql/types/x509_certificate_type_spec.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe GitlabSchema.types['X509Certificate'] do + specify { expect(described_class.graphql_name).to eq('X509Certificate') } + + it 'contains attributes for X.509 certifcates' do + expect(described_class).to have_graphql_fields( + :certificate_status, :created_at, :email, :id, :serial_number, :subject, + :subject_key_identifier, :updated_at, :x509_issuer + ) + end +end diff --git a/spec/graphql/types/x509_issuer_type_spec.rb b/spec/graphql/types/x509_issuer_type_spec.rb new file mode 100644 index 00000000000..5446dcf07c7 --- /dev/null +++ b/spec/graphql/types/x509_issuer_type_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe GitlabSchema.types['X509Issuer'] do + specify { expect(described_class.graphql_name).to eq('X509Issuer') } + + it 'contains attributes for X.509 issuers' do + expect(described_class).to have_graphql_fields( + :created_at, :crl_url, :id, :subject, :subject_key_identifier, :updated_at + ) + end +end |