diff options
Diffstat (limited to 'spec')
34 files changed, 481 insertions, 425 deletions
diff --git a/spec/controllers/projects/analytics/cycle_analytics/summary_controller_spec.rb b/spec/controllers/projects/analytics/cycle_analytics/summary_controller_spec.rb new file mode 100644 index 00000000000..1832b84ab6e --- /dev/null +++ b/spec/controllers/projects/analytics/cycle_analytics/summary_controller_spec.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Projects::Analytics::CycleAnalytics::SummaryController do + let_it_be(:user) { create(:user) } + let_it_be(:project) { create(:project) } + + let(:params) { { namespace_id: project.namespace.to_param, project_id: project.to_param, created_after: '2010-01-01', created_before: '2010-01-02' } } + + before do + sign_in(user) + end + + describe 'GET "show"' do + subject { get :show, params: params } + + it 'succeeds' do + project.add_reporter(user) + + subject + + expect(response).to be_successful + expect(response).to match_response_schema('analytics/cycle_analytics/summary') + end + + context 'when analytics_disabled features are disabled' do + it 'renders 404' do + project.add_reporter(user) + project.project_feature.update!(analytics_access_level: ProjectFeature::DISABLED) + + subject + + expect(response).to have_gitlab_http_status(:not_found) + end + end + + context 'when user is not part of the project' do + it 'renders 404' do + subject + + expect(response).to have_gitlab_http_status(:not_found) + end + end + end +end diff --git a/spec/controllers/projects/pipelines_controller_spec.rb b/spec/controllers/projects/pipelines_controller_spec.rb index 19f9e8b780b..050d5e00670 100644 --- a/spec/controllers/projects/pipelines_controller_spec.rb +++ b/spec/controllers/projects/pipelines_controller_spec.rb @@ -878,19 +878,6 @@ RSpec.describe Projects::PipelinesController do expect(::Ci::RetryPipelineWorker).to have_received(:perform_async).with(pipeline.id, user.id) end - context 'when feature flag is disabled' do - before do - stub_feature_flags(background_pipeline_retry_endpoint: false) - end - - it 'retries the pipeline without returning any content' do - post_retry - - expect(response).to have_gitlab_http_status(:no_content) - expect(build.reload).to be_retried - end - end - context 'when builds are disabled' do let(:feature) { ProjectFeature::DISABLED } diff --git a/spec/factories/clusters/applications/helm.rb b/spec/factories/clusters/applications/helm.rb index 1ff1292c36e..73103956ee8 100644 --- a/spec/factories/clusters/applications/helm.rb +++ b/spec/factories/clusters/applications/helm.rb @@ -96,26 +96,7 @@ FactoryBot.define do end factory :clusters_applications_ingress, class: 'Clusters::Applications::Ingress' do - modsecurity_enabled { false } cluster factory: %i(cluster with_installed_helm provided_by_gcp) - - trait :modsecurity_blocking do - modsecurity_enabled { true } - modsecurity_mode { :blocking } - end - - trait :modsecurity_logging do - modsecurity_enabled { true } - modsecurity_mode { :logging } - end - - trait :modsecurity_disabled do - modsecurity_enabled { false } - end - - trait :modsecurity_not_installed do - modsecurity_enabled { nil } - end end factory :clusters_applications_cert_manager, class: 'Clusters::Applications::CertManager' do @@ -153,7 +134,6 @@ FactoryBot.define do factory :clusters_applications_fluentd, class: 'Clusters::Applications::Fluentd' do host { 'example.com' } - waf_log_enabled { true } cilium_log_enabled { true } cluster factory: %i(cluster with_installed_helm provided_by_gcp) end diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb index 3cb18f21a47..cc561ef65a2 100644 --- a/spec/factories/projects.rb +++ b/spec/factories/projects.rb @@ -47,6 +47,7 @@ FactoryBot.define do import_last_error { nil } forward_deployment_enabled { nil } restrict_user_defined_variables { nil } + ci_job_token_scope_enabled { nil } end before(:create) do |project, evaluator| @@ -88,6 +89,7 @@ FactoryBot.define do project.merge_trains_enabled = evaluator.merge_trains_enabled unless evaluator.merge_trains_enabled.nil? project.keep_latest_artifact = evaluator.keep_latest_artifact unless evaluator.keep_latest_artifact.nil? project.restrict_user_defined_variables = evaluator.restrict_user_defined_variables unless evaluator.restrict_user_defined_variables.nil? + project.ci_job_token_scope_enabled = evaluator.ci_job_token_scope_enabled unless evaluator.ci_job_token_scope_enabled.nil? if evaluator.import_status import_state = project.import_state || project.build_import_state diff --git a/spec/finders/ci/runners_finder_spec.rb b/spec/finders/ci/runners_finder_spec.rb index 4df026f2f5f..250a85dde30 100644 --- a/spec/finders/ci/runners_finder_spec.rb +++ b/spec/finders/ci/runners_finder_spec.rb @@ -51,23 +51,55 @@ RSpec.describe Ci::RunnersFinder do end context 'sort' do + let_it_be(:runner1) { create :ci_runner, created_at: '2018-07-12 07:00', contacted_at: 1.minute.ago } + let_it_be(:runner2) { create :ci_runner, created_at: '2018-07-12 08:00', contacted_at: 3.minutes.ago } + let_it_be(:runner3) { create :ci_runner, created_at: '2018-07-12 09:00', contacted_at: 2.minutes.ago } + + subject do + described_class.new(current_user: admin, params: params).execute + end + + shared_examples 'sorts by created_at descending' do + it 'sorts by created_at descending' do + is_expected.to eq [runner3, runner2, runner1] + end + end + context 'without sort param' do - it 'sorts by created_at' do - runner1 = create :ci_runner, created_at: '2018-07-12 07:00' - runner2 = create :ci_runner, created_at: '2018-07-12 08:00' - runner3 = create :ci_runner, created_at: '2018-07-12 09:00' + let(:params) { {} } + + it_behaves_like 'sorts by created_at descending' + end + + %w(created_date created_at_desc).each do |sort| + context "with sort param equal to #{sort}" do + let(:params) { { sort: sort } } + + it_behaves_like 'sorts by created_at descending' + end + end + + context 'with sort param equal to created_at_asc' do + let(:params) { { sort: 'created_at_asc' } } + + it 'sorts by created_at ascending' do + is_expected.to eq [runner1, runner2, runner3] + end + end + + context 'with sort param equal to contacted_asc' do + let(:params) { { sort: 'contacted_asc' } } - expect(described_class.new(current_user: admin, params: {}).execute).to eq [runner3, runner2, runner1] + it 'sorts by contacted_at ascending' do + is_expected.to eq [runner2, runner3, runner1] end end - context 'with sort param' do - it 'sorts by specified attribute' do - runner1 = create :ci_runner, contacted_at: 1.minute.ago - runner2 = create :ci_runner, contacted_at: 3.minutes.ago - runner3 = create :ci_runner, contacted_at: 2.minutes.ago + context 'with sort param equal to contacted_desc' do + let(:params) { { sort: 'contacted_desc' } } - expect(described_class.new(current_user: admin, params: { sort: 'contacted_asc' }).execute).to eq [runner2, runner3, runner1] + it 'sorts by contacted_at descending' do + is_expected.to eq [runner1, runner3, runner2] end end end @@ -246,8 +278,8 @@ RSpec.describe Ci::RunnersFinder do subject { described_class.new(current_user: user, group: group, params: params).sort_key } context 'no params' do - it 'returns created_date' do - expect(subject).to eq('created_date') + it 'returns created_at_desc' do + expect(subject).to eq('created_at_desc') end end diff --git a/spec/fixtures/api/schemas/analytics/cycle_analytics/summary.json b/spec/fixtures/api/schemas/analytics/cycle_analytics/summary.json new file mode 100644 index 00000000000..73904438ede --- /dev/null +++ b/spec/fixtures/api/schemas/analytics/cycle_analytics/summary.json @@ -0,0 +1,21 @@ +{ + "type": "array", + "items": { + "minItems": 2, + "maxItems": 3, + "type": "object", + "required": ["value", "title"], + "properties": { + "value": { + "type": "string" + }, + "title": { + "type": "string" + }, + "unit": { + "type": "string" + } + }, + "additionalProperties": false + } +} diff --git a/spec/fixtures/api/schemas/cluster_status.json b/spec/fixtures/api/schemas/cluster_status.json index f6db336fe65..c919cd54a28 100644 --- a/spec/fixtures/api/schemas/cluster_status.json +++ b/spec/fixtures/api/schemas/cluster_status.json @@ -42,7 +42,6 @@ "host": {"type": ["string", "null"]}, "port": {"type": ["integer", "514"]}, "protocol": {"type": ["integer", "0"]}, - "waf_log_enabled": {"type": ["boolean", "true"]}, "cilium_log_enabled": {"type": ["boolean", "true"]}, "update_available": { "type": ["boolean", "null"] }, "can_uninstall": { "type": "boolean" }, diff --git a/spec/frontend/lib/utils/url_utility_spec.js b/spec/frontend/lib/utils/url_utility_spec.js index bffe108896a..305d3de3c53 100644 --- a/spec/frontend/lib/utils/url_utility_spec.js +++ b/spec/frontend/lib/utils/url_utility_spec.js @@ -471,6 +471,7 @@ describe('URL utility', () => { ${'notaurl'} | ${false} ${'../relative_url'} | ${false} ${'<a></a>'} | ${false} + ${'//other-host.test'} | ${false} `('returns $valid for $url', ({ url, valid }) => { expect(urlUtils.isRootRelative(url)).toBe(valid); }); diff --git a/spec/frontend/packages/details/components/__snapshots__/file_sha_spec.js.snap b/spec/frontend/packages/details/components/__snapshots__/file_sha_spec.js.snap new file mode 100644 index 00000000000..881d441e116 --- /dev/null +++ b/spec/frontend/packages/details/components/__snapshots__/file_sha_spec.js.snap @@ -0,0 +1,30 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`FileSha renders 1`] = ` +<div + class="gl-display-flex gl-align-items-center gl-font-monospace gl-font-sm gl-word-break-all gl-py-2 gl-border-b-solid gl-border-gray-100 gl-border-b-1" +> + <!----> + + <span> + <div + class="gl-px-4" + > + + bar: + foo + + <gl-button-stub + aria-label="Copy this value" + buttontextclasses="" + category="tertiary" + data-clipboard-text="foo" + icon="copy-to-clipboard" + size="small" + title="Copy SHA" + variant="default" + /> + </div> + </span> +</div> +`; diff --git a/spec/frontend/packages/details/components/file_sha_spec.js b/spec/frontend/packages/details/components/file_sha_spec.js new file mode 100644 index 00000000000..7bfcf78baab --- /dev/null +++ b/spec/frontend/packages/details/components/file_sha_spec.js @@ -0,0 +1,33 @@ +import { shallowMount } from '@vue/test-utils'; + +import FileSha from '~/packages/details/components/file_sha.vue'; +import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; +import DetailsRow from '~/vue_shared/components/registry/details_row.vue'; + +describe('FileSha', () => { + let wrapper; + + const defaultProps = { sha: 'foo', title: 'bar' }; + + function createComponent() { + wrapper = shallowMount(FileSha, { + propsData: { + ...defaultProps, + }, + stubs: { + ClipboardButton, + DetailsRow, + }, + }); + } + + afterEach(() => { + wrapper.destroy(); + }); + + it('renders', () => { + createComponent(); + + expect(wrapper.element).toMatchSnapshot(); + }); +}); diff --git a/spec/frontend/packages/details/components/package_files_spec.js b/spec/frontend/packages/details/components/package_files_spec.js index 494aa631d9d..e8e5a24d3a3 100644 --- a/spec/frontend/packages/details/components/package_files_spec.js +++ b/spec/frontend/packages/details/components/package_files_spec.js @@ -1,5 +1,6 @@ -import { GlDropdown } from '@gitlab/ui'; +import { GlDropdown, GlButton } from '@gitlab/ui'; import { mount } from '@vue/test-utils'; +import { nextTick } from 'vue/'; import stubChildren from 'helpers/stub_children'; import component from '~/packages/details/components/package_files.vue'; import FileIcon from '~/vue_shared/components/file_icon.vue'; @@ -20,6 +21,8 @@ describe('Package Files', () => { const findFirstRowCreatedAt = () => findFirstRow().find(TimeAgoTooltip); const findFirstActionMenu = () => findFirstRow().findComponent(GlDropdown); const findActionMenuDelete = () => findFirstActionMenu().find('[data-testid="delete-file"]'); + const findFirstToggleDetailsButton = () => findFirstRow().findComponent(GlButton); + const findFirstRowShaComponent = (id) => wrapper.find(`[data-testid="${id}"]`); const createComponent = ({ packageFiles = npmFiles, canDelete = true } = {}) => { wrapper = mount(component, { @@ -181,4 +184,76 @@ describe('Package Files', () => { }); }); }); + + describe('additional details', () => { + describe('details toggle button', () => { + it('exists', () => { + createComponent(); + + expect(findFirstToggleDetailsButton().exists()).toBe(true); + }); + + it('is hidden when no details is present', () => { + const [{ ...noShaFile }] = npmFiles; + noShaFile.file_sha256 = null; + noShaFile.file_md5 = null; + noShaFile.file_sha1 = null; + createComponent({ packageFiles: [noShaFile] }); + + expect(findFirstToggleDetailsButton().exists()).toBe(false); + }); + + it('toggles the details row', async () => { + createComponent(); + + expect(findFirstToggleDetailsButton().props('icon')).toBe('angle-down'); + + findFirstToggleDetailsButton().vm.$emit('click'); + await nextTick(); + + expect(findFirstRowShaComponent('sha-256').exists()).toBe(true); + expect(findFirstToggleDetailsButton().props('icon')).toBe('angle-up'); + + findFirstToggleDetailsButton().vm.$emit('click'); + await nextTick(); + + expect(findFirstRowShaComponent('sha-256').exists()).toBe(false); + expect(findFirstToggleDetailsButton().props('icon')).toBe('angle-down'); + }); + }); + + describe('file shas', () => { + const showShaFiles = () => { + findFirstToggleDetailsButton().vm.$emit('click'); + return nextTick(); + }; + + it.each` + selector | title | sha + ${'sha-256'} | ${'SHA-256'} | ${'file_sha256'} + ${'md5'} | ${'MD5'} | ${'file_md5'} + ${'sha-1'} | ${'SHA-1'} | ${'file_sha1'} + `('has a $title row', async ({ selector, title, sha }) => { + createComponent(); + + await showShaFiles(); + + expect(findFirstRowShaComponent(selector).props()).toMatchObject({ + title, + sha, + }); + }); + + it('does not display a row when the data is missing', async () => { + const [{ ...missingMd5 }] = npmFiles; + missingMd5.file_md5 = null; + + createComponent({ packageFiles: [missingMd5] }); + + await showShaFiles(); + + expect(findFirstRowShaComponent('md5').exists()).toBe(false); + }); + }); + }); }); diff --git a/spec/frontend/packages/mock_data.js b/spec/frontend/packages/mock_data.js index 06009daba54..46ccf5994b9 100644 --- a/spec/frontend/packages/mock_data.js +++ b/spec/frontend/packages/mock_data.js @@ -79,6 +79,9 @@ export const npmFiles = [ pipelines: [ { id: 1, project: { commit_url: 'http://foo.bar' }, git_commit_message: 'foo bar baz?' }, ], + file_sha256: 'file_sha256', + file_md5: 'file_md5', + file_sha1: 'file_sha1', }, ]; diff --git a/spec/frontend/pages/projects/forks/new/components/app_spec.js b/spec/frontend/pages/projects/forks/new/components/app_spec.js index e1820606704..a7b4b9c42bd 100644 --- a/spec/frontend/pages/projects/forks/new/components/app_spec.js +++ b/spec/frontend/pages/projects/forks/new/components/app_spec.js @@ -13,6 +13,7 @@ describe('App component', () => { projectPath: 'project-name', projectDescription: 'some project description', projectVisibility: 'private', + restrictedVisibilityLevels: [], }; const createComponent = (props = {}) => { diff --git a/spec/frontend/pages/projects/forks/new/components/fork_form_spec.js b/spec/frontend/pages/projects/forks/new/components/fork_form_spec.js index 03338b1930c..c80ccfa8256 100644 --- a/spec/frontend/pages/projects/forks/new/components/fork_form_spec.js +++ b/spec/frontend/pages/projects/forks/new/components/fork_form_spec.js @@ -1,4 +1,5 @@ -import { GlFormInputGroup, GlFormInput, GlForm, GlFormRadio, GlFormSelect } from '@gitlab/ui'; +import { GlFormInputGroup, GlFormInput, GlForm, GlFormRadioGroup, GlFormRadio } from '@gitlab/ui'; +import { getByRole, getAllByRole } from '@testing-library/dom'; import { mount, shallowMount } from '@vue/test-utils'; import axios from 'axios'; import AxiosMockAdapter from 'axios-mock-adapter'; @@ -44,6 +45,7 @@ describe('ForkForm component', () => { projectPath: 'project-name', projectDescription: 'some project description', projectVisibility: 'private', + restrictedVisibilityLevels: [], }; const mockGetRequest = (data = {}, statusCode = httpStatus.OK) => { @@ -68,6 +70,7 @@ describe('ForkForm component', () => { stubs: { GlFormInputGroup, GlFormInput, + GlFormRadioGroup, GlFormRadio, }, }); @@ -89,7 +92,7 @@ describe('ForkForm component', () => { axiosMock.restore(); }); - const findFormSelect = () => wrapper.find(GlFormSelect); + const findFormSelectOptions = () => wrapper.find('select[name="namespace"]').findAll('option'); const findPrivateRadio = () => wrapper.find('[data-testid="radio-private"]'); const findInternalRadio = () => wrapper.find('[data-testid="radio-internal"]'); const findPublicRadio = () => wrapper.find('[data-testid="radio-public"]'); @@ -230,7 +233,7 @@ describe('ForkForm component', () => { expect(wrapper.findAll(GlFormRadio)).toHaveLength(3); }); - it('resets the visibility to default "private" when the namespace is changed', async () => { + describe('when the namespace is changed', () => { const namespaces = [ { visibility: 'private', @@ -243,42 +246,114 @@ describe('ForkForm component', () => { }, ]; - mockGetRequest(); - createComponent( - { - projectVisibility: 'public', - }, - { - namespaces, - }, - ); + beforeEach(() => { + mockGetRequest(); + }); - expect(wrapper.vm.form.fields.visibility.value).toBe('public'); - findFormSelect().vm.$emit('input', namespaces[1]); + it('resets the visibility to default "private"', async () => { + createFullComponent({ projectVisibility: 'public' }, { namespaces }); - await wrapper.vm.$nextTick(); + expect(wrapper.vm.form.fields.visibility.value).toBe('public'); + await findFormSelectOptions().at(1).setSelected(); + + await wrapper.vm.$nextTick(); + + expect(getByRole(wrapper.element, 'radio', { name: /private/i }).checked).toBe(true); + }); + + it('sets the visibility to be null when restrictedVisibilityLevels is set', async () => { + createFullComponent({ restrictedVisibilityLevels: [10] }, { namespaces }); + + await findFormSelectOptions().at(1).setSelected(); + + await wrapper.vm.$nextTick(); + + const container = getByRole(wrapper.element, 'radiogroup', { name: /visibility/i }); + const visibilityRadios = getAllByRole(container, 'radio'); + expect(visibilityRadios.filter((e) => e.checked)).toHaveLength(0); + }); + }); + + it.each` + project | restrictedVisibilityLevels + ${'private'} | ${[]} + ${'internal'} | ${[]} + ${'public'} | ${[]} + ${'private'} | ${[0]} + ${'private'} | ${[10]} + ${'private'} | ${[20]} + ${'private'} | ${[0, 10]} + ${'private'} | ${[0, 20]} + ${'private'} | ${[10, 20]} + ${'private'} | ${[0, 10, 20]} + ${'internal'} | ${[0]} + ${'internal'} | ${[10]} + ${'internal'} | ${[20]} + ${'internal'} | ${[0, 10]} + ${'internal'} | ${[0, 20]} + ${'internal'} | ${[10, 20]} + ${'internal'} | ${[0, 10, 20]} + ${'public'} | ${[0]} + ${'public'} | ${[10]} + ${'public'} | ${[0, 10]} + ${'public'} | ${[0, 20]} + ${'public'} | ${[10, 20]} + ${'public'} | ${[0, 10, 20]} + `('checks the correct radio button', async ({ project, restrictedVisibilityLevels }) => { + mockGetRequest(); + createFullComponent({ + projectVisibility: project, + restrictedVisibilityLevels, + }); - expect(wrapper.vm.form.fields.visibility.value).toBe('private'); + if (restrictedVisibilityLevels.length === 0) { + expect(wrapper.find('[name="visibility"]:checked').attributes('value')).toBe(project); + } else { + expect(wrapper.find('[name="visibility"]:checked').exists()).toBe(false); + } }); it.each` - project | namespace | privateIsDisabled | internalIsDisabled | publicIsDisabled - ${'private'} | ${'private'} | ${undefined} | ${'true'} | ${'true'} - ${'private'} | ${'internal'} | ${undefined} | ${'true'} | ${'true'} - ${'private'} | ${'public'} | ${undefined} | ${'true'} | ${'true'} - ${'internal'} | ${'private'} | ${undefined} | ${'true'} | ${'true'} - ${'internal'} | ${'internal'} | ${undefined} | ${undefined} | ${'true'} - ${'internal'} | ${'public'} | ${undefined} | ${undefined} | ${'true'} - ${'public'} | ${'private'} | ${undefined} | ${'true'} | ${'true'} - ${'public'} | ${'internal'} | ${undefined} | ${undefined} | ${'true'} - ${'public'} | ${'public'} | ${undefined} | ${undefined} | ${undefined} + project | namespace | privateIsDisabled | internalIsDisabled | publicIsDisabled | restrictedVisibilityLevels + ${'private'} | ${'private'} | ${undefined} | ${'true'} | ${'true'} | ${[]} + ${'private'} | ${'internal'} | ${undefined} | ${'true'} | ${'true'} | ${[]} + ${'private'} | ${'public'} | ${undefined} | ${'true'} | ${'true'} | ${[]} + ${'internal'} | ${'private'} | ${undefined} | ${'true'} | ${'true'} | ${[]} + ${'internal'} | ${'internal'} | ${undefined} | ${undefined} | ${'true'} | ${[]} + ${'internal'} | ${'public'} | ${undefined} | ${undefined} | ${'true'} | ${[]} + ${'public'} | ${'private'} | ${undefined} | ${'true'} | ${'true'} | ${[]} + ${'public'} | ${'internal'} | ${undefined} | ${undefined} | ${'true'} | ${[]} + ${'public'} | ${'public'} | ${undefined} | ${undefined} | ${undefined} | ${[]} + ${'private'} | ${'private'} | ${undefined} | ${'true'} | ${'true'} | ${[0]} + ${'internal'} | ${'internal'} | ${'true'} | ${undefined} | ${'true'} | ${[0]} + ${'public'} | ${'public'} | ${'true'} | ${undefined} | ${undefined} | ${[0]} + ${'private'} | ${'private'} | ${undefined} | ${'true'} | ${'true'} | ${[10]} + ${'internal'} | ${'internal'} | ${undefined} | ${'true'} | ${'true'} | ${[10]} + ${'public'} | ${'public'} | ${undefined} | ${'true'} | ${undefined} | ${[10]} + ${'private'} | ${'private'} | ${undefined} | ${'true'} | ${'true'} | ${[20]} + ${'internal'} | ${'internal'} | ${undefined} | ${undefined} | ${'true'} | ${[20]} + ${'public'} | ${'public'} | ${undefined} | ${undefined} | ${'true'} | ${[20]} + ${'private'} | ${'private'} | ${undefined} | ${'true'} | ${'true'} | ${[10, 20]} + ${'internal'} | ${'internal'} | ${undefined} | ${'true'} | ${'true'} | ${[10, 20]} + ${'public'} | ${'public'} | ${undefined} | ${'true'} | ${'true'} | ${[10, 20]} + ${'private'} | ${'private'} | ${undefined} | ${'true'} | ${'true'} | ${[0, 10, 20]} + ${'internal'} | ${'internal'} | ${undefined} | ${'true'} | ${'true'} | ${[0, 10, 20]} + ${'public'} | ${'public'} | ${undefined} | ${'true'} | ${'true'} | ${[0, 10, 20]} `( 'sets appropriate radio button disabled state', - async ({ project, namespace, privateIsDisabled, internalIsDisabled, publicIsDisabled }) => { + async ({ + project, + namespace, + privateIsDisabled, + internalIsDisabled, + publicIsDisabled, + restrictedVisibilityLevels, + }) => { mockGetRequest(); createComponent( { projectVisibility: project, + restrictedVisibilityLevels, }, { form: { fields: { namespace: { value: { visibility: namespace } } } }, diff --git a/spec/frontend/repository/log_tree_spec.js b/spec/frontend/repository/log_tree_spec.js index d338af88ce3..8cabf902a4f 100644 --- a/spec/frontend/repository/log_tree_spec.js +++ b/spec/frontend/repository/log_tree_spec.js @@ -69,6 +69,16 @@ describe('fetchLogsTree', () => { mock.restore(); }); + it('persists the offset for a given page if offset is larger than maximum offset', async () => { + await fetchLogsTree(client, 'path', '1000', resolver, 900).then(() => {}); + + await fetchLogsTree(client, 'path', '1100', resolver, 1200).then(() => { + expect(axios.get).toHaveBeenCalledWith('/gitlab-org/gitlab-foss/-/refs/main/logs_tree/path', { + params: { format: 'json', offset: 975 }, + }); + }); + }); + it('does not call axios get if offset is larger than the maximum offset', () => fetchLogsTree(client, '', '1000', resolver, 900).then(() => { expect(axios.get).not.toHaveBeenCalled(); diff --git a/spec/graphql/resolvers/ci/runners_resolver_spec.rb b/spec/graphql/resolvers/ci/runners_resolver_spec.rb index d89beb183f4..5ac15d5729f 100644 --- a/spec/graphql/resolvers/ci/runners_resolver_spec.rb +++ b/spec/graphql/resolvers/ci/runners_resolver_spec.rb @@ -50,13 +50,29 @@ RSpec.describe Resolvers::Ci::RunnersResolver do it { is_expected.to eq([offline_project_runner, instance_runner, inactive_project_runner, group_runner]) } end - context "set to :created_date" do + context "set to :contacted_desc" do let(:args) do - { sort: :created_date } + { sort: :contacted_desc } + end + + it { is_expected.to eq([offline_project_runner, instance_runner, inactive_project_runner, group_runner].reverse) } + end + + context "set to :created_at_desc" do + let(:args) do + { sort: :created_at_desc } end it { is_expected.to eq([instance_runner, group_runner, offline_project_runner, inactive_project_runner]) } end + + context "set to :created_at_asc" do + let(:args) do + { sort: :created_at_asc } + end + + it { is_expected.to eq([instance_runner, group_runner, offline_project_runner, inactive_project_runner].reverse) } + end end context 'when type is filtered' do diff --git a/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb b/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb index 2cdf95ea101..b9e0132badb 100644 --- a/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb @@ -4,14 +4,15 @@ require 'spec_helper' RSpec.describe Gitlab::CycleAnalytics::StageSummary do let(:project) { create(:project, :repository) } - let(:options) { { from: 1.day.ago, current_user: user } } + let(:options) { { from: 1.day.ago } } + let(:args) { { options: options, current_user: user } } let(:user) { create(:user, :admin) } before do project.add_maintainer(user) end - let(:stage_summary) { described_class.new(project, **options).data } + let(:stage_summary) { described_class.new(project, **args).data } describe "#new_issues" do subject { stage_summary.first } @@ -117,11 +118,11 @@ RSpec.describe Gitlab::CycleAnalytics::StageSummary do before do project.add_guest(guest_user) - options.merge!({ current_user: guest_user }) + args.merge!({ current_user: guest_user }) end it 'does not include commit stats' do - data = described_class.new(project, **options).data + data = described_class.new(project, **args).data expect(includes_commits?(data)).to be_falsy end diff --git a/spec/lib/gitlab/database/load_balancing/load_balancer_spec.rb b/spec/lib/gitlab/database/load_balancing/load_balancer_spec.rb index 28d78c182ad..4705bb23885 100644 --- a/spec/lib/gitlab/database/load_balancing/load_balancer_spec.rb +++ b/spec/lib/gitlab/database/load_balancing/load_balancer_spec.rb @@ -459,7 +459,7 @@ RSpec.describe Gitlab::Database::LoadBalancing::LoadBalancer, :request_store do expect(hosts).to all(receive(:caught_up?).with(location).and_return(false)) end - it 'returns true and has does not set the valid hosts' do + it 'returns false and does not set the valid hosts' do expect(subject).to be false expect(valid_host_list).to be_nil end @@ -487,4 +487,36 @@ RSpec.describe Gitlab::Database::LoadBalancing::LoadBalancer, :request_store do end end end + + describe '#select_caught_up_hosts' do + let(:location) { 'AB/12345'} + let(:hosts) { lb.host_list.hosts } + let(:set_host) { RequestStore[described_class::CACHE_KEY] } + + subject { lb.select_up_to_date_host(location) } + + context 'when none of the replicas are caught up' do + before do + expect(hosts).to all(receive(:caught_up?).with(location).and_return(false)) + end + + it 'returns false and does not update the host thread-local variable' do + expect(subject).to be false + expect(set_host).to be_nil + end + end + + context 'when any of the replicas is caught up' do + before do + # `allow` for non-caught up host, because we may not even check it, if will find the caught up one earlier + allow(hosts[0]).to receive(:caught_up?).with(location).and_return(false) + expect(hosts[1]).to receive(:caught_up?).with(location).and_return(true) + end + + it 'returns true and sets host thread-local variable' do + expect(subject).to be true + expect(set_host).to eq(hosts[1]) + end + end + end end diff --git a/spec/lib/gitlab/database/load_balancing/sidekiq_server_middleware_spec.rb b/spec/lib/gitlab/database/load_balancing/sidekiq_server_middleware_spec.rb index f1cd84b63c1..b7cd0caa922 100644 --- a/spec/lib/gitlab/database/load_balancing/sidekiq_server_middleware_spec.rb +++ b/spec/lib/gitlab/database/load_balancing/sidekiq_server_middleware_spec.rb @@ -126,7 +126,7 @@ RSpec.describe Gitlab::Database::LoadBalancing::SidekiqServerMiddleware do context 'when replica is not up to date' do before do allow(::Gitlab::Database::LoadBalancing).to receive_message_chain(:proxy, :load_balancer, :release_host) - allow(::Gitlab::Database::LoadBalancing).to receive_message_chain(:proxy, :load_balancer, :host, :caught_up?).and_return(false) + allow(::Gitlab::Database::LoadBalancing).to receive_message_chain(:proxy, :load_balancer, :select_up_to_date_host).and_return(false) end around do |example| @@ -157,6 +157,20 @@ RSpec.describe Gitlab::Database::LoadBalancing::SidekiqServerMiddleware do expect(job[:database_chosen]).to eq('primary') end end + + context 'replica selection mechanism feature flag rollout' do + before do + stub_feature_flags(sidekiq_load_balancing_rotate_up_to_date_replica: false) + end + + it 'uses different implmentation' do + expect(::Gitlab::Database::LoadBalancing).to receive_message_chain(:proxy, :load_balancer, :host, :caught_up?).and_return(false) + + expect do + process_job(job) + end.to raise_error(Sidekiq::JobRetry::Skip) + end + end end end diff --git a/spec/lib/gitlab/database/load_balancing_spec.rb b/spec/lib/gitlab/database/load_balancing_spec.rb index f8aeafbf61a..e7de7f2b43b 100644 --- a/spec/lib/gitlab/database/load_balancing_spec.rb +++ b/spec/lib/gitlab/database/load_balancing_spec.rb @@ -394,7 +394,7 @@ RSpec.describe Gitlab::Database::LoadBalancing do end shared_context 'LoadBalancing setup' do - let(:development_db_config) { ActiveRecord::Base.configurations.default_hash("development").with_indifferent_access } + let(:development_db_config) { ActiveRecord::Base.configurations.configs_for(env_name: 'development').first.configuration_hash } let(:hosts) { [development_db_config[:host]] } let(:model) do Class.new(ApplicationRecord) do diff --git a/spec/lib/gitlab/usage/metrics/name_suggestion_spec.rb b/spec/lib/gitlab/usage/metrics/name_suggestion_spec.rb index 2da0e7df72f..6955fbcaf5a 100644 --- a/spec/lib/gitlab/usage/metrics/name_suggestion_spec.rb +++ b/spec/lib/gitlab/usage/metrics/name_suggestion_spec.rb @@ -38,22 +38,6 @@ RSpec.describe Gitlab::Usage::Metrics::NameSuggestion do end context 'joined relations' do - context 'counted attribute comes from joined relation' do - it_behaves_like 'name suggestion' do - let(:operation) { :distinct_count } - let(:column) { ::Deployment.arel_table[:environment_id] } - let(:relation) do - ::Clusters::Applications::Ingress.modsecurity_enabled.logging - .joins(cluster: :deployments) - .merge(::Clusters::Cluster.enabled) - .merge(Deployment.success) - end - - let(:constraints) { /'\(clusters_applications_ingress\.modsecurity_enabled = TRUE AND clusters_applications_ingress\.modsecurity_mode = \d+ AND clusters.enabled = TRUE AND deployments.status = \d+\)'/ } - let(:name_suggestion) { /count_distinct_environment_id_from_<adjective describing\: #{constraints}>_deployments_<with>_<adjective describing\: #{constraints}>_clusters_<having>_<adjective describing\: #{constraints}>_clusters_applications_ingress/ } - end - end - context 'counted attribute comes from source relation' do it_behaves_like 'name suggestion' do # corresponding metric is collected with count(Issue.with_alert_management_alerts.not_authored_by(::User.alert_bot), start: issue_minimum_id, finish: issue_maximum_id) diff --git a/spec/models/clusters/applications/fluentd_spec.rb b/spec/models/clusters/applications/fluentd_spec.rb index ccdf6b0e40d..a4df44225f3 100644 --- a/spec/models/clusters/applications/fluentd_spec.rb +++ b/spec/models/clusters/applications/fluentd_spec.rb @@ -3,9 +3,8 @@ require 'spec_helper' RSpec.describe Clusters::Applications::Fluentd do - let(:waf_log_enabled) { true } let(:cilium_log_enabled) { true } - let(:fluentd) { create(:clusters_applications_fluentd, waf_log_enabled: waf_log_enabled, cilium_log_enabled: cilium_log_enabled) } + let(:fluentd) { create(:clusters_applications_fluentd, cilium_log_enabled: cilium_log_enabled) } include_examples 'cluster application core specs', :clusters_applications_fluentd include_examples 'cluster application status specs', :clusters_applications_fluentd @@ -51,13 +50,11 @@ RSpec.describe Clusters::Applications::Fluentd do end describe '#values' do - let(:modsecurity_log_path) { "/var/log/containers/*#{Clusters::Applications::Ingress::MODSECURITY_LOG_CONTAINER_NAME}*.log" } let(:cilium_log_path) { "/var/log/containers/*#{described_class::CILIUM_CONTAINER_NAME}*.log" } subject { fluentd.values } - context 'with both logs variables set to false' do - let(:waf_log_enabled) { false } + context 'with cilium_log_enabled set to false' do let(:cilium_log_enabled) { false } it "raises ActiveRecord::RecordInvalid" do @@ -65,18 +62,8 @@ RSpec.describe Clusters::Applications::Fluentd do end end - context 'with both logs variables set to true' do - it { is_expected.to include("#{modsecurity_log_path},#{cilium_log_path}") } - end - - context 'with waf_log_enabled set to true' do - let(:cilium_log_enabled) { false } - - it { is_expected.to include(modsecurity_log_path) } - end - context 'with cilium_log_enabled set to true' do - let(:waf_log_enabled) { false } + let(:cilium_log_enabled) { true } it { is_expected.to include(cilium_log_path) } end diff --git a/spec/models/clusters/applications/ingress_spec.rb b/spec/models/clusters/applications/ingress_spec.rb index 1bc1a4343aa..e16d97c42d9 100644 --- a/spec/models/clusters/applications/ingress_spec.rb +++ b/spec/models/clusters/applications/ingress_spec.rb @@ -172,94 +172,4 @@ RSpec.describe Clusters::Applications::Ingress do expect(values).to include('clusterIP') end end - - describe '#values' do - subject { ingress } - - context 'when modsecurity_enabled is enabled' do - before do - allow(subject).to receive(:modsecurity_enabled).and_return(true) - end - - it 'includes modsecurity module enablement' do - expect(subject.values).to include("enable-modsecurity: 'true'") - end - - it 'includes modsecurity core ruleset enablement set to false' do - expect(subject.values).to include("enable-owasp-modsecurity-crs: 'false'") - end - - it 'includes modsecurity snippet with information related to security rules' do - expect(subject.values).to include("SecRuleEngine DetectionOnly") - expect(subject.values).to include("Include #{described_class::MODSECURITY_OWASP_RULES_FILE}") - end - - context 'when modsecurity_mode is set to :blocking' do - before do - subject.blocking! - end - - it 'includes modsecurity snippet with information related to security rules' do - expect(subject.values).to include("SecRuleEngine On") - expect(subject.values).to include("Include #{described_class::MODSECURITY_OWASP_RULES_FILE}") - end - end - - it 'includes modsecurity.conf content' do - expect(subject.values).to include('modsecurity.conf') - # Includes file content from Ingress#modsecurity_config_content - expect(subject.values).to include('SecAuditLog') - - expect(subject.values).to include('extraVolumes') - expect(subject.values).to include('extraVolumeMounts') - end - - it 'includes modsecurity sidecar container' do - expect(subject.values).to include('modsecurity-log-volume') - - expect(subject.values).to include('extraContainers') - end - - it 'executes command to tail modsecurity logs with -F option' do - args = YAML.safe_load(subject.values).dig('controller', 'extraContainers', 0, 'args') - - expect(args).to eq(['/bin/sh', '-c', 'tail -F /var/log/modsec/audit.log']) - end - - it 'includes livenessProbe for modsecurity sidecar container' do - probe_config = YAML.safe_load(subject.values).dig('controller', 'extraContainers', 0, 'livenessProbe') - - expect(probe_config).to eq('exec' => { 'command' => ['ls', '/var/log/modsec/audit.log'] }) - end - end - - context 'when modsecurity_enabled is disabled' do - before do - allow(subject).to receive(:modsecurity_enabled).and_return(false) - end - - it 'excludes modsecurity module enablement' do - expect(subject.values).not_to include('enable-modsecurity') - end - - it 'excludes modsecurity core ruleset enablement' do - expect(subject.values).not_to include('enable-owasp-modsecurity-crs') - end - - it 'excludes modsecurity.conf content' do - expect(subject.values).not_to include('modsecurity.conf') - # Excludes file content from Ingress#modsecurity_config_content - expect(subject.values).not_to include('SecAuditLog') - - expect(subject.values).not_to include('extraVolumes') - expect(subject.values).not_to include('extraVolumeMounts') - end - - it 'excludes modsecurity sidecar container' do - expect(subject.values).not_to include('modsecurity-log-volume') - - expect(subject.values).not_to include('extraContainers') - end - end - end end diff --git a/spec/models/clusters/cluster_spec.rb b/spec/models/clusters/cluster_spec.rb index 28dba3e7efa..8a7ffc315db 100644 --- a/spec/models/clusters/cluster_spec.rb +++ b/spec/models/clusters/cluster_spec.rb @@ -196,28 +196,6 @@ RSpec.describe Clusters::Cluster, :use_clean_rails_memory_store_caching do end end - describe '.with_enabled_modsecurity' do - subject { described_class.with_enabled_modsecurity } - - let_it_be(:cluster) { create(:cluster) } - - context 'cluster has ingress application with enabled modsecurity' do - let!(:application) { create(:clusters_applications_ingress, :installed, :modsecurity_logging, cluster: cluster) } - - it { is_expected.to include(cluster) } - end - - context 'cluster has ingress application with disabled modsecurity' do - let!(:application) { create(:clusters_applications_ingress, :installed, :modsecurity_disabled, cluster: cluster) } - - it { is_expected.not_to include(cluster) } - end - - context 'cluster does not have ingress application' do - it { is_expected.not_to include(cluster) } - end - end - describe '.with_available_elasticstack' do subject { described_class.with_available_elasticstack } diff --git a/spec/models/members/last_group_owner_assigner_spec.rb b/spec/models/members/last_group_owner_assigner_spec.rb index 3c9a7a11555..bb0f751e7d5 100644 --- a/spec/models/members/last_group_owner_assigner_spec.rb +++ b/spec/models/members/last_group_owner_assigner_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Members::LastGroupOwnerAssigner do +RSpec.describe LastGroupOwnerAssigner do describe "#execute" do let_it_be(:user, reload: true) { create(:user) } let_it_be(:group) { create(:group) } diff --git a/spec/requests/api/graphql/ci/ci_cd_setting_spec.rb b/spec/requests/api/graphql/ci/ci_cd_setting_spec.rb index 99647d0fa3a..578a71a7272 100644 --- a/spec/requests/api/graphql/ci/ci_cd_setting_spec.rb +++ b/spec/requests/api/graphql/ci/ci_cd_setting_spec.rb @@ -47,6 +47,7 @@ RSpec.describe 'Getting Ci Cd Setting' do expect(settings_data['mergePipelinesEnabled']).to eql project.ci_cd_settings.merge_pipelines_enabled? expect(settings_data['mergeTrainsEnabled']).to eql project.ci_cd_settings.merge_trains_enabled? expect(settings_data['keepLatestArtifact']).to eql project.keep_latest_artifacts_available? + expect(settings_data['jobTokenScopeEnabled']).to eql project.ci_cd_settings.job_token_scope_enabled? end end end diff --git a/spec/requests/api/graphql/mutations/ci/ci_cd_settings_update_spec.rb b/spec/requests/api/graphql/mutations/ci/ci_cd_settings_update_spec.rb index 0dcae28ac5d..0d7571d91ca 100644 --- a/spec/requests/api/graphql/mutations/ci/ci_cd_settings_update_spec.rb +++ b/spec/requests/api/graphql/mutations/ci/ci_cd_settings_update_spec.rb @@ -5,8 +5,16 @@ require 'spec_helper' RSpec.describe 'CiCdSettingsUpdate' do include GraphqlHelpers - let_it_be(:project) { create(:project, keep_latest_artifact: true) } - let(:variables) { { full_path: project.full_path, keep_latest_artifact: false } } + let_it_be(:project) { create(:project, keep_latest_artifact: true, ci_job_token_scope_enabled: true) } + + let(:variables) do + { + full_path: project.full_path, + keep_latest_artifact: false, + job_token_scope_enabled: false + } + end + let(:mutation) { graphql_mutation(:ci_cd_settings_update, variables) } context 'when unauthorized' do @@ -45,6 +53,26 @@ RSpec.describe 'CiCdSettingsUpdate' do expect(project.keep_latest_artifact).to eq(false) end + it 'updates job_token_scope_enabled' do + post_graphql_mutation(mutation, current_user: user) + + project.reload + + expect(response).to have_gitlab_http_status(:success) + expect(project.ci_job_token_scope_enabled).to eq(false) + end + + it 'does not update job_token_scope_enabled if not specified' do + variables.except!(:job_token_scope_enabled) + + post_graphql_mutation(mutation, current_user: user) + + project.reload + + expect(response).to have_gitlab_http_status(:success) + expect(project.ci_job_token_scope_enabled).to eq(true) + end + context 'when bad arguments are provided' do let(:variables) { { full_path: '', keep_latest_artifact: false } } diff --git a/spec/requests/api/tags_spec.rb b/spec/requests/api/tags_spec.rb index ce7405201ab..1aa1ad87be9 100644 --- a/spec/requests/api/tags_spec.rb +++ b/spec/requests/api/tags_spec.rb @@ -358,26 +358,6 @@ RSpec.describe API::Tags do expect(json_response['message']).to eq('Target foo is invalid') end - context 'when release_description is passed' do - it 'returns error' do - post api(route, current_user), params: { tag_name: tag_name, ref: 'master', release_description: 'Wow' } - - expect(response).to have_gitlab_http_status(:bad_request) - expect(json_response["message"]).to eq("Release notes modification via tags API is deprecated, see https://gitlab.com/gitlab-org/gitlab/-/issues/290311") - end - - it 'creates a new tag with release if feature is enabled' do - stub_feature_flags(remove_release_notes_from_tags_api: false) - - post api(route, current_user), params: { tag_name: tag_name, ref: 'master', release_description: 'Wow' } - - expect(response).to have_gitlab_http_status(:created) - expect(response).to match_response_schema('public_api/v4/tag') - expect(json_response['name']).to eq(tag_name) - expect(json_response['release']['description']).to eq('Wow') - end - end - context 'annotated tag' do it 'creates a new annotated tag' do # Identity must be set in .gitconfig to create annotated tag. @@ -449,148 +429,4 @@ RSpec.describe API::Tags do end end end - - describe 'POST /projects/:id/repository/tags/:tag_name/release' do - let(:route) { "/projects/#{project_id}/repository/tags/#{tag_name}/release" } - let(:description) { 'Awesome release!' } - - before do - stub_feature_flags(remove_release_notes_from_tags_api: false) - end - - shared_examples_for 'repository new release' do - it 'creates description for existing git tag' do - post api(route, user), params: { description: description } - - expect(response).to have_gitlab_http_status(:created) - expect(response).to match_response_schema('public_api/v4/release/tag_release') - expect(json_response['tag_name']).to eq(tag_name) - expect(json_response['description']).to eq(description) - end - - it 'returns error if feature is removed' do - stub_feature_flags(remove_release_notes_from_tags_api: true) - - post api(route, user), params: { description: description } - - expect(response).to have_gitlab_http_status(:bad_request) - expect(json_response["message"]).to eq("Release notes modification via tags API is deprecated, see https://gitlab.com/gitlab-org/gitlab/-/issues/290311") - end - - context 'when tag does not exist' do - let(:tag_name) { 'unknown' } - - it_behaves_like '404 response' do - let(:request) { post api(route, current_user), params: { description: description } } - let(:message) { '404 Tag Not Found' } - end - end - - context 'when repository is disabled' do - include_context 'disabled repository' - - it_behaves_like '403 response' do - let(:request) { post api(route, current_user), params: { description: description } } - end - end - end - - context 'when authenticated', 'as a maintainer' do - let(:current_user) { user } - - it_behaves_like 'repository new release' - - context 'requesting with the escaped project full path' do - let(:project_id) { CGI.escape(project.full_path) } - - it_behaves_like 'repository new release' - end - - context 'on tag with existing release' do - let!(:release) { create(:release, :legacy, project: project, tag: tag_name, description: description) } - - it 'returns 409 if there is already a release' do - post api(route, user), params: { description: description } - - expect(response).to have_gitlab_http_status(:conflict) - expect(json_response['message']).to eq('Release already exists') - end - end - end - end - - describe 'PUT id/repository/tags/:tag_name/release' do - let(:route) { "/projects/#{project_id}/repository/tags/#{tag_name}/release" } - let(:description) { 'Awesome release!' } - let(:new_description) { 'The best release!' } - - before do - stub_feature_flags(remove_release_notes_from_tags_api: false) - end - - shared_examples_for 'repository update release' do - context 'on tag with existing release' do - let!(:release) do - create(:release, - :legacy, - project: project, - tag: tag_name, - description: description) - end - - it 'updates the release description' do - put api(route, current_user), params: { description: new_description } - - expect(response).to have_gitlab_http_status(:ok) - expect(json_response['tag_name']).to eq(tag_name) - expect(json_response['description']).to eq(new_description) - end - - it 'returns error if feature is removed' do - stub_feature_flags(remove_release_notes_from_tags_api: true) - - put api(route, current_user), params: { description: new_description } - - expect(response).to have_gitlab_http_status(:bad_request) - expect(json_response["message"]).to eq("Release notes modification via tags API is deprecated, see https://gitlab.com/gitlab-org/gitlab/-/issues/290311") - end - end - - context 'when tag does not exist' do - let(:tag_name) { 'unknown' } - - it_behaves_like '403 response' do - let(:request) { put api(route, current_user), params: { description: new_description } } - let(:message) { '403 Forbidden' } - end - end - - context 'when repository is disabled' do - include_context 'disabled repository' - - it_behaves_like '403 response' do - let(:request) { put api(route, current_user), params: { description: new_description } } - end - end - end - - context 'when authenticated', 'as a maintainer' do - let(:current_user) { user } - - it_behaves_like 'repository update release' - - context 'requesting with the escaped project full path' do - let(:project_id) { CGI.escape(project.full_path) } - - it_behaves_like 'repository update release' - end - - context 'when release does not exist' do - it_behaves_like '403 response' do - let(:request) { put api(route, current_user), params: { description: new_description } } - let(:message) { '403 Forbidden' } - end - end - end - end end diff --git a/spec/serializers/analytics_summary_serializer_spec.rb b/spec/serializers/analytics_summary_serializer_spec.rb index cd8be07827d..9429c9d571a 100644 --- a/spec/serializers/analytics_summary_serializer_spec.rb +++ b/spec/serializers/analytics_summary_serializer_spec.rb @@ -12,7 +12,7 @@ RSpec.describe AnalyticsSummarySerializer do let(:resource) do Gitlab::CycleAnalytics::Summary::Issue - .new(project: double, from: 1.day.ago, current_user: user) + .new(project: double, options: { from: 1.day.ago }, current_user: user) end before do @@ -36,7 +36,7 @@ RSpec.describe AnalyticsSummarySerializer do context 'when representing with unit' do let(:resource) do Gitlab::CycleAnalytics::Summary::DeploymentFrequency - .new(deployments: 10, from: 1.day.ago) + .new(deployments: 10, options: { from: 1.day.ago }) end subject { described_class.new.represent(resource, with_unit: true) } diff --git a/spec/serializers/cluster_application_entity_spec.rb b/spec/serializers/cluster_application_entity_spec.rb index aa2bb25b17c..3941aad540a 100644 --- a/spec/serializers/cluster_application_entity_spec.rb +++ b/spec/serializers/cluster_application_entity_spec.rb @@ -85,7 +85,6 @@ RSpec.describe ClusterApplicationEntity do expect(subject[:port]).to eq(514) expect(subject[:host]).to eq("example.com") expect(subject[:protocol]).to eq("tcp") - expect(subject[:waf_log_enabled]).to be true expect(subject[:cilium_log_enabled]).to be true end end diff --git a/spec/serializers/member_serializer_spec.rb b/spec/serializers/member_serializer_spec.rb index 687d69f86ea..bc256432c46 100644 --- a/spec/serializers/member_serializer_spec.rb +++ b/spec/serializers/member_serializer_spec.rb @@ -42,7 +42,7 @@ RSpec.describe MemberSerializer do it_behaves_like 'members.json' it 'does not invoke group owner assignment' do - expect(Members::LastGroupOwnerAssigner).not_to receive(:new) + expect(LastGroupOwnerAssigner).not_to receive(:new) representation end diff --git a/spec/services/clusters/applications/create_service_spec.rb b/spec/services/clusters/applications/create_service_spec.rb index f3b420510a6..eb907377ca8 100644 --- a/spec/services/clusters/applications/create_service_spec.rb +++ b/spec/services/clusters/applications/create_service_spec.rb @@ -46,8 +46,7 @@ RSpec.describe Clusters::Applications::CreateService do context 'ingress application' do let(:params) do { - application: 'ingress', - modsecurity_enabled: true + application: 'ingress' } end @@ -64,10 +63,6 @@ RSpec.describe Clusters::Applications::CreateService do cluster.reload end.to change(cluster, :application_ingress) end - - it 'sets modsecurity_enabled' do - expect(subject.modsecurity_enabled).to eq(true) - end end context 'cert manager application' do diff --git a/spec/workers/ssh_keys/expired_notification_worker_spec.rb b/spec/workers/ssh_keys/expired_notification_worker_spec.rb index 84f8f8d7b83..109d24f03ab 100644 --- a/spec/workers/ssh_keys/expired_notification_worker_spec.rb +++ b/spec/workers/ssh_keys/expired_notification_worker_spec.rb @@ -49,16 +49,6 @@ RSpec.describe SshKeys::ExpiredNotificationWorker, type: :worker do perform_multiple(worker: worker) end end - - context 'when feature is not enabled' do - before do - stub_feature_flags(ssh_key_expiration_email_notification: false) - end - - it 'does not update notified column' do - expect { worker.perform }.not_to change { expired_today.reload.expiry_notification_delivered_at } - end - end end context 'when key has expired in the past' do diff --git a/spec/workers/ssh_keys/expiring_soon_notification_worker_spec.rb b/spec/workers/ssh_keys/expiring_soon_notification_worker_spec.rb index f9276c86cdf..0a1d4a14ad0 100644 --- a/spec/workers/ssh_keys/expiring_soon_notification_worker_spec.rb +++ b/spec/workers/ssh_keys/expiring_soon_notification_worker_spec.rb @@ -35,16 +35,6 @@ RSpec.describe SshKeys::ExpiringSoonNotificationWorker, type: :worker do perform_multiple(worker: worker) end end - - context 'when feature is not enabled' do - before do - stub_feature_flags(ssh_key_expiration_email_notification: false) - end - - it 'does not update notified column' do - expect { worker.perform }.not_to change { expiring_soon.reload.before_expiry_notification_delivered_at } - end - end end context 'when key has expired in the past' do |