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
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/vue_merge_request_widget')
-rw-r--r--spec/frontend/vue_merge_request_widget/components/mr_collapsible_extension_spec.js8
-rw-r--r--spec/frontend/vue_merge_request_widget/components/states/__snapshots__/mr_widget_auto_merge_enabled_spec.js.snap163
-rw-r--r--spec/frontend/vue_merge_request_widget/components/states/mr_widget_auto_merge_enabled_spec.js8
-rw-r--r--spec/frontend/vue_merge_request_widget/components/widget/widget_spec.js20
-rw-r--r--spec/frontend/vue_merge_request_widget/extensions/security_reports/mock_data.js141
-rw-r--r--spec/frontend/vue_merge_request_widget/extensions/security_reports/mr_widget_security_reports_spec.js93
-rw-r--r--spec/frontend/vue_merge_request_widget/extensions/test_report/index_spec.js28
-rw-r--r--spec/frontend/vue_merge_request_widget/extentions/accessibility/index_spec.js12
-rw-r--r--spec/frontend/vue_merge_request_widget/extentions/code_quality/index_spec.js75
-rw-r--r--spec/frontend/vue_merge_request_widget/extentions/code_quality/mock_data.js37
-rw-r--r--spec/frontend/vue_merge_request_widget/mr_widget_how_to_merge_modal_spec.js16
11 files changed, 373 insertions, 228 deletions
diff --git a/spec/frontend/vue_merge_request_widget/components/mr_collapsible_extension_spec.js b/spec/frontend/vue_merge_request_widget/components/mr_collapsible_extension_spec.js
index c253dc63f23..81f266d8070 100644
--- a/spec/frontend/vue_merge_request_widget/components/mr_collapsible_extension_spec.js
+++ b/spec/frontend/vue_merge_request_widget/components/mr_collapsible_extension_spec.js
@@ -42,8 +42,8 @@ describe('Merge Request Collapsible Extension', () => {
expect(wrapper.find('[data-testid="collapsed-header"]').text()).toBe('hello there');
});
- it('renders chevron-lg-right icon', () => {
- expect(findIcon().props('name')).toBe('chevron-lg-right');
+ it('renders chevron-right icon', () => {
+ expect(findIcon().props('name')).toBe('chevron-right');
});
describe('onClick', () => {
@@ -60,8 +60,8 @@ describe('Merge Request Collapsible Extension', () => {
expect(findTitle().text()).toBe('Collapse');
});
- it('renders chevron-lg-down icon', () => {
- expect(findIcon().props('name')).toBe('chevron-lg-down');
+ it('renders chevron-down icon', () => {
+ expect(findIcon().props('name')).toBe('chevron-down');
});
});
});
diff --git a/spec/frontend/vue_merge_request_widget/components/states/__snapshots__/mr_widget_auto_merge_enabled_spec.js.snap b/spec/frontend/vue_merge_request_widget/components/states/__snapshots__/mr_widget_auto_merge_enabled_spec.js.snap
deleted file mode 100644
index 4077564486c..00000000000
--- a/spec/frontend/vue_merge_request_widget/components/states/__snapshots__/mr_widget_auto_merge_enabled_spec.js.snap
+++ /dev/null
@@ -1,163 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`MRWidgetAutoMergeEnabled template should have correct elements 1`] = `
-<div
- class="mr-widget-body media gl-display-flex gl-align-items-center"
->
- <div
- class="gl-w-6 gl-h-6 gl-display-flex gl-align-self-start gl-mr-3"
- >
- <div
- class="gl-display-flex gl-m-auto"
- >
- <div
- class="gl-mr-3 gl-p-2 gl-m-0! gl-text-blue-500 gl-w-6 gl-p-2"
- >
- <div
- class="gl-rounded-full gl-relative gl-display-flex mr-widget-extension-icon"
- >
- <div
- class="gl-absolute gl-top-half gl-left-50p gl-translate-x-n50 gl-display-flex gl-m-auto"
- >
- <div
- class="gl-display-flex gl-m-auto gl-translate-y-n50"
- >
- <svg
- aria-label="Scheduled "
- class="gl-display-block gl-icon s12"
- data-qa-selector="status_scheduled_icon"
- data-testid="status-scheduled-icon"
- role="img"
- >
- <use
- href="#status-scheduled"
- />
- </svg>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
-
- <div
- class="gl-display-flex gl-w-full"
- >
- <div
- class="media-body gl-display-flex gl-align-items-center"
- >
-
- <h4
- class="gl-mr-3"
- data-testid="statusText"
- >
- Set by to be merged automatically when the pipeline succeeds
- </h4>
-
- <div
- class="gl-display-flex gl-font-size-0 gl-ml-auto gl-gap-3"
- >
- <div
- class="gl-display-flex gl-align-items-flex-start"
- >
- <div
- class="dropdown b-dropdown gl-dropdown gl-display-block gl-md-display-none! btn-group"
- lazy=""
- no-caret=""
- title="Options"
- >
- <!---->
- <button
- aria-expanded="false"
- aria-haspopup="true"
- class="btn dropdown-toggle btn-default btn-sm gl-p-2! gl-button gl-dropdown-toggle btn-default-tertiary dropdown-icon-only dropdown-toggle-no-caret"
- type="button"
- >
- <!---->
-
- <svg
- aria-hidden="true"
- class="dropdown-icon gl-icon s16"
- data-testid="ellipsis_v-icon"
- role="img"
- >
- <use
- href="#ellipsis_v"
- />
- </svg>
-
- <span
- class="gl-dropdown-button-text gl-sr-only"
- >
-
- </span>
-
- <svg
- aria-hidden="true"
- class="gl-button-icon dropdown-chevron gl-icon s16"
- data-testid="chevron-down-icon"
- role="img"
- >
- <use
- href="#chevron-down"
- />
- </svg>
- </button>
- <ul
- class="dropdown-menu dropdown-menu-right"
- role="menu"
- tabindex="-1"
- >
- <!---->
- </ul>
- </div>
-
- <button
- class="btn gl-display-none gl-md-display-block gl-float-left btn-confirm btn-sm gl-button btn-confirm-tertiary js-cancel-auto-merge"
- data-qa-selector="cancel_auto_merge_button"
- data-testid="cancelAutomaticMergeButton"
- type="button"
- >
- <!---->
-
- <!---->
-
- <span
- class="gl-button-text"
- >
-
- Cancel auto-merge
-
- </span>
- </button>
- </div>
- </div>
- </div>
-
- <div
- class="gl-md-display-none gl-border-l-1 gl-border-l-solid gl-border-gray-100 gl-ml-3 gl-pl-3 gl-h-6 gl-mt-1"
- >
- <button
- class="btn gl-vertical-align-top btn-default btn-sm gl-button btn-default-tertiary btn-icon"
- title="Collapse merge details"
- type="button"
- >
- <!---->
-
- <svg
- aria-hidden="true"
- class="gl-button-icon gl-icon s16"
- data-testid="chevron-lg-up-icon"
- role="img"
- >
- <use
- href="#chevron-lg-up"
- />
- </svg>
-
- <!---->
- </button>
- </div>
- </div>
-</div>
-`;
diff --git a/spec/frontend/vue_merge_request_widget/components/states/mr_widget_auto_merge_enabled_spec.js b/spec/frontend/vue_merge_request_widget/components/states/mr_widget_auto_merge_enabled_spec.js
index 5b9f30dfb86..fef5fee5f19 100644
--- a/spec/frontend/vue_merge_request_widget/components/states/mr_widget_auto_merge_enabled_spec.js
+++ b/spec/frontend/vue_merge_request_widget/components/states/mr_widget_auto_merge_enabled_spec.js
@@ -128,14 +128,6 @@ describe('MRWidgetAutoMergeEnabled', () => {
});
describe('template', () => {
- it('should have correct elements', () => {
- factory({
- ...defaultMrProps(),
- });
-
- expect(wrapper.element).toMatchSnapshot();
- });
-
it('should disable cancel auto merge button when the action is in progress', async () => {
factory({
...defaultMrProps(),
diff --git a/spec/frontend/vue_merge_request_widget/components/widget/widget_spec.js b/spec/frontend/vue_merge_request_widget/components/widget/widget_spec.js
index 4c93c88de16..7e941c5ceaa 100644
--- a/spec/frontend/vue_merge_request_widget/components/widget/widget_spec.js
+++ b/spec/frontend/vue_merge_request_widget/components/widget/widget_spec.js
@@ -1,6 +1,6 @@
import { nextTick } from 'vue';
import * as Sentry from '@sentry/browser';
-import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import { shallowMountExtended, mountExtended } from 'helpers/vue_test_utils_helper';
import HelpPopover from '~/vue_shared/components/help_popover.vue';
import waitForPromises from 'helpers/wait_for_promises';
import StatusIcon from '~/vue_merge_request_widget/components/extensions/status_icon.vue';
@@ -26,8 +26,8 @@ describe('~/vue_merge_request_widget/components/widget/widget.vue', () => {
const findHelpPopover = () => wrapper.findComponent(HelpPopover);
const findDynamicScroller = () => wrapper.findByTestId('dynamic-content-scroller');
- const createComponent = ({ propsData, slots } = {}) => {
- wrapper = shallowMountExtended(Widget, {
+ const createComponent = ({ propsData, slots, mountFn = shallowMountExtended } = {}) => {
+ wrapper = mountFn(Widget, {
propsData: {
isCollapsible: false,
loadingText: 'Loading widget',
@@ -73,6 +73,13 @@ describe('~/vue_merge_request_widget/components/widget/widget.vue', () => {
expect(findStatusIcon().props()).toMatchObject({ iconName: 'failed', isLoading: false });
});
+ it('displays the error text when :has-error is true', () => {
+ createComponent({
+ propsData: { hasError: true, errorText: 'API error' },
+ });
+ expect(wrapper.findByText('API error').exists()).toBe(true);
+ });
+
it('displays loading icon until request is made and then displays status icon when the request is complete', async () => {
const fetchCollapsedData = jest
.fn()
@@ -425,6 +432,7 @@ describe('~/vue_merge_request_widget/components/widget/widget.vue', () => {
beforeEach(() => {
createComponent({
+ mountFn: mountExtended,
propsData: {
isCollapsible: true,
content,
@@ -437,5 +445,11 @@ describe('~/vue_merge_request_widget/components/widget/widget.vue', () => {
await waitForPromises();
expect(findDynamicScroller().props('items')).toEqual(content);
});
+
+ it('renders the dynamic content inside the dynamic scroller', async () => {
+ findToggleButton().vm.$emit('click');
+ await waitForPromises();
+ expect(wrapper.findByText('Main text for the row').exists()).toBe(true);
+ });
});
});
diff --git a/spec/frontend/vue_merge_request_widget/extensions/security_reports/mock_data.js b/spec/frontend/vue_merge_request_widget/extensions/security_reports/mock_data.js
new file mode 100644
index 00000000000..c7354483e8b
--- /dev/null
+++ b/spec/frontend/vue_merge_request_widget/extensions/security_reports/mock_data.js
@@ -0,0 +1,141 @@
+export const mockArtifacts = () => ({
+ data: {
+ project: {
+ id: 'gid://gitlab/Project/9',
+ mergeRequest: {
+ id: 'gid://gitlab/MergeRequest/1',
+ headPipeline: {
+ id: 'gid://gitlab/Ci::Pipeline/1',
+ jobs: {
+ nodes: [
+ {
+ id: 'gid://gitlab/Ci::Build/14',
+ name: 'sam_scan',
+ artifacts: {
+ nodes: [
+ {
+ downloadPath:
+ '/root/security-reports/-/jobs/14/artifacts/download?file_type=trace',
+ fileType: 'TRACE',
+ __typename: 'CiJobArtifact',
+ },
+ {
+ downloadPath:
+ '/root/security-reports/-/jobs/14/artifacts/download?file_type=sast',
+ fileType: 'SAST',
+ __typename: 'CiJobArtifact',
+ },
+ ],
+ __typename: 'CiJobArtifactConnection',
+ },
+ __typename: 'CiJob',
+ },
+ {
+ id: 'gid://gitlab/Ci::Build/11',
+ name: 'sast-spotbugs',
+ artifacts: {
+ nodes: [
+ {
+ downloadPath:
+ '/root/security-reports/-/jobs/11/artifacts/download?file_type=trace',
+ fileType: 'TRACE',
+ __typename: 'CiJobArtifact',
+ },
+ {
+ downloadPath:
+ '/root/security-reports/-/jobs/11/artifacts/download?file_type=sast',
+ fileType: 'SAST',
+ __typename: 'CiJobArtifact',
+ },
+ ],
+ __typename: 'CiJobArtifactConnection',
+ },
+ __typename: 'CiJob',
+ },
+ {
+ id: 'gid://gitlab/Ci::Build/10',
+ name: 'sast-sobelow',
+ artifacts: {
+ nodes: [
+ {
+ downloadPath:
+ '/root/security-reports/-/jobs/10/artifacts/download?file_type=trace',
+ fileType: 'TRACE',
+ __typename: 'CiJobArtifact',
+ },
+ ],
+ __typename: 'CiJobArtifactConnection',
+ },
+ __typename: 'CiJob',
+ },
+ {
+ id: 'gid://gitlab/Ci::Build/9',
+ name: 'sast-pmd-apex',
+ artifacts: {
+ nodes: [
+ {
+ downloadPath:
+ '/root/security-reports/-/jobs/9/artifacts/download?file_type=trace',
+ fileType: 'TRACE',
+ __typename: 'CiJobArtifact',
+ },
+ ],
+ __typename: 'CiJobArtifactConnection',
+ },
+ __typename: 'CiJob',
+ },
+ {
+ id: 'gid://gitlab/Ci::Build/8',
+ name: 'sast-eslint',
+ artifacts: {
+ nodes: [
+ {
+ downloadPath:
+ '/root/security-reports/-/jobs/8/artifacts/download?file_type=trace',
+ fileType: 'TRACE',
+ __typename: 'CiJobArtifact',
+ },
+ {
+ downloadPath:
+ '/root/security-reports/-/jobs/8/artifacts/download?file_type=sast',
+ fileType: 'SAST',
+ __typename: 'CiJobArtifact',
+ },
+ ],
+ __typename: 'CiJobArtifactConnection',
+ },
+ __typename: 'CiJob',
+ },
+ {
+ id: 'gid://gitlab/Ci::Build/7',
+ name: 'secrets',
+ artifacts: {
+ nodes: [
+ {
+ downloadPath:
+ '/root/security-reports/-/jobs/7/artifacts/download?file_type=trace',
+ fileType: 'TRACE',
+ __typename: 'CiJobArtifact',
+ },
+ {
+ downloadPath:
+ '/root/security-reports/-/jobs/7/artifacts/download?file_type=secret_detection',
+ fileType: 'SECRET_DETECTION',
+ __typename: 'CiJobArtifact',
+ },
+ ],
+ __typename: 'CiJobArtifactConnection',
+ },
+ __typename: 'CiJob',
+ },
+ ],
+ __typename: 'CiJobConnection',
+ },
+ __typename: 'Pipeline',
+ },
+ __typename: 'MergeRequest',
+ },
+ __typename: 'Project',
+ },
+ },
+});
diff --git a/spec/frontend/vue_merge_request_widget/extensions/security_reports/mr_widget_security_reports_spec.js b/spec/frontend/vue_merge_request_widget/extensions/security_reports/mr_widget_security_reports_spec.js
new file mode 100644
index 00000000000..16c2adaffaf
--- /dev/null
+++ b/spec/frontend/vue_merge_request_widget/extensions/security_reports/mr_widget_security_reports_spec.js
@@ -0,0 +1,93 @@
+import Vue from 'vue';
+import { GlDropdown } from '@gitlab/ui';
+import VueApollo from 'vue-apollo';
+import MRSecurityWidget from '~/vue_merge_request_widget/extensions/security_reports/mr_widget_security_reports.vue';
+import Widget from '~/vue_merge_request_widget/components/widget/widget.vue';
+import securityReportMergeRequestDownloadPathsQuery from '~/vue_merge_request_widget/extensions/security_reports/graphql/security_report_merge_request_download_paths.query.graphql';
+import { mountExtended } from 'helpers/vue_test_utils_helper';
+import waitForPromises from 'helpers/wait_for_promises';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import { mockArtifacts } from './mock_data';
+
+Vue.use(VueApollo);
+
+describe('vue_merge_request_widget/extensions/security_reports/mr_widget_security_reports.vue', () => {
+ let wrapper;
+
+ const createComponent = ({ propsData, mockResponse = mockArtifacts() } = {}) => {
+ wrapper = mountExtended(MRSecurityWidget, {
+ apolloProvider: createMockApollo([
+ [securityReportMergeRequestDownloadPathsQuery, jest.fn().mockResolvedValue(mockResponse)],
+ ]),
+ propsData: {
+ ...propsData,
+ mr: {},
+ },
+ });
+ };
+
+ const findWidget = () => wrapper.findComponent(Widget);
+ const findDropdown = () => wrapper.findComponent(GlDropdown);
+ const findDropdownItem = (name) => wrapper.findByTestId(name);
+
+ describe('with data', () => {
+ beforeEach(async () => {
+ createComponent();
+ await waitForPromises();
+ });
+
+ it('displays the correct message', () => {
+ expect(wrapper.findByText('Security scans have run').exists()).toBe(true);
+ });
+
+ it('displays the help popover', () => {
+ expect(findWidget().props('helpPopover')).toEqual({
+ content: {
+ learnMorePath:
+ '/help/user/application_security/index#view-security-scan-information-in-merge-requests',
+ text:
+ 'New vulnerabilities are vulnerabilities that the security scan detects in the merge request that are different to existing vulnerabilities in the default branch.',
+ },
+ options: {
+ title: 'Security scan results',
+ },
+ });
+ });
+
+ it.each`
+ artifactName | exists | downloadPath
+ ${'sam_scan'} | ${true} | ${'/root/security-reports/-/jobs/14/artifacts/download?file_type=sast'}
+ ${'sast-spotbugs'} | ${true} | ${'/root/security-reports/-/jobs/11/artifacts/download?file_type=sast'}
+ ${'sast-sobelow'} | ${false} | ${''}
+ ${'sast-pmd-apex'} | ${false} | ${''}
+ ${'sast-eslint'} | ${true} | ${'/root/security-reports/-/jobs/8/artifacts/download?file_type=sast'}
+ ${'secrets'} | ${true} | ${'/root/security-reports/-/jobs/7/artifacts/download?file_type=secret_detection'}
+ `(
+ 'has a dropdown to download $artifactName artifacts',
+ ({ artifactName, exists, downloadPath }) => {
+ expect(findDropdown().exists()).toBe(true);
+ expect(wrapper.findByText(`Download ${artifactName}`).exists()).toBe(exists);
+
+ if (exists) {
+ const dropdownItem = findDropdownItem(`download-${artifactName}`);
+ expect(dropdownItem.attributes('download')).toBe('');
+ expect(dropdownItem.attributes('href')).toBe(downloadPath);
+ }
+ },
+ );
+ });
+
+ describe('without data', () => {
+ beforeEach(() => {
+ createComponent({ mockResponse: { data: { project: { id: 'project-id' } } } });
+ });
+
+ it('displays the correct message', () => {
+ expect(wrapper.findByText('Security scans have run').exists()).toBe(true);
+ });
+
+ it('should not display the artifacts dropdown', () => {
+ expect(findDropdown().exists()).toBe(false);
+ });
+ });
+});
diff --git a/spec/frontend/vue_merge_request_widget/extensions/test_report/index_spec.js b/spec/frontend/vue_merge_request_widget/extensions/test_report/index_spec.js
index baef247b649..548b68bc103 100644
--- a/spec/frontend/vue_merge_request_widget/extensions/test_report/index_spec.js
+++ b/spec/frontend/vue_merge_request_widget/extensions/test_report/index_spec.js
@@ -8,7 +8,11 @@ import waitForPromises from 'helpers/wait_for_promises';
import axios from '~/lib/utils/axios_utils';
import extensionsContainer from '~/vue_merge_request_widget/components/extensions/container';
import { registerExtension } from '~/vue_merge_request_widget/components/extensions';
-import httpStatusCodes, { HTTP_STATUS_NO_CONTENT } from '~/lib/utils/http_status';
+import {
+ HTTP_STATUS_INTERNAL_SERVER_ERROR,
+ HTTP_STATUS_NO_CONTENT,
+ HTTP_STATUS_OK,
+} from '~/lib/utils/http_status';
import TestCaseDetails from '~/pipelines/components/test_reports/test_case_details.vue';
import { failedReport } from 'jest/ci/reports/mock_data/mock_data';
@@ -57,7 +61,7 @@ describe('Test report extension', () => {
};
const createExpandedWidgetWithData = async (data = mixedResultsTestReports) => {
- mockApi(httpStatusCodes.OK, data);
+ mockApi(HTTP_STATUS_OK, data);
createComponent();
await waitForPromises();
findToggleCollapsedButton().trigger('click');
@@ -75,7 +79,7 @@ describe('Test report extension', () => {
describe('summary', () => {
it('displays loading state initially', () => {
- mockApi(httpStatusCodes.OK);
+ mockApi(HTTP_STATUS_OK);
createComponent();
expect(wrapper.text()).toContain(i18n.loading);
@@ -91,7 +95,7 @@ describe('Test report extension', () => {
});
it('with an error response, displays failed to load text', async () => {
- mockApi(httpStatusCodes.INTERNAL_SERVER_ERROR);
+ mockApi(HTTP_STATUS_INTERNAL_SERVER_ERROR);
createComponent();
await waitForPromises();
@@ -107,7 +111,7 @@ describe('Test report extension', () => {
${'failed test results'} | ${newFailedTestReports} | ${'Test summary: 2 failed, 11 total tests'}
${'resolved failures'} | ${resolvedFailures} | ${'Test summary: 4 fixed test results, 11 total tests'}
`('displays summary text for $description', async ({ mockData, expectedResult }) => {
- mockApi(httpStatusCodes.OK, mockData);
+ mockApi(HTTP_STATUS_OK, mockData);
createComponent();
await waitForPromises();
@@ -116,7 +120,7 @@ describe('Test report extension', () => {
});
it('displays report level recently failed count', async () => {
- mockApi(httpStatusCodes.OK, recentFailures);
+ mockApi(HTTP_STATUS_OK, recentFailures);
createComponent();
await waitForPromises();
@@ -127,7 +131,7 @@ describe('Test report extension', () => {
});
it('displays a link to the full report', async () => {
- mockApi(httpStatusCodes.OK);
+ mockApi(HTTP_STATUS_OK);
createComponent();
await waitForPromises();
@@ -137,7 +141,7 @@ describe('Test report extension', () => {
});
it('hides copy failed tests button when there are no failing tests', async () => {
- mockApi(httpStatusCodes.OK);
+ mockApi(HTTP_STATUS_OK);
createComponent();
await waitForPromises();
@@ -146,7 +150,7 @@ describe('Test report extension', () => {
});
it('displays copy failed tests button when there are failing tests', async () => {
- mockApi(httpStatusCodes.OK, newFailedTestReports);
+ mockApi(HTTP_STATUS_OK, newFailedTestReports);
createComponent();
await waitForPromises();
@@ -159,7 +163,7 @@ describe('Test report extension', () => {
});
it('hides copy failed tests button when endpoint returns null files', async () => {
- mockApi(httpStatusCodes.OK, newFailedTestWithNullFilesReport);
+ mockApi(HTTP_STATUS_OK, newFailedTestWithNullFilesReport);
createComponent();
await waitForPromises();
@@ -168,7 +172,7 @@ describe('Test report extension', () => {
});
it('copy failed tests button updates tooltip text when clicked', async () => {
- mockApi(httpStatusCodes.OK, newFailedTestReports);
+ mockApi(HTTP_STATUS_OK, newFailedTestReports);
createComponent();
await waitForPromises();
@@ -195,7 +199,7 @@ describe('Test report extension', () => {
});
it('shows an error when a suite has a parsing error', async () => {
- mockApi(httpStatusCodes.OK, reportWithParsingErrors);
+ mockApi(HTTP_STATUS_OK, reportWithParsingErrors);
createComponent();
await waitForPromises();
diff --git a/spec/frontend/vue_merge_request_widget/extentions/accessibility/index_spec.js b/spec/frontend/vue_merge_request_widget/extentions/accessibility/index_spec.js
index a06ad930abe..01049e54a7f 100644
--- a/spec/frontend/vue_merge_request_widget/extentions/accessibility/index_spec.js
+++ b/spec/frontend/vue_merge_request_widget/extentions/accessibility/index_spec.js
@@ -6,7 +6,7 @@ import axios from '~/lib/utils/axios_utils';
import extensionsContainer from '~/vue_merge_request_widget/components/extensions/container';
import { registerExtension } from '~/vue_merge_request_widget/components/extensions';
import accessibilityExtension from '~/vue_merge_request_widget/extensions/accessibility';
-import httpStatusCodes from '~/lib/utils/http_status';
+import { HTTP_STATUS_INTERNAL_SERVER_ERROR, HTTP_STATUS_OK } from '~/lib/utils/http_status';
import { accessibilityReportResponseErrors, accessibilityReportResponseSuccess } from './mock_data';
describe('Accessibility extension', () => {
@@ -45,7 +45,7 @@ describe('Accessibility extension', () => {
describe('summary', () => {
it('displays loading text', () => {
- mockApi(httpStatusCodes.OK, accessibilityReportResponseErrors);
+ mockApi(HTTP_STATUS_OK, accessibilityReportResponseErrors);
createComponent();
@@ -53,7 +53,7 @@ describe('Accessibility extension', () => {
});
it('displays failed loading text', async () => {
- mockApi(httpStatusCodes.INTERNAL_SERVER_ERROR);
+ mockApi(HTTP_STATUS_INTERNAL_SERVER_ERROR);
createComponent();
@@ -63,7 +63,7 @@ describe('Accessibility extension', () => {
});
it('displays detected errors and is expandable', async () => {
- mockApi(httpStatusCodes.OK, accessibilityReportResponseErrors);
+ mockApi(HTTP_STATUS_OK, accessibilityReportResponseErrors);
createComponent();
@@ -76,7 +76,7 @@ describe('Accessibility extension', () => {
});
it('displays no detected errors and is not expandable', async () => {
- mockApi(httpStatusCodes.OK, accessibilityReportResponseSuccess);
+ mockApi(HTTP_STATUS_OK, accessibilityReportResponseSuccess);
createComponent();
@@ -91,7 +91,7 @@ describe('Accessibility extension', () => {
describe('expanded data', () => {
beforeEach(async () => {
- mockApi(httpStatusCodes.OK, accessibilityReportResponseErrors);
+ mockApi(HTTP_STATUS_OK, accessibilityReportResponseErrors);
createComponent();
diff --git a/spec/frontend/vue_merge_request_widget/extentions/code_quality/index_spec.js b/spec/frontend/vue_merge_request_widget/extentions/code_quality/index_spec.js
index f0ebbb1a82e..67b327217ef 100644
--- a/spec/frontend/vue_merge_request_widget/extentions/code_quality/index_spec.js
+++ b/spec/frontend/vue_merge_request_widget/extentions/code_quality/index_spec.js
@@ -7,10 +7,18 @@ import axios from '~/lib/utils/axios_utils';
import extensionsContainer from '~/vue_merge_request_widget/components/extensions/container';
import { registerExtension } from '~/vue_merge_request_widget/components/extensions';
import codeQualityExtension from '~/vue_merge_request_widget/extensions/code_quality';
-import httpStatusCodes, { HTTP_STATUS_NO_CONTENT } from '~/lib/utils/http_status';
-import { i18n } from '~/vue_merge_request_widget/extensions/code_quality/constants';
+import {
+ HTTP_STATUS_INTERNAL_SERVER_ERROR,
+ HTTP_STATUS_NO_CONTENT,
+ HTTP_STATUS_OK,
+} from '~/lib/utils/http_status';
+import {
+ i18n,
+ codeQualityPrefixes,
+} from '~/vue_merge_request_widget/extensions/code_quality/constants';
import {
codeQualityResponseNewErrors,
+ codeQualityResponseResolvedErrors,
codeQualityResponseResolvedAndNewErrors,
codeQualityResponseNoErrors,
} from './mock_data';
@@ -29,6 +37,10 @@ describe('Code Quality extension', () => {
const findToggleCollapsedButton = () => wrapper.findByTestId('toggle-button');
const findAllExtensionListItems = () => wrapper.findAllByTestId('extension-list-item');
+ const isCollapsable = () => wrapper.findByTestId('toggle-button').exists();
+ const getNeutralIcon = () => wrapper.findByTestId('status-neutral-icon').exists();
+ const getAlertIcon = () => wrapper.findByTestId('status-alert-icon').exists();
+ const getSuccessIcon = () => wrapper.findByTestId('status-success-icon').exists();
const createComponent = () => {
wrapper = mountExtended(extensionsContainer, {
@@ -55,7 +67,7 @@ describe('Code Quality extension', () => {
describe('summary', () => {
it('displays loading text', () => {
- mockApi(httpStatusCodes.OK, codeQualityResponseNewErrors);
+ mockApi(HTTP_STATUS_OK, codeQualityResponseNewErrors);
createComponent();
@@ -72,28 +84,57 @@ describe('Code Quality extension', () => {
});
it('displays failed loading text', async () => {
- mockApi(httpStatusCodes.INTERNAL_SERVER_ERROR);
+ mockApi(HTTP_STATUS_INTERNAL_SERVER_ERROR);
createComponent();
await waitForPromises();
+
expect(wrapper.text()).toBe(i18n.error);
+ expect(isCollapsable()).toBe(false);
});
- it('displays correct single Report', async () => {
- mockApi(httpStatusCodes.OK, codeQualityResponseNewErrors);
+ it('displays new Errors finding', async () => {
+ mockApi(HTTP_STATUS_OK, codeQualityResponseNewErrors);
createComponent();
await waitForPromises();
+ expect(wrapper.text()).toBe(
+ i18n
+ .singularCopy(
+ i18n.findings(codeQualityResponseNewErrors.new_errors, codeQualityPrefixes.new),
+ )
+ .replace(/%{strong_start}/g, '')
+ .replace(/%{strong_end}/g, ''),
+ );
+ expect(isCollapsable()).toBe(true);
+ expect(getAlertIcon()).toBe(true);
+ });
+
+ it('displays resolved Errors finding', async () => {
+ mockApi(HTTP_STATUS_OK, codeQualityResponseResolvedErrors);
+ createComponent();
+
+ await waitForPromises();
expect(wrapper.text()).toBe(
- i18n.degradedCopy(i18n.singularReport(codeQualityResponseNewErrors.new_errors)),
+ i18n
+ .singularCopy(
+ i18n.findings(
+ codeQualityResponseResolvedErrors.resolved_errors,
+ codeQualityPrefixes.fixed,
+ ),
+ )
+ .replace(/%{strong_start}/g, '')
+ .replace(/%{strong_end}/g, ''),
);
+ expect(isCollapsable()).toBe(true);
+ expect(getSuccessIcon()).toBe(true);
});
it('displays quality improvement and degradation', async () => {
- mockApi(httpStatusCodes.OK, codeQualityResponseResolvedAndNewErrors);
+ mockApi(HTTP_STATUS_OK, codeQualityResponseResolvedAndNewErrors);
createComponent();
await waitForPromises();
@@ -102,28 +143,38 @@ describe('Code Quality extension', () => {
expect(wrapper.text()).toBe(
i18n
.improvementAndDegradationCopy(
- i18n.pluralReport(codeQualityResponseResolvedAndNewErrors.resolved_errors),
- i18n.pluralReport(codeQualityResponseResolvedAndNewErrors.new_errors),
+ i18n.findings(
+ codeQualityResponseResolvedAndNewErrors.resolved_errors,
+ codeQualityPrefixes.fixed,
+ ),
+ i18n.findings(
+ codeQualityResponseResolvedAndNewErrors.new_errors,
+ codeQualityPrefixes.new,
+ ),
)
.replace(/%{strong_start}/g, '')
.replace(/%{strong_end}/g, ''),
);
+ expect(isCollapsable()).toBe(true);
+ expect(getAlertIcon()).toBe(true);
});
it('displays no detected errors', async () => {
- mockApi(httpStatusCodes.OK, codeQualityResponseNoErrors);
+ mockApi(HTTP_STATUS_OK, codeQualityResponseNoErrors);
createComponent();
await waitForPromises();
expect(wrapper.text()).toBe(i18n.noChanges);
+ expect(isCollapsable()).toBe(false);
+ expect(getNeutralIcon()).toBe(true);
});
});
describe('expanded data', () => {
beforeEach(async () => {
- mockApi(httpStatusCodes.OK, codeQualityResponseResolvedAndNewErrors);
+ mockApi(HTTP_STATUS_OK, codeQualityResponseResolvedAndNewErrors);
createComponent();
diff --git a/spec/frontend/vue_merge_request_widget/extentions/code_quality/mock_data.js b/spec/frontend/vue_merge_request_widget/extentions/code_quality/mock_data.js
index 2e8e70f25db..cb23b730a93 100644
--- a/spec/frontend/vue_merge_request_widget/extentions/code_quality/mock_data.js
+++ b/spec/frontend/vue_merge_request_widget/extentions/code_quality/mock_data.js
@@ -17,9 +17,34 @@ export const codeQualityResponseNewErrors = {
resolved_errors: [],
existing_errors: [],
summary: {
- total: 2,
+ total: 12235,
resolved: 0,
- errored: 2,
+ errored: 12235,
+ },
+};
+
+export const codeQualityResponseResolvedErrors = {
+ status: 'success',
+ new_errors: [],
+ resolved_errors: [
+ {
+ description: "Parsing error: 'return' outside of function",
+ severity: 'minor',
+ file_path: 'index.js',
+ line: 12,
+ },
+ {
+ description: 'TODO found',
+ severity: 'minor',
+ file_path: '.gitlab-ci.yml',
+ line: 73,
+ },
+ ],
+ existing_errors: [],
+ summary: {
+ total: 12235,
+ resolved: 0,
+ errored: 12235,
},
};
@@ -43,9 +68,9 @@ export const codeQualityResponseResolvedAndNewErrors = {
],
existing_errors: [],
summary: {
- total: 2,
+ total: 12233,
resolved: 1,
- errored: 1,
+ errored: 12233,
},
};
@@ -55,8 +80,8 @@ export const codeQualityResponseNoErrors = {
resolved_errors: [],
existing_errors: [],
summary: {
- total: 0,
+ total: 12234,
resolved: 0,
- errored: 0,
+ errored: 12234,
},
};
diff --git a/spec/frontend/vue_merge_request_widget/mr_widget_how_to_merge_modal_spec.js b/spec/frontend/vue_merge_request_widget/mr_widget_how_to_merge_modal_spec.js
index d038660e6d3..015d394312a 100644
--- a/spec/frontend/vue_merge_request_widget/mr_widget_how_to_merge_modal_spec.js
+++ b/spec/frontend/vue_merge_request_widget/mr_widget_how_to_merge_modal_spec.js
@@ -34,7 +34,7 @@ describe('MRWidgetHowToMerge', () => {
});
it('renders a selection of markdown fields', () => {
- expect(findInstructionsFields().length).toBe(3);
+ expect(findInstructionsFields().length).toBe(2);
});
it('renders a tip including a link to docs when a valid link is present', () => {
@@ -48,23 +48,11 @@ describe('MRWidgetHowToMerge', () => {
it('should render different instructions based on if the user can merge', () => {
mountComponent({ props: { canMerge: true } });
- expect(findInstructionsFields().at(2).text()).toContain('git push origin');
- });
-
- it('should render different instructions based on if the merge is based off a fork', () => {
- mountComponent({ props: { isFork: true } });
- expect(findInstructionsFields().at(0).text()).toContain('FETCH_HEAD');
- });
-
- it('escapes the target branch name shell-secure', () => {
- mountComponent({ props: { targetBranch: '";echo$IFS"you_shouldnt_run_this' } });
-
- expect(findInstructionsFields().at(1).text()).toContain('\'";echo$IFS"you_shouldnt_run_this\'');
+ expect(findInstructionsFields().at(1).text()).toContain('git push origin');
});
it('escapes the source branch name shell-secure', () => {
mountComponent({ props: { sourceBranch: 'branch-of-$USER' } });
-
expect(findInstructionsFields().at(0).text()).toContain("'branch-of-$USER'");
});
});