Commit 8f86a4f6 authored by Nick Kipling's avatar Nick Kipling Committed by Paul Slaughter

Changed test_reports tests to use dynamic fixtures

Created test_report fixture
Updated existing tests to use new fixtures
Removed as much mock_data as possible
Exported util function for use in test
parent 54514133
import { TestStatus } from '~/pipelines/constants'; import { TestStatus } from '~/pipelines/constants';
import { formatTime, secondsToMilliseconds } from '~/lib/utils/datetime_utility'; import { formatTime, secondsToMilliseconds } from '~/lib/utils/datetime_utility';
function iconForTestStatus(status) { export function iconForTestStatus(status) {
switch (status) { switch (status) {
case 'success': case 'success':
return 'status_success_borderless'; return 'status_success_borderless';
......
# frozen_string_literal: true
require "spec_helper"
describe Projects::PipelinesController, "(JavaScript fixtures)", type: :controller do
include JavaScriptFixturesHelpers
let(:namespace) { create(:namespace, name: "frontend-fixtures") }
let(:project) { create(:project, :repository, namespace: namespace, path: "pipelines-project") }
let(:commit) { create(:commit, project: project) }
let(:user) { create(:user, developer_projects: [project], email: commit.author_email) }
let(:pipeline) { create(:ci_pipeline, :with_test_reports, project: project, user: user) }
render_views
before do
sign_in(user)
stub_feature_flags(junit_pipeline_view: true)
end
it "pipelines/test_report.json" do
get :test_report, params: {
namespace_id: project.namespace,
project_id: project,
id: pipeline.id
}, format: :json
expect(response).to be_successful
end
end
import { formatTime } from '~/lib/utils/datetime_utility';
import { TestStatus } from '~/pipelines/constants'; import { TestStatus } from '~/pipelines/constants';
export const testCases = [ export default [
{
classname: 'spec.test_spec',
execution_time: 0.000748,
name: 'Test#subtract when a is 1 and b is 2 raises an error',
stack_trace: null,
status: TestStatus.SUCCESS,
system_output: null,
},
{
classname: 'spec.test_spec',
execution_time: 0.000064,
name: 'Test#subtract when a is 2 and b is 1 returns correct result',
stack_trace: null,
status: TestStatus.SUCCESS,
system_output: null,
},
{
classname: 'spec.test_spec',
execution_time: 0.009292,
name: 'Test#sum when a is 1 and b is 2 returns summary',
stack_trace: null,
status: TestStatus.FAILED,
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)>'",
},
{
classname: 'spec.test_spec',
execution_time: 0.00018,
name: 'Test#sum when a is 100 and b is 200 returns summary',
stack_trace: null,
status: TestStatus.FAILED,
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)>'",
},
{ {
classname: 'spec.test_spec', classname: 'spec.test_spec',
execution_time: 0, execution_time: 0,
...@@ -45,79 +10,3 @@ export const testCases = [ ...@@ -45,79 +10,3 @@ export const testCases = [
system_output: null, system_output: null,
}, },
]; ];
export const testCasesFormatted = [
{
...testCases[2],
icon: 'status_failed_borderless',
formattedTime: formatTime(testCases[0].execution_time * 1000),
},
{
...testCases[3],
icon: 'status_failed_borderless',
formattedTime: formatTime(testCases[1].execution_time * 1000),
},
{
...testCases[4],
icon: 'status_skipped_borderless',
formattedTime: formatTime(testCases[2].execution_time * 1000),
},
{
...testCases[0],
icon: 'status_success_borderless',
formattedTime: formatTime(testCases[3].execution_time * 1000),
},
{
...testCases[1],
icon: 'status_success_borderless',
formattedTime: formatTime(testCases[4].execution_time * 1000),
},
];
export const testSuites = [
{
error_count: 0,
failed_count: 2,
name: 'rspec:osx',
skipped_count: 0,
success_count: 2,
test_cases: testCases,
total_count: 4,
total_time: 60,
},
{
error_count: 0,
failed_count: 10,
name: 'rspec:osx',
skipped_count: 0,
success_count: 50,
test_cases: [],
total_count: 60,
total_time: 0.010284,
},
];
export const testSuitesFormatted = testSuites.map(x => ({
...x,
formattedTime: formatTime(x.total_time * 1000),
}));
export const testReports = {
error_count: 0,
failed_count: 2,
skipped_count: 0,
success_count: 2,
test_suites: testSuites,
total_count: 4,
total_time: 0.010284,
};
export const testReportsWithNoSuites = {
error_count: 0,
failed_count: 2,
skipped_count: 0,
success_count: 2,
test_suites: [],
total_count: 4,
total_time: 0.010284,
};
...@@ -2,10 +2,10 @@ import MockAdapter from 'axios-mock-adapter'; ...@@ -2,10 +2,10 @@ import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import * as actions from '~/pipelines/stores/test_reports/actions'; import * as actions from '~/pipelines/stores/test_reports/actions';
import * as types from '~/pipelines/stores/test_reports/mutation_types'; import * as types from '~/pipelines/stores/test_reports/mutation_types';
import { getJSONFixture } from 'helpers/fixtures';
import { TEST_HOST } from '../../../helpers/test_constants'; import { TEST_HOST } from '../../../helpers/test_constants';
import testAction from '../../../helpers/vuex_action_helper'; import testAction from '../../../helpers/vuex_action_helper';
import createFlash from '~/flash'; import createFlash from '~/flash';
import { testReports } from '../mock_data';
jest.mock('~/flash.js'); jest.mock('~/flash.js');
...@@ -13,6 +13,8 @@ describe('Actions TestReports Store', () => { ...@@ -13,6 +13,8 @@ describe('Actions TestReports Store', () => {
let mock; let mock;
let state; let state;
const testReports = getJSONFixture('pipelines/test_report.json');
const endpoint = `${TEST_HOST}/test_reports.json`; const endpoint = `${TEST_HOST}/test_reports.json`;
const defaultState = { const defaultState = {
endpoint, endpoint,
......
import * as getters from '~/pipelines/stores/test_reports/getters'; import * as getters from '~/pipelines/stores/test_reports/getters';
import { testReports, testSuitesFormatted, testCasesFormatted } from '../mock_data'; import { iconForTestStatus } from '~/pipelines/stores/test_reports/utils';
import { getJSONFixture } from 'helpers/fixtures';
describe('Getters TestReports Store', () => { describe('Getters TestReports Store', () => {
let state; let state;
const testReports = getJSONFixture('pipelines/test_report.json');
const defaultState = { const defaultState = {
testReports, testReports,
selectedSuite: testReports.test_suites[0], selectedSuite: testReports.test_suites[0],
...@@ -28,7 +31,13 @@ describe('Getters TestReports Store', () => { ...@@ -28,7 +31,13 @@ describe('Getters TestReports Store', () => {
it('should return the test suites', () => { it('should return the test suites', () => {
setupState(); setupState();
expect(getters.getTestSuites(state)).toEqual(testSuitesFormatted); const suites = getters.getTestSuites(state);
const expected = testReports.test_suites.map(x => ({
...x,
formattedTime: '00:00:00',
}));
expect(suites).toEqual(expected);
}); });
it('should return an empty array when testReports is empty', () => { it('should return an empty array when testReports is empty', () => {
...@@ -42,7 +51,14 @@ describe('Getters TestReports Store', () => { ...@@ -42,7 +51,14 @@ describe('Getters TestReports Store', () => {
it('should return the test cases inside the suite', () => { it('should return the test cases inside the suite', () => {
setupState(); setupState();
expect(getters.getSuiteTests(state)).toEqual(testCasesFormatted); const cases = getters.getSuiteTests(state);
const expected = testReports.test_suites[0].test_cases.map(x => ({
...x,
formattedTime: '00:00:00',
icon: iconForTestStatus(x.status),
}));
expect(cases).toEqual(expected);
}); });
it('should return an empty array when testReports is empty', () => { it('should return an empty array when testReports is empty', () => {
......
import * as types from '~/pipelines/stores/test_reports/mutation_types'; import * as types from '~/pipelines/stores/test_reports/mutation_types';
import mutations from '~/pipelines/stores/test_reports/mutations'; import mutations from '~/pipelines/stores/test_reports/mutations';
import { testReports, testSuites } from '../mock_data'; import { getJSONFixture } from 'helpers/fixtures';
describe('Mutations TestReports Store', () => { describe('Mutations TestReports Store', () => {
let mockState; let mockState;
const testReports = getJSONFixture('pipelines/test_report.json');
const defaultState = { const defaultState = {
endpoint: '', endpoint: '',
testReports: {}, testReports: {},
...@@ -27,7 +29,7 @@ describe('Mutations TestReports Store', () => { ...@@ -27,7 +29,7 @@ describe('Mutations TestReports Store', () => {
describe('set reports', () => { describe('set reports', () => {
it('should set testReports', () => { it('should set testReports', () => {
const expectedState = Object.assign({}, mockState, { testReports }); const expectedState = { ...mockState, testReports };
mutations[types.SET_REPORTS](mockState, testReports); mutations[types.SET_REPORTS](mockState, testReports);
expect(mockState.testReports).toEqual(expectedState.testReports); expect(mockState.testReports).toEqual(expectedState.testReports);
...@@ -36,10 +38,10 @@ describe('Mutations TestReports Store', () => { ...@@ -36,10 +38,10 @@ describe('Mutations TestReports Store', () => {
describe('set selected suite', () => { describe('set selected suite', () => {
it('should set selectedSuite', () => { it('should set selectedSuite', () => {
const expectedState = Object.assign({}, mockState, { selectedSuite: testSuites[0] }); const selectedSuite = testReports.test_suites[0];
mutations[types.SET_SELECTED_SUITE](mockState, testSuites[0]); mutations[types.SET_SELECTED_SUITE](mockState, selectedSuite);
expect(mockState.selectedSuite).toEqual(expectedState.selectedSuite); expect(mockState.selectedSuite).toEqual(selectedSuite);
}); });
}); });
......
import Vuex from 'vuex'; import Vuex from 'vuex';
import TestReports from '~/pipelines/components/test_reports/test_reports.vue'; import TestReports from '~/pipelines/components/test_reports/test_reports.vue';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { testReports } from './mock_data';
import * as actions from '~/pipelines/stores/test_reports/actions'; import * as actions from '~/pipelines/stores/test_reports/actions';
import { getJSONFixture } from 'helpers/fixtures';
describe('Test reports app', () => { describe('Test reports app', () => {
let wrapper; let wrapper;
let store; let store;
const testReports = getJSONFixture('pipelines/test_report.json');
const loadingSpinner = () => wrapper.find('.js-loading-spinner'); const loadingSpinner = () => wrapper.find('.js-loading-spinner');
const testsDetail = () => wrapper.find('.js-tests-detail'); const testsDetail = () => wrapper.find('.js-tests-detail');
const noTestsToShow = () => wrapper.find('.js-no-tests-to-show'); const noTestsToShow = () => wrapper.find('.js-no-tests-to-show');
......
...@@ -3,18 +3,26 @@ import SuiteTable from '~/pipelines/components/test_reports/test_suite_table.vue ...@@ -3,18 +3,26 @@ import SuiteTable from '~/pipelines/components/test_reports/test_suite_table.vue
import * as getters from '~/pipelines/stores/test_reports/getters'; import * as getters from '~/pipelines/stores/test_reports/getters';
import { TestStatus } from '~/pipelines/constants'; import { TestStatus } from '~/pipelines/constants';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { testSuites, testCases } from './mock_data'; import { getJSONFixture } from 'helpers/fixtures';
import skippedTestCases from './mock_data';
describe('Test reports suite table', () => { describe('Test reports suite table', () => {
let wrapper; let wrapper;
let store; let store;
const {
test_suites: [testSuite],
} = getJSONFixture('pipelines/test_report.json');
testSuite.test_cases = [...testSuite.test_cases, ...skippedTestCases];
const testCases = testSuite.test_cases;
const noCasesMessage = () => wrapper.find('.js-no-test-cases'); const noCasesMessage = () => wrapper.find('.js-no-test-cases');
const allCaseRows = () => wrapper.findAll('.js-case-row'); const allCaseRows = () => wrapper.findAll('.js-case-row');
const findCaseRowAtIndex = index => wrapper.findAll('.js-case-row').at(index); const findCaseRowAtIndex = index => wrapper.findAll('.js-case-row').at(index);
const findIconForRow = (row, status) => row.find(`.ci-status-icon-${status}`); const findIconForRow = (row, status) => row.find(`.ci-status-icon-${status}`);
const createComponent = (suite = testSuites[0]) => { const createComponent = (suite = testSuite) => {
store = new Vuex.Store({ store = new Vuex.Store({
state: { state: {
selectedSuite: suite, selectedSuite: suite,
......
import Summary from '~/pipelines/components/test_reports/test_summary.vue'; import Summary from '~/pipelines/components/test_reports/test_summary.vue';
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import { testSuites } from './mock_data'; import { getJSONFixture } from 'helpers/fixtures';
describe('Test reports summary', () => { describe('Test reports summary', () => {
let wrapper; let wrapper;
const {
test_suites: [testSuite],
} = getJSONFixture('pipelines/test_report.json');
const backButton = () => wrapper.find('.js-back-button'); const backButton = () => wrapper.find('.js-back-button');
const totalTests = () => wrapper.find('.js-total-tests'); const totalTests = () => wrapper.find('.js-total-tests');
const failedTests = () => wrapper.find('.js-failed-tests'); const failedTests = () => wrapper.find('.js-failed-tests');
...@@ -13,7 +17,7 @@ describe('Test reports summary', () => { ...@@ -13,7 +17,7 @@ describe('Test reports summary', () => {
const duration = () => wrapper.find('.js-duration'); const duration = () => wrapper.find('.js-duration');
const defaultProps = { const defaultProps = {
report: testSuites[0], report: testSuite,
showBack: false, showBack: false,
}; };
...@@ -72,7 +76,7 @@ describe('Test reports summary', () => { ...@@ -72,7 +76,7 @@ describe('Test reports summary', () => {
}); });
it('displays the correctly formatted duration', () => { it('displays the correctly formatted duration', () => {
expect(duration().text()).toBe('00:01:00'); expect(duration().text()).toBe('00:00:00');
}); });
}); });
}); });
...@@ -2,7 +2,7 @@ import Vuex from 'vuex'; ...@@ -2,7 +2,7 @@ import Vuex from 'vuex';
import SummaryTable from '~/pipelines/components/test_reports/test_summary_table.vue'; import SummaryTable from '~/pipelines/components/test_reports/test_summary_table.vue';
import * as getters from '~/pipelines/stores/test_reports/getters'; import * as getters from '~/pipelines/stores/test_reports/getters';
import { mount, createLocalVue } from '@vue/test-utils'; import { mount, createLocalVue } from '@vue/test-utils';
import { testReports, testReportsWithNoSuites } from './mock_data'; import { getJSONFixture } from 'helpers/fixtures';
const localVue = createLocalVue(); const localVue = createLocalVue();
localVue.use(Vuex); localVue.use(Vuex);
...@@ -11,6 +11,8 @@ describe('Test reports summary table', () => { ...@@ -11,6 +11,8 @@ describe('Test reports summary table', () => {
let wrapper; let wrapper;
let store; let store;
const testReports = getJSONFixture('pipelines/test_report.json');
const allSuitesRows = () => wrapper.findAll('.js-suite-row'); const allSuitesRows = () => wrapper.findAll('.js-suite-row');
const noSuitesToShow = () => wrapper.find('.js-no-tests-suites'); const noSuitesToShow = () => wrapper.find('.js-no-tests-suites');
...@@ -44,7 +46,7 @@ describe('Test reports summary table', () => { ...@@ -44,7 +46,7 @@ describe('Test reports summary table', () => {
describe('when there are no test suites', () => { describe('when there are no test suites', () => {
beforeEach(() => { beforeEach(() => {
createComponent({ testReportsWithNoSuites }); createComponent({ test_suites: [] });
}); });
it('displays the no suites to show message', () => { it('displays the no suites to show message', () => {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment