added component specs
This commit is contained in:
parent
dd17a48406
commit
66bf2de830
|
|
@ -9,13 +9,16 @@ import pipelines from './modules/pipelines';
|
|||
|
||||
Vue.use(Vuex);
|
||||
|
||||
export default new Vuex.Store({
|
||||
state: state(),
|
||||
actions,
|
||||
mutations,
|
||||
getters,
|
||||
modules: {
|
||||
commit: commitModule,
|
||||
pipelines,
|
||||
},
|
||||
});
|
||||
export const createStore = () =>
|
||||
new Vuex.Store({
|
||||
state: state(),
|
||||
actions,
|
||||
mutations,
|
||||
getters,
|
||||
modules: {
|
||||
commit: commitModule,
|
||||
pipelines,
|
||||
},
|
||||
});
|
||||
|
||||
export default createStore();
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ export const pipelineFailed = state =>
|
|||
state.latestPipeline && state.latestPipeline.details.status.text === 'failed';
|
||||
|
||||
export const failedStages = state =>
|
||||
state.stages.filter(stage => stage.status.text === 'failed').map(stage => ({
|
||||
state.stages.filter(stage => stage.status.text.toLowerCase() === 'failed').map(stage => ({
|
||||
...stage,
|
||||
jobs: stage.jobs.filter(job => job.status.text === 'failed'),
|
||||
jobs: stage.jobs.filter(job => job.status.text.toLowerCase() === 'failed'),
|
||||
}));
|
||||
|
||||
export const failedJobsCount = state =>
|
||||
|
|
|
|||
|
|
@ -38,16 +38,18 @@ export default {
|
|||
}
|
||||
},
|
||||
[types.REQUEST_JOBS](state, id) {
|
||||
state.stages = state.stages.map(stage => ({
|
||||
...stage,
|
||||
isLoading: id === stage.id ? true : stage.isLoading,
|
||||
}));
|
||||
state.stages = state.stages.map(stage =>
|
||||
Object.assign(stage, {
|
||||
isLoading: id === stage.id ? true : stage.isLoading,
|
||||
}),
|
||||
);
|
||||
},
|
||||
[types.RECEIVE_JOBS_ERROR](state, id) {
|
||||
state.stages = state.stages.map(stage => ({
|
||||
...stage,
|
||||
isLoading: id === stage.id ? true : stage.isLoading,
|
||||
}));
|
||||
state.stages = state.stages.map(stage =>
|
||||
Object.assign(stage, {
|
||||
isLoading: id === stage.id ? true : stage.isLoading,
|
||||
}),
|
||||
);
|
||||
},
|
||||
[types.RECEIVE_JOBS_SUCCESS](state, { id, data }) {
|
||||
const normalizeData = job => ({
|
||||
|
|
@ -57,16 +59,18 @@ export default {
|
|||
path: job.build_path,
|
||||
});
|
||||
|
||||
state.stages = state.stages.map(stage => ({
|
||||
...stage,
|
||||
isLoading: id === stage.id ? false : stage.isLoading,
|
||||
jobs: id === stage.id ? data.latest_statuses.map(normalizeData) : stage.jobs,
|
||||
}));
|
||||
state.stages = state.stages.map(stage =>
|
||||
Object.assign(stage, {
|
||||
isLoading: id === stage.id ? false : stage.isLoading,
|
||||
jobs: id === stage.id ? data.latest_statuses.map(normalizeData) : stage.jobs,
|
||||
}),
|
||||
);
|
||||
},
|
||||
[types.TOGGLE_STAGE_COLLAPSE](state, id) {
|
||||
state.stages = state.stages.map(stage => ({
|
||||
...stage,
|
||||
isCollapsed: stage.id === id ? !stage.isCollapsed : stage.isCollapsed,
|
||||
}));
|
||||
state.stages = state.stages.map(stage =>
|
||||
Object.assign(stage, {
|
||||
isCollapsed: stage.id === id ? !stage.isCollapsed : stage.isCollapsed,
|
||||
}),
|
||||
);
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -24,4 +24,5 @@ export default () => ({
|
|||
unusedSeal: true,
|
||||
fileFindVisible: false,
|
||||
rightPane: null,
|
||||
links: {},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
import Vue from 'vue';
|
||||
import JobItem from '~/ide/components/jobs/item.vue';
|
||||
import mountComponent from '../../../helpers/vue_mount_component_helper';
|
||||
import { jobs } from '../../mock_data';
|
||||
|
||||
describe('IDE jobs item', () => {
|
||||
const Component = Vue.extend(JobItem);
|
||||
const job = jobs[0];
|
||||
let vm;
|
||||
|
||||
beforeEach(() => {
|
||||
vm = mountComponent(Component, {
|
||||
job,
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vm.$destroy();
|
||||
});
|
||||
|
||||
it('renders job details', () => {
|
||||
expect(vm.$el.textContent).toContain(job.name);
|
||||
expect(vm.$el.textContent).toContain(`#${job.id}`);
|
||||
});
|
||||
|
||||
it('renders CI icon', () => {
|
||||
expect(vm.$el.querySelector('.ic-status_passed_borderless')).not.toBe(null);
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
import Vue from 'vue';
|
||||
import StageList from '~/ide/components/jobs/list.vue';
|
||||
import { createStore } from '~/ide/stores';
|
||||
import { createComponentWithStore } from '../../../helpers/vue_mount_component_helper';
|
||||
import { stages, jobs } from '../../mock_data';
|
||||
|
||||
describe('IDE stages list', () => {
|
||||
const Component = Vue.extend(StageList);
|
||||
let vm;
|
||||
|
||||
beforeEach(() => {
|
||||
const store = createStore();
|
||||
|
||||
vm = createComponentWithStore(Component, store, {
|
||||
stages: stages.map((mappedState, i) => ({
|
||||
...mappedState,
|
||||
id: i,
|
||||
dropdownPath: mappedState.dropdown_path,
|
||||
jobs: [...jobs],
|
||||
isLoading: false,
|
||||
isCollapsed: false,
|
||||
})),
|
||||
loading: false,
|
||||
}).$mount();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vm.$destroy();
|
||||
});
|
||||
|
||||
it('renders list of stages', () => {
|
||||
expect(vm.$el.querySelectorAll('.card').length).toBe(2);
|
||||
});
|
||||
|
||||
it('renders loading icon when no stages & is loading', done => {
|
||||
vm.stages = [];
|
||||
vm.loading = true;
|
||||
|
||||
vm.$nextTick(() => {
|
||||
expect(vm.$el.querySelector('.loading-container')).not.toBe(null);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
import Vue from 'vue';
|
||||
import MockAdapter from 'axios-mock-adapter';
|
||||
import axios from '~/lib/utils/axios_utils';
|
||||
import { createStore } from '~/ide/stores';
|
||||
import Stage from '~/ide/components/jobs/stage.vue';
|
||||
import { createComponentWithStore } from '../../../helpers/vue_mount_component_helper';
|
||||
import { stages, jobs } from '../../mock_data';
|
||||
|
||||
describe('IDE pipeline stage', () => {
|
||||
const Component = Vue.extend(Stage);
|
||||
let vm;
|
||||
let mock;
|
||||
let stage;
|
||||
|
||||
beforeEach(done => {
|
||||
const store = createStore();
|
||||
mock = new MockAdapter(axios);
|
||||
|
||||
store.state.pipelines.stages = stages.map((mappedState, i) => ({
|
||||
...mappedState,
|
||||
id: i,
|
||||
dropdownPath: mappedState.dropdown_path,
|
||||
jobs: [],
|
||||
isLoading: false,
|
||||
isCollapsed: false,
|
||||
}));
|
||||
|
||||
stage = store.state.pipelines.stages[0];
|
||||
|
||||
mock.onGet(stage.dropdownPath).reply(200, {
|
||||
latest_statuses: jobs,
|
||||
});
|
||||
|
||||
vm = createComponentWithStore(Component, store, {
|
||||
stage,
|
||||
}).$mount();
|
||||
|
||||
setTimeout(done);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vm.$destroy();
|
||||
|
||||
mock.restore();
|
||||
});
|
||||
|
||||
it('renders stages details', () => {
|
||||
expect(vm.$el.textContent).toContain(vm.stage.name);
|
||||
});
|
||||
|
||||
it('renders CI icon', () => {
|
||||
expect(vm.$el.querySelector('.ic-status_failed')).not.toBe(null);
|
||||
});
|
||||
|
||||
describe('collapsed', () => {
|
||||
it('toggles collapse status when clicking header', done => {
|
||||
vm.$el.querySelector('.card-header').click();
|
||||
|
||||
vm.$nextTick(() => {
|
||||
expect(vm.$el.querySelector('.card-body').style.display).toBe('none');
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('sets border bottom class when collapsed', done => {
|
||||
vm.$el.querySelector('.card-header').click();
|
||||
|
||||
vm.$nextTick(() => {
|
||||
expect(vm.$el.querySelector('.card-header').classList).toContain('border-bottom-0');
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('renders jobs count', () => {
|
||||
expect(vm.$el.querySelector('.badge').textContent).toContain('4');
|
||||
});
|
||||
|
||||
it('renders loading icon when no jobs and isLoading is true', done => {
|
||||
vm.stage.isLoading = true;
|
||||
vm.stage.jobs = [];
|
||||
|
||||
vm.$nextTick(() => {
|
||||
expect(vm.$el.querySelector('.loading-container')).not.toBe(null);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('renders list of jobs', () => {
|
||||
expect(vm.$el.querySelectorAll('.ide-job-item').length).toBe(4);
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
import Vue from 'vue';
|
||||
import MockAdapter from 'axios-mock-adapter';
|
||||
import axios from '~/lib/utils/axios_utils';
|
||||
import { createStore } from '~/ide/stores';
|
||||
import List from '~/ide/components/pipelines/list.vue';
|
||||
import { createComponentWithStore } from '../../../helpers/vue_mount_component_helper';
|
||||
import { pipelines, projectData, stages, jobs } from '../../mock_data';
|
||||
|
||||
describe('IDE pipelines list', () => {
|
||||
const Component = Vue.extend(List);
|
||||
let vm;
|
||||
let mock;
|
||||
|
||||
beforeEach(done => {
|
||||
const store = createStore();
|
||||
|
||||
mock = new MockAdapter(axios);
|
||||
|
||||
store.state.currentProjectId = 'abc/def';
|
||||
store.state.currentBranchId = 'master';
|
||||
store.state.projects['abc/def'] = {
|
||||
...projectData,
|
||||
path_with_namespace: 'abc/def',
|
||||
branches: {
|
||||
master: { commit: { id: '123' } },
|
||||
},
|
||||
};
|
||||
store.state.links = { ciHelpPagePath: gl.TEST_HOST };
|
||||
store.state.pipelinesEmptyStateSvgPath = gl.TEST_HOST;
|
||||
store.state.pipelines.stages = stages.map((mappedState, i) => ({
|
||||
...mappedState,
|
||||
id: i,
|
||||
dropdownPath: mappedState.dropdown_path,
|
||||
jobs: [...jobs],
|
||||
isLoading: false,
|
||||
isCollapsed: false,
|
||||
}));
|
||||
|
||||
mock
|
||||
.onGet('/abc/def/commit/123/pipelines')
|
||||
.reply(200, { pipelines: [...pipelines] }, { 'poll-interval': '-1' });
|
||||
|
||||
vm = createComponentWithStore(Component, store).$mount();
|
||||
|
||||
setTimeout(done);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vm.$destroy();
|
||||
mock.restore();
|
||||
});
|
||||
|
||||
it('renders pipeline data', () => {
|
||||
expect(vm.$el.textContent).toContain('#1');
|
||||
});
|
||||
|
||||
it('renders CI icon', () => {
|
||||
expect(vm.$el.querySelector('.ci-status-icon-failed')).not.toBe(null);
|
||||
});
|
||||
|
||||
it('renders list of jobs', () => {
|
||||
expect(vm.$el.querySelectorAll('.tab-pane:first-child .ide-job-item').length).toBe(
|
||||
jobs.length * stages.length,
|
||||
);
|
||||
});
|
||||
|
||||
it('renders list of failed jobs on failed jobs tab', done => {
|
||||
vm.$el.querySelectorAll('.tab-links a')[1].click();
|
||||
|
||||
vm.$nextTick(() => {
|
||||
expect(vm.$el.querySelectorAll('.tab-pane.active .ide-job-item').length).toBe(2);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('YAML error', () => {
|
||||
it('renders YAML error', done => {
|
||||
vm.$store.state.pipelines.latestPipeline.yamlError = 'test yaml error';
|
||||
|
||||
vm.$nextTick(() => {
|
||||
expect(vm.$el.textContent).toContain('Found errors in your .gitlab-ci.yml:');
|
||||
expect(vm.$el.textContent).toContain('test yaml error');
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('empty state', () => {
|
||||
it('renders pipelines empty state', done => {
|
||||
vm.$store.state.pipelines.latestPipeline = false;
|
||||
|
||||
vm.$nextTick(() => {
|
||||
expect(vm.$el.querySelector('.empty-state')).not.toBe(null);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('loading state', () => {
|
||||
it('renders loading state when there is no latest pipeline', done => {
|
||||
vm.$store.state.pipelines.latestPipeline = null;
|
||||
vm.$store.state.pipelines.isLoadingPipeline = true;
|
||||
|
||||
vm.$nextTick(() => {
|
||||
expect(vm.$el.querySelector('.loading-container')).not.toBe(null);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -1,11 +1,13 @@
|
|||
import { decorateData } from '~/ide/stores/utils';
|
||||
import state from '~/ide/stores/state';
|
||||
import commitState from '~/ide/stores/modules/commit/state';
|
||||
import pipelinesState from '~/ide/stores/modules/pipelines/state';
|
||||
|
||||
export const resetStore = store => {
|
||||
const newState = {
|
||||
...state(),
|
||||
commit: commitState(),
|
||||
pipelines: pipelinesState(),
|
||||
};
|
||||
store.replaceState(newState);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -19,26 +19,38 @@ export const pipelines = [
|
|||
id: 1,
|
||||
ref: 'master',
|
||||
sha: '123',
|
||||
status: 'failed',
|
||||
details: {
|
||||
status: {
|
||||
icon: 'status_failed',
|
||||
group: 'failed',
|
||||
text: 'Failed',
|
||||
},
|
||||
},
|
||||
commit: { id: '123' },
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
ref: 'master',
|
||||
sha: '213',
|
||||
status: 'success',
|
||||
details: {
|
||||
status: {
|
||||
icon: 'status_failed',
|
||||
group: 'failed',
|
||||
text: 'Failed',
|
||||
},
|
||||
},
|
||||
commit: { id: '213' },
|
||||
},
|
||||
];
|
||||
|
||||
export const stages = [
|
||||
{
|
||||
dropdown_path: 'testing',
|
||||
dropdown_path: `${gl.TEST_HOST}/testing`,
|
||||
name: 'build',
|
||||
status: {
|
||||
icon: 'status_failed',
|
||||
group: 'failed',
|
||||
text: 'Failed',
|
||||
text: 'failed',
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -47,7 +59,7 @@ export const stages = [
|
|||
status: {
|
||||
icon: 'status_failed',
|
||||
group: 'failed',
|
||||
text: 'Failed',
|
||||
text: 'failed',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
|
@ -56,28 +68,44 @@ export const jobs = [
|
|||
{
|
||||
id: 1,
|
||||
name: 'test',
|
||||
status: 'failed',
|
||||
path: 'testing',
|
||||
status: {
|
||||
icon: 'status_passed',
|
||||
text: 'passed',
|
||||
},
|
||||
stage: 'test',
|
||||
duration: 1,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: 'test 2',
|
||||
status: 'failed',
|
||||
path: 'testing2',
|
||||
status: {
|
||||
icon: 'status_passed',
|
||||
text: 'passed',
|
||||
},
|
||||
stage: 'test',
|
||||
duration: 1,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: 'test 3',
|
||||
status: 'failed',
|
||||
path: 'testing3',
|
||||
status: {
|
||||
icon: 'status_passed',
|
||||
text: 'passed',
|
||||
},
|
||||
stage: 'test',
|
||||
duration: 1,
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: 'test 3',
|
||||
status: 'failed',
|
||||
name: 'test 4',
|
||||
path: 'testing4',
|
||||
status: {
|
||||
icon: 'status_failed',
|
||||
text: 'failed',
|
||||
},
|
||||
stage: 'build',
|
||||
duration: 1,
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in New Issue