Commit 8171af01 authored by Clement Ho's avatar Clement Ho

Merge branch 'refactor-stage-spec-to-jest' into 'master'

Refactor stage_spec to Jest

Closes #31625

See merge request gitlab-org/gitlab!16854
parents 50e51888 1de6c1d2
...@@ -58,6 +58,7 @@ export default { ...@@ -58,6 +58,7 @@ export default {
<template> <template>
<div class="ide-stage card prepend-top-default"> <div class="ide-stage card prepend-top-default">
<div <div
ref="cardHeader"
:class="{ :class="{
'border-bottom-0': stage.isCollapsed, 'border-bottom-0': stage.isCollapsed,
}" }"
...@@ -79,7 +80,7 @@ export default { ...@@ -79,7 +80,7 @@ export default {
</div> </div>
<icon :name="collapseIcon" class="ide-stage-collapse-icon" /> <icon :name="collapseIcon" class="ide-stage-collapse-icon" />
</div> </div>
<div v-show="!stage.isCollapsed" class="card-body"> <div v-show="!stage.isCollapsed" ref="jobList" class="card-body">
<gl-loading-icon v-if="showLoadingIcon" /> <gl-loading-icon v-if="showLoadingIcon" />
<template v-else> <template v-else>
<item v-for="job in stage.jobs" :key="job.id" :job="job" @clickViewLog="clickViewLog" /> <item v-for="job in stage.jobs" :key="job.id" :job="job" @clickViewLog="clickViewLog" />
......
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`IDE pipeline stage renders stage details & icon 1`] = `
<div
class="ide-stage card prepend-top-default"
>
<div
class="card-header"
>
<ciicon-stub
cssclasses=""
size="24"
status="[object Object]"
/>
<strong
class="prepend-left-8 ide-stage-title"
data-container="body"
data-original-title=""
title=""
>
build
</strong>
<div
class="append-right-8 prepend-left-4"
>
<span
class="badge badge-pill"
>
4
</span>
</div>
<icon-stub
class="ide-stage-collapse-icon"
name="angle-down"
size="16"
/>
</div>
<div
class="card-body"
>
<item-stub
job="[object Object]"
/>
<item-stub
job="[object Object]"
/>
<item-stub
job="[object Object]"
/>
<item-stub
job="[object Object]"
/>
</div>
</div>
`;
import { shallowMount } from '@vue/test-utils';
import { GlLoadingIcon } from '@gitlab/ui';
import Stage from '~/ide/components/jobs/stage.vue';
import Item from '~/ide/components/jobs/item.vue';
import { stages, jobs } from '../../mock_data';
describe('IDE pipeline stage', () => {
let wrapper;
const defaultProps = {
stage: {
...stages[0],
id: 0,
dropdownPath: stages[0].dropdown_path,
jobs: [...jobs],
isLoading: false,
isCollapsed: false,
},
};
const findHeader = () => wrapper.find({ ref: 'cardHeader' });
const findJobList = () => wrapper.find({ ref: 'jobList' });
const createComponent = props => {
wrapper = shallowMount(Stage, {
propsData: {
...defaultProps,
...props,
},
sync: false,
});
};
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
it('emits fetch event when mounted', () => {
createComponent();
expect(wrapper.emitted().fetch).toBeDefined();
});
it('renders loading icon when no jobs and isLoading is true', () => {
createComponent({
stage: { ...defaultProps.stage, isLoading: true, jobs: [] },
});
expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
});
it('emits toggleCollaped event with stage id when clicking header', () => {
const id = 5;
createComponent({ stage: { ...defaultProps.stage, id } });
findHeader().trigger('click');
expect(wrapper.emitted().toggleCollapsed[0][0]).toBe(id);
});
it('emits clickViewLog entity with job', () => {
const [job] = defaultProps.stage.jobs;
createComponent();
wrapper
.findAll(Item)
.at(0)
.vm.$emit('clickViewLog', job);
expect(wrapper.emitted().clickViewLog[0][0]).toBe(job);
});
it('renders stage details & icon', () => {
createComponent();
expect(wrapper.element).toMatchSnapshot();
});
describe('when collapsed', () => {
beforeEach(() => {
createComponent({ stage: { ...defaultProps.stage, isCollapsed: true } });
});
it('does not render job list', () => {
expect(findJobList().isVisible()).toBe(false);
});
it('sets border bottom class', () => {
expect(findHeader().classes('border-bottom-0')).toBe(true);
});
});
});
import Vue from 'vue';
import Stage from '~/ide/components/jobs/stage.vue';
import { stages, jobs } from '../../mock_data';
describe('IDE pipeline stage', () => {
const Component = Vue.extend(Stage);
let vm;
let stage;
beforeEach(() => {
stage = {
...stages[0],
id: 0,
dropdownPath: stages[0].dropdown_path,
jobs: [...jobs],
isLoading: false,
isCollapsed: false,
};
vm = new Component({
propsData: { stage },
});
spyOn(vm, '$emit');
vm.$mount();
});
afterEach(() => {
vm.$destroy();
});
it('emits fetch event when mounted', () => {
expect(vm.$emit).toHaveBeenCalledWith('fetch', vm.stage);
});
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('emits event when clicking header', done => {
vm.$el.querySelector('.card-header').click();
vm.$nextTick(() => {
expect(vm.$emit).toHaveBeenCalledWith('toggleCollapsed', vm.stage.id);
done();
});
});
it('toggles collapse status when collapsed', done => {
vm.stage.isCollapsed = true;
vm.$nextTick(() => {
expect(vm.$el.querySelector('.card-body').style.display).toBe('none');
done();
});
});
it('sets border bottom class when collapsed', done => {
vm.stage.isCollapsed = true;
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);
});
});
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