Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-05-06 15:09:05 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-05-06 15:09:05 +0300
commit669ad9e431c7647f01bda681aab2c0ad2cb58826 (patch)
tree13fac2c7a8f4c4f8f715ed0dd351470dee3918a1 /spec
parent3c21cbd6a81d7b962a5d9a72ba8e03f3bf449af8 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/projects/jobs_controller_spec.rb13
-rw-r--r--spec/controllers/projects/services_controller_spec.rb82
-rw-r--r--spec/controllers/projects/settings/operations_controller_spec.rb31
-rw-r--r--spec/features/projects/integrations/user_activates_prometheus_spec.rb5
-rw-r--r--spec/features/projects/pipelines/pipeline_spec.rb39
-rw-r--r--spec/frontend/pipelines/components/jobs/failed_jobs_app_spec.js87
-rw-r--r--spec/frontend/pipelines/components/jobs/failed_jobs_table_spec.js117
-rw-r--r--spec/frontend/pipelines/components/jobs/utils_spec.js14
-rw-r--r--spec/frontend/pipelines/mock_data.js215
-rw-r--r--spec/graphql/types/ci/runner_type_spec.rb2
-rw-r--r--spec/helpers/ci/builds_helper_spec.rb14
-rw-r--r--spec/lib/gitlab/background_migration/extract_project_topics_into_separate_table_spec.rb2
-rw-r--r--spec/lib/gitlab/checks/branch_check_spec.rb6
-rw-r--r--spec/lib/gitlab/database/migration_helpers_spec.rb28
-rw-r--r--spec/lib/gitlab/email/handler/create_note_handler_spec.rb4
-rw-r--r--spec/lib/gitlab/email/message/in_product_marketing/base_spec.rb2
-rw-r--r--spec/lib/gitlab/git/diff_spec.rb6
-rw-r--r--spec/lib/gitlab/popen_spec.rb2
-rw-r--r--spec/lib/gitlab/tracking/event_definition_spec.rb2
-rw-r--r--spec/migrations/finalize_project_namespaces_backfill_spec.rb2
-rw-r--r--spec/models/clusters/platforms/kubernetes_spec.rb2
-rw-r--r--spec/models/concerns/reactive_caching_spec.rb2
-rw-r--r--spec/models/environment_spec.rb2
-rw-r--r--spec/models/integration_spec.rb2
-rw-r--r--spec/models/packages/package_spec.rb2
-rw-r--r--spec/models/project_spec.rb2
-rw-r--r--spec/models/protected_branch/push_access_level_spec.rb2
-rw-r--r--spec/models/release_spec.rb5
-rw-r--r--spec/requests/api/graphql/ci/runner_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/clusters/agents/delete_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/merge_requests_spec.rb25
-rw-r--r--spec/services/ci/pipeline_artifacts/coverage_report_service_spec.rb2
-rw-r--r--spec/services/clusters/agents/delete_service_spec.rb2
-rw-r--r--spec/support/rspec.rb2
-rw-r--r--spec/support/shared_contexts/email_shared_context.rb2
-rw-r--r--spec/support_specs/helpers/active_record/query_recorder_spec.rb10
-rw-r--r--spec/views/admin/application_settings/general.html.haml_spec.rb22
-rw-r--r--spec/views/projects/settings/operations/show.html.haml_spec.rb24
-rw-r--r--spec/workers/clusters/applications/activate_service_worker_spec.rb2
-rw-r--r--spec/workers/delete_diff_files_worker_spec.rb6
40 files changed, 584 insertions, 209 deletions
diff --git a/spec/controllers/projects/jobs_controller_spec.rb b/spec/controllers/projects/jobs_controller_spec.rb
index e9f1232b5e7..162c36f5069 100644
--- a/spec/controllers/projects/jobs_controller_spec.rb
+++ b/spec/controllers/projects/jobs_controller_spec.rb
@@ -929,13 +929,13 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do
context 'when continue url is present' do
let(:job) { create(:ci_build, :cancelable, pipeline: pipeline) }
+ before do
+ post_cancel(continue: { to: url })
+ end
+
context 'when continue to is a safe url' do
let(:url) { '/test' }
- before do
- post_cancel(continue: { to: url })
- end
-
it 'redirects to the continue url' do
expect(response).to have_gitlab_http_status(:found)
expect(response).to redirect_to(url)
@@ -949,8 +949,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do
context 'when continue to is not a safe url' do
let(:url) { 'http://example.com' }
- it 'raises an error' do
- expect { cancel_with_redirect(url) }.to raise_error
+ it 'redirects to the builds page' do
+ expect(response).to have_gitlab_http_status(:found)
+ expect(response).to redirect_to(builds_namespace_project_pipeline_path(id: pipeline.id))
end
end
end
diff --git a/spec/controllers/projects/services_controller_spec.rb b/spec/controllers/projects/services_controller_spec.rb
index 7e96c59fbb1..6802ebeb63e 100644
--- a/spec/controllers/projects/services_controller_spec.rb
+++ b/spec/controllers/projects/services_controller_spec.rb
@@ -326,56 +326,6 @@ RSpec.describe Projects::ServicesController do
end
end
end
-
- context 'with Prometheus integration' do
- let_it_be(:prometheus_integration) { create(:prometheus_integration, project: project) }
-
- let(:integration) { prometheus_integration }
- let(:integration_params) { { manual_configuration: '1', api_url: 'http://example.com' } }
-
- context 'when feature flag :settings_operations_prometheus_service is enabled' do
- before do
- stub_feature_flags(settings_operations_prometheus_service: true)
- end
-
- it 'redirects user back to edit page with alert' do
- put :update, params: project_params.merge(service: integration_params)
-
- expect(response).to redirect_to(edit_project_integration_path(project, integration))
- expected_alert = [
- "You can now manage your Prometheus settings on the",
- %(<a href="#{project_settings_operations_path(project)}">Operations</a> page.),
- "Fields on this page have been deprecated."
- ].join(' ')
-
- expect(controller).to set_flash.now[:alert].to(expected_alert)
- end
-
- it 'does not modify integration' do
- expect { put :update, params: project_params.merge(service: integration_params) }
- .not_to change { prometheus_integration_as_data }
- end
-
- def prometheus_integration_as_data
- pi = project.prometheus_integration.reload
- attrs = pi.attributes.except('encrypted_properties',
- 'encrypted_properties_iv')
-
- [attrs, pi.properties]
- end
- end
-
- context 'when feature flag :settings_operations_prometheus_service is disabled' do
- before do
- stub_feature_flags(settings_operations_prometheus_service: false)
- end
-
- it 'modifies integration' do
- expect { put :update, params: project_params.merge(service: integration_params) }
- .to change { project.prometheus_integration.reload.attributes }
- end
- end
- end
end
describe 'GET #edit' do
@@ -392,38 +342,6 @@ RSpec.describe Projects::ServicesController do
end
end
end
-
- context 'with Prometheus service' do
- let(:integration_param) { 'prometheus' }
-
- context 'when feature flag :settings_operations_prometheus_service is enabled' do
- before do
- stub_feature_flags(settings_operations_prometheus_service: true)
- get :edit, params: project_params(id: integration_param)
- end
-
- it 'renders deprecation warning notice' do
- expected_alert = [
- "You can now manage your Prometheus settings on the",
- %(<a href="#{project_settings_operations_path(project)}">Operations</a> page.),
- "Fields on this page have been deprecated."
- ].join(' ')
-
- expect(controller).to set_flash.now[:alert].to(expected_alert)
- end
- end
-
- context 'when feature flag :settings_operations_prometheus_service is disabled' do
- before do
- stub_feature_flags(settings_operations_prometheus_service: false)
- get :edit, params: project_params(id: integration_param)
- end
-
- it 'does not render deprecation warning notice' do
- expect(controller).not_to set_flash.now[:alert]
- end
- end
- end
end
private
diff --git a/spec/controllers/projects/settings/operations_controller_spec.rb b/spec/controllers/projects/settings/operations_controller_spec.rb
index 7ef5371f2b5..c1fa91e9f8b 100644
--- a/spec/controllers/projects/settings/operations_controller_spec.rb
+++ b/spec/controllers/projects/settings/operations_controller_spec.rb
@@ -354,37 +354,6 @@ RSpec.describe Projects::Settings::OperationsController do
end
context 'prometheus integration' do
- describe 'PATCH #update' do
- let(:params) do
- {
- prometheus_integration_attributes: {
- manual_configuration: '0',
- api_url: 'https://gitlab.prometheus.rocks'
- }
- }
- end
-
- context 'feature flag :settings_operations_prometheus_service is enabled' do
- before do
- stub_feature_flags(settings_operations_prometheus_service: true)
- end
-
- it_behaves_like 'PATCHable'
- end
-
- context 'feature flag :settings_operations_prometheus_service is disabled' do
- before do
- stub_feature_flags(settings_operations_prometheus_service: false)
- end
-
- it_behaves_like 'PATCHable' do
- let(:permitted_params) do
- ActionController::Parameters.new(params.except(:prometheus_integration_attributes)).permit!
- end
- end
- end
- end
-
describe 'POST #reset_alerting_token' do
context 'with existing alerting setting' do
let!(:alerting_setting) do
diff --git a/spec/features/projects/integrations/user_activates_prometheus_spec.rb b/spec/features/projects/integrations/user_activates_prometheus_spec.rb
index 80629af6fce..56b895919b8 100644
--- a/spec/features/projects/integrations/user_activates_prometheus_spec.rb
+++ b/spec/features/projects/integrations/user_activates_prometheus_spec.rb
@@ -9,14 +9,13 @@ RSpec.describe 'User activates Prometheus' do
stub_request(:get, /.*prometheus.example.com.*/)
end
- it 'does not activate integration and informs about deprecation', :js do
+ it 'saves and activates integration', :js do
visit_project_integration('Prometheus')
check('Active')
fill_in('API URL', with: 'http://prometheus.example.com')
click_button('Save changes')
- expect(page).not_to have_content('Prometheus settings saved and active.')
- expect(page).to have_content('Fields on this page have been deprecated.')
+ expect(page).to have_content('Prometheus settings saved and active.')
end
end
diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb
index 8581584aea4..c6a2ccb3e8c 100644
--- a/spec/features/projects/pipelines/pipeline_spec.rb
+++ b/spec/features/projects/pipelines/pipeline_spec.rb
@@ -1188,12 +1188,43 @@ RSpec.describe 'Pipeline', :js do
expect(page).to have_content('There is an unknown failure, please try again')
end
+ context 'when failed_jobs_tab_vue feature flag is disabled' do
+ before do
+ stub_feature_flags(failed_jobs_tab_vue: false)
+ end
+
+ context 'when user does not have permission to retry build' do
+ it 'shows retry button for failed build' do
+ subject
+
+ page.within(find('.build-failures', match: :first)) do
+ expect(page).not_to have_link('Retry')
+ end
+ end
+ end
+
+ context 'when user does have permission to retry build' do
+ before do
+ create(:protected_branch, :developers_can_merge,
+ name: pipeline.ref, project: project)
+ end
+
+ it 'shows retry button for failed build' do
+ subject
+
+ page.within(find('.build-failures', match: :first)) do
+ expect(page).to have_link('Retry')
+ end
+ end
+ end
+ end
+
context 'when user does not have permission to retry build' do
it 'shows retry button for failed build' do
subject
- page.within(find('.build-failures', match: :first)) do
- expect(page).not_to have_link('Retry')
+ page.within(find('#js-tab-failures', match: :first)) do
+ expect(page).not_to have_button('Retry')
end
end
end
@@ -1207,8 +1238,8 @@ RSpec.describe 'Pipeline', :js do
it 'shows retry button for failed build' do
subject
- page.within(find('.build-failures', match: :first)) do
- expect(page).to have_link('Retry')
+ page.within(find('#js-tab-failures', match: :first)) do
+ expect(page).to have_button('Retry')
end
end
end
diff --git a/spec/frontend/pipelines/components/jobs/failed_jobs_app_spec.js b/spec/frontend/pipelines/components/jobs/failed_jobs_app_spec.js
new file mode 100644
index 00000000000..3b5632a8a4e
--- /dev/null
+++ b/spec/frontend/pipelines/components/jobs/failed_jobs_app_spec.js
@@ -0,0 +1,87 @@
+import { GlLoadingIcon } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import Vue from 'vue';
+import VueApollo from 'vue-apollo';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import waitForPromises from 'helpers/wait_for_promises';
+import createFlash from '~/flash';
+import FailedJobsApp from '~/pipelines/components/jobs/failed_jobs_app.vue';
+import FailedJobsTable from '~/pipelines/components/jobs/failed_jobs_table.vue';
+import GetFailedJobsQuery from '~/pipelines/graphql/queries/get_failed_jobs.query.graphql';
+import { mockFailedJobsQueryResponse, mockFailedJobsSummaryData } from '../../mock_data';
+
+Vue.use(VueApollo);
+
+jest.mock('~/flash');
+
+describe('Failed Jobs App', () => {
+ let wrapper;
+ let resolverSpy;
+
+ const findLoadingSpinner = () => wrapper.findComponent(GlLoadingIcon);
+ const findJobsTable = () => wrapper.findComponent(FailedJobsTable);
+
+ const createMockApolloProvider = (resolver) => {
+ const requestHandlers = [[GetFailedJobsQuery, resolver]];
+
+ return createMockApollo(requestHandlers);
+ };
+
+ const createComponent = (resolver, failedJobsSummaryData = mockFailedJobsSummaryData) => {
+ wrapper = shallowMount(FailedJobsApp, {
+ provide: {
+ fullPath: 'root/ci-project',
+ pipelineIid: 1,
+ },
+ propsData: {
+ failedJobsSummary: failedJobsSummaryData,
+ },
+ apolloProvider: createMockApolloProvider(resolver),
+ });
+ };
+
+ beforeEach(() => {
+ resolverSpy = jest.fn().mockResolvedValue(mockFailedJobsQueryResponse);
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('loading spinner', () => {
+ beforeEach(() => {
+ createComponent(resolverSpy);
+ });
+
+ it('displays loading spinner when fetching failed jobs', () => {
+ expect(findLoadingSpinner().exists()).toBe(true);
+ });
+
+ it('hides loading spinner after the failed jobs have been fetched', async () => {
+ await waitForPromises();
+
+ expect(findLoadingSpinner().exists()).toBe(false);
+ });
+ });
+
+ it('displays the failed jobs table', async () => {
+ createComponent(resolverSpy);
+
+ await waitForPromises();
+
+ expect(findJobsTable().exists()).toBe(true);
+ expect(createFlash).not.toHaveBeenCalled();
+ });
+
+ it('handles query fetch error correctly', async () => {
+ resolverSpy = jest.fn().mockRejectedValue(new Error('GraphQL error'));
+
+ createComponent(resolverSpy);
+
+ await waitForPromises();
+
+ expect(createFlash).toHaveBeenCalledWith({
+ message: 'There was a problem fetching the failed jobs.',
+ });
+ });
+});
diff --git a/spec/frontend/pipelines/components/jobs/failed_jobs_table_spec.js b/spec/frontend/pipelines/components/jobs/failed_jobs_table_spec.js
new file mode 100644
index 00000000000..b597a3bf4b0
--- /dev/null
+++ b/spec/frontend/pipelines/components/jobs/failed_jobs_table_spec.js
@@ -0,0 +1,117 @@
+import { GlButton, GlLink, GlTableLite } from '@gitlab/ui';
+import Vue from 'vue';
+import VueApollo from 'vue-apollo';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import waitForPromises from 'helpers/wait_for_promises';
+import { mountExtended } from 'helpers/vue_test_utils_helper';
+import createFlash from '~/flash';
+import { redirectTo } from '~/lib/utils/url_utility';
+import FailedJobsTable from '~/pipelines/components/jobs/failed_jobs_table.vue';
+import RetryFailedJobMutation from '~/pipelines/graphql/mutations/retry_failed_job.mutation.graphql';
+import {
+ successRetryMutationResponse,
+ failedRetryMutationResponse,
+ mockPreparedFailedJobsData,
+ mockPreparedFailedJobsDataNoPermission,
+} from '../../mock_data';
+
+jest.mock('~/flash');
+jest.mock('~/lib/utils/url_utility');
+
+Vue.use(VueApollo);
+
+describe('Failed Jobs Table', () => {
+ let wrapper;
+
+ const successRetryMutationHandler = jest.fn().mockResolvedValue(successRetryMutationResponse);
+ const failedRetryMutationHandler = jest.fn().mockResolvedValue(failedRetryMutationResponse);
+
+ const findJobsTable = () => wrapper.findComponent(GlTableLite);
+ const findRetryButton = () => wrapper.findComponent(GlButton);
+ const findJobLink = () => wrapper.findComponent(GlLink);
+ const findJobLog = () => wrapper.findByTestId('job-log');
+
+ const createMockApolloProvider = (resolver) => {
+ const requestHandlers = [[RetryFailedJobMutation, resolver]];
+ return createMockApollo(requestHandlers);
+ };
+
+ const createComponent = (resolver, failedJobsData = mockPreparedFailedJobsData) => {
+ wrapper = mountExtended(FailedJobsTable, {
+ propsData: {
+ failedJobs: failedJobsData,
+ },
+ apolloProvider: createMockApolloProvider(resolver),
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('displays the failed jobs table', () => {
+ createComponent();
+
+ expect(findJobsTable().exists()).toBe(true);
+ });
+
+ it('calls the retry failed job mutation correctly', () => {
+ createComponent(successRetryMutationHandler);
+
+ findRetryButton().trigger('click');
+
+ expect(successRetryMutationHandler).toHaveBeenCalledWith({
+ id: mockPreparedFailedJobsData[0].id,
+ });
+ });
+
+ it('redirects to the new job after the mutation', async () => {
+ const {
+ data: {
+ jobRetry: { job },
+ },
+ } = successRetryMutationResponse;
+
+ createComponent(successRetryMutationHandler);
+
+ findRetryButton().trigger('click');
+
+ await waitForPromises();
+
+ expect(redirectTo).toHaveBeenCalledWith(job.detailedStatus.detailsPath);
+ });
+
+ it('shows error message if the retry failed job mutation fails', async () => {
+ createComponent(failedRetryMutationHandler);
+
+ findRetryButton().trigger('click');
+
+ await waitForPromises();
+
+ expect(createFlash).toHaveBeenCalledWith({
+ message: 'There was a problem retrying the failed job.',
+ });
+ });
+
+ it('hides the job log and retry button if a user does not have permission', () => {
+ createComponent([[]], mockPreparedFailedJobsDataNoPermission);
+
+ expect(findJobLog().exists()).toBe(false);
+ expect(findRetryButton().exists()).toBe(false);
+ });
+
+ it('displays the job log and retry button if a user has permission', () => {
+ createComponent();
+
+ expect(findJobLog().exists()).toBe(true);
+ expect(findRetryButton().exists()).toBe(true);
+ });
+
+ it('job name links to the correct job', () => {
+ createComponent();
+
+ expect(findJobLink().attributes('href')).toBe(
+ mockPreparedFailedJobsData[0].detailedStatus.detailsPath,
+ );
+ });
+});
diff --git a/spec/frontend/pipelines/components/jobs/utils_spec.js b/spec/frontend/pipelines/components/jobs/utils_spec.js
new file mode 100644
index 00000000000..720446cfda3
--- /dev/null
+++ b/spec/frontend/pipelines/components/jobs/utils_spec.js
@@ -0,0 +1,14 @@
+import { prepareFailedJobs } from '~/pipelines/components/jobs/utils';
+import {
+ mockFailedJobsData,
+ mockFailedJobsSummaryData,
+ mockPreparedFailedJobsData,
+} from '../../mock_data';
+
+describe('Utils', () => {
+ it('prepares failed jobs data correctly', () => {
+ expect(prepareFailedJobs(mockFailedJobsData, mockFailedJobsSummaryData)).toEqual(
+ mockPreparedFailedJobsData,
+ );
+ });
+});
diff --git a/spec/frontend/pipelines/mock_data.js b/spec/frontend/pipelines/mock_data.js
index 59d4e808b32..57d1511d859 100644
--- a/spec/frontend/pipelines/mock_data.js
+++ b/spec/frontend/pipelines/mock_data.js
@@ -1141,3 +1141,218 @@ export const mockPipelineBranch = () => {
viewType: 'root',
};
};
+
+export const mockFailedJobsQueryResponse = {
+ data: {
+ project: {
+ __typename: 'Project',
+ id: 'gid://gitlab/Project/20',
+ pipeline: {
+ __typename: 'Pipeline',
+ id: 'gid://gitlab/Ci::Pipeline/300',
+ jobs: {
+ __typename: 'CiJobConnection',
+ nodes: [
+ {
+ __typename: 'CiJob',
+ status: 'FAILED',
+ detailedStatus: {
+ __typename: 'DetailedStatus',
+ id: 'failed-1848-1848',
+ detailsPath: '/root/ci-project/-/jobs/1848',
+ group: 'failed',
+ icon: 'status_failed',
+ label: 'failed',
+ text: 'failed',
+ tooltip: 'failed - (script failure)',
+ action: {
+ __typename: 'StatusAction',
+ id: 'Ci::Build-failed-1848',
+ buttonTitle: 'Retry this job',
+ icon: 'retry',
+ method: 'post',
+ path: '/root/ci-project/-/jobs/1848/retry',
+ title: 'Retry',
+ },
+ },
+ id: 'gid://gitlab/Ci::Build/1848',
+ stage: {
+ __typename: 'CiStage',
+ id: 'gid://gitlab/Ci::Stage/358',
+ name: 'build',
+ },
+ name: 'wait_job',
+ retryable: true,
+ userPermissions: {
+ __typename: 'JobPermissions',
+ readBuild: true,
+ updateBuild: true,
+ },
+ },
+ {
+ __typename: 'CiJob',
+ status: 'FAILED',
+ detailedStatus: {
+ __typename: 'DetailedStatus',
+ id: 'failed-1710-1710',
+ detailsPath: '/root/ci-project/-/jobs/1710',
+ group: 'failed',
+ icon: 'status_failed',
+ label: 'failed',
+ text: 'failed',
+ tooltip: 'failed - (script failure) (retried)',
+ action: null,
+ },
+ id: 'gid://gitlab/Ci::Build/1710',
+ stage: {
+ __typename: 'CiStage',
+ id: 'gid://gitlab/Ci::Stage/358',
+ name: 'build',
+ },
+ name: 'wait_job',
+ retryable: false,
+ userPermissions: {
+ __typename: 'JobPermissions',
+ readBuild: true,
+ updateBuild: true,
+ },
+ },
+ ],
+ },
+ },
+ },
+ },
+};
+
+export const mockFailedJobsSummaryData = [
+ {
+ id: 1848,
+ failure: null,
+ failure_summary:
+ '<span>Pulling docker image node:latest ...<br/></span><span>Using docker image sha256:738d733448be00c72cb6618b7a06a1424806c6d239d8885e92f9b1e8727092b5 for node:latest with digest node@sha256:e5b7b349d517159246070bf14242027a9e220ffa8bd98a67ba1495d969c06c01 ...<br/></span><div class="section-start" data-timestamp="1651175313" data-section="prepare-script" role="button"></div><span class="term-fg-l-cyan term-bold section section-header js-s-prepare-script">Preparing environment</span><span class="section section-header js-s-prepare-script"><br/></span><span class="section line js-s-prepare-script">Running on runner-kvkqh24-project-20-concurrent-0 via 0706719b1b8d...<br/></span><div class="section-end" data-section="prepare-script"></div><div class="section-start" data-timestamp="1651175313" data-section="get-sources" role="button"></div><span class="term-fg-l-cyan term-bold section section-header js-s-get-sources">Getting source from Git repository</span><span class="section section-header js-s-get-sources"><br/></span><span class="term-fg-l-green term-bold section line js-s-get-sources">Fetching changes with git depth set to 50...</span><span class="section line js-s-get-sources"><br/>Reinitialized existing Git repository in /builds/root/ci-project/.git/<br/>fatal: couldn\'t find remote ref refs/heads/test<br/></span><div class="section-end" data-section="get-sources"></div><span class="term-fg-l-red term-bold">ERROR: Job failed: exit code 1<br/></span>',
+ },
+];
+
+export const mockFailedJobsData = [
+ {
+ normalizedId: 1848,
+ __typename: 'CiJob',
+ status: 'FAILED',
+ detailedStatus: {
+ __typename: 'DetailedStatus',
+ id: 'failed-1848-1848',
+ detailsPath: '/root/ci-project/-/jobs/1848',
+ group: 'failed',
+ icon: 'status_failed',
+ label: 'failed',
+ text: 'failed',
+ tooltip: 'failed - (script failure)',
+ action: {
+ __typename: 'StatusAction',
+ id: 'Ci::Build-failed-1848',
+ buttonTitle: 'Retry this job',
+ icon: 'retry',
+ method: 'post',
+ path: '/root/ci-project/-/jobs/1848/retry',
+ title: 'Retry',
+ },
+ },
+ id: 'gid://gitlab/Ci::Build/1848',
+ stage: { __typename: 'CiStage', id: 'gid://gitlab/Ci::Stage/358', name: 'build' },
+ name: 'wait_job',
+ retryable: true,
+ userPermissions: { __typename: 'JobPermissions', readBuild: true, updateBuild: true },
+ },
+ {
+ normalizedId: 1710,
+ __typename: 'CiJob',
+ status: 'FAILED',
+ detailedStatus: {
+ __typename: 'DetailedStatus',
+ id: 'failed-1710-1710',
+ detailsPath: '/root/ci-project/-/jobs/1710',
+ group: 'failed',
+ icon: 'status_failed',
+ label: 'failed',
+ text: 'failed',
+ tooltip: 'failed - (script failure) (retried)',
+ action: null,
+ },
+ id: 'gid://gitlab/Ci::Build/1710',
+ stage: { __typename: 'CiStage', id: 'gid://gitlab/Ci::Stage/358', name: 'build' },
+ name: 'wait_job',
+ retryable: false,
+ userPermissions: { __typename: 'JobPermissions', readBuild: true, updateBuild: true },
+ },
+];
+
+export const mockPreparedFailedJobsData = [
+ {
+ __typename: 'CiJob',
+ _showDetails: true,
+ detailedStatus: {
+ __typename: 'DetailedStatus',
+ action: {
+ __typename: 'StatusAction',
+ buttonTitle: 'Retry this job',
+ icon: 'retry',
+ id: 'Ci::Build-failed-1848',
+ method: 'post',
+ path: '/root/ci-project/-/jobs/1848/retry',
+ title: 'Retry',
+ },
+ detailsPath: '/root/ci-project/-/jobs/1848',
+ group: 'failed',
+ icon: 'status_failed',
+ id: 'failed-1848-1848',
+ label: 'failed',
+ text: 'failed',
+ tooltip: 'failed - (script failure)',
+ },
+ failure: null,
+ failureSummary:
+ '<span>Pulling docker image node:latest ...<br/></span><span>Using docker image sha256:738d733448be00c72cb6618b7a06a1424806c6d239d8885e92f9b1e8727092b5 for node:latest with digest node@sha256:e5b7b349d517159246070bf14242027a9e220ffa8bd98a67ba1495d969c06c01 ...<br/></span><div class="section-start" data-timestamp="1651175313" data-section="prepare-script" role="button"></div><span class="term-fg-l-cyan term-bold section section-header js-s-prepare-script">Preparing environment</span><span class="section section-header js-s-prepare-script"><br/></span><span class="section line js-s-prepare-script">Running on runner-kvkqh24-project-20-concurrent-0 via 0706719b1b8d...<br/></span><div class="section-end" data-section="prepare-script"></div><div class="section-start" data-timestamp="1651175313" data-section="get-sources" role="button"></div><span class="term-fg-l-cyan term-bold section section-header js-s-get-sources">Getting source from Git repository</span><span class="section section-header js-s-get-sources"><br/></span><span class="term-fg-l-green term-bold section line js-s-get-sources">Fetching changes with git depth set to 50...</span><span class="section line js-s-get-sources"><br/>Reinitialized existing Git repository in /builds/root/ci-project/.git/<br/>fatal: couldn\'t find remote ref refs/heads/test<br/></span><div class="section-end" data-section="get-sources"></div><span class="term-fg-l-red term-bold">ERROR: Job failed: exit code 1<br/></span>',
+ id: 'gid://gitlab/Ci::Build/1848',
+ name: 'wait_job',
+ normalizedId: 1848,
+ retryable: true,
+ stage: { __typename: 'CiStage', id: 'gid://gitlab/Ci::Stage/358', name: 'build' },
+ status: 'FAILED',
+ userPermissions: { __typename: 'JobPermissions', readBuild: true, updateBuild: true },
+ },
+];
+
+export const mockPreparedFailedJobsDataNoPermission = [
+ {
+ ...mockPreparedFailedJobsData[0],
+ userPermissions: { __typename: 'JobPermissions', readBuild: false, updateBuild: false },
+ },
+];
+
+export const successRetryMutationResponse = {
+ data: {
+ jobRetry: {
+ job: {
+ __typename: 'CiJob',
+ id: '"gid://gitlab/Ci::Build/1985"',
+ detailedStatus: {
+ detailsPath: '/root/project/-/jobs/1985',
+ id: 'pending-1985-1985',
+ __typename: 'DetailedStatus',
+ },
+ },
+ errors: [],
+ __typename: 'JobRetryPayload',
+ },
+ },
+};
+
+export const failedRetryMutationResponse = {
+ data: {
+ jobRetry: {
+ job: {},
+ errors: ['New Error'],
+ __typename: 'JobRetryPayload',
+ },
+ },
+};
diff --git a/spec/graphql/types/ci/runner_type_spec.rb b/spec/graphql/types/ci/runner_type_spec.rb
index 7697cd0ef79..b2fbfda898e 100644
--- a/spec/graphql/types/ci/runner_type_spec.rb
+++ b/spec/graphql/types/ci/runner_type_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe GitlabSchema.types['CiRunner'] do
expected_fields = %w[
id description created_at contacted_at maximum_timeout access_level active paused status
version short_sha revision locked run_untagged ip_address runner_type tag_list
- project_count job_count admin_url edit_admin_url user_permissions executor_name
+ project_count job_count admin_url edit_admin_url user_permissions executor_name architecture_name platform_name
groups projects jobs token_expires_at
]
diff --git a/spec/helpers/ci/builds_helper_spec.rb b/spec/helpers/ci/builds_helper_spec.rb
index 143d96cf632..ea3b5aac4ea 100644
--- a/spec/helpers/ci/builds_helper_spec.rb
+++ b/spec/helpers/ci/builds_helper_spec.rb
@@ -97,6 +97,20 @@ RSpec.describe Ci::BuildsHelper do
end
end
+ describe '#prepare_failed_jobs_summary_data' do
+ let(:failed_build) { create(:ci_build, :failed, :trace_live) }
+
+ subject { helper.prepare_failed_jobs_summary_data([failed_build]) }
+
+ it 'returns array of failed jobs with id, failure and failure summary' do
+ expect(subject).to eq([{
+ id: failed_build.id,
+ failure: failed_build.present.callout_failure_message,
+ failure_summary: helper.build_summary(failed_build)
+ }].to_json)
+ end
+ end
+
def assign_project
build(:project).tap do |project|
assign(:project, project)
diff --git a/spec/lib/gitlab/background_migration/extract_project_topics_into_separate_table_spec.rb b/spec/lib/gitlab/background_migration/extract_project_topics_into_separate_table_spec.rb
index a111007a984..65d55f85a98 100644
--- a/spec/lib/gitlab/background_migration/extract_project_topics_into_separate_table_spec.rb
+++ b/spec/lib/gitlab/background_migration/extract_project_topics_into_separate_table_spec.rb
@@ -29,7 +29,7 @@ RSpec.describe Gitlab::BackgroundMigration::ExtractProjectTopicsIntoSeparateTabl
# Tagging records
expect { tagging_1.reload }.to raise_error(ActiveRecord::RecordNotFound)
expect { tagging_2.reload }.to raise_error(ActiveRecord::RecordNotFound)
- expect { other_tagging.reload }.not_to raise_error(ActiveRecord::RecordNotFound)
+ expect { other_tagging.reload }.not_to raise_error
expect { tagging_3.reload }.to raise_error(ActiveRecord::RecordNotFound)
expect { tagging_4.reload }.to raise_error(ActiveRecord::RecordNotFound)
expect { tagging_5.reload }.to raise_error(ActiveRecord::RecordNotFound)
diff --git a/spec/lib/gitlab/checks/branch_check_spec.rb b/spec/lib/gitlab/checks/branch_check_spec.rb
index c06d26d1441..d6280d3c28c 100644
--- a/spec/lib/gitlab/checks/branch_check_spec.rb
+++ b/spec/lib/gitlab/checks/branch_check_spec.rb
@@ -103,7 +103,7 @@ RSpec.describe Gitlab::Checks::BranchCheck do
it 'prevents force push' do
expect(Gitlab::Checks::ForcePush).to receive(:force_push?).and_return(true)
- expect { subject.validate! }.to raise_error
+ expect { subject.validate! }.to raise_error(Gitlab::GitAccess::ForbiddenError)
end
end
end
@@ -126,7 +126,7 @@ RSpec.describe Gitlab::Checks::BranchCheck do
it 'prevents force push' do
expect(Gitlab::Checks::ForcePush).to receive(:force_push?).and_return(true)
- expect { subject.validate! }.to raise_error
+ expect { subject.validate! }.to raise_error(Gitlab::GitAccess::ForbiddenError)
end
end
@@ -141,7 +141,7 @@ RSpec.describe Gitlab::Checks::BranchCheck do
it 'prevents force push' do
expect(Gitlab::Checks::ForcePush).to receive(:force_push?).and_return(true)
- expect { subject.validate! }.to raise_error
+ expect { subject.validate! }.to raise_error(Gitlab::GitAccess::ForbiddenError)
end
end
end
diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb
index 28fd0011673..fd80cf3b396 100644
--- a/spec/lib/gitlab/database/migration_helpers_spec.rb
+++ b/spec/lib/gitlab/database/migration_helpers_spec.rb
@@ -3180,15 +3180,15 @@ RSpec.describe Gitlab::Database::MigrationHelpers do
context 'without proper permissions' do
before do
- allow(model).to receive(:execute).with(/CREATE EXTENSION IF NOT EXISTS #{extension}/).and_raise(ActiveRecord::StatementInvalid, 'InsufficientPrivilege: permission denied')
+ allow(model).to receive(:execute)
+ .with(/CREATE EXTENSION IF NOT EXISTS #{extension}/)
+ .and_raise(ActiveRecord::StatementInvalid, 'InsufficientPrivilege: permission denied')
end
- it 'raises the exception' do
- expect { subject }.to raise_error(ActiveRecord::StatementInvalid, /InsufficientPrivilege/)
- end
-
- it 'prints an error message' do
- expect { subject }.to output(/user is not allowed/).to_stderr.and raise_error
+ it 'raises an exception and prints an error message' do
+ expect { subject }
+ .to output(/user is not allowed/).to_stderr
+ .and raise_error(ActiveRecord::StatementInvalid, /InsufficientPrivilege/)
end
end
end
@@ -3206,15 +3206,15 @@ RSpec.describe Gitlab::Database::MigrationHelpers do
context 'without proper permissions' do
before do
- allow(model).to receive(:execute).with(/DROP EXTENSION IF EXISTS #{extension}/).and_raise(ActiveRecord::StatementInvalid, 'InsufficientPrivilege: permission denied')
- end
-
- it 'raises the exception' do
- expect { subject }.to raise_error(ActiveRecord::StatementInvalid, /InsufficientPrivilege/)
+ allow(model).to receive(:execute)
+ .with(/DROP EXTENSION IF EXISTS #{extension}/)
+ .and_raise(ActiveRecord::StatementInvalid, 'InsufficientPrivilege: permission denied')
end
- it 'prints an error message' do
- expect { subject }.to output(/user is not allowed/).to_stderr.and raise_error
+ it 'raises an exception and prints an error message' do
+ expect { subject }
+ .to output(/user is not allowed/).to_stderr
+ .and raise_error(ActiveRecord::StatementInvalid, /InsufficientPrivilege/)
end
end
end
diff --git a/spec/lib/gitlab/email/handler/create_note_handler_spec.rb b/spec/lib/gitlab/email/handler/create_note_handler_spec.rb
index 59b87c5d8e7..9ff395070ea 100644
--- a/spec/lib/gitlab/email/handler/create_note_handler_spec.rb
+++ b/spec/lib/gitlab/email/handler/create_note_handler_spec.rb
@@ -62,7 +62,7 @@ RSpec.describe Gitlab::Email::Handler::CreateNoteHandler do
end
it 'does not raise a UserNotFoundError' do
- expect { receiver.execute }.not_to raise_error(Gitlab::Email::UserNotFoundError)
+ expect { receiver.execute }.not_to raise_error
end
end
end
@@ -71,7 +71,7 @@ RSpec.describe Gitlab::Email::Handler::CreateNoteHandler do
let(:original_recipient) { User.support_bot }
it 'does not raise a UserNotFoundError' do
- expect { receiver.execute }.not_to raise_error(Gitlab::Email::UserNotFoundError)
+ expect { receiver.execute }.not_to raise_error
end
end
end
diff --git a/spec/lib/gitlab/email/message/in_product_marketing/base_spec.rb b/spec/lib/gitlab/email/message/in_product_marketing/base_spec.rb
index 8bd873cf008..dfa18c27d5e 100644
--- a/spec/lib/gitlab/email/message/in_product_marketing/base_spec.rb
+++ b/spec/lib/gitlab/email/message/in_product_marketing/base_spec.rb
@@ -24,7 +24,7 @@ RSpec.describe Gitlab::Email::Message::InProductMarketing::Base do
let(:series) { 0 }
it 'does not raise error' do
- expect { subject }.not_to raise_error(ArgumentError)
+ expect { subject }.not_to raise_error
end
end
end
diff --git a/spec/lib/gitlab/git/diff_spec.rb b/spec/lib/gitlab/git/diff_spec.rb
index 4c47912e218..2c931a999f1 100644
--- a/spec/lib/gitlab/git/diff_spec.rb
+++ b/spec/lib/gitlab/git/diff_spec.rb
@@ -177,9 +177,9 @@ EOT
expect(diff_two.diff).to include(Gitlab::EncodingHelper::UNICODE_REPLACEMENT_CHARACTER)
expect(diff_three.diff).to include(Gitlab::EncodingHelper::UNICODE_REPLACEMENT_CHARACTER)
- expect { Oj.dump(diff) }.not_to raise_error(EncodingError)
- expect { Oj.dump(diff_two) }.not_to raise_error(EncodingError)
- expect { Oj.dump(diff_three) }.not_to raise_error(EncodingError)
+ expect { Oj.dump(diff) }.not_to raise_error
+ expect { Oj.dump(diff_two) }.not_to raise_error
+ expect { Oj.dump(diff_three) }.not_to raise_error
end
context 'when the diff is binary' do
diff --git a/spec/lib/gitlab/popen_spec.rb b/spec/lib/gitlab/popen_spec.rb
index 8211806a809..0a186b07d19 100644
--- a/spec/lib/gitlab/popen_spec.rb
+++ b/spec/lib/gitlab/popen_spec.rb
@@ -103,7 +103,7 @@ RSpec.describe Gitlab::Popen do
it 'raises error' do
expect do
@klass.new.popen(%w[foobar])
- end.to raise_error
+ end.to raise_error(Errno::ENOENT)
end
end
end
diff --git a/spec/lib/gitlab/tracking/event_definition_spec.rb b/spec/lib/gitlab/tracking/event_definition_spec.rb
index 51c62840819..623009e9a30 100644
--- a/spec/lib/gitlab/tracking/event_definition_spec.rb
+++ b/spec/lib/gitlab/tracking/event_definition_spec.rb
@@ -33,7 +33,7 @@ RSpec.describe Gitlab::Tracking::EventDefinition do
end
it 'has all definitions valid' do
- expect { described_class.definitions }.not_to raise_error(Gitlab::Tracking::InvalidEventError)
+ expect { described_class.definitions }.not_to raise_error
end
describe '#validate' do
diff --git a/spec/migrations/finalize_project_namespaces_backfill_spec.rb b/spec/migrations/finalize_project_namespaces_backfill_spec.rb
index 3d0b0ec13fe..f70f1612f9d 100644
--- a/spec/migrations/finalize_project_namespaces_backfill_spec.rb
+++ b/spec/migrations/finalize_project_namespaces_backfill_spec.rb
@@ -42,7 +42,7 @@ RSpec.describe FinalizeProjectNamespacesBackfill, :migration do
context 'when project namespace backfilling migration finished successfully' do
it 'does not raise exception' do
- expect { migrate! }.not_to raise_error(/Expected batched background migration for the given configuration to be marked as 'finished'/)
+ expect { migrate! }.not_to raise_error
end
end
diff --git a/spec/models/clusters/platforms/kubernetes_spec.rb b/spec/models/clusters/platforms/kubernetes_spec.rb
index 8c0f07047e4..a0ede9fb0d9 100644
--- a/spec/models/clusters/platforms/kubernetes_spec.rb
+++ b/spec/models/clusters/platforms/kubernetes_spec.rb
@@ -494,7 +494,7 @@ RSpec.describe Clusters::Platforms::Kubernetes do
end
it 'does not raise kubeclient http error' do
- expect { subject }.not_to raise_error(Kubeclient::HttpError)
+ expect { subject }.not_to raise_error
end
end
diff --git a/spec/models/concerns/reactive_caching_spec.rb b/spec/models/concerns/reactive_caching_spec.rb
index 4f3b95e43cd..5468699f9dd 100644
--- a/spec/models/concerns/reactive_caching_spec.rb
+++ b/spec/models/concerns/reactive_caching_spec.rb
@@ -237,7 +237,7 @@ RSpec.describe ReactiveCaching, :use_clean_rails_memory_store_caching do
end
it 'does not raise the exception' do
- expect { go! }.not_to raise_exception(ReactiveCaching::ExceededReactiveCacheLimit)
+ expect { go! }.not_to raise_exception
end
end
diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb
index 3cab2b67ec5..2769e94cef7 100644
--- a/spec/models/environment_spec.rb
+++ b/spec/models/environment_spec.rb
@@ -621,7 +621,7 @@ RSpec.describe Environment, :use_clean_rails_memory_store_caching do
expect(close_action.processed).to be_falsey
# it encounters the StaleObjectError at first, but reloads the object and runs `build.play`
- expect { subject }.not_to raise_error(ActiveRecord::StaleObjectError)
+ expect { subject }.not_to raise_error
# Now the build should be processed.
expect(close_action.reload.processed).to be_truthy
diff --git a/spec/models/integration_spec.rb b/spec/models/integration_spec.rb
index b7f75bfe8bf..7d4a50788f3 100644
--- a/spec/models/integration_spec.rb
+++ b/spec/models/integration_spec.rb
@@ -681,7 +681,7 @@ RSpec.describe Integration do
integration.properties = { foo: 1, bar: 2 }
- expect { integration.properties[:foo] = 3 }.to raise_error
+ expect { integration.properties[:foo] = 3 }.to raise_error(FrozenError)
end
end
diff --git a/spec/models/packages/package_spec.rb b/spec/models/packages/package_spec.rb
index 6c86db1197f..a9ed811e77d 100644
--- a/spec/models/packages/package_spec.rb
+++ b/spec/models/packages/package_spec.rb
@@ -1182,7 +1182,7 @@ RSpec.describe Packages::Package, type: :model do
it "plan_limits includes column #{plan_limit_name}" do
expect { package.project.actual_limits.send(plan_limit_name) }
- .not_to raise_error(NoMethodError)
+ .not_to raise_error
end
end
end
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 42fe9f03141..d315b62b23e 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -2030,7 +2030,7 @@ RSpec.describe Project, factory_default: :keep do
it 'returns nil if the path detection throws an error' do
expect(Rails.application.routes).to receive(:recognize_path).with(url) { raise ActionController::RoutingError, 'test' }
- expect { subject }.not_to raise_error(ActionController::RoutingError)
+ expect { subject }.not_to raise_error
expect(subject).to be_nil
end
end
diff --git a/spec/models/protected_branch/push_access_level_spec.rb b/spec/models/protected_branch/push_access_level_spec.rb
index 13d33b95b16..008ae6275f0 100644
--- a/spec/models/protected_branch/push_access_level_spec.rb
+++ b/spec/models/protected_branch/push_access_level_spec.rb
@@ -30,7 +30,7 @@ RSpec.describe ProtectedBranch::PushAccessLevel do
it 'checks that a deploy key is enabled for the same project as the protected branch\'s' do
level = build(:protected_branch_push_access_level, deploy_key: create(:deploy_key))
- expect { level.save! }.to raise_error
+ expect { level.save! }.to raise_error(ActiveRecord::RecordInvalid)
expect(level.errors.full_messages).to contain_exactly('Deploy key is not enabled for this project')
end
end
diff --git a/spec/models/release_spec.rb b/spec/models/release_spec.rb
index 125fec61d72..4ae1927dcca 100644
--- a/spec/models/release_spec.rb
+++ b/spec/models/release_spec.rb
@@ -53,7 +53,10 @@ RSpec.describe Release do
context 'when a release is tied to a milestone for another project' do
it 'creates a validation error' do
milestone = build(:milestone, project: create(:project))
- expect { release.milestones << milestone }.to raise_error
+
+ expect { release.milestones << milestone }
+ .to raise_error(ActiveRecord::RecordInvalid,
+ 'Validation failed: Release does not have the same project as the milestone')
end
end
diff --git a/spec/requests/api/graphql/ci/runner_spec.rb b/spec/requests/api/graphql/ci/runner_spec.rb
index 6102e15012b..542876438cc 100644
--- a/spec/requests/api/graphql/ci/runner_spec.rb
+++ b/spec/requests/api/graphql/ci/runner_spec.rb
@@ -62,6 +62,8 @@ RSpec.describe 'Query.runner(id)' do
'ipAddress' => runner.ip_address,
'runnerType' => runner.instance_type? ? 'INSTANCE_TYPE' : 'PROJECT_TYPE',
'executorName' => runner.executor_type&.dasherize,
+ 'architectureName' => runner.architecture,
+ 'platformName' => runner.platform,
'jobCount' => 0,
'jobs' => a_hash_including("count" => 0, "nodes" => [], "pageInfo" => anything),
'projectCount' => nil,
diff --git a/spec/requests/api/graphql/mutations/clusters/agents/delete_spec.rb b/spec/requests/api/graphql/mutations/clusters/agents/delete_spec.rb
index 5f6822223ca..4891e64aab8 100644
--- a/spec/requests/api/graphql/mutations/clusters/agents/delete_spec.rb
+++ b/spec/requests/api/graphql/mutations/clusters/agents/delete_spec.rb
@@ -26,7 +26,7 @@ RSpec.describe 'Delete a cluster agent' do
'or you don\'t have permission to perform this action']
it 'does not delete cluster agent' do
- expect { cluster_agent.reload }.not_to raise_error(ActiveRecord::RecordNotFound)
+ expect { cluster_agent.reload }.not_to raise_error
end
end
diff --git a/spec/requests/api/graphql/project/merge_requests_spec.rb b/spec/requests/api/graphql/project/merge_requests_spec.rb
index c7f121c48ab..d69f542cd18 100644
--- a/spec/requests/api/graphql/project/merge_requests_spec.rb
+++ b/spec/requests/api/graphql/project/merge_requests_spec.rb
@@ -506,10 +506,12 @@ RSpec.describe 'getting merge request listings nested in a project' do
end
context 'when only the count is requested' do
+ let_it_be(:merged_at) { Time.new(2020, 1, 3) }
+
context 'when merged at filter is present' do
let_it_be(:merge_request) do
create(:merge_request, :unique_branches, source_project: project).tap do |mr|
- mr.metrics.update!(merged_at: Time.new(2020, 1, 3))
+ mr.metrics.update!(merged_at: merged_at, created_at: merged_at - 2.days)
end
end
@@ -526,12 +528,18 @@ RSpec.describe 'getting merge request listings nested in a project' do
it 'does not query the merge requests table for the count' do
query_recorder = ActiveRecord::QueryRecorder.new { post_graphql(query, current_user: current_user) }
- queries = query_recorder.data.each_value.first[:occurrences]
+ queries = query_recorder.log
expect(queries).not_to include(match(/SELECT COUNT\(\*\) FROM "merge_requests"/))
expect(queries).to include(match(/SELECT COUNT\(\*\) FROM "merge_request_metrics"/))
end
context 'when total_time_to_merge and count is queried' do
+ let_it_be(:merge_request_2) do
+ create(:merge_request, :unique_branches, source_project: project).tap do |mr|
+ mr.metrics.update!(merged_at: merged_at, created_at: merged_at - 1.day)
+ end
+ end
+
let(:query) do
graphql_query_for(:project, { full_path: project.full_path }, <<~QUERY)
mergeRequests(mergedAfter: "2020-01-01", mergedBefore: "2020-01-05", first: 0) {
@@ -541,11 +549,18 @@ RSpec.describe 'getting merge request listings nested in a project' do
QUERY
end
- it 'does not query the merge requests table for the total_time_to_merge' do
+ it 'uses the merge_request_metrics table for total_time_to_merge' do
query_recorder = ActiveRecord::QueryRecorder.new { post_graphql(query, current_user: current_user) }
- queries = query_recorder.data.each_value.first[:occurrences]
- expect(queries).to include(match(/SELECT.+SUM.+FROM "merge_request_metrics" WHERE/))
+ expect(query_recorder.log).to include(match(/SELECT.+SUM.+FROM "merge_request_metrics" WHERE/))
+ end
+
+ it 'returns the correct total time to merge' do
+ post_graphql(query, current_user: current_user)
+
+ sum = graphql_data_at(:project, :merge_requests, :total_time_to_merge)
+
+ expect(sum).to eq(3.days.to_f)
end
end
diff --git a/spec/services/ci/pipeline_artifacts/coverage_report_service_spec.rb b/spec/services/ci/pipeline_artifacts/coverage_report_service_spec.rb
index b48ea70aa4c..98b01e2b303 100644
--- a/spec/services/ci/pipeline_artifacts/coverage_report_service_spec.rb
+++ b/spec/services/ci/pipeline_artifacts/coverage_report_service_spec.rb
@@ -38,7 +38,7 @@ RSpec.describe ::Ci::PipelineArtifacts::CoverageReportService do
context 'when pipeline artifact has already been created' do
it 'do not raise an error and do not persist the same artifact twice' do
- expect { 2.times { described_class.new.execute(pipeline) } }.not_to raise_error(ActiveRecord::RecordNotUnique)
+ expect { 2.times { described_class.new.execute(pipeline) } }.not_to raise_error
expect(Ci::PipelineArtifact.count).to eq(1)
end
diff --git a/spec/services/clusters/agents/delete_service_spec.rb b/spec/services/clusters/agents/delete_service_spec.rb
index 1d6bc9618dd..abe1bdaab27 100644
--- a/spec/services/clusters/agents/delete_service_spec.rb
+++ b/spec/services/clusters/agents/delete_service_spec.rb
@@ -17,7 +17,7 @@ RSpec.describe Clusters::Agents::DeleteService do
expect(response.status).to eq(:error)
expect(response.message).to eq('You have insufficient permissions to delete this cluster agent')
- expect { cluster_agent.reload }.not_to raise_error(ActiveRecord::RecordNotFound)
+ expect { cluster_agent.reload }.not_to raise_error
end
end
diff --git a/spec/support/rspec.rb b/spec/support/rspec.rb
index b4a25fd121d..30e48b3baf1 100644
--- a/spec/support/rspec.rb
+++ b/spec/support/rspec.rb
@@ -14,6 +14,8 @@ require_relative "helpers/fast_rails_root"
require 'rubocop'
require 'rubocop/rspec/support'
+RSpec::Expectations.configuration.on_potential_false_positives = :raise
+
RSpec.configure do |config|
config.mock_with :rspec do |mocks|
mocks.verify_doubled_constant_names = true
diff --git a/spec/support/shared_contexts/email_shared_context.rb b/spec/support/shared_contexts/email_shared_context.rb
index 0dc66eeb2ee..086cdf50e9d 100644
--- a/spec/support/shared_contexts/email_shared_context.rb
+++ b/spec/support/shared_contexts/email_shared_context.rb
@@ -148,7 +148,7 @@ RSpec.shared_examples :note_handler_shared_examples do |forwardable|
end
it 'allows email to only have quoted text', if: forwardable do
- expect { receiver.execute }.not_to raise_error(Gitlab::Email::EmptyEmailError)
+ expect { receiver.execute }.not_to raise_error
end
end
diff --git a/spec/support_specs/helpers/active_record/query_recorder_spec.rb b/spec/support_specs/helpers/active_record/query_recorder_spec.rb
index f1af9ceffb9..d6c52b22449 100644
--- a/spec/support_specs/helpers/active_record/query_recorder_spec.rb
+++ b/spec/support_specs/helpers/active_record/query_recorder_spec.rb
@@ -78,12 +78,14 @@ RSpec.describe ActiveRecord::QueryRecorder do
end
describe 'detecting the right number of calls and their origin' do
- it 'detects two separate queries' do
- control = ActiveRecord::QueryRecorder.new query_recorder_debug: true do
+ let(:control) do
+ ActiveRecord::QueryRecorder.new query_recorder_debug: true do
2.times { TestQueries.count }
TestQueries.first
end
+ end
+ it 'detects two separate queries' do
# Check #find_query
expect(control.find_query(/.*/, 0).size)
.to eq(control.data.keys.size)
@@ -98,8 +100,8 @@ RSpec.describe ActiveRecord::QueryRecorder do
expect(control.log.size).to eq(3)
# Ensure memoization value match the raw value above
expect(control.count).to eq(control.log.size)
- # Ensure we have only two sources of queries
- expect(control.data.keys.size).to eq(1)
+ # Ensure we have two sources of queries
+ expect(control.data.keys.size).to eq(2)
end
end
end
diff --git a/spec/views/admin/application_settings/general.html.haml_spec.rb b/spec/views/admin/application_settings/general.html.haml_spec.rb
index 7d28175d134..503e41eabc9 100644
--- a/spec/views/admin/application_settings/general.html.haml_spec.rb
+++ b/spec/views/admin/application_settings/general.html.haml_spec.rb
@@ -6,13 +6,16 @@ RSpec.describe 'admin/application_settings/general.html.haml' do
let(:app_settings) { build(:application_setting) }
let(:user) { create(:admin) }
+ before do
+ assign(:application_setting, app_settings)
+ allow(view).to receive(:current_user).and_return(user)
+ end
+
describe 'sourcegraph integration' do
let(:sourcegraph_flag) { true }
before do
- assign(:application_setting, app_settings)
allow(Gitlab::Sourcegraph).to receive(:feature_available?).and_return(sourcegraph_flag)
- allow(view).to receive(:current_user).and_return(user)
end
context 'when sourcegraph feature is enabled' do
@@ -35,11 +38,6 @@ RSpec.describe 'admin/application_settings/general.html.haml' do
end
describe 'prompt user about registration features' do
- before do
- assign(:application_setting, app_settings)
- allow(view).to receive(:current_user).and_return(user)
- end
-
context 'when service ping is enabled' do
before do
stub_application_setting(usage_ping_enabled: true)
@@ -60,4 +58,14 @@ RSpec.describe 'admin/application_settings/general.html.haml' do
it_behaves_like 'renders registration features prompt', :application_setting_disabled_repository_size_limit
end
end
+
+ describe 'add license' do
+ before do
+ render
+ end
+
+ it 'does not show the Add License section' do
+ expect(rendered).not_to have_css('#js-add-license-toggle')
+ end
+ end
end
diff --git a/spec/views/projects/settings/operations/show.html.haml_spec.rb b/spec/views/projects/settings/operations/show.html.haml_spec.rb
index c0ec86a41a7..8853b34074a 100644
--- a/spec/views/projects/settings/operations/show.html.haml_spec.rb
+++ b/spec/views/projects/settings/operations/show.html.haml_spec.rb
@@ -52,30 +52,6 @@ RSpec.describe 'projects/settings/operations/show' do
end
end
- describe 'Operations > Prometheus' do
- context 'when settings_operations_prometheus_service flag is enabled' do
- it 'renders the Operations Settings page' do
- render
-
- expect(rendered).to have_content _('Prometheus')
- expect(rendered).to have_content _('Link Prometheus monitoring to GitLab.')
- expect(rendered).to have_content _('To use a Prometheus installed on a cluster, deactivate the manual configuration.')
- end
- end
-
- context 'when settings_operations_prometheus_service is disabled' do
- before do
- stub_feature_flags(settings_operations_prometheus_service: false)
- end
-
- it 'renders the Operations Settings page' do
- render
-
- expect(rendered).not_to have_content _('Auto configuration settings are used unless you override their values here.')
- end
- end
- end
-
describe 'Operations > Tracing' do
context 'Settings page ' do
it 'renders the Tracing Settings page' do
diff --git a/spec/workers/clusters/applications/activate_service_worker_spec.rb b/spec/workers/clusters/applications/activate_service_worker_spec.rb
index 019bfe7a750..d13ff76613c 100644
--- a/spec/workers/clusters/applications/activate_service_worker_spec.rb
+++ b/spec/workers/clusters/applications/activate_service_worker_spec.rb
@@ -46,7 +46,7 @@ RSpec.describe Clusters::Applications::ActivateServiceWorker, '#perform' do
context 'cluster does not exist' do
it 'does not raise Record Not Found error' do
- expect { described_class.new.perform(0, 'ignored in this context') }.not_to raise_error(ActiveRecord::RecordNotFound)
+ expect { described_class.new.perform(0, 'ignored in this context') }.not_to raise_error
end
end
end
diff --git a/spec/workers/delete_diff_files_worker_spec.rb b/spec/workers/delete_diff_files_worker_spec.rb
index cf26dbabb97..c124847ca45 100644
--- a/spec/workers/delete_diff_files_worker_spec.rb
+++ b/spec/workers/delete_diff_files_worker_spec.rb
@@ -34,11 +34,13 @@ RSpec.describe DeleteDiffFilesWorker do
end
it 'rollsback if something goes wrong' do
+ error = RuntimeError.new('something went wrong')
+
expect(MergeRequestDiffFile).to receive_message_chain(:where, :delete_all)
- .and_raise
+ .and_raise(error)
expect { described_class.new.perform(merge_request_diff.id) }
- .to raise_error
+ .to raise_error(error)
merge_request_diff.reload