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/reports')
-rw-r--r--spec/frontend/reports/codequality_report/components/codequality_issue_body_spec.js57
-rw-r--r--spec/frontend/reports/components/grouped_test_reports_app_spec.js110
-rw-r--r--spec/frontend/reports/components/report_section_spec.js2
-rw-r--r--spec/frontend/reports/mock_data/recent_failures_report.json46
-rw-r--r--spec/frontend/reports/store/mutations_spec.js2
-rw-r--r--spec/frontend/reports/store/utils_spec.js48
6 files changed, 251 insertions, 14 deletions
diff --git a/spec/frontend/reports/codequality_report/components/codequality_issue_body_spec.js b/spec/frontend/reports/codequality_report/components/codequality_issue_body_spec.js
index 3e11af9c9df..f99dcbffdff 100644
--- a/spec/frontend/reports/codequality_report/components/codequality_issue_body_spec.js
+++ b/spec/frontend/reports/codequality_report/components/codequality_issue_body_spec.js
@@ -1,10 +1,15 @@
+import { GlIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import component from '~/reports/codequality_report/components/codequality_issue_body.vue';
import { STATUS_FAILED, STATUS_NEUTRAL, STATUS_SUCCESS } from '~/reports/constants';
describe('code quality issue body issue body', () => {
let wrapper;
+ const findSeverityIcon = () => wrapper.findByTestId('codequality-severity-icon');
+ const findGlIcon = () => wrapper.find(GlIcon);
+
const codequalityIssue = {
name:
'rubygem-rest-client: session fixation vulnerability via Set-Cookie headers in 30x redirection responses',
@@ -14,13 +19,15 @@ describe('code quality issue body issue body', () => {
urlPath: '/Gemfile.lock#L22',
};
- const mountWithStatus = initialStatus => {
- wrapper = shallowMount(component, {
- propsData: {
- issue: codequalityIssue,
- status: initialStatus,
- },
- });
+ const createComponent = (initialStatus, issue = codequalityIssue) => {
+ wrapper = extendedWrapper(
+ shallowMount(component, {
+ propsData: {
+ issue,
+ status: initialStatus,
+ },
+ }),
+ );
};
afterEach(() => {
@@ -28,17 +35,43 @@ describe('code quality issue body issue body', () => {
wrapper = null;
});
+ describe('severity rating', () => {
+ it.each`
+ severity | iconClass | iconName
+ ${'info'} | ${'text-primary-400'} | ${'severity-info'}
+ ${'minor'} | ${'text-warning-200'} | ${'severity-low'}
+ ${'major'} | ${'text-warning-400'} | ${'severity-medium'}
+ ${'critical'} | ${'text-danger-600'} | ${'severity-high'}
+ ${'blocker'} | ${'text-danger-800'} | ${'severity-critical'}
+ ${'unknown'} | ${'text-secondary-400'} | ${'severity-unknown'}
+ ${'invalid'} | ${'text-secondary-400'} | ${'severity-unknown'}
+ `(
+ 'renders correct icon for "$severity" severity rating',
+ ({ severity, iconClass, iconName }) => {
+ createComponent(STATUS_FAILED, {
+ ...codequalityIssue,
+ severity,
+ });
+ const icon = findGlIcon();
+
+ expect(findSeverityIcon().classes()).toContain(iconClass);
+ expect(icon.exists()).toBe(true);
+ expect(icon.props('name')).toBe(iconName);
+ },
+ );
+ });
+
describe('with success', () => {
it('renders fixed label', () => {
- mountWithStatus(STATUS_SUCCESS);
+ createComponent(STATUS_SUCCESS);
expect(wrapper.text()).toContain('Fixed');
});
});
describe('without success', () => {
- it('renders fixed label', () => {
- mountWithStatus(STATUS_FAILED);
+ it('does not render fixed label', () => {
+ createComponent(STATUS_FAILED);
expect(wrapper.text()).not.toContain('Fixed');
});
@@ -46,7 +79,7 @@ describe('code quality issue body issue body', () => {
describe('name', () => {
it('renders name', () => {
- mountWithStatus(STATUS_NEUTRAL);
+ createComponent(STATUS_NEUTRAL);
expect(wrapper.text()).toContain(codequalityIssue.name);
});
@@ -54,7 +87,7 @@ describe('code quality issue body issue body', () => {
describe('path', () => {
it('renders the report-link path using the correct code quality issue', () => {
- mountWithStatus(STATUS_NEUTRAL);
+ createComponent(STATUS_NEUTRAL);
expect(wrapper.find('report-link-stub').props('issue')).toBe(codequalityIssue);
});
diff --git a/spec/frontend/reports/components/grouped_test_reports_app_spec.js b/spec/frontend/reports/components/grouped_test_reports_app_spec.js
index 556904b7da5..ae2718db17f 100644
--- a/spec/frontend/reports/components/grouped_test_reports_app_spec.js
+++ b/spec/frontend/reports/components/grouped_test_reports_app_spec.js
@@ -1,11 +1,13 @@
import { mount, createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex';
+import { mockTracking } from 'helpers/tracking_helper';
import GroupedTestReportsApp from '~/reports/components/grouped_test_reports_app.vue';
import { getStoreConfig } from '~/reports/store';
import { failedReport } from '../mock_data/mock_data';
import successTestReports from '../mock_data/no_failures_report.json';
import newFailedTestReports from '../mock_data/new_failures_report.json';
+import recentFailuresTestReports from '../mock_data/recent_failures_report.json';
import newErrorsTestReports from '../mock_data/new_errors_report.json';
import mixedResultsTestReports from '../mock_data/new_and_fixed_failures_report.json';
import resolvedFailures from '../mock_data/resolved_failures.json';
@@ -20,7 +22,7 @@ describe('Grouped test reports app', () => {
let wrapper;
let mockStore;
- const mountComponent = ({ props = { pipelinePath } } = {}) => {
+ const mountComponent = ({ props = { pipelinePath }, testFailureHistory = false } = {}) => {
wrapper = mount(Component, {
store: mockStore,
localVue,
@@ -29,6 +31,11 @@ describe('Grouped test reports app', () => {
pipelinePath,
...props,
},
+ provide: {
+ glFeatures: {
+ testFailureHistory,
+ },
+ },
});
};
@@ -39,6 +46,7 @@ describe('Grouped test reports app', () => {
};
const findHeader = () => wrapper.find('[data-testid="report-section-code-text"]');
+ const findExpandButton = () => wrapper.find('[data-testid="report-section-expand-button"]');
const findFullTestReportLink = () => wrapper.find('[data-testid="group-test-reports-full-link"]');
const findSummaryDescription = () => wrapper.find('[data-testid="test-summary-row-description"]');
const findIssueDescription = () => wrapper.find('[data-testid="test-issue-body-description"]');
@@ -96,6 +104,35 @@ describe('Grouped test reports app', () => {
});
});
+ describe('`Expand` button', () => {
+ let trackingSpy;
+
+ beforeEach(() => {
+ setReports(newFailedTestReports);
+ mountComponent();
+ document.body.dataset.page = 'projects:merge_requests:show';
+ trackingSpy = mockTracking('_category_', wrapper.element, jest.spyOn);
+ });
+
+ it('tracks an event on click', () => {
+ findExpandButton().trigger('click');
+
+ expect(trackingSpy).toHaveBeenCalledWith(undefined, 'expand_test_report_widget', {});
+ });
+
+ it('only tracks the first expansion', () => {
+ expect(trackingSpy).not.toHaveBeenCalled();
+
+ const button = findExpandButton();
+
+ button.trigger('click');
+ button.trigger('click');
+ button.trigger('click');
+
+ expect(trackingSpy).toHaveBeenCalledTimes(1);
+ });
+ });
+
describe('with new failed result', () => {
beforeEach(() => {
setReports(newFailedTestReports);
@@ -203,6 +240,77 @@ describe('Grouped test reports app', () => {
});
});
+ describe('recent failures counts', () => {
+ describe('with recent failures counts', () => {
+ beforeEach(() => {
+ setReports(recentFailuresTestReports);
+ });
+
+ describe('with feature flag enabled', () => {
+ beforeEach(() => {
+ mountComponent({ testFailureHistory: true });
+ });
+
+ it('renders the recently failed tests summary', () => {
+ expect(findHeader().text()).toContain(
+ '2 out of 3 failed tests have failed more than once in the last 14 days',
+ );
+ });
+
+ it('renders the recently failed count on the test suite', () => {
+ expect(findSummaryDescription().text()).toContain(
+ '1 out of 2 failed tests has failed more than once in the last 14 days',
+ );
+ });
+
+ it('renders the recent failures count on the test case', () => {
+ expect(findIssueDescription().text()).toContain('Failed 8 times in the last 14 days');
+ });
+ });
+
+ describe('with feature flag disabled', () => {
+ beforeEach(() => {
+ mountComponent({ testFailureHistory: false });
+ });
+
+ it('does not render the recently failed tests summary', () => {
+ expect(findHeader().text()).not.toContain('failed more than once in the last 14 days');
+ });
+
+ it('does not render the recently failed count on the test suite', () => {
+ expect(findSummaryDescription().text()).not.toContain(
+ 'failed more than once in the last 14 days',
+ );
+ });
+
+ it('renders the recent failures count on the test case', () => {
+ expect(findIssueDescription().text()).not.toContain('in the last 14 days');
+ });
+ });
+ });
+
+ describe('without recent failures counts', () => {
+ beforeEach(() => {
+ setReports(mixedResultsTestReports);
+ mountComponent();
+ });
+
+ it('does not render the recently failed tests summary', () => {
+ expect(findHeader().text()).not.toContain('failed more than once in the last 14 days');
+ });
+
+ it('does not render the recently failed count on the test suite', () => {
+ expect(findSummaryDescription().text()).not.toContain(
+ 'failed more than once in the last 14 days',
+ );
+ });
+
+ it('does not render the recent failures count on the test case', () => {
+ expect(findIssueDescription().text()).not.toContain('in the last 14 days');
+ });
+ });
+ });
+
describe('with a report that failed to load', () => {
beforeEach(() => {
setReports(failedReport);
diff --git a/spec/frontend/reports/components/report_section_spec.js b/spec/frontend/reports/components/report_section_spec.js
index a620b5d9afc..2d228313a9b 100644
--- a/spec/frontend/reports/components/report_section_spec.js
+++ b/spec/frontend/reports/components/report_section_spec.js
@@ -244,7 +244,7 @@ describe('Report section', () => {
hasIssues: true,
},
slots: {
- actionButtons: ['Action!'],
+ 'action-buttons': ['Action!'],
},
});
});
diff --git a/spec/frontend/reports/mock_data/recent_failures_report.json b/spec/frontend/reports/mock_data/recent_failures_report.json
new file mode 100644
index 00000000000..a47bc30a8e5
--- /dev/null
+++ b/spec/frontend/reports/mock_data/recent_failures_report.json
@@ -0,0 +1,46 @@
+{
+ "summary": { "total": 11, "resolved": 0, "errored": 0, "failed": 3, "recentlyFailed": 2 },
+ "suites": [
+ {
+ "name": "rspec:pg",
+ "summary": { "total": 8, "resolved": 0, "errored": 0, "failed": 2, "recentlyFailed": 1 },
+ "new_failures": [
+ {
+ "result": "failure",
+ "name": "Test#sum when a is 1 and b is 2 returns summary",
+ "execution_time": 0.009411,
+ "system_output": "Failure/Error: is_expected.to eq(3)\n\n expected: 3\n got: -1\n\n (compared using ==)\n./spec/test_spec.rb:12:in `block (4 levels) in <top (required)>'",
+ "recent_failures": 8
+ },
+ {
+ "result": "failure",
+ "name": "Test#sum when a is 100 and b is 200 returns summary",
+ "execution_time": 0.000162,
+ "system_output": "Failure/Error: is_expected.to eq(300)\n\n expected: 300\n got: -100\n\n (compared using ==)\n./spec/test_spec.rb:21:in `block (4 levels) in <top (required)>'"
+ }
+ ],
+ "resolved_failures": [],
+ "existing_failures": [],
+ "new_errors": [],
+ "resolved_errors": [],
+ "existing_errors": []
+ },
+ {
+ "name": "java ant",
+ "summary": { "total": 3, "resolved": 0, "errored": 0, "failed": 1, "recentlyFailed": 1 },
+ "new_failures": [
+ {
+ "result": "failure",
+ "name": "Test#sum when a is 100 and b is 200 returns summary",
+ "execution_time": 0.000562,
+ "recent_failures": 3
+ }
+ ],
+ "resolved_failures": [],
+ "existing_failures": [],
+ "new_errors": [],
+ "resolved_errors": [],
+ "existing_errors": []
+ }
+ ]
+}
diff --git a/spec/frontend/reports/store/mutations_spec.js b/spec/frontend/reports/store/mutations_spec.js
index 9446cd454ab..82a399c876d 100644
--- a/spec/frontend/reports/store/mutations_spec.js
+++ b/spec/frontend/reports/store/mutations_spec.js
@@ -46,6 +46,7 @@ describe('Reports Store Mutations', () => {
name: 'StringHelper#concatenate when a is git and b is lab returns summary',
execution_time: 0.0092435,
system_output: "Failure/Error: is_expected.to eq('gitlab')",
+ recent_failures: 4,
},
],
resolved_failures: [
@@ -82,6 +83,7 @@ describe('Reports Store Mutations', () => {
expect(stateCopy.summary.total).toEqual(mockedResponse.summary.total);
expect(stateCopy.summary.resolved).toEqual(mockedResponse.summary.resolved);
expect(stateCopy.summary.failed).toEqual(mockedResponse.summary.failed);
+ expect(stateCopy.summary.recentlyFailed).toEqual(1);
});
it('should set reports', () => {
diff --git a/spec/frontend/reports/store/utils_spec.js b/spec/frontend/reports/store/utils_spec.js
index 9ae456658dc..8977268115e 100644
--- a/spec/frontend/reports/store/utils_spec.js
+++ b/spec/frontend/reports/store/utils_spec.js
@@ -168,6 +168,54 @@ describe('Reports store utils', () => {
});
});
+ describe('recentFailuresTextBuilder', () => {
+ it.each`
+ recentlyFailed | failed | expected
+ ${0} | ${1} | ${''}
+ ${1} | ${1} | ${'1 out of 1 failed test has failed more than once in the last 14 days'}
+ ${1} | ${2} | ${'1 out of 2 failed tests has failed more than once in the last 14 days'}
+ ${2} | ${3} | ${'2 out of 3 failed tests have failed more than once in the last 14 days'}
+ `(
+ 'should render summary for $recentlyFailed out of $failed failures',
+ ({ recentlyFailed, failed, expected }) => {
+ const result = utils.recentFailuresTextBuilder({ recentlyFailed, failed });
+
+ expect(result).toBe(expected);
+ },
+ );
+ });
+
+ describe('countRecentlyFailedTests', () => {
+ it('counts tests with more than one recent failure in a report', () => {
+ const report = {
+ new_failures: [{ recent_failures: 2 }],
+ existing_failures: [{ recent_failures: 1 }],
+ resolved_failures: [{ recent_failures: 20 }, { recent_failures: 5 }],
+ };
+ const result = utils.countRecentlyFailedTests(report);
+
+ expect(result).toBe(3);
+ });
+
+ it('counts tests with more than one recent failure in an array of reports', () => {
+ const reports = [
+ {
+ new_failures: [{ recent_failures: 2 }],
+ existing_failures: [{ recent_failures: 20 }, { recent_failures: 5 }],
+ resolved_failures: [{ recent_failures: 2 }],
+ },
+ {
+ new_failures: [{ recent_failures: 8 }, { recent_failures: 14 }],
+ existing_failures: [{ recent_failures: 1 }],
+ resolved_failures: [{ recent_failures: 7 }, { recent_failures: 5 }],
+ },
+ ];
+ const result = utils.countRecentlyFailedTests(reports);
+
+ expect(result).toBe(8);
+ });
+ });
+
describe('statusIcon', () => {
describe('with failed status', () => {
it('returns ICON_WARNING', () => {