diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-05-06 15:09:36 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-05-06 15:09:36 +0300 |
commit | 4279f24a19836d3e74e4aae8bea7acc2dd8222cc (patch) | |
tree | 76e4b3cf4d6bd85ff50e40bf011e7f9bc350441a /spec | |
parent | 51c20446a0dcf2f5f4a0254230876bd472a254e7 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
21 files changed, 323 insertions, 190 deletions
diff --git a/spec/frontend/registry/explorer/pages/details_spec.js b/spec/frontend/registry/explorer/pages/details_spec.js index d6741aa3141..0c579db52ea 100644 --- a/spec/frontend/registry/explorer/pages/details_spec.js +++ b/spec/frontend/registry/explorer/pages/details_spec.js @@ -4,7 +4,12 @@ import Tracking from '~/tracking'; import stubChildren from 'helpers/stub_children'; import component from '~/registry/explorer/pages/details.vue'; import { createStore } from '~/registry/explorer/stores/'; -import { SET_MAIN_LOADING, SET_INITIAL_STATE } from '~/registry/explorer/stores/mutation_types/'; +import { + SET_MAIN_LOADING, + SET_INITIAL_STATE, + SET_TAGS_LIST_SUCCESS, + SET_TAGS_PAGINATION, +} from '~/registry/explorer/stores/mutation_types/'; import { DELETE_TAG_SUCCESS_MESSAGE, DELETE_TAG_ERROR_MESSAGE, @@ -60,7 +65,9 @@ describe('Details Page', () => { beforeEach(() => { store = createStore(); dispatchSpy = jest.spyOn(store, 'dispatch'); - store.dispatch('receiveTagsListSuccess', tagsListResponse); + dispatchSpy.mockResolvedValue(); + store.commit(SET_TAGS_LIST_SUCCESS, tagsListResponse.data); + store.commit(SET_TAGS_PAGINATION, tagsListResponse.headers); jest.spyOn(Tracking, 'event'); }); diff --git a/spec/frontend/registry/explorer/pages/list_spec.js b/spec/frontend/registry/explorer/pages/list_spec.js index f69b849521d..1d530483093 100644 --- a/spec/frontend/registry/explorer/pages/list_spec.js +++ b/spec/frontend/registry/explorer/pages/list_spec.js @@ -1,5 +1,4 @@ -import VueRouter from 'vue-router'; -import { shallowMount, createLocalVue } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; import { GlPagination, GlSkeletonLoader, GlSprintf, GlAlert } from '@gitlab/ui'; import Tracking from '~/tracking'; import component from '~/registry/explorer/pages/list.vue'; @@ -7,22 +6,25 @@ import QuickstartDropdown from '~/registry/explorer/components/quickstart_dropdo import GroupEmptyState from '~/registry/explorer/components/group_empty_state.vue'; import ProjectEmptyState from '~/registry/explorer/components/project_empty_state.vue'; import ProjectPolicyAlert from '~/registry/explorer/components/project_policy_alert.vue'; -import store from '~/registry/explorer/stores/'; -import { SET_MAIN_LOADING } from '~/registry/explorer/stores/mutation_types/'; +import { createStore } from '~/registry/explorer/stores/'; +import { + SET_MAIN_LOADING, + SET_IMAGES_LIST_SUCCESS, + SET_PAGINATION, + SET_INITIAL_STATE, +} from '~/registry/explorer/stores/mutation_types/'; import { DELETE_IMAGE_SUCCESS_MESSAGE, DELETE_IMAGE_ERROR_MESSAGE, } from '~/registry/explorer/constants'; import { imagesListResponse } from '../mock_data'; -import { GlModal, GlEmptyState } from '../stubs'; +import { GlModal, GlEmptyState, RouterLink } from '../stubs'; import { $toast } from '../../shared/mocks'; -const localVue = createLocalVue(); -localVue.use(VueRouter); - describe('List Page', () => { let wrapper; let dispatchSpy; + let store; const findDeleteBtn = () => wrapper.find({ ref: 'deleteImageButton' }); const findDeleteModal = () => wrapper.find(GlModal); @@ -39,21 +41,31 @@ describe('List Page', () => { const findProjectPolicyAlert = () => wrapper.find(ProjectPolicyAlert); const findDeleteAlert = () => wrapper.find(GlAlert); - beforeEach(() => { + const mountComponent = ({ mocks } = {}) => { wrapper = shallowMount(component, { - localVue, store, stubs: { GlModal, GlEmptyState, GlSprintf, + RouterLink, }, mocks: { $toast, + $route: { + name: 'foo', + }, + ...mocks, }, }); + }; + + beforeEach(() => { + store = createStore(); dispatchSpy = jest.spyOn(store, 'dispatch'); - store.dispatch('receiveImagesListSuccess', imagesListResponse); + dispatchSpy.mockResolvedValue(); + store.commit(SET_IMAGES_LIST_SUCCESS, imagesListResponse.data); + store.commit(SET_PAGINATION, imagesListResponse.headers); }); afterEach(() => { @@ -61,17 +73,38 @@ describe('List Page', () => { }); describe('Expiration policy notification', () => { + beforeEach(() => { + mountComponent(); + }); it('shows up on project page', () => { expect(findProjectPolicyAlert().exists()).toBe(true); }); it('does show up on group page', () => { - store.dispatch('setInitialState', { isGroupPage: true }); + store.commit(SET_INITIAL_STATE, { isGroupPage: true }); return wrapper.vm.$nextTick().then(() => { expect(findProjectPolicyAlert().exists()).toBe(false); }); }); }); + describe('API calls', () => { + it.each` + imageList | name | called + ${[]} | ${'foo'} | ${['requestImagesList']} + ${imagesListResponse.data} | ${undefined} | ${['requestImagesList']} + ${imagesListResponse.data} | ${'foo'} | ${undefined} + `( + 'with images equal $imageList and name $name dispatch calls $called', + ({ imageList, name, called }) => { + store.commit(SET_IMAGES_LIST_SUCCESS, imageList); + dispatchSpy.mockClear(); + mountComponent({ mocks: { $route: { name } } }); + + expect(dispatchSpy.mock.calls[0]).toEqual(called); + }, + ); + }); + describe('connection error', () => { const config = { characterError: true, @@ -79,12 +112,13 @@ describe('List Page', () => { helpPagePath: 'bar', }; - beforeAll(() => { - store.dispatch('setInitialState', config); + beforeEach(() => { + store.commit(SET_INITIAL_STATE, config); + mountComponent(); }); - afterAll(() => { - store.dispatch('setInitialState', {}); + afterEach(() => { + store.commit(SET_INITIAL_STATE, {}); }); it('should show an empty state', () => { @@ -106,9 +140,12 @@ describe('List Page', () => { }); describe('isLoading is true', () => { - beforeAll(() => store.commit(SET_MAIN_LOADING, true)); + beforeEach(() => { + store.commit(SET_MAIN_LOADING, true); + mountComponent(); + }); - afterAll(() => store.commit(SET_MAIN_LOADING, false)); + afterEach(() => store.commit(SET_MAIN_LOADING, false)); it('shows the skeleton loader', () => { expect(findSkeletonLoader().exists()).toBe(true); @@ -125,7 +162,8 @@ describe('List Page', () => { describe('list is empty', () => { beforeEach(() => { - store.dispatch('receiveImagesListSuccess', { data: [] }); + store.commit(SET_IMAGES_LIST_SUCCESS, []); + mountComponent(); }); it('quick start is not visible', () => { @@ -137,12 +175,13 @@ describe('List Page', () => { }); describe('is group page is true', () => { - beforeAll(() => { - store.dispatch('setInitialState', { isGroupPage: true }); + beforeEach(() => { + store.commit(SET_INITIAL_STATE, { isGroupPage: true }); + mountComponent(); }); - afterAll(() => { - store.dispatch('setInitialState', { isGroupPage: undefined }); + afterEach(() => { + store.commit(SET_INITIAL_STATE, { isGroupPage: undefined }); }); it('group empty state is visible', () => { @@ -156,6 +195,10 @@ describe('List Page', () => { }); describe('list is not empty', () => { + beforeEach(() => { + mountComponent(); + }); + it('quick start is visible', () => { expect(findQuickStartDropdown().exists()).toBe(true); }); diff --git a/spec/frontend/registry/explorer/stubs.js b/spec/frontend/registry/explorer/stubs.js index 2c2c7587af9..0e178abfbed 100644 --- a/spec/frontend/registry/explorer/stubs.js +++ b/spec/frontend/registry/explorer/stubs.js @@ -9,3 +9,8 @@ export const GlEmptyState = { template: '<div><slot name="description"></slot></div>', name: 'GlEmptyStateSTub', }; + +export const RouterLink = { + template: `<div><slot></slot></div>`, + props: ['to'], +}; diff --git a/spec/frontend/snippets/components/snippet_header_spec.js b/spec/frontend/snippets/components/snippet_header_spec.js index 16a66c70d6a..fb04959a7bf 100644 --- a/spec/frontend/snippets/components/snippet_header_spec.js +++ b/spec/frontend/snippets/components/snippet_header_spec.js @@ -7,26 +7,27 @@ import { shallowMount } from '@vue/test-utils'; describe('Snippet header component', () => { let wrapper; const snippet = { - snippet: { - id: 'gid://gitlab/PersonalSnippet/50', - title: 'The property of Thor', - visibilityLevel: 'private', - webUrl: 'http://personal.dev.null/42', - userPermissions: { - adminSnippet: true, - updateSnippet: true, - reportSnippet: false, - }, - project: null, - author: { - name: 'Thor Odinson', - }, + id: 'gid://gitlab/PersonalSnippet/50', + title: 'The property of Thor', + visibilityLevel: 'private', + webUrl: 'http://personal.dev.null/42', + userPermissions: { + adminSnippet: true, + updateSnippet: true, + reportSnippet: false, + }, + project: null, + author: { + name: 'Thor Odinson', + }, + blob: { + binary: false, }, }; const mutationVariables = { mutation: DeleteSnippetMutation, variables: { - id: snippet.snippet.id, + id: snippet.id, }, }; const errorMsg = 'Foo bar'; @@ -46,10 +47,12 @@ describe('Snippet header component', () => { loading = false, permissions = {}, mutationRes = mutationTypes.RESOLVE, + snippetProps = {}, } = {}) { - const defaultProps = Object.assign({}, snippet); + // const defaultProps = Object.assign({}, snippet, snippetProps); + const defaultProps = Object.assign(snippet, snippetProps); if (permissions) { - Object.assign(defaultProps.snippet.userPermissions, { + Object.assign(defaultProps.userPermissions, { ...permissions, }); } @@ -65,7 +68,9 @@ describe('Snippet header component', () => { wrapper = shallowMount(SnippetHeader, { mocks: { $apollo }, propsData: { - ...defaultProps, + snippet: { + ...defaultProps, + }, }, stubs: { ApolloMutation, @@ -126,6 +131,17 @@ describe('Snippet header component', () => { expect(wrapper.find(GlModal).exists()).toBe(true); }); + it('renders Edit button as disabled for binary snippets', () => { + createComponent({ + snippetProps: { + blob: { + binary: true, + }, + }, + }); + expect(wrapper.find('[href*="edit"]').props('disabled')).toBe(true); + }); + describe('Delete mutation', () => { const { location } = window; diff --git a/spec/graphql/mutations/alert_management/update_alert_status_spec.rb b/spec/graphql/mutations/alert_management/update_alert_status_spec.rb new file mode 100644 index 00000000000..3cd5e217571 --- /dev/null +++ b/spec/graphql/mutations/alert_management/update_alert_status_spec.rb @@ -0,0 +1,73 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Mutations::AlertManagement::UpdateAlertStatus do + let_it_be(:current_user) { create(:user) } + let_it_be(:alert) { create(:alert_management_alert, status: 'triggered') } + let_it_be(:project) { alert.project } + let(:new_status) { 'acknowledged' } + let(:args) { { status: new_status, project_path: project.full_path, iid: alert.iid } } + + specify { expect(described_class).to require_graphql_authorizations(:update_alert_management_alerts) } + + describe '#resolve' do + subject(:resolve) { mutation_for(project, current_user).resolve(args) } + + context 'user has access to project' do + before do + project.add_developer(current_user) + end + + it 'changes the status' do + expect { resolve }.to change { alert.reload.status }.from(alert.status).to(new_status) + end + + it 'returns the alert with no errors' do + expect(resolve).to eq( + alert: alert, + errors: [] + ) + end + + context 'error occurs when updating' do + it 'returns the alert with errors' do + # Stub an error on the alert + allow_next_instance_of(Resolvers::AlertManagementAlertResolver) do |resolver| + allow(resolver).to receive(:resolve).and_return(alert) + end + + allow(alert).to receive(:save).and_return(false) + allow(alert).to receive(:errors).and_return( + double(full_messages: %w(foo bar)) + ) + expect(resolve).to eq( + alert: alert, + errors: ['foo and bar'] + ) + end + + context 'invalid status given' do + let(:new_status) { 'invalid_status' } + + it 'returns the alert with errors' do + expect(resolve).to eq( + alert: alert, + errors: ['Invalid status'] + ) + end + end + end + end + + it 'raises an error if the resource is not accessible to the user' do + expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable) + 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/types/alert_management/alert_type_spec.rb b/spec/graphql/types/alert_management/alert_type_spec.rb index f66a135171e..169611b2e18 100644 --- a/spec/graphql/types/alert_management/alert_type_spec.rb +++ b/spec/graphql/types/alert_management/alert_type_spec.rb @@ -11,13 +11,18 @@ describe GitlabSchema.types['AlertManagementAlert'] do expected_fields = %i[ iid title + description severity status service monitoring_tool + hosts started_at ended_at event_count + details + created_at + updated_at ] expect(described_class).to have_graphql_fields(*expected_fields) diff --git a/spec/lib/gitlab/graphql/authorize/authorize_field_service_spec.rb b/spec/lib/gitlab/graphql/authorize/authorize_field_service_spec.rb index 98659dbed57..c1dab5feb91 100644 --- a/spec/lib/gitlab/graphql/authorize/authorize_field_service_spec.rb +++ b/spec/lib/gitlab/graphql/authorize/authorize_field_service_spec.rb @@ -84,6 +84,16 @@ describe Gitlab::Graphql::Authorize::AuthorizeFieldService do end end + context 'when the field is a connection' do + context 'when it resolves to nil' do + let(:field) { type_with_field(Types::QueryType.connection_type, :read_field, nil).fields['testField'].to_graphql } + + it 'does not fail when authorizing' do + expect(resolved).to be_nil + end + end + end + context 'when the field is a specific type' do let(:custom_type) { type(:read_type) } let(:object_in_field) { double('presented in field') } diff --git a/spec/lib/gitlab/kubernetes/helm/api_spec.rb b/spec/lib/gitlab/kubernetes/helm/api_spec.rb index 8147990ecc3..1f925fd45af 100644 --- a/spec/lib/gitlab/kubernetes/helm/api_spec.rb +++ b/spec/lib/gitlab/kubernetes/helm/api_spec.rb @@ -92,7 +92,6 @@ describe Gitlab::Kubernetes::Helm::API do allow(client).to receive(:get_config_map).and_return(nil) allow(client).to receive(:create_config_map).and_return(nil) allow(client).to receive(:create_service_account).and_return(nil) - allow(client).to receive(:create_cluster_role_binding).and_return(nil) allow(client).to receive(:delete_pod).and_return(nil) allow(namespace).to receive(:ensure_exists!).once end @@ -136,7 +135,7 @@ describe Gitlab::Kubernetes::Helm::API do context 'without a service account' do it 'does not create a service account on kubeclient' do expect(client).not_to receive(:create_service_account) - expect(client).not_to receive(:create_cluster_role_binding) + expect(client).not_to receive(:update_cluster_role_binding) subject.install(command) end @@ -160,15 +159,14 @@ describe Gitlab::Kubernetes::Helm::API do ) end - context 'service account and cluster role binding does not exist' do + context 'service account does not exist' do before do expect(client).to receive(:get_service_account).with('tiller', 'gitlab-managed-apps').and_raise(Kubeclient::ResourceNotFoundError.new(404, 'Not found', nil)) - expect(client).to receive(:get_cluster_role_binding).with('tiller-admin').and_raise(Kubeclient::ResourceNotFoundError.new(404, 'Not found', nil)) end it 'creates a service account, followed the cluster role binding on kubeclient' do expect(client).to receive(:create_service_account).with(service_account_resource).once.ordered - expect(client).to receive(:create_cluster_role_binding).with(cluster_role_binding_resource).once.ordered + expect(client).to receive(:update_cluster_role_binding).with(cluster_role_binding_resource).once.ordered subject.install(command) end @@ -177,21 +175,6 @@ describe Gitlab::Kubernetes::Helm::API do context 'service account already exists' do before do expect(client).to receive(:get_service_account).with('tiller', 'gitlab-managed-apps').and_return(service_account_resource) - expect(client).to receive(:get_cluster_role_binding).with('tiller-admin').and_raise(Kubeclient::ResourceNotFoundError.new(404, 'Not found', nil)) - end - - it 'updates the service account, followed by creating the cluster role binding' do - expect(client).to receive(:update_service_account).with(service_account_resource).once.ordered - expect(client).to receive(:create_cluster_role_binding).with(cluster_role_binding_resource).once.ordered - - subject.install(command) - end - end - - context 'service account and cluster role binding already exists' do - before do - expect(client).to receive(:get_service_account).with('tiller', 'gitlab-managed-apps').and_return(service_account_resource) - expect(client).to receive(:get_cluster_role_binding).with('tiller-admin').and_return(cluster_role_binding_resource) end it 'updates the service account, followed by creating the cluster role binding' do @@ -216,7 +199,7 @@ describe Gitlab::Kubernetes::Helm::API do context 'legacy abac cluster' do it 'does not create a service account on kubeclient' do expect(client).not_to receive(:create_service_account) - expect(client).not_to receive(:create_cluster_role_binding) + expect(client).not_to receive(:update_cluster_role_binding) subject.install(command) end diff --git a/spec/lib/gitlab/kubernetes/kube_client_spec.rb b/spec/lib/gitlab/kubernetes/kube_client_spec.rb index 56838f2cb7a..af328eaec9a 100644 --- a/spec/lib/gitlab/kubernetes/kube_client_spec.rb +++ b/spec/lib/gitlab/kubernetes/kube_client_spec.rb @@ -234,8 +234,6 @@ describe Gitlab::Kubernetes::KubeClient do :create_role, :get_role, :update_role, - :create_cluster_role_binding, - :get_cluster_role_binding, :update_cluster_role_binding ].each do |method| describe "##{method}" do @@ -354,6 +352,16 @@ describe Gitlab::Kubernetes::KubeClient do end end + shared_examples 'create_or_update method using put' do + let(:update_method) { "update_#{resource_type}" } + + it 'calls the update method' do + expect(client).to receive(update_method).with(resource) + + subject + end + end + shared_examples 'create_or_update method' do let(:get_method) { "get_#{resource_type}" } let(:update_method) { "update_#{resource_type}" } @@ -393,7 +401,7 @@ describe Gitlab::Kubernetes::KubeClient do subject { client.create_or_update_cluster_role_binding(resource) } - it_behaves_like 'create_or_update method' + it_behaves_like 'create_or_update method using put' end describe '#create_or_update_role_binding' do @@ -405,7 +413,7 @@ describe Gitlab::Kubernetes::KubeClient do subject { client.create_or_update_role_binding(resource) } - it_behaves_like 'create_or_update method' + it_behaves_like 'create_or_update method using put' end describe '#create_or_update_service_account' do diff --git a/spec/lib/gitlab/sidekiq_config/cli_methods_spec.rb b/spec/lib/gitlab/sidekiq_config/cli_methods_spec.rb index 0aaff12f278..80e8da58f23 100644 --- a/spec/lib/gitlab/sidekiq_config/cli_methods_spec.rb +++ b/spec/lib/gitlab/sidekiq_config/cli_methods_spec.rb @@ -54,14 +54,6 @@ describe Gitlab::SidekiqConfig::CliMethods do end end - context 'when the file contains an array of strings' do - before do - stub_contents(['queue_a'], ['queue_b']) - end - - include_examples 'valid file contents' - end - context 'when the file contains an array of hashes' do before do stub_contents([{ name: 'queue_a' }], [{ name: 'queue_b' }]) diff --git a/spec/models/alert_management/alert_spec.rb b/spec/models/alert_management/alert_spec.rb index 2e552875252..b40b18aeb4c 100644 --- a/spec/models/alert_management/alert_spec.rb +++ b/spec/models/alert_management/alert_spec.rb @@ -126,4 +126,30 @@ describe AlertManagement::Alert do it { is_expected.to match_array(alert_1) } end + + describe '.details' do + let(:payload) do + { + 'title' => 'Details title', + 'custom' => { + 'alert' => { + 'fields' => %w[one two] + } + }, + 'yet' => { + 'another' => 'field' + } + } + end + let(:alert) { build(:alert_management_alert, title: 'Details title', payload: payload) } + + subject { alert.details } + + it 'renders the payload as inline hash' do + is_expected.to eq( + 'custom.alert.fields' => %w[one two], + 'yet.another' => 'field' + ) + end + end end diff --git a/spec/models/ci/persistent_ref_spec.rb b/spec/models/ci/persistent_ref_spec.rb index 4cece0664cf..89dd9b05331 100644 --- a/spec/models/ci/persistent_ref_spec.rb +++ b/spec/models/ci/persistent_ref_spec.rb @@ -45,18 +45,6 @@ describe Ci::PersistentRef do expect(pipeline.persistent_ref).to be_exist end - context 'when depend_on_persistent_pipeline_ref feature flag is disabled' do - before do - stub_feature_flags(depend_on_persistent_pipeline_ref: false) - end - - it 'does not create a persistent ref' do - expect(project.repository).not_to receive(:create_ref) - - subject - end - end - context 'when sha does not exist in the repository' do let(:sha) { 'not-exist' } diff --git a/spec/policies/alert_management/alert_policy_spec.rb b/spec/policies/alert_management/alert_policy_spec.rb index 698264e4ac7..523464d8ff1 100644 --- a/spec/policies/alert_management/alert_policy_spec.rb +++ b/spec/policies/alert_management/alert_policy_spec.rb @@ -6,17 +6,20 @@ describe AlertManagement::AlertPolicy, :models do let(:alert) { create(:alert_management_alert) } let(:project) { alert.project } let(:user) { create(:user) } - let(:policy) { described_class.new(user, alert) } + + subject(:policy) { described_class.new(user, alert) } describe 'rules' do - it { expect(policy).to be_disallowed :read_alert_management_alerts } + it { is_expected.to be_disallowed :read_alert_management_alerts } + it { is_expected.to be_disallowed :update_alert_management_alerts } context 'when developer' do before do project.add_developer(user) end - it { expect(policy).to be_allowed :read_alert_management_alerts } + it { is_expected.to be_allowed :read_alert_management_alerts } + it { is_expected.to be_allowed :update_alert_management_alerts } end end end diff --git a/spec/presenters/ci/build_runner_presenter_spec.rb b/spec/presenters/ci/build_runner_presenter_spec.rb index 28806a1c7e3..6b2b031dbd0 100644 --- a/spec/presenters/ci/build_runner_presenter_spec.rb +++ b/spec/presenters/ci/build_runner_presenter_spec.rb @@ -173,81 +173,34 @@ describe Ci::BuildRunnerPresenter do let(:pipeline) { merge_request.all_pipelines.first } let(:build) { create(:ci_build, ref: pipeline.ref, pipeline: pipeline) } - context 'when depend_on_persistent_pipeline_ref feature flag is enabled' do - before do - stub_feature_flags(ci_force_exposing_merge_request_refs: false) - pipeline.persistent_ref.create - end - - it 'returns the correct refspecs' do - is_expected - .to contain_exactly("+refs/pipelines/#{pipeline.id}:refs/pipelines/#{pipeline.id}") - end - - context 'when ci_force_exposing_merge_request_refs feature flag is enabled' do - before do - stub_feature_flags(ci_force_exposing_merge_request_refs: true) - end - - it 'returns the correct refspecs' do - is_expected - .to contain_exactly("+refs/pipelines/#{pipeline.id}:refs/pipelines/#{pipeline.id}", - '+refs/merge-requests/1/head:refs/merge-requests/1/head') - end - end - - context 'when GIT_DEPTH is zero' do - before do - create(:ci_pipeline_variable, key: 'GIT_DEPTH', value: 0, pipeline: build.pipeline) - end - - it 'returns the correct refspecs' do - is_expected - .to contain_exactly("+refs/pipelines/#{pipeline.id}:refs/pipelines/#{pipeline.id}", - '+refs/heads/*:refs/remotes/origin/*', - '+refs/tags/*:refs/tags/*') - end - end - - context 'when pipeline is legacy detached merge request pipeline' do - let(:merge_request) { create(:merge_request, :with_legacy_detached_merge_request_pipeline) } + before do + pipeline.persistent_ref.create + end - it 'returns the correct refspecs' do - is_expected.to contain_exactly("+refs/pipelines/#{pipeline.id}:refs/pipelines/#{pipeline.id}", - "+refs/heads/#{build.ref}:refs/remotes/origin/#{build.ref}") - end - end + it 'returns the correct refspecs' do + is_expected + .to contain_exactly("+refs/pipelines/#{pipeline.id}:refs/pipelines/#{pipeline.id}") end - context 'when depend_on_persistent_pipeline_ref feature flag is disabled' do + context 'when GIT_DEPTH is zero' do before do - stub_feature_flags(depend_on_persistent_pipeline_ref: false) + create(:ci_pipeline_variable, key: 'GIT_DEPTH', value: 0, pipeline: build.pipeline) end it 'returns the correct refspecs' do is_expected - .to contain_exactly('+refs/merge-requests/1/head:refs/merge-requests/1/head') - end - - context 'when GIT_DEPTH is zero' do - before do - create(:ci_pipeline_variable, key: 'GIT_DEPTH', value: 0, pipeline: build.pipeline) - end - - it 'returns the correct refspecs' do - is_expected - .to contain_exactly('+refs/merge-requests/1/head:refs/merge-requests/1/head', - '+refs/heads/*:refs/remotes/origin/*', - '+refs/tags/*:refs/tags/*') - end + .to contain_exactly("+refs/pipelines/#{pipeline.id}:refs/pipelines/#{pipeline.id}", + '+refs/heads/*:refs/remotes/origin/*', + '+refs/tags/*:refs/tags/*') end + end - context 'when pipeline is legacy detached merge request pipeline' do - let(:merge_request) { create(:merge_request, :with_legacy_detached_merge_request_pipeline) } + context 'when pipeline is legacy detached merge request pipeline' do + let(:merge_request) { create(:merge_request, :with_legacy_detached_merge_request_pipeline) } - it 'returns the correct refspecs' do - is_expected.to contain_exactly("+refs/heads/#{build.ref}:refs/remotes/origin/#{build.ref}") - end + it 'returns the correct refspecs' do + is_expected.to contain_exactly("+refs/pipelines/#{pipeline.id}:refs/pipelines/#{pipeline.id}", + "+refs/heads/#{build.ref}:refs/remotes/origin/#{build.ref}") end end end diff --git a/spec/requests/api/graphql/project/alert_management/alerts_spec.rb b/spec/requests/api/graphql/project/alert_management/alerts_spec.rb index 6722357f76d..5d60f054bf2 100644 --- a/spec/requests/api/graphql/project/alert_management/alerts_spec.rb +++ b/spec/requests/api/graphql/project/alert_management/alerts_spec.rb @@ -4,10 +4,11 @@ require 'spec_helper' describe 'getting Alert Management Alerts' do include GraphqlHelpers + let_it_be(:payload) { { 'custom' => { 'alert' => 'payload' } } } let_it_be(:project) { create(:project, :repository) } let_it_be(:current_user) { create(:user) } let_it_be(:alert_1) { create(:alert_management_alert, :all_fields, project: project) } - let_it_be(:alert_2) { create(:alert_management_alert, :all_fields, project: project) } + let_it_be(:alert_2) { create(:alert_management_alert, :all_fields, project: project, payload: payload) } let(:fields) do <<~QUERY @@ -55,13 +56,18 @@ describe 'getting Alert Management Alerts' do expect(first_alert).to include( 'iid' => alert_2.iid.to_s, 'title' => alert_2.title, + 'description' => alert_2.description, 'severity' => alert_2.severity.upcase, 'status' => alert_2.status.upcase, 'monitoringTool' => alert_2.monitoring_tool, 'service' => alert_2.service, + 'hosts' => alert_2.hosts, 'eventCount' => alert_2.events, 'startedAt' => alert_2.started_at.strftime('%Y-%m-%dT%H:%M:%SZ'), - 'endedAt' => alert_2.ended_at.strftime('%Y-%m-%dT%H:%M:%SZ') + 'endedAt' => alert_2.ended_at.strftime('%Y-%m-%dT%H:%M:%SZ'), + 'details' => { 'custom.alert' => 'payload' }, + 'createdAt' => alert_2.created_at.strftime('%Y-%m-%dT%H:%M:%SZ'), + 'updatedAt' => alert_2.updated_at.strftime('%Y-%m-%dT%H:%M:%SZ') ) end diff --git a/spec/services/alert_management/update_alert_status_service_spec.rb b/spec/services/alert_management/update_alert_status_service_spec.rb new file mode 100644 index 00000000000..325b03840d3 --- /dev/null +++ b/spec/services/alert_management/update_alert_status_service_spec.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe AlertManagement::UpdateAlertStatusService do + let_it_be(:alert) { create(:alert_management_alert, status: 'triggered') } + + describe '#execute' do + subject(:execute) { described_class.new(alert, new_status).execute } + + let(:new_status) { 'acknowledged' } + + it 'updates the status' do + expect { execute }.to change { alert.status }.to(new_status) + end + + context 'with unknown status' do + let(:new_status) { 'random_status' } + + it 'returns an error' do + expect(execute.status).to eq(:error) + end + + it 'does not update the status' do + expect { execute }.not_to change { alert.status } + end + end + end +end diff --git a/spec/services/clusters/gcp/finalize_creation_service_spec.rb b/spec/services/clusters/gcp/finalize_creation_service_spec.rb index 43dbea959a2..4d1548c9786 100644 --- a/spec/services/clusters/gcp/finalize_creation_service_spec.rb +++ b/spec/services/clusters/gcp/finalize_creation_service_spec.rb @@ -108,8 +108,7 @@ describe Clusters::Gcp::FinalizeCreationService, '#execute' do } ) - stub_kubeclient_get_cluster_role_binding_error(api_url, 'gitlab-admin') - stub_kubeclient_create_cluster_role_binding(api_url) + stub_kubeclient_put_cluster_role_binding(api_url, 'gitlab-admin') end end diff --git a/spec/services/clusters/kubernetes/create_or_update_namespace_service_spec.rb b/spec/services/clusters/kubernetes/create_or_update_namespace_service_spec.rb index 3982d2310d8..6d8b1617c17 100644 --- a/spec/services/clusters/kubernetes/create_or_update_namespace_service_spec.rb +++ b/spec/services/clusters/kubernetes/create_or_update_namespace_service_spec.rb @@ -28,7 +28,6 @@ describe Clusters::Kubernetes::CreateOrUpdateNamespaceService, '#execute' do stub_kubeclient_get_secret_error(api_url, 'gitlab-token') stub_kubeclient_create_secret(api_url) - stub_kubeclient_get_role_binding(api_url, "gitlab-#{namespace}", namespace: namespace) stub_kubeclient_put_role_binding(api_url, "gitlab-#{namespace}", namespace: namespace) stub_kubeclient_get_namespace(api_url, namespace: namespace) stub_kubeclient_get_service_account_error(api_url, "#{namespace}-service-account", namespace: namespace) diff --git a/spec/services/clusters/kubernetes/create_or_update_service_account_service_spec.rb b/spec/services/clusters/kubernetes/create_or_update_service_account_service_spec.rb index 8fa22422074..4bcd5c6933e 100644 --- a/spec/services/clusters/kubernetes/create_or_update_service_account_service_spec.rb +++ b/spec/services/clusters/kubernetes/create_or_update_service_account_service_spec.rb @@ -83,8 +83,7 @@ describe Clusters::Kubernetes::CreateOrUpdateServiceAccountService do before do cluster.platform_kubernetes.rbac! - stub_kubeclient_get_cluster_role_binding_error(api_url, cluster_role_binding_name) - stub_kubeclient_create_cluster_role_binding(api_url) + stub_kubeclient_put_cluster_role_binding(api_url, cluster_role_binding_name) end it_behaves_like 'creates service account and token' @@ -92,9 +91,8 @@ describe Clusters::Kubernetes::CreateOrUpdateServiceAccountService do it 'creates a cluster role binding with cluster-admin access' do subject - expect(WebMock).to have_requested(:post, api_url + "/apis/rbac.authorization.k8s.io/v1/clusterrolebindings").with( + expect(WebMock).to have_requested(:put, api_url + "/apis/rbac.authorization.k8s.io/v1/clusterrolebindings/gitlab-admin").with( body: hash_including( - kind: 'ClusterRoleBinding', metadata: { name: 'gitlab-admin' }, roleRef: { apiGroup: 'rbac.authorization.k8s.io', @@ -143,8 +141,7 @@ describe Clusters::Kubernetes::CreateOrUpdateServiceAccountService do before do cluster.platform_kubernetes.rbac! - stub_kubeclient_get_role_binding_error(api_url, role_binding_name, namespace: namespace) - stub_kubeclient_create_role_binding(api_url, namespace: namespace) + stub_kubeclient_put_role_binding(api_url, role_binding_name, namespace: namespace) stub_kubeclient_put_role(api_url, Clusters::Kubernetes::GITLAB_KNATIVE_SERVING_ROLE_NAME, namespace: namespace) stub_kubeclient_put_role_binding(api_url, Clusters::Kubernetes::GITLAB_KNATIVE_SERVING_ROLE_BINDING_NAME, namespace: namespace) stub_kubeclient_put_role(api_url, Clusters::Kubernetes::GITLAB_CROSSPLANE_DATABASE_ROLE_NAME, namespace: namespace) @@ -166,9 +163,8 @@ describe Clusters::Kubernetes::CreateOrUpdateServiceAccountService do it 'creates a namespaced role binding with edit access' do subject - expect(WebMock).to have_requested(:post, api_url + "/apis/rbac.authorization.k8s.io/v1/namespaces/#{namespace}/rolebindings").with( + expect(WebMock).to have_requested(:put, api_url + "/apis/rbac.authorization.k8s.io/v1/namespaces/#{namespace}/rolebindings/#{role_binding_name}").with( body: hash_including( - kind: 'RoleBinding', metadata: { name: "gitlab-#{namespace}", namespace: "#{namespace}" }, roleRef: { apiGroup: 'rbac.authorization.k8s.io', diff --git a/spec/services/spam/spam_action_service_spec.rb b/spec/services/spam/spam_action_service_spec.rb index ff60eacc79d..560833aba97 100644 --- a/spec/services/spam/spam_action_service_spec.rb +++ b/spec/services/spam/spam_action_service_spec.rb @@ -73,11 +73,13 @@ describe Spam::SpamActionService do describe '#execute' do let(:request) { double(:request, env: env) } let(:fake_verdict_service) { double(:spam_verdict_service) } + let(:allowlisted) { false } let_it_be(:existing_spam_log) { create(:spam_log, user: user, recaptcha_verified: false) } subject do described_service = described_class.new(spammable: issue, request: request) + allow(described_service).to receive(:allowlisted?).and_return(allowlisted) described_service.execute(user: user, api: nil, recaptcha_verified: recaptcha_verified, spam_log_id: existing_spam_log.id) end @@ -121,6 +123,16 @@ describe Spam::SpamActionService do issue.description = 'SPAM!' end + context 'if allowlisted' do + let(:allowlisted) { true } + + it 'does not perform spam check' do + expect(Spam::SpamVerdictService).not_to receive(:new) + + subject + end + end + context 'when disallowed by the spam verdict service' do before do allow(fake_verdict_service).to receive(:execute).and_return(DISALLOW) diff --git a/spec/support/helpers/kubernetes_helpers.rb b/spec/support/helpers/kubernetes_helpers.rb index ca910e47695..6d33d1f213f 100644 --- a/spec/support/helpers/kubernetes_helpers.rb +++ b/spec/support/helpers/kubernetes_helpers.rb @@ -201,28 +201,8 @@ module KubernetesHelpers .to_return(kube_response({})) end - def stub_kubeclient_get_cluster_role_binding_error(api_url, name, status: 404) - WebMock.stub_request(:get, api_url + "/apis/rbac.authorization.k8s.io/v1/clusterrolebindings/#{name}") - .to_return(status: [status, "Internal Server Error"]) - end - - def stub_kubeclient_create_cluster_role_binding(api_url) - WebMock.stub_request(:post, api_url + '/apis/rbac.authorization.k8s.io/v1/clusterrolebindings') - .to_return(kube_response({})) - end - - def stub_kubeclient_get_role_binding(api_url, name, namespace: 'default') - WebMock.stub_request(:get, api_url + "/apis/rbac.authorization.k8s.io/v1/namespaces/#{namespace}/rolebindings/#{name}") - .to_return(kube_response({})) - end - - def stub_kubeclient_get_role_binding_error(api_url, name, namespace: 'default', status: 404) - WebMock.stub_request(:get, api_url + "/apis/rbac.authorization.k8s.io/v1/namespaces/#{namespace}/rolebindings/#{name}") - .to_return(status: [status, "Internal Server Error"]) - end - - def stub_kubeclient_create_role_binding(api_url, namespace: 'default') - WebMock.stub_request(:post, api_url + "/apis/rbac.authorization.k8s.io/v1/namespaces/#{namespace}/rolebindings") + def stub_kubeclient_put_cluster_role_binding(api_url, name) + WebMock.stub_request(:put, api_url + "/apis/rbac.authorization.k8s.io/v1/clusterrolebindings/#{name}") .to_return(kube_response({})) end |