Commit b169ada0 authored by Enrique Alcántara's avatar Enrique Alcántara

Merge branch 'vs-migrate-ee-vue-shared-to-jest' into 'master'

Migrate ee/vue_shared tests to Jest

Closes #194310

See merge request gitlab-org/gitlab!29337
parents 93ad0fcc 20bfde42
...@@ -4,10 +4,12 @@ import mockData from './linked_pipelines_mock_data'; ...@@ -4,10 +4,12 @@ import mockData from './linked_pipelines_mock_data';
const ListComponent = Vue.extend(LinkedPipelinesMiniList); const ListComponent = Vue.extend(LinkedPipelinesMiniList);
describe('Linked pipeline mini list', function() { describe('Linked pipeline mini list', () => {
let component;
describe('when passed an upstream pipeline as prop', () => { describe('when passed an upstream pipeline as prop', () => {
beforeEach(() => { beforeEach(() => {
this.component = new ListComponent({ component = new ListComponent({
propsData: { propsData: {
triggeredBy: [mockData.triggered_by], triggeredBy: [mockData.triggered_by],
}, },
...@@ -15,55 +17,55 @@ describe('Linked pipeline mini list', function() { ...@@ -15,55 +17,55 @@ describe('Linked pipeline mini list', function() {
}); });
it('should render one linked pipeline item', () => { it('should render one linked pipeline item', () => {
expect(this.component.$el.querySelectorAll('.linked-pipeline-mini-item').length).toBe(1); expect(component.$el.querySelectorAll('.linked-pipeline-mini-item').length).toBe(1);
}); });
it('should render a linked pipeline with the correct href', () => { it('should render a linked pipeline with the correct href', () => {
const linkElement = this.component.$el.querySelector('.linked-pipeline-mini-item'); const linkElement = component.$el.querySelector('.linked-pipeline-mini-item');
expect(linkElement.getAttribute('href')).toBe('/gitlab-org/gitlab-foss/pipelines/129'); expect(linkElement.getAttribute('href')).toBe('/gitlab-org/gitlab-foss/pipelines/129');
}); });
it('should render one ci status icon', () => { it('should render one ci status icon', () => {
expect(this.component.$el.querySelectorAll('.linked-pipeline-mini-item svg').length).toBe(1); expect(component.$el.querySelectorAll('.linked-pipeline-mini-item svg').length).toBe(1);
}); });
it('should render the correct ci status icon', () => { it('should render the correct ci status icon', () => {
const iconElement = this.component.$el.querySelector('.linked-pipeline-mini-item'); const iconElement = component.$el.querySelector('.linked-pipeline-mini-item');
expect(iconElement.classList.contains('ci-status-icon-running')).toBe(true); expect(iconElement.classList.contains('ci-status-icon-running')).toBe(true);
expect(iconElement.innerHTML).toContain('<svg'); expect(iconElement.innerHTML).toContain('<svg');
}); });
it('should render an arrow icon', () => { it('should render an arrow icon', () => {
const iconElement = this.component.$el.querySelector('.arrow-icon'); const iconElement = component.$el.querySelector('.arrow-icon');
expect(iconElement).not.toBeNull(); expect(iconElement).not.toBeNull();
expect(iconElement.innerHTML).toContain('long-arrow'); expect(iconElement.innerHTML).toContain('long-arrow');
}); });
it('should have an activated tooltip', () => { it('should have an activated tooltip', () => {
const itemElement = this.component.$el.querySelector('.linked-pipeline-mini-item'); const itemElement = component.$el.querySelector('.linked-pipeline-mini-item');
expect(itemElement.getAttribute('data-original-title')).toBe('GitLabCE - running'); expect(itemElement.getAttribute('data-original-title')).toBe('GitLabCE - running');
}); });
it('should correctly set is-upstream', () => { it('should correctly set is-upstream', () => {
expect(this.component.$el.classList.contains('is-upstream')).toBe(true); expect(component.$el.classList.contains('is-upstream')).toBe(true);
}); });
it('should correctly compute shouldRenderCounter', () => { it('should correctly compute shouldRenderCounter', () => {
expect(this.component.shouldRenderCounter).toBe(false); expect(component.shouldRenderCounter).toBe(false);
}); });
it('should not render the pipeline counter', () => { it('should not render the pipeline counter', () => {
expect(this.component.$el.querySelector('.linked-pipelines-counter')).toBeNull(); expect(component.$el.querySelector('.linked-pipelines-counter')).toBeNull();
}); });
}); });
describe('when passed downstream pipelines as props', () => { describe('when passed downstream pipelines as props', () => {
beforeEach(() => { beforeEach(() => {
this.component = new ListComponent({ component = new ListComponent({
propsData: { propsData: {
triggered: mockData.triggered, triggered: mockData.triggered,
pipelinePath: 'my/pipeline/path', pipelinePath: 'my/pipeline/path',
...@@ -73,65 +75,64 @@ describe('Linked pipeline mini list', function() { ...@@ -73,65 +75,64 @@ describe('Linked pipeline mini list', function() {
it('should render one linked pipeline item', () => { it('should render one linked pipeline item', () => {
expect( expect(
this.component.$el.querySelectorAll( component.$el.querySelectorAll('.linked-pipeline-mini-item:not(.linked-pipelines-counter)')
'.linked-pipeline-mini-item:not(.linked-pipelines-counter)', .length,
).length,
).toBe(3); ).toBe(3);
}); });
it('should render three ci status icons', () => { it('should render three ci status icons', () => {
expect(this.component.$el.querySelectorAll('.linked-pipeline-mini-item svg').length).toBe(3); expect(component.$el.querySelectorAll('.linked-pipeline-mini-item svg').length).toBe(3);
}); });
it('should render the correct ci status icon', () => { it('should render the correct ci status icon', () => {
const iconElement = this.component.$el.querySelector('.linked-pipeline-mini-item'); const iconElement = component.$el.querySelector('.linked-pipeline-mini-item');
expect(iconElement.classList.contains('ci-status-icon-running')).toBe(true); expect(iconElement.classList.contains('ci-status-icon-running')).toBe(true);
expect(iconElement.innerHTML).toContain('<svg'); expect(iconElement.innerHTML).toContain('<svg');
}); });
it('should render an arrow icon', () => { it('should render an arrow icon', () => {
const iconElement = this.component.$el.querySelector('.arrow-icon'); const iconElement = component.$el.querySelector('.arrow-icon');
expect(iconElement).not.toBeNull(); expect(iconElement).not.toBeNull();
expect(iconElement.innerHTML).toContain('long-arrow'); expect(iconElement.innerHTML).toContain('long-arrow');
}); });
it('should have prepped tooltips', () => { it('should have prepped tooltips', () => {
const itemElement = this.component.$el.querySelectorAll('.linked-pipeline-mini-item')[2]; const itemElement = component.$el.querySelectorAll('.linked-pipeline-mini-item')[2];
expect(itemElement.getAttribute('data-original-title')).toBe('GitLabCE - running'); expect(itemElement.getAttribute('data-original-title')).toBe('GitLabCE - running');
}); });
it('should correctly set is-downstream', () => { it('should correctly set is-downstream', () => {
expect(this.component.$el.classList.contains('is-downstream')).toBe(true); expect(component.$el.classList.contains('is-downstream')).toBe(true);
}); });
it('should correctly compute shouldRenderCounter', () => { it('should correctly compute shouldRenderCounter', () => {
expect(this.component.shouldRenderCounter).toBe(true); expect(component.shouldRenderCounter).toBe(true);
}); });
it('should correctly trim linkedPipelines', () => { it('should correctly trim linkedPipelines', () => {
expect(this.component.triggered.length).toBe(6); expect(component.triggered.length).toBe(6);
expect(this.component.linkedPipelinesTrimmed.length).toBe(3); expect(component.linkedPipelinesTrimmed.length).toBe(3);
}); });
it('should render the pipeline counter', () => { it('should render the pipeline counter', () => {
expect(this.component.$el.querySelector('.linked-pipelines-counter')).not.toBeNull(); expect(component.$el.querySelector('.linked-pipelines-counter')).not.toBeNull();
}); });
it('should set the correct pipeline path', () => { it('should set the correct pipeline path', () => {
expect( expect(component.$el.querySelector('.linked-pipelines-counter').getAttribute('href')).toBe(
this.component.$el.querySelector('.linked-pipelines-counter').getAttribute('href'), 'my/pipeline/path',
).toBe('my/pipeline/path'); );
}); });
it('should render the correct counterTooltipText', () => { it('should render the correct counterTooltipText', () => {
expect( expect(
this.component.$el component.$el
.querySelector('.linked-pipelines-counter') .querySelector('.linked-pipelines-counter')
.getAttribute('data-original-title'), .getAttribute('data-original-title'),
).toBe(this.component.counterTooltipText); ).toBe(component.counterTooltipText);
}); });
}); });
}); });
import Vue from 'vue'; import Vue from 'vue';
import { componentNames } from 'ee/reports/components/issue_body'; import { componentNames } from 'ee/reports/components/issue_body';
import store from 'ee/vue_shared/security_reports/store'; import store from 'ee/vue_shared/security_reports/store';
import mountComponent, { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper'; import mountComponent, { mountComponentWithStore } from 'helpers/vue_mount_component_helper';
import { codequalityParsedIssues } from 'ee_spec/vue_mr_widget/mock_data'; import { codequalityParsedIssues } from 'ee_jest/vue_mr_widget/mock_data';
import { import {
sastParsedIssues, sastParsedIssues,
dockerReportParsed, dockerReportParsed,
parsedDast, parsedDast,
secretScanningParsedIssues, secretScanningParsedIssues,
} from 'ee_spec/vue_shared/security_reports/mock_data'; } from 'ee_jest/vue_shared/security_reports/mock_data';
import { STATUS_FAILED, STATUS_SUCCESS } from '~/reports/constants'; import { STATUS_FAILED, STATUS_SUCCESS } from '~/reports/constants';
import reportIssues from '~/reports/components/report_item.vue'; import reportIssues from '~/reports/components/report_item.vue';
......
import Vue from 'vue'; import Vue from 'vue';
import { componentNames } from 'ee/reports/components/issue_body'; import { componentNames } from 'ee/reports/components/issue_body';
import store from 'ee/vue_shared/security_reports/store'; import store from 'ee/vue_shared/security_reports/store';
import mountComponent, { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper'; import mountComponent, { mountComponentWithStore } from 'helpers/vue_mount_component_helper';
import { codequalityParsedIssues } from 'ee_spec/vue_mr_widget/mock_data'; import { codequalityParsedIssues } from 'ee_jest/vue_mr_widget/mock_data';
import { import {
sastParsedIssues, sastParsedIssues,
dockerReportParsed, dockerReportParsed,
parsedDast, parsedDast,
secretScanningParsedIssues, secretScanningParsedIssues,
} from 'ee_spec/vue_shared/security_reports/mock_data'; } from 'ee_jest/vue_shared/security_reports/mock_data';
import { STATUS_FAILED, STATUS_SUCCESS } from '~/reports/constants'; import { STATUS_FAILED, STATUS_SUCCESS } from '~/reports/constants';
import reportIssue from '~/reports/components/report_item.vue'; import reportIssue from '~/reports/components/report_item.vue';
......
import SafeLink from 'ee/vue_shared/components/safe_link.vue'; import SafeLink from 'ee/vue_shared/components/safe_link.vue';
import { mountComponentWithSlots } from 'spec/helpers/vue_mount_component_helper'; import { mountComponentWithSlots } from 'helpers/vue_mount_component_helper';
import { TEST_HOST } from 'spec/test_constants'; import { TEST_HOST } from 'helpers/test_constants';
import Vue from 'vue'; import Vue from 'vue';
describe('SafeLink', () => { describe('SafeLink', () => {
......
import { shallowMount, createLocalVue } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import Alerts from 'ee/vue_shared/dashboards/components/alerts.vue'; import Alerts from 'ee/vue_shared/dashboards/components/alerts.vue';
const localVue = createLocalVue();
describe('alerts component', () => { describe('alerts component', () => {
const AlertsComponent = localVue.extend(Alerts);
let wrapper; let wrapper;
const mount = (propsData = {}) => const mount = (propsData = {}) =>
shallowMount(AlertsComponent, { shallowMount(Alerts, {
propsData, propsData,
}); });
......
import { mount, createLocalVue } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import ProjectPipeline from 'ee/vue_shared/dashboards/components/project_pipeline.vue'; import ProjectPipeline from 'ee/vue_shared/dashboards/components/project_pipeline.vue';
import { mockPipelineData } from '../mock_data'; import { mockPipelineData } from 'ee_jest/vue_shared/dashboards/mock_data';
const localVue = createLocalVue();
describe('project pipeline component', () => { describe('project pipeline component', () => {
const ProjectPipelineComponent = localVue.extend(ProjectPipeline);
let wrapper; let wrapper;
const mountComponent = (propsData = {}) => const mountComponent = (propsData = {}) =>
mount(ProjectPipelineComponent, { mount(ProjectPipeline, {
propsData, propsData,
}); });
......
import { shallowMount, createLocalVue } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import TimeAgo from 'ee/vue_shared/dashboards/components/time_ago.vue'; import TimeAgo from 'ee/vue_shared/dashboards/components/time_ago.vue';
const localVue = createLocalVue();
describe('time ago component', () => { describe('time ago component', () => {
const TimeAgoComponent = localVue.extend(TimeAgo);
let wrapper; let wrapper;
beforeEach(() => { beforeEach(() => {
wrapper = shallowMount(TimeAgoComponent, { wrapper = shallowMount(TimeAgo, {
localVue,
propsData: { propsData: {
time: new Date(Date.now() - 86400000).toISOString(), time: new Date(Date.now() - 86400000).toISOString(),
tooltipText: 'Finished', tooltipText: 'Finished',
......
import MockAdapter from 'axios-mock-adapter'; import MockAdapter from 'axios-mock-adapter';
import createStore from 'ee/vue_shared/dashboards/store/index'; import createStore from 'ee/vue_shared/dashboards/store/index';
import * as types from 'ee/vue_shared/dashboards/store/mutation_types'; import * as types from 'ee/vue_shared/dashboards/store/mutation_types';
import defaultActions, * as actions from 'ee/vue_shared/dashboards/store/actions'; import * as actions from 'ee/vue_shared/dashboards/store/actions';
import testAction from 'spec/helpers/vuex_action_helper'; import testAction from 'helpers/vuex_action_helper';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import createFlash from '~/flash';
import clearState from '../helpers'; import clearState from '../helpers';
import { mockHeaders, mockText, mockProjectData } from '../mock_data'; import { mockHeaders, mockText, mockProjectData } from 'ee_jest/vue_shared/dashboards/mock_data';
jest.mock('~/flash');
describe('actions', () => { describe('actions', () => {
const mockAddEndpoint = 'mock-add_endpoint'; const mockAddEndpoint = 'mock-add_endpoint';
...@@ -28,13 +32,13 @@ describe('actions', () => { ...@@ -28,13 +32,13 @@ describe('actions', () => {
}); });
describe('addProjectsToDashboard', () => { describe('addProjectsToDashboard', () => {
it('posts selected project ids to project add endpoint', done => { it('posts selected project ids to project add endpoint', () => {
store.state.projectEndpoints.add = mockAddEndpoint; store.state.projectEndpoints.add = mockAddEndpoint;
store.state.selectedProjects = mockProjects; store.state.selectedProjects = mockProjects;
mockAxios.onPost(mockAddEndpoint).replyOnce(200, mockResponse); mockAxios.onPost(mockAddEndpoint).replyOnce(200, mockResponse);
testAction( return testAction(
actions.addProjectsToDashboard, actions.addProjectsToDashboard,
null, null,
store.state, store.state,
...@@ -45,27 +49,25 @@ describe('actions', () => { ...@@ -45,27 +49,25 @@ describe('actions', () => {
payload: mockResponse, payload: mockResponse,
}, },
], ],
done,
); );
}); });
it('calls addProjectsToDashboard error handler on error', done => { it('calls addProjectsToDashboard error handler on error', () => {
mockAxios.onPost(mockAddEndpoint).replyOnce(500); mockAxios.onPost(mockAddEndpoint).replyOnce(500);
testAction( return testAction(
actions.addProjectsToDashboard, actions.addProjectsToDashboard,
null, null,
store.state, store.state,
[], [],
[{ type: 'receiveAddProjectsToDashboardError' }], [{ type: 'receiveAddProjectsToDashboardError' }],
done,
); );
}); });
}); });
describe('toggleSelectedProject', () => { describe('toggleSelectedProject', () => {
it(`adds a project to selectedProjects if it doesn't already exist in the list`, done => { it(`adds a project to selectedProjects if it doesn't already exist in the list`, () => {
testAction( return testAction(
actions.toggleSelectedProject, actions.toggleSelectedProject,
mockOneProject, mockOneProject,
store.state, store.state,
...@@ -76,14 +78,13 @@ describe('actions', () => { ...@@ -76,14 +78,13 @@ describe('actions', () => {
}, },
], ],
[], [],
done,
); );
}); });
it(`removes a project from selectedProjects if it already exist in the list`, done => { it(`removes a project from selectedProjects if it already exist in the list`, () => {
store.state.selectedProjects = mockProjects; store.state.selectedProjects = mockProjects;
testAction( return testAction(
actions.toggleSelectedProject, actions.toggleSelectedProject,
mockOneProject, mockOneProject,
store.state, store.state,
...@@ -94,14 +95,13 @@ describe('actions', () => { ...@@ -94,14 +95,13 @@ describe('actions', () => {
}, },
], ],
[], [],
done,
); );
}); });
}); });
describe('receiveAddProjectsToDashboardSuccess', () => { describe('receiveAddProjectsToDashboardSuccess', () => {
it('fetches projects when new projects are added to the dashboard', done => { it('fetches projects when new projects are added to the dashboard', () => {
testAction( return testAction(
actions.receiveAddProjectsToDashboardSuccess, actions.receiveAddProjectsToDashboardSuccess,
{ {
added: [1], added: [1],
...@@ -115,7 +115,6 @@ describe('actions', () => { ...@@ -115,7 +115,6 @@ describe('actions', () => {
type: 'forceProjectsRequest', type: 'forceProjectsRequest',
}, },
], ],
done,
); );
}); });
...@@ -137,27 +136,26 @@ describe('actions', () => { ...@@ -137,27 +136,26 @@ describe('actions', () => {
}); });
it('displays an error when user tries to add one invalid project to dashboard', () => { it('displays an error when user tries to add one invalid project to dashboard', () => {
const spy = spyOnDependency(defaultActions, 'createFlash');
selectProjects(1); selectProjects(1);
addInvalidProjects([0]); addInvalidProjects([0]);
expect(spy).toHaveBeenCalledWith(`Unable to add mock-name. ${errorMessage}`); expect(createFlash).toHaveBeenCalledWith(`Unable to add mock-name. ${errorMessage}`);
}); });
it('displays an error when user tries to add two invalid projects to dashboard', () => { it('displays an error when user tries to add two invalid projects to dashboard', () => {
const spy = spyOnDependency(defaultActions, 'createFlash');
selectProjects(2); selectProjects(2);
addInvalidProjects([0, 1]); addInvalidProjects([0, 1]);
expect(spy).toHaveBeenCalledWith(`Unable to add mock-name and mock-name. ${errorMessage}`); expect(createFlash).toHaveBeenCalledWith(
`Unable to add mock-name and mock-name. ${errorMessage}`,
);
}); });
it('displays an error when user tries to add more than two invalid projects to dashboard', () => { it('displays an error when user tries to add more than two invalid projects to dashboard', () => {
const spy = spyOnDependency(defaultActions, 'createFlash');
selectProjects(3); selectProjects(3);
addInvalidProjects([0, 1, 2]); addInvalidProjects([0, 1, 2]);
expect(spy).toHaveBeenCalledWith( expect(createFlash).toHaveBeenCalledWith(
`Unable to add mock-name, mock-name, and mock-name. ${errorMessage}`, `Unable to add mock-name, mock-name, and mock-name. ${errorMessage}`,
); );
}); });
...@@ -165,18 +163,17 @@ describe('actions', () => { ...@@ -165,18 +163,17 @@ describe('actions', () => {
describe('receiveAddProjectsToDashboardError', () => { describe('receiveAddProjectsToDashboardError', () => {
it('shows error message', () => { it('shows error message', () => {
const spy = spyOnDependency(defaultActions, 'createFlash');
store.dispatch('receiveAddProjectsToDashboardError'); store.dispatch('receiveAddProjectsToDashboardError');
expect(spy).toHaveBeenCalledWith(mockText.ADD_PROJECTS_ERROR); expect(createFlash).toHaveBeenCalledWith(mockText.ADD_PROJECTS_ERROR);
}); });
}); });
describe('clearSearchResults', () => { describe('clearSearchResults', () => {
it('clears all project search results', done => { it('clears all project search results', () => {
store.state.projectSearchResults = mockProjects; store.state.projectSearchResults = mockProjects;
testAction( return testAction(
actions.clearSearchResults, actions.clearSearchResults,
null, null,
store.state, store.state,
...@@ -186,57 +183,53 @@ describe('actions', () => { ...@@ -186,57 +183,53 @@ describe('actions', () => {
}, },
], ],
[], [],
done,
); );
}); });
}); });
describe('fetchProjects', () => { describe('fetchProjects', () => {
it('calls project list endpoint', done => { it('calls project list endpoint', () => {
store.state.projectEndpoints.list = mockListEndpoint; store.state.projectEndpoints.list = mockListEndpoint;
mockAxios.onGet(mockListEndpoint).replyOnce(200); mockAxios.onGet(mockListEndpoint).replyOnce(200);
testAction( return testAction(
actions.fetchProjects, actions.fetchProjects,
null, null,
store.state, store.state,
[], [],
[{ type: 'requestProjects' }, { type: 'receiveProjectsSuccess' }], [{ type: 'requestProjects' }, { type: 'receiveProjectsSuccess' }],
done,
); );
}); });
it('handles response errors', done => { it('handles response errors', () => {
store.state.projectEndpoints.list = mockListEndpoint; store.state.projectEndpoints.list = mockListEndpoint;
mockAxios.onGet(mockListEndpoint).replyOnce(500); mockAxios.onGet(mockListEndpoint).replyOnce(500);
testAction( return testAction(
actions.fetchProjects, actions.fetchProjects,
null, null,
store.state, store.state,
[], [],
[{ type: 'requestProjects' }, { type: 'receiveProjectsError' }], [{ type: 'requestProjects' }, { type: 'receiveProjectsError' }],
done,
); );
}); });
}); });
describe('requestProjects', () => { describe('requestProjects', () => {
it('toggles project loading state', done => { it('toggles project loading state', () => {
testAction( return testAction(
actions.requestProjects, actions.requestProjects,
null, null,
store.state, store.state,
[{ type: types.REQUEST_PROJECTS }], [{ type: types.REQUEST_PROJECTS }],
[], [],
done,
); );
}); });
}); });
describe('receiveProjectsSuccess', () => { describe('receiveProjectsSuccess', () => {
it('sets projects from data on success', done => { it('sets projects from data on success', () => {
testAction( return testAction(
actions.receiveProjectsSuccess, actions.receiveProjectsSuccess,
{ projects: mockProjects }, { projects: mockProjects },
store.state, store.state,
...@@ -247,14 +240,12 @@ describe('actions', () => { ...@@ -247,14 +240,12 @@ describe('actions', () => {
}, },
], ],
[], [],
done,
); );
}); });
}); });
describe('receiveProjectsError', () => { describe('receiveProjectsError', () => {
it('clears projects and alerts user of error', done => { it('clears projects and alerts user of error', () => {
const spy = spyOnDependency(defaultActions, 'createFlash');
store.state.projects = mockProjects; store.state.projects = mockProjects;
testAction( testAction(
...@@ -267,71 +258,65 @@ describe('actions', () => { ...@@ -267,71 +258,65 @@ describe('actions', () => {
}, },
], ],
[], [],
done,
); );
expect(spy).toHaveBeenCalledWith(mockText.RECEIVE_PROJECTS_ERROR); expect(createFlash).toHaveBeenCalledWith(mockText.RECEIVE_PROJECTS_ERROR);
}); });
}); });
describe('removeProject', () => { describe('removeProject', () => {
const mockRemovePath = 'mock-removePath'; const mockRemovePath = 'mock-removePath';
it('calls project removal path and fetches projects on success', done => { it('calls project removal path and fetches projects on success', () => {
mockAxios.onDelete(mockRemovePath).replyOnce(200); mockAxios.onDelete(mockRemovePath).replyOnce(200);
testAction( return testAction(
actions.removeProject, actions.removeProject,
mockRemovePath, mockRemovePath,
null, null,
[], [],
[{ type: 'receiveRemoveProjectSuccess' }], [{ type: 'receiveRemoveProjectSuccess' }],
done,
); );
}); });
it('passes off handling of project removal errors', done => { it('passes off handling of project removal errors', () => {
mockAxios.onDelete(mockRemovePath).replyOnce(500); mockAxios.onDelete(mockRemovePath).replyOnce(500);
testAction( return testAction(
actions.removeProject, actions.removeProject,
mockRemovePath, mockRemovePath,
null, null,
[], [],
[{ type: 'receiveRemoveProjectError' }], [{ type: 'receiveRemoveProjectError' }],
done,
); );
}); });
}); });
describe('receiveRemoveProjectSuccess', () => { describe('receiveRemoveProjectSuccess', () => {
it('fetches dashboard projects', done => { it('fetches dashboard projects', () => {
testAction( return testAction(
actions.receiveRemoveProjectSuccess, actions.receiveRemoveProjectSuccess,
null, null,
null, null,
[], [],
[{ type: 'forceProjectsRequest' }], [{ type: 'forceProjectsRequest' }],
done,
); );
}); });
}); });
describe('receiveRemoveProjectError', () => { describe('receiveRemoveProjectError', () => {
it('displays project removal error', done => { it('displays project removal error', () => {
const spy = spyOnDependency(defaultActions, 'createFlash'); return testAction(actions.receiveRemoveProjectError, null, null, [], []).then(() => {
expect(createFlash).toHaveBeenCalledWith(mockText.REMOVE_PROJECT_ERROR);
testAction(actions.receiveRemoveProjectError, null, null, [], [], done); });
expect(spy).toHaveBeenCalledWith(mockText.REMOVE_PROJECT_ERROR);
}); });
}); });
describe('fetchSearchResults', () => { describe('fetchSearchResults', () => {
it('dispatches minimumQueryMessage if the search query is falsy', done => { it('dispatches minimumQueryMessage if the search query is falsy', () => {
const searchQueries = [null, undefined, false, NaN]; const searchQueries = [null, undefined, false, NaN];
Promise.all( return Promise.all(
searchQueries.map(searchQuery => { searchQueries.map(searchQuery => {
store.state.searchQuery = searchQuery; store.state.searchQuery = searchQuery;
...@@ -350,15 +335,13 @@ describe('actions', () => { ...@@ -350,15 +335,13 @@ describe('actions', () => {
], ],
); );
}), }),
) );
.then(done)
.catch(done.fail);
}); });
it('dispatches minimumQueryMessage if the search query was empty', done => { it('dispatches minimumQueryMessage if the search query was empty', () => {
store.state.searchQuery = ''; store.state.searchQuery = '';
testAction( return testAction(
actions.fetchSearchResults, actions.fetchSearchResults,
null, null,
store.state, store.state,
...@@ -371,14 +354,13 @@ describe('actions', () => { ...@@ -371,14 +354,13 @@ describe('actions', () => {
type: 'minimumQueryMessage', type: 'minimumQueryMessage',
}, },
], ],
done,
); );
}); });
it(`dispatches minimumQueryMessage if the search query wasn't long enough`, done => { it(`dispatches minimumQueryMessage if the search query wasn't long enough`, () => {
store.state.searchQuery = 'a'; store.state.searchQuery = 'a';
testAction( return testAction(
actions.fetchSearchResults, actions.fetchSearchResults,
null, null,
store.state, store.state,
...@@ -391,15 +373,14 @@ describe('actions', () => { ...@@ -391,15 +373,14 @@ describe('actions', () => {
type: 'minimumQueryMessage', type: 'minimumQueryMessage',
}, },
], ],
done,
); );
}); });
it(`dispatches the correct actions when the query is valid`, done => { it(`dispatches the correct actions when the query is valid`, () => {
mockAxios.onAny().reply(200, mockProjects, mockHeaders); mockAxios.onAny().reply(200, mockProjects, mockHeaders);
store.state.searchQuery = 'mock-query'; store.state.searchQuery = 'mock-query';
testAction( return testAction(
actions.fetchSearchResults, actions.fetchSearchResults,
null, null,
store.state, store.state,
...@@ -413,16 +394,16 @@ describe('actions', () => { ...@@ -413,16 +394,16 @@ describe('actions', () => {
payload: { data: mockProjects, headers: mockHeaders }, payload: { data: mockProjects, headers: mockHeaders },
}, },
], ],
done,
); );
}); });
}); });
describe('fetchNextPage', () => { describe('fetchNextPage', () => {
it(`fetches the next page`, done => { it(`fetches the next page`, () => {
mockAxios.onAny().reply(200, mockProjects, mockHeaders); mockAxios.onAny().reply(200, mockProjects, mockHeaders);
store.state.pageInfo = mockHeaders.pageInfo; store.state.pageInfo = mockHeaders.pageInfo;
testAction(
return testAction(
actions.fetchNextPage, actions.fetchNextPage,
null, null,
store.state, store.state,
...@@ -433,21 +414,21 @@ describe('actions', () => { ...@@ -433,21 +414,21 @@ describe('actions', () => {
payload: { data: mockProjects, headers: mockHeaders }, payload: { data: mockProjects, headers: mockHeaders },
}, },
], ],
done,
); );
}); });
it(`stops fetching if current page is the last page`, done => { it(`stops fetching if current page is the last page`, () => {
mockAxios.onAny().reply(200, mockProjects, mockHeaders); mockAxios.onAny().reply(200, mockProjects, mockHeaders);
store.state.pageInfo.totalPages = 3; store.state.pageInfo.totalPages = 3;
store.state.pageInfo.currentPage = 3; store.state.pageInfo.currentPage = 3;
testAction(actions.fetchNextPage, mockHeaders, store.state, [], [], done);
return testAction(actions.fetchNextPage, mockHeaders, store.state, [], []);
}); });
}); });
describe('requestSearchResults', () => { describe('requestSearchResults', () => {
it(`commits the REQUEST_SEARCH_RESULTS mutation`, done => { it(`commits the REQUEST_SEARCH_RESULTS mutation`, () => {
testAction( return testAction(
actions.requestSearchResults, actions.requestSearchResults,
null, null,
store.state, store.state,
...@@ -457,14 +438,13 @@ describe('actions', () => { ...@@ -457,14 +438,13 @@ describe('actions', () => {
}, },
], ],
[], [],
done,
); );
}); });
}); });
describe('receiveNextPageSuccess', () => { describe('receiveNextPageSuccess', () => {
it(`commits the RECEIVE_NEXT_PAGE_SUCCESS mutation`, done => { it(`commits the RECEIVE_NEXT_PAGE_SUCCESS mutation`, () => {
testAction( return testAction(
actions.receiveNextPageSuccess, actions.receiveNextPageSuccess,
mockHeaders, mockHeaders,
store.state, store.state,
...@@ -475,14 +455,13 @@ describe('actions', () => { ...@@ -475,14 +455,13 @@ describe('actions', () => {
}, },
], ],
[], [],
done,
); );
}); });
}); });
describe('receiveSearchResultsSuccess', () => { describe('receiveSearchResultsSuccess', () => {
it('commits the RECEIVE_SEARCH_RESULTS_SUCCESS mutation', done => { it('commits the RECEIVE_SEARCH_RESULTS_SUCCESS mutation', () => {
testAction( return testAction(
actions.receiveSearchResultsSuccess, actions.receiveSearchResultsSuccess,
mockProjects, mockProjects,
store.state, store.state,
...@@ -493,14 +472,13 @@ describe('actions', () => { ...@@ -493,14 +472,13 @@ describe('actions', () => {
}, },
], ],
[], [],
done,
); );
}); });
}); });
describe('receiveSearchResultsError', () => { describe('receiveSearchResultsError', () => {
it('commits the RECEIVE_SEARCH_RESULTS_ERROR mutation', done => { it('commits the RECEIVE_SEARCH_RESULTS_ERROR mutation', () => {
testAction( return testAction(
actions.receiveSearchResultsError, actions.receiveSearchResultsError,
['error'], ['error'],
store.state, store.state,
...@@ -510,14 +488,13 @@ describe('actions', () => { ...@@ -510,14 +488,13 @@ describe('actions', () => {
}, },
], ],
[], [],
done,
); );
}); });
}); });
describe('setProjectEndpoints', () => { describe('setProjectEndpoints', () => {
it('commits project list and add endpoints', done => { it('commits project list and add endpoints', () => {
testAction( return testAction(
actions.setProjectEndpoints, actions.setProjectEndpoints,
{ {
add: mockAddEndpoint, add: mockAddEndpoint,
...@@ -535,7 +512,6 @@ describe('actions', () => { ...@@ -535,7 +512,6 @@ describe('actions', () => {
}, },
], ],
[], [],
done,
); );
}); });
}); });
......
import state from 'ee/vue_shared/dashboards/store/state'; import state from 'ee/vue_shared/dashboards/store/state';
import mutations from 'ee/vue_shared/dashboards/store/mutations'; import mutations from 'ee/vue_shared/dashboards/store/mutations';
import * as types from 'ee/vue_shared/dashboards/store/mutation_types'; import * as types from 'ee/vue_shared/dashboards/store/mutation_types';
import { mockProjectData } from '../mock_data'; import { mockProjectData } from 'ee_jest/vue_shared/dashboards/mock_data';
import createFlash from '~/flash';
import { useLocalStorageSpy } from 'helpers/local_storage_helper';
jest.mock('~/flash');
describe('mutations', () => { describe('mutations', () => {
useLocalStorageSpy();
const projects = mockProjectData(3); const projects = mockProjectData(3);
const projectIds = projects.map(p => p.id); const projectIds = projects.map(p => p.id);
const mockEndpoint = 'https://mock-endpoint'; const mockEndpoint = 'https://mock-endpoint';
...@@ -35,8 +41,6 @@ describe('mutations', () => { ...@@ -35,8 +41,6 @@ describe('mutations', () => {
}); });
it('sets projects', () => { it('sets projects', () => {
spyOn(window.localStorage, 'setItem');
mutations[types.SET_PROJECTS](localState, projects); mutations[types.SET_PROJECTS](localState, projects);
expect(localState.projects).toEqual(projects); expect(localState.projects).toEqual(projects);
...@@ -44,16 +48,15 @@ describe('mutations', () => { ...@@ -44,16 +48,15 @@ describe('mutations', () => {
}); });
it('stores project IDs in localstorage', () => { it('stores project IDs in localstorage', () => {
const saveToLocalStorage = spyOn(window.localStorage, 'setItem');
mutations[types.SET_PROJECTS](localState, projects); mutations[types.SET_PROJECTS](localState, projects);
expect(saveToLocalStorage).toHaveBeenCalledWith('listEndpoint', projectIds); expect(window.localStorage.setItem).toHaveBeenCalledWith('listEndpoint', projectIds);
}); });
it('shows warning Alert if localStorage not available', () => { it('shows warning Alert if localStorage not available', () => {
spyOn(window.localStorage, 'setItem').and.throwError('QUOTA_EXCEEDED_ERR: DOM Exception 22'); jest.spyOn(window.localStorage, 'setItem').mockImplementation(() => {
const createFlash = spyOnDependency(mutations, 'createFlash'); throw new Error('QUOTA_EXCEEDED_ERR: DOM Exception 22');
});
mutations[types.SET_PROJECTS](localState, projects); mutations[types.SET_PROJECTS](localState, projects);
...@@ -112,11 +115,9 @@ describe('mutations', () => { ...@@ -112,11 +115,9 @@ describe('mutations', () => {
describe('RECEIVE_PROJECTS_SUCCESS', () => { describe('RECEIVE_PROJECTS_SUCCESS', () => {
const projectListEndpoint = 'projectListEndpoint'; const projectListEndpoint = 'projectListEndpoint';
let saveToLocalStorage;
beforeEach(() => { beforeEach(() => {
localState.projectEndpoints.list = projectListEndpoint; localState.projectEndpoints.list = projectListEndpoint;
saveToLocalStorage = spyOn(window.localStorage, 'setItem');
}); });
it('sets the project list and clears the loading status', () => { it('sets the project list and clears the loading status', () => {
...@@ -129,11 +130,11 @@ describe('mutations', () => { ...@@ -129,11 +130,11 @@ describe('mutations', () => {
it('saves projects to localStorage', () => { it('saves projects to localStorage', () => {
mutations[types.RECEIVE_PROJECTS_SUCCESS](localState, projects); mutations[types.RECEIVE_PROJECTS_SUCCESS](localState, projects);
expect(saveToLocalStorage).toHaveBeenCalledWith(projectListEndpoint, projectIds); expect(window.localStorage.setItem).toHaveBeenCalledWith(projectListEndpoint, projectIds);
}); });
it('orders the projects from localstorage', () => { it('orders the projects from localstorage', () => {
spyOn(window.localStorage, 'getItem').and.callFake(key => { jest.spyOn(window.localStorage, 'getItem').mockImplementation(key => {
if (key === projectListEndpoint) { if (key === projectListEndpoint) {
return '2,0,1'; return '2,0,1';
} }
...@@ -147,7 +148,7 @@ describe('mutations', () => { ...@@ -147,7 +148,7 @@ describe('mutations', () => {
}); });
it('places unsorted projects after sorted ones', () => { it('places unsorted projects after sorted ones', () => {
spyOn(window.localStorage, 'getItem').and.callFake(key => { jest.spyOn(window.localStorage, 'getItem').mockImplementation(key => {
if (key === projectListEndpoint) { if (key === projectListEndpoint) {
return '1,2'; return '1,2';
} }
......
import { shallowMount, createLocalVue } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import MetricReportsIssueBody from 'ee/vue_shared/metrics_reports/components/metrics_reports_issue_body.vue'; import MetricReportsIssueBody from 'ee/vue_shared/metrics_reports/components/metrics_reports_issue_body.vue';
const localVue = createLocalVue();
describe('Metrics reports issue body', () => { describe('Metrics reports issue body', () => {
const Component = localVue.extend(MetricReportsIssueBody);
let wrapper; let wrapper;
afterEach(() => { afterEach(() => {
...@@ -15,8 +12,7 @@ describe('Metrics reports issue body', () => { ...@@ -15,8 +12,7 @@ describe('Metrics reports issue body', () => {
describe('when metric did not change', () => { describe('when metric did not change', () => {
it('should render metric with no changes text', () => { it('should render metric with no changes text', () => {
wrapper = shallowMount(Component, { wrapper = shallowMount(MetricReportsIssueBody, {
localVue,
propsData: { propsData: {
issue: { issue: {
name: 'name', name: 'name',
...@@ -33,8 +29,7 @@ describe('Metrics reports issue body', () => { ...@@ -33,8 +29,7 @@ describe('Metrics reports issue body', () => {
describe('when metric changed', () => { describe('when metric changed', () => {
it('should render metric with change', () => { it('should render metric with change', () => {
wrapper = shallowMount(Component, { wrapper = shallowMount(MetricReportsIssueBody, {
localVue,
propsData: { propsData: {
issue: { issue: {
name: 'name', name: 'name',
...@@ -52,8 +47,7 @@ describe('Metrics reports issue body', () => { ...@@ -52,8 +47,7 @@ describe('Metrics reports issue body', () => {
describe('when metric is new', () => { describe('when metric is new', () => {
it('should render metric with new badge', () => { it('should render metric with new badge', () => {
wrapper = shallowMount(Component, { wrapper = shallowMount(MetricReportsIssueBody, {
localVue,
propsData: { propsData: {
issue: { issue: {
name: 'name', name: 'name',
...@@ -73,8 +67,7 @@ describe('Metrics reports issue body', () => { ...@@ -73,8 +67,7 @@ describe('Metrics reports issue body', () => {
describe('when metric was removed', () => { describe('when metric was removed', () => {
it('should render metric with removed badge', () => { it('should render metric with removed badge', () => {
wrapper = shallowMount(Component, { wrapper = shallowMount(MetricReportsIssueBody, {
localVue,
propsData: { propsData: {
issue: { issue: {
name: 'name', name: 'name',
......
...@@ -8,12 +8,11 @@ const localVue = createLocalVue(); ...@@ -8,12 +8,11 @@ const localVue = createLocalVue();
localVue.use(Vuex); localVue.use(Vuex);
describe('Grouped metrics reports app', () => { describe('Grouped metrics reports app', () => {
const Component = localVue.extend(GroupedMetricsReportsApp);
let wrapper; let wrapper;
let mockStore; let mockStore;
const mountComponent = () => { const mountComponent = () => {
wrapper = mount(Component, { wrapper = mount(GroupedMetricsReportsApp, {
store: mockStore, store: mockStore,
localVue, localVue,
propsData: { propsData: {
......
...@@ -8,7 +8,7 @@ import { ...@@ -8,7 +8,7 @@ import {
} from 'ee/vue_shared/metrics_reports/store/actions'; } from 'ee/vue_shared/metrics_reports/store/actions';
import * as types from 'ee/vue_shared/metrics_reports/store/mutation_types'; import * as types from 'ee/vue_shared/metrics_reports/store/mutation_types';
import state from 'ee/vue_shared/metrics_reports/store/state'; import state from 'ee/vue_shared/metrics_reports/store/state';
import testAction from 'spec/helpers/vuex_action_helper'; import testAction from 'helpers/vuex_action_helper';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
describe('metrics reports actions', () => { describe('metrics reports actions', () => {
...@@ -25,8 +25,8 @@ describe('metrics reports actions', () => { ...@@ -25,8 +25,8 @@ describe('metrics reports actions', () => {
}); });
describe('setEndpoint', () => { describe('setEndpoint', () => {
it('should commit set endpoint', done => { it('should commit set endpoint', () => {
testAction( return testAction(
setEndpoint, setEndpoint,
'path', 'path',
mockedState, mockedState,
...@@ -37,14 +37,13 @@ describe('metrics reports actions', () => { ...@@ -37,14 +37,13 @@ describe('metrics reports actions', () => {
}, },
], ],
[], [],
done,
); );
}); });
}); });
describe('requestMetrics', () => { describe('requestMetrics', () => {
it('should commit request mutation', done => { it('should commit request mutation', () => {
testAction( return testAction(
requestMetrics, requestMetrics,
null, null,
mockedState, mockedState,
...@@ -54,13 +53,12 @@ describe('metrics reports actions', () => { ...@@ -54,13 +53,12 @@ describe('metrics reports actions', () => {
}, },
], ],
[], [],
done,
); );
}); });
}); });
describe('fetchMetrics', () => { describe('fetchMetrics', () => {
it('should call metrics endpoint', done => { it('should call metrics endpoint', () => {
const data = { const data = {
metrics: [ metrics: [
{ {
...@@ -73,7 +71,7 @@ describe('metrics reports actions', () => { ...@@ -73,7 +71,7 @@ describe('metrics reports actions', () => {
mockedState.endpoint = endpoint; mockedState.endpoint = endpoint;
mock.onGet(endpoint).replyOnce(200, data); mock.onGet(endpoint).replyOnce(200, data);
testAction( return testAction(
fetchMetrics, fetchMetrics,
null, null,
mockedState, mockedState,
...@@ -87,16 +85,15 @@ describe('metrics reports actions', () => { ...@@ -87,16 +85,15 @@ describe('metrics reports actions', () => {
type: 'receiveMetricsSuccess', type: 'receiveMetricsSuccess',
}, },
], ],
done,
); );
}); });
it('handles errors', done => { it('handles errors', () => {
const endpoint = '/mock-endpoint.json'; const endpoint = '/mock-endpoint.json';
mockedState.endpoint = endpoint; mockedState.endpoint = endpoint;
mock.onGet(endpoint).replyOnce(500); mock.onGet(endpoint).replyOnce(500);
testAction( return testAction(
fetchMetrics, fetchMetrics,
null, null,
mockedState, mockedState,
...@@ -109,15 +106,14 @@ describe('metrics reports actions', () => { ...@@ -109,15 +106,14 @@ describe('metrics reports actions', () => {
type: 'receiveMetricsError', type: 'receiveMetricsError',
}, },
], ],
done,
); );
}); });
}); });
describe('receiveMetricsSuccess', () => { describe('receiveMetricsSuccess', () => {
it('should commit request mutation', done => { it('should commit request mutation', () => {
const response = { metrics: [] }; const response = { metrics: [] };
testAction( return testAction(
receiveMetricsSuccess, receiveMetricsSuccess,
response, response,
mockedState, mockedState,
...@@ -128,14 +124,13 @@ describe('metrics reports actions', () => { ...@@ -128,14 +124,13 @@ describe('metrics reports actions', () => {
}, },
], ],
[], [],
done,
); );
}); });
}); });
describe('receiveMetricsError', () => { describe('receiveMetricsError', () => {
it('should commit request mutation', done => { it('should commit request mutation', () => {
testAction( return testAction(
receiveMetricsError, receiveMetricsError,
null, null,
mockedState, mockedState,
...@@ -145,7 +140,6 @@ describe('metrics reports actions', () => { ...@@ -145,7 +140,6 @@ describe('metrics reports actions', () => {
}, },
], ],
[], [],
done,
); );
}); });
}); });
......
export { default } from 'ee_jest/vue_shared/components/linked_pipelines_mock_data';
// No new code should be added to this file. Instead, modify the
// file this one re-exports from. For more detail about why, see:
// https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/31349
export * from '../../../../spec/frontend/vue_shared/dashboards/mock_data';
import * as mockData from '../../../frontend/vue_shared/security_reports/mock_data';
// This is done to help keep the mock data across testing suites in sync.
// https://gitlab.com/gitlab-org/gitlab/merge_requests/10466#note_156218753
export const {
dockerReportParsed,
parsedDast,
sastParsedIssues,
secretScanningParsedIssues,
sastDiffSuccessMock,
dastDiffSuccessMock,
containerScanningDiffSuccessMock,
dependencyScanningDiffSuccessMock,
secretScanningDiffSuccessMock,
} = mockData;
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