Commit ca4fa069 authored by Andrew Fontaine's avatar Andrew Fontaine

Merge branch 'cngo-move-tests-from-karma-to-jest' into 'master'

Move tests from Karma to Jest

See merge request gitlab-org/gitlab!30500
parents 3bbdea20 86b56868
...@@ -95,22 +95,18 @@ export default { ...@@ -95,22 +95,18 @@ export default {
@click="onClickCollapsedIcon" @click="onClickCollapsedIcon"
> >
<i class="fa fa-users" aria-hidden="true"> </i> <i class="fa fa-users" aria-hidden="true"> </i>
<gl-loading-icon v-if="loading" class="js-participants-collapsed-loading-icon" /> <gl-loading-icon v-if="loading" />
<span v-else class="js-participants-collapsed-count"> {{ participantCount }} </span> <span v-else data-testid="collapsed-count"> {{ participantCount }} </span>
</div> </div>
<div v-if="showParticipantLabel" class="title hide-collapsed"> <div v-if="showParticipantLabel" class="title hide-collapsed">
<gl-loading-icon <gl-loading-icon v-if="loading" :inline="true" />
v-if="loading"
:inline="true"
class="js-participants-expanded-loading-icon"
/>
{{ participantLabel }} {{ participantLabel }}
</div> </div>
<div class="participants-list hide-collapsed"> <div class="participants-list hide-collapsed">
<div <div
v-for="participant in visibleParticipants" v-for="participant in visibleParticipants"
:key="participant.id" :key="participant.id"
class="participants-author js-participants-author" class="participants-author"
> >
<a :href="participant.web_url" class="author-link"> <a :href="participant.web_url" class="author-link">
<user-avatar-image <user-avatar-image
...@@ -125,11 +121,7 @@ export default { ...@@ -125,11 +121,7 @@ export default {
</div> </div>
</div> </div>
<div v-if="hasMoreParticipants" class="participants-more hide-collapsed"> <div v-if="hasMoreParticipants" class="participants-more hide-collapsed">
<button <button type="button" class="btn-transparent btn-link" @click="toggleMoreParticipants">
type="button"
class="btn-transparent btn-link js-toggle-participants-button"
@click="toggleMoreParticipants"
>
{{ toggleLabel }} {{ toggleLabel }}
</button> </button>
</div> </div>
......
export const logMockData = [
'[2018-05-17 16:31:10] INFO WEBrick 1.3.1',
'[2018-05-17 16:31:10] INFO ruby 2.4.1 (2017-03-22) [x86_64-linux-musl]',
'[2018-05-17 16:31:10] INFO WEBrick::HTTPServer#start: pid=5 port=5000',
"172.17.0.1 - - [17/May/2018:16:31:14 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:31:24 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:31:32 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:31:34 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:31:42 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:31:44 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:31:52 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:31:54 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:32:02 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:32:04 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:32:12 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:32:14 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:32:22 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:32:24 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:32:32 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:32:34 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:32:42 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:32:44 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:32:52 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:32:54 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:33:02 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:33:04 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:33:12 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:33:14 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:33:22 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:33:24 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:33:32 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:33:34 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:33:42 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:33:44 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:33:52 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:33:54 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:34:02 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:34:04 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:34:12 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:34:14 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:34:22 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:34:24 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:34:32 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:34:34 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:34:42 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:34:44 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:34:52 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:34:54 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:35:02 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:35:04 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:35:12 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:35:14 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:35:22 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
"172.17.0.1 - - [17/May/2018:16:35:24 UTC] 'GET / HTTP/1.1' 200 13",
'- -> /',
];
export const podMockData = ['production-tanuki-1', 'production-tanuki-2', 'production-tanuki-3'];
export const mockEnvironmentData = [
{
name: 'production',
logs_path: '/namespace/project/environments/1/logs',
id: 1,
},
{
name: 'stating',
logs_path: '/namespace/project/environments/2/logs',
id: 2,
},
{
name: 'review/my-new-branch',
logs_path: '/namespace/project/environments/3/logs',
id: 3,
},
];
export default {};
import { shallowMount } from '@vue/test-utils';
import EditFormButtons from '~/sidebar/components/lock/edit_form_buttons.vue';
describe('EditFormButtons', () => {
let wrapper;
const mountComponent = propsData => shallowMount(EditFormButtons, { propsData });
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
it('displays "Unlock" when locked', () => {
wrapper = mountComponent({
isLocked: true,
updateLockedAttribute: () => {},
});
expect(wrapper.text()).toContain('Unlock');
});
it('displays "Lock" when unlocked', () => {
wrapper = mountComponent({
isLocked: false,
updateLockedAttribute: () => {},
});
expect(wrapper.text()).toContain('Lock');
});
});
import { GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue'; import Vue from 'vue';
import mountComponent from 'spec/helpers/vue_mount_component_helper'; import Participants from '~/sidebar/components/participants/participants.vue';
import participants from '~/sidebar/components/participants/participants.vue';
const PARTICIPANT = { const PARTICIPANT = {
id: 1, id: 1,
...@@ -13,190 +14,193 @@ const PARTICIPANT = { ...@@ -13,190 +14,193 @@ const PARTICIPANT = {
const PARTICIPANT_LIST = [PARTICIPANT, { ...PARTICIPANT, id: 2 }, { ...PARTICIPANT, id: 3 }]; const PARTICIPANT_LIST = [PARTICIPANT, { ...PARTICIPANT, id: 2 }, { ...PARTICIPANT, id: 3 }];
describe('Participants', function() { describe('Participants', () => {
let vm; let wrapper;
let Participants;
beforeEach(() => { const getMoreParticipantsButton = () => wrapper.find('button');
Participants = Vue.extend(participants);
const getCollapsedParticipantsCount = () => wrapper.find('[data-testid="collapsed-count"]');
const mountComponent = propsData =>
shallowMount(Participants, {
propsData,
}); });
afterEach(() => { afterEach(() => {
vm.$destroy(); wrapper.destroy();
wrapper = null;
}); });
describe('collapsed sidebar state', () => { describe('collapsed sidebar state', () => {
it('shows loading spinner when loading', () => { it('shows loading spinner when loading', () => {
vm = mountComponent(Participants, { wrapper = mountComponent({
loading: true, loading: true,
}); });
expect(vm.$el.querySelector('.js-participants-collapsed-loading-icon')).toBeDefined(); expect(wrapper.contains(GlLoadingIcon)).toBe(true);
});
it('does not show loading spinner not loading', () => {
wrapper = mountComponent({
loading: false,
});
expect(wrapper.contains(GlLoadingIcon)).toBe(false);
}); });
it('shows participant count when given', () => { it('shows participant count when given', () => {
vm = mountComponent(Participants, { wrapper = mountComponent({
loading: false, loading: false,
participants: PARTICIPANT_LIST, participants: PARTICIPANT_LIST,
}); });
const countEl = vm.$el.querySelector('.js-participants-collapsed-count');
expect(countEl.textContent.trim()).toBe(`${PARTICIPANT_LIST.length}`); expect(getCollapsedParticipantsCount().text()).toBe(`${PARTICIPANT_LIST.length}`);
}); });
it('shows full participant count when there are hidden participants', () => { it('shows full participant count when there are hidden participants', () => {
vm = mountComponent(Participants, { wrapper = mountComponent({
loading: false, loading: false,
participants: PARTICIPANT_LIST, participants: PARTICIPANT_LIST,
numberOfLessParticipants: 1, numberOfLessParticipants: 1,
}); });
const countEl = vm.$el.querySelector('.js-participants-collapsed-count');
expect(countEl.textContent.trim()).toBe(`${PARTICIPANT_LIST.length}`); expect(getCollapsedParticipantsCount().text()).toBe(`${PARTICIPANT_LIST.length}`);
}); });
}); });
describe('expanded sidebar state', () => { describe('expanded sidebar state', () => {
it('shows loading spinner when loading', () => { it('shows loading spinner when loading', () => {
vm = mountComponent(Participants, { wrapper = mountComponent({
loading: true, loading: true,
}); });
expect(vm.$el.querySelector('.js-participants-expanded-loading-icon')).toBeDefined(); expect(wrapper.contains(GlLoadingIcon)).toBe(true);
}); });
it('when only showing visible participants, shows an avatar only for each participant under the limit', done => { it('when only showing visible participants, shows an avatar only for each participant under the limit', () => {
const numberOfLessParticipants = 2; const numberOfLessParticipants = 2;
vm = mountComponent(Participants, { wrapper = mountComponent({
loading: false, loading: false,
participants: PARTICIPANT_LIST, participants: PARTICIPANT_LIST,
numberOfLessParticipants, numberOfLessParticipants,
}); });
vm.isShowingMoreParticipants = false;
Vue.nextTick() wrapper.setData({
.then(() => { isShowingMoreParticipants: false,
const participantEls = vm.$el.querySelectorAll('.js-participants-author'); });
expect(participantEls.length).toBe(numberOfLessParticipants); return Vue.nextTick().then(() => {
}) expect(wrapper.findAll('.participants-author')).toHaveLength(numberOfLessParticipants);
.then(done) });
.catch(done.fail);
}); });
it('when only showing all participants, each has an avatar', done => { it('when only showing all participants, each has an avatar', () => {
const numberOfLessParticipants = 2; wrapper = mountComponent({
vm = mountComponent(Participants, {
loading: false, loading: false,
participants: PARTICIPANT_LIST, participants: PARTICIPANT_LIST,
numberOfLessParticipants, numberOfLessParticipants: 2,
}); });
vm.isShowingMoreParticipants = true;
Vue.nextTick() wrapper.setData({
.then(() => { isShowingMoreParticipants: true,
const participantEls = vm.$el.querySelectorAll('.js-participants-author'); });
expect(participantEls.length).toBe(PARTICIPANT_LIST.length); return Vue.nextTick().then(() => {
}) expect(wrapper.findAll('.participants-author')).toHaveLength(PARTICIPANT_LIST.length);
.then(done) });
.catch(done.fail);
}); });
it('does not have more participants link when they can all be shown', () => { it('does not have more participants link when they can all be shown', () => {
const numberOfLessParticipants = 100; const numberOfLessParticipants = 100;
vm = mountComponent(Participants, { wrapper = mountComponent({
loading: false, loading: false,
participants: PARTICIPANT_LIST, participants: PARTICIPANT_LIST,
numberOfLessParticipants, numberOfLessParticipants,
}); });
const moreParticipantLink = vm.$el.querySelector('.js-toggle-participants-button');
expect(PARTICIPANT_LIST.length).toBeLessThan(numberOfLessParticipants); expect(PARTICIPANT_LIST.length).toBeLessThan(numberOfLessParticipants);
expect(moreParticipantLink).toBeNull(); expect(getMoreParticipantsButton().exists()).toBe(false);
}); });
it('when too many participants, has more participants link to show more', done => { it('when too many participants, has more participants link to show more', () => {
vm = mountComponent(Participants, { wrapper = mountComponent({
loading: false, loading: false,
participants: PARTICIPANT_LIST, participants: PARTICIPANT_LIST,
numberOfLessParticipants: 2, numberOfLessParticipants: 2,
}); });
vm.isShowingMoreParticipants = false;
Vue.nextTick() wrapper.setData({
.then(() => { isShowingMoreParticipants: false,
const moreParticipantLink = vm.$el.querySelector('.js-toggle-participants-button'); });
expect(moreParticipantLink.textContent.trim()).toBe('+ 1 more'); return Vue.nextTick().then(() => {
}) expect(getMoreParticipantsButton().text()).toBe('+ 1 more');
.then(done) });
.catch(done.fail);
}); });
it('when too many participants and already showing them, has more participants link to show less', done => { it('when too many participants and already showing them, has more participants link to show less', () => {
vm = mountComponent(Participants, { wrapper = mountComponent({
loading: false, loading: false,
participants: PARTICIPANT_LIST, participants: PARTICIPANT_LIST,
numberOfLessParticipants: 2, numberOfLessParticipants: 2,
}); });
vm.isShowingMoreParticipants = true;
Vue.nextTick() wrapper.setData({
.then(() => { isShowingMoreParticipants: true,
const moreParticipantLink = vm.$el.querySelector('.js-toggle-participants-button'); });
expect(moreParticipantLink.textContent.trim()).toBe('- show less'); return Vue.nextTick().then(() => {
}) expect(getMoreParticipantsButton().text()).toBe('- show less');
.then(done) });
.catch(done.fail);
}); });
it('clicking more participants link emits event', () => { it('clicking more participants link emits event', () => {
vm = mountComponent(Participants, { wrapper = mountComponent({
loading: false, loading: false,
participants: PARTICIPANT_LIST, participants: PARTICIPANT_LIST,
numberOfLessParticipants: 2, numberOfLessParticipants: 2,
}); });
const moreParticipantLink = vm.$el.querySelector('.js-toggle-participants-button');
expect(vm.isShowingMoreParticipants).toBe(false); expect(wrapper.vm.isShowingMoreParticipants).toBe(false);
moreParticipantLink.click(); getMoreParticipantsButton().trigger('click');
expect(vm.isShowingMoreParticipants).toBe(true); expect(wrapper.vm.isShowingMoreParticipants).toBe(true);
}); });
it('clicking on participants icon emits `toggleSidebar` event', () => { it('clicking on participants icon emits `toggleSidebar` event', () => {
vm = mountComponent(Participants, { wrapper = mountComponent({
loading: false, loading: false,
participants: PARTICIPANT_LIST, participants: PARTICIPANT_LIST,
numberOfLessParticipants: 2, numberOfLessParticipants: 2,
}); });
spyOn(vm, '$emit');
const participantsIconEl = vm.$el.querySelector('.sidebar-collapsed-icon'); const spy = jest.spyOn(wrapper.vm, '$emit');
participantsIconEl.click(); wrapper.find('.sidebar-collapsed-icon').trigger('click');
expect(vm.$emit).toHaveBeenCalledWith('toggleSidebar'); return Vue.nextTick(() => {
expect(spy).toHaveBeenCalledWith('toggleSidebar');
spy.mockRestore();
});
}); });
}); });
describe('when not showing participants label', () => { describe('when not showing participants label', () => {
beforeEach(() => { beforeEach(() => {
vm = mountComponent(Participants, { wrapper = mountComponent({
participants: PARTICIPANT_LIST, participants: PARTICIPANT_LIST,
showParticipantLabel: false, showParticipantLabel: false,
}); });
}); });
it('does not show sidebar collapsed icon', () => { it('does not show sidebar collapsed icon', () => {
expect(vm.$el.querySelector('.sidebar-collapsed-icon')).not.toBeTruthy(); expect(wrapper.contains('.sidebar-collapsed-icon')).toBe(false);
}); });
it('does not show participants label title', () => { it('does not show participants label title', () => {
expect(vm.$el.querySelector('.title')).not.toBeTruthy(); expect(wrapper.contains('.title')).toBe(false);
}); });
}); });
}); });
import MockAdapter from 'axios-mock-adapter'; import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import * as urlUtility from '~/lib/utils/url_utility';
import SidebarService, { gqClient } from '~/sidebar/services/sidebar_service';
import SidebarMediator from '~/sidebar/sidebar_mediator'; import SidebarMediator from '~/sidebar/sidebar_mediator';
import SidebarStore from '~/sidebar/stores/sidebar_store'; import SidebarStore from '~/sidebar/stores/sidebar_store';
import SidebarService, { gqClient } from '~/sidebar/services/sidebar_service';
import Mock from './mock_data'; import Mock from './mock_data';
const { mediator: mediatorMockData } = Mock; describe('Sidebar mediator', () => {
const { mediator: mediatorMockData } = Mock;
describe('Sidebar mediator', function() {
let mock; let mock;
let mediator;
beforeEach(() => { beforeEach(() => {
mock = new MockAdapter(axios); mock = new MockAdapter(axios);
mediator = new SidebarMediator(mediatorMockData);
this.mediator = new SidebarMediator(mediatorMockData);
}); });
afterEach(() => { afterEach(() => {
...@@ -24,111 +24,112 @@ describe('Sidebar mediator', function() { ...@@ -24,111 +24,112 @@ describe('Sidebar mediator', function() {
}); });
it('assigns yourself ', () => { it('assigns yourself ', () => {
this.mediator.assignYourself(); mediator.assignYourself();
expect(this.mediator.store.currentUser).toEqual(mediatorMockData.currentUser); expect(mediator.store.currentUser).toEqual(mediatorMockData.currentUser);
expect(this.mediator.store.assignees[0]).toEqual(mediatorMockData.currentUser); expect(mediator.store.assignees[0]).toEqual(mediatorMockData.currentUser);
}); });
it('saves assignees', done => { it('saves assignees', () => {
mock.onPut(mediatorMockData.endpoint).reply(200, {}); mock.onPut(mediatorMockData.endpoint).reply(200, {});
this.mediator
.saveAssignees('issue[assignee_ids]') return mediator.saveAssignees('issue[assignee_ids]').then(resp => {
.then(resp => {
expect(resp.status).toEqual(200); expect(resp.status).toEqual(200);
done(); });
})
.catch(done.fail);
}); });
it('fetches the data', done => { it('fetches the data', () => {
const mockData = Mock.responseMap.GET[mediatorMockData.endpoint]; const mockData = Mock.responseMap.GET[mediatorMockData.endpoint];
mock.onGet(mediatorMockData.endpoint).reply(200, mockData); mock.onGet(mediatorMockData.endpoint).reply(200, mockData);
const mockGraphQlData = Mock.graphQlResponseData; const mockGraphQlData = Mock.graphQlResponseData;
spyOn(gqClient, 'query').and.returnValue({ const graphQlSpy = jest.spyOn(gqClient, 'query').mockReturnValue({
data: mockGraphQlData, data: mockGraphQlData,
}); });
const spy = jest.spyOn(mediator, 'processFetchedData').mockReturnValue(Promise.resolve());
spyOn(this.mediator, 'processFetchedData').and.callThrough(); return mediator.fetch().then(() => {
expect(spy).toHaveBeenCalledWith(mockData, mockGraphQlData);
this.mediator spy.mockRestore();
.fetch() graphQlSpy.mockRestore();
.then(() => { });
expect(this.mediator.processFetchedData).toHaveBeenCalledWith(mockData, mockGraphQlData);
})
.then(done)
.catch(done.fail);
}); });
it('processes fetched data', () => { it('processes fetched data', () => {
const mockData = Mock.responseMap.GET[mediatorMockData.endpoint]; const mockData = Mock.responseMap.GET[mediatorMockData.endpoint];
this.mediator.processFetchedData(mockData); mediator.processFetchedData(mockData);
expect(this.mediator.store.assignees).toEqual(mockData.assignees); expect(mediator.store.assignees).toEqual(mockData.assignees);
expect(this.mediator.store.humanTimeEstimate).toEqual(mockData.human_time_estimate); expect(mediator.store.humanTimeEstimate).toEqual(mockData.human_time_estimate);
expect(this.mediator.store.humanTotalTimeSpent).toEqual(mockData.human_total_time_spent); expect(mediator.store.humanTotalTimeSpent).toEqual(mockData.human_total_time_spent);
expect(this.mediator.store.participants).toEqual(mockData.participants); expect(mediator.store.participants).toEqual(mockData.participants);
expect(this.mediator.store.subscribed).toEqual(mockData.subscribed); expect(mediator.store.subscribed).toEqual(mockData.subscribed);
expect(this.mediator.store.timeEstimate).toEqual(mockData.time_estimate); expect(mediator.store.timeEstimate).toEqual(mockData.time_estimate);
expect(this.mediator.store.totalTimeSpent).toEqual(mockData.total_time_spent); expect(mediator.store.totalTimeSpent).toEqual(mockData.total_time_spent);
}); });
it('sets moveToProjectId', () => { it('sets moveToProjectId', () => {
const projectId = 7; const projectId = 7;
spyOn(this.mediator.store, 'setMoveToProjectId').and.callThrough(); const spy = jest.spyOn(mediator.store, 'setMoveToProjectId').mockReturnValue(Promise.resolve());
mediator.setMoveToProjectId(projectId);
this.mediator.setMoveToProjectId(projectId); expect(spy).toHaveBeenCalledWith(projectId);
expect(this.mediator.store.setMoveToProjectId).toHaveBeenCalledWith(projectId); spy.mockRestore();
}); });
it('fetches autocomplete projects', done => { it('fetches autocomplete projects', () => {
const searchTerm = 'foo'; const searchTerm = 'foo';
mock.onGet(mediatorMockData.projectsAutocompleteEndpoint).reply(200, {}); mock.onGet(mediatorMockData.projectsAutocompleteEndpoint).reply(200, {});
spyOn(this.mediator.service, 'getProjectsAutocomplete').and.callThrough(); const getterSpy = jest
spyOn(this.mediator.store, 'setAutocompleteProjects').and.callThrough(); .spyOn(mediator.service, 'getProjectsAutocomplete')
.mockReturnValue(Promise.resolve({ data: {} }));
this.mediator const setterSpy = jest
.fetchAutocompleteProjects(searchTerm) .spyOn(mediator.store, 'setAutocompleteProjects')
.then(() => { .mockReturnValue(Promise.resolve());
expect(this.mediator.service.getProjectsAutocomplete).toHaveBeenCalledWith(searchTerm);
expect(this.mediator.store.setAutocompleteProjects).toHaveBeenCalled(); return mediator.fetchAutocompleteProjects(searchTerm).then(() => {
}) expect(getterSpy).toHaveBeenCalledWith(searchTerm);
.then(done) expect(setterSpy).toHaveBeenCalled();
.catch(done.fail);
getterSpy.mockRestore();
setterSpy.mockRestore();
});
}); });
it('moves issue', done => { it('moves issue', () => {
const mockData = Mock.responseMap.POST[mediatorMockData.moveIssueEndpoint]; const mockData = Mock.responseMap.POST[mediatorMockData.moveIssueEndpoint];
const moveToProjectId = 7; const moveToProjectId = 7;
mock.onPost(mediatorMockData.moveIssueEndpoint).reply(200, mockData); mock.onPost(mediatorMockData.moveIssueEndpoint).reply(200, mockData);
this.mediator.store.setMoveToProjectId(moveToProjectId); mediator.store.setMoveToProjectId(moveToProjectId);
spyOn(this.mediator.service, 'moveIssue').and.callThrough(); const moveIssueSpy = jest
const visitUrl = spyOnDependency(SidebarMediator, 'visitUrl'); .spyOn(mediator.service, 'moveIssue')
.mockReturnValue(Promise.resolve({ data: { web_url: mockData.web_url } }));
this.mediator const urlSpy = jest.spyOn(urlUtility, 'visitUrl').mockReturnValue({});
.moveIssue()
.then(() => { return mediator.moveIssue().then(() => {
expect(this.mediator.service.moveIssue).toHaveBeenCalledWith(moveToProjectId); expect(moveIssueSpy).toHaveBeenCalledWith(moveToProjectId);
expect(visitUrl).toHaveBeenCalledWith(mockData.web_url); expect(urlSpy).toHaveBeenCalledWith(mockData.web_url);
})
.then(done) moveIssueSpy.mockRestore();
.catch(done.fail); urlSpy.mockRestore();
}); });
});
it('toggle subscription', done => {
this.mediator.store.setSubscribedState(false); it('toggle subscription', () => {
mediator.store.setSubscribedState(false);
mock.onPost(mediatorMockData.toggleSubscriptionEndpoint).reply(200, {}); mock.onPost(mediatorMockData.toggleSubscriptionEndpoint).reply(200, {});
spyOn(this.mediator.service, 'toggleSubscription').and.callThrough(); const spy = jest
.spyOn(mediator.service, 'toggleSubscription')
this.mediator .mockReturnValue(Promise.resolve());
.toggleSubscription()
.then(() => { return mediator.toggleSubscription().then(() => {
expect(this.mediator.service.toggleSubscription).toHaveBeenCalled(); expect(spy).toHaveBeenCalled();
expect(this.mediator.store.subscribed).toEqual(true); expect(mediator.store.subscribed).toEqual(true);
})
.then(done) spy.mockRestore();
.catch(done.fail); });
}); });
}); });
import Vue from 'vue'; import { shallowMount } from '@vue/test-utils';
import mountComponent from 'spec/helpers/vue_mount_component_helper'; import SidebarSubscriptions from '~/sidebar/components/subscriptions/sidebar_subscriptions.vue';
import sidebarSubscriptions from '~/sidebar/components/subscriptions/sidebar_subscriptions.vue';
import SidebarMediator from '~/sidebar/sidebar_mediator'; import SidebarMediator from '~/sidebar/sidebar_mediator';
import SidebarService from '~/sidebar/services/sidebar_service'; import SidebarService from '~/sidebar/services/sidebar_service';
import SidebarStore from '~/sidebar/stores/sidebar_store'; import SidebarStore from '~/sidebar/stores/sidebar_store';
import Mock from './mock_data'; import Mock from './mock_data';
describe('Sidebar Subscriptions', function() { describe('Sidebar Subscriptions', () => {
let vm; let wrapper;
let SidebarSubscriptions; let mediator;
beforeEach(() => { beforeEach(() => {
SidebarSubscriptions = Vue.extend(sidebarSubscriptions); mediator = new SidebarMediator(Mock.mediator);
// Set up the stores, services, etc wrapper = shallowMount(SidebarSubscriptions, {
// eslint-disable-next-line no-new propsData: {
new SidebarMediator(Mock.mediator); mediator,
},
});
}); });
afterEach(() => { afterEach(() => {
vm.$destroy(); wrapper.destroy();
SidebarService.singleton = null; SidebarService.singleton = null;
SidebarStore.singleton = null; SidebarStore.singleton = null;
SidebarMediator.singleton = null; SidebarMediator.singleton = null;
}); });
it('calls the mediator toggleSubscription on event', () => { it('calls the mediator toggleSubscription on event', () => {
const mediator = new SidebarMediator(); const spy = jest.spyOn(mediator, 'toggleSubscription').mockReturnValue(Promise.resolve());
spyOn(mediator, 'toggleSubscription').and.returnValue(Promise.resolve());
vm = mountComponent(SidebarSubscriptions, {
mediator,
});
vm.onToggleSubscription(); wrapper.vm.onToggleSubscription();
expect(mediator.toggleSubscription).toHaveBeenCalled(); expect(spy).toHaveBeenCalled();
spy.mockRestore();
}); });
}); });
import Vue from 'vue'; import { shallowMount } from '@vue/test-utils';
import mountComponent from 'spec/helpers/vue_mount_component_helper'; import Subscriptions from '~/sidebar/components/subscriptions/subscriptions.vue';
import { mockTracking } from 'spec/helpers/tracking_helper';
import subscriptions from '~/sidebar/components/subscriptions/subscriptions.vue';
import eventHub from '~/sidebar/event_hub'; import eventHub from '~/sidebar/event_hub';
import ToggleButton from '~/vue_shared/components/toggle_button.vue';
describe('Subscriptions', function() { describe('Subscriptions', () => {
let vm; let wrapper;
let Subscriptions;
beforeEach(() => { const findToggleButton = () => wrapper.find(ToggleButton);
Subscriptions = Vue.extend(subscriptions);
const mountComponent = propsData =>
shallowMount(Subscriptions, {
propsData,
}); });
afterEach(() => { afterEach(() => {
vm.$destroy(); wrapper.destroy();
wrapper = null;
}); });
it('shows loading spinner when loading', () => { it('shows loading spinner when loading', () => {
vm = mountComponent(Subscriptions, { wrapper = mountComponent({
loading: true, loading: true,
subscribed: undefined, subscribed: undefined,
}); });
expect(vm.$refs.toggleButton.isLoading).toBe(true); expect(findToggleButton().attributes('isloading')).toBe('true');
expect(vm.$refs.toggleButton.$el.querySelector('.project-feature-toggle')).toHaveClass(
'is-loading',
);
}); });
it('is toggled "off" when currently not subscribed', () => { it('is toggled "off" when currently not subscribed', () => {
vm = mountComponent(Subscriptions, { wrapper = mountComponent({
subscribed: false, subscribed: false,
}); });
expect(vm.$refs.toggleButton.$el.querySelector('.project-feature-toggle')).not.toHaveClass( expect(findToggleButton().attributes('value')).toBeFalsy();
'is-checked',
);
}); });
it('is toggled "on" when currently subscribed', () => { it('is toggled "on" when currently subscribed', () => {
vm = mountComponent(Subscriptions, { wrapper = mountComponent({
subscribed: true, subscribed: true,
}); });
expect(vm.$refs.toggleButton.$el.querySelector('.project-feature-toggle')).toHaveClass( expect(findToggleButton().attributes('value')).toBe('true');
'is-checked',
);
}); });
it('toggleSubscription method emits `toggleSubscription` event on eventHub and Component', () => { it('toggleSubscription method emits `toggleSubscription` event on eventHub and Component', () => {
vm = mountComponent(Subscriptions, { subscribed: true }); const id = 42;
spyOn(eventHub, '$emit'); wrapper = mountComponent({ subscribed: true, id });
spyOn(vm, '$emit'); const eventHubSpy = jest.spyOn(eventHub, '$emit');
spyOn(vm, 'track'); const wrapperEmitSpy = jest.spyOn(wrapper.vm, '$emit');
vm.toggleSubscription(); wrapper.vm.toggleSubscription();
expect(eventHub.$emit).toHaveBeenCalledWith('toggleSubscription', jasmine.any(Object)); expect(eventHubSpy).toHaveBeenCalledWith('toggleSubscription', id);
expect(vm.$emit).toHaveBeenCalledWith('toggleSubscription', jasmine.any(Object)); expect(wrapperEmitSpy).toHaveBeenCalledWith('toggleSubscription', id);
eventHubSpy.mockRestore();
wrapperEmitSpy.mockRestore();
}); });
it('tracks the event when toggled', () => { it('tracks the event when toggled', () => {
vm = mountComponent(Subscriptions, { subscribed: true }); wrapper = mountComponent({ subscribed: true });
const spy = mockTracking('_category_', vm.$el, spyOn);
vm.toggleSubscription();
expect(spy).toHaveBeenCalled(); const wrapperTrackSpy = jest.spyOn(wrapper.vm, 'track');
wrapper.vm.toggleSubscription();
expect(wrapperTrackSpy).toHaveBeenCalledWith('toggle_button', {
property: 'notifications',
value: 0,
});
wrapperTrackSpy.mockRestore();
}); });
it('onClickCollapsedIcon method emits `toggleSidebar` event on component', () => { it('onClickCollapsedIcon method emits `toggleSidebar` event on component', () => {
vm = mountComponent(Subscriptions, { subscribed: true }); wrapper = mountComponent({ subscribed: true });
spyOn(vm, '$emit'); const spy = jest.spyOn(wrapper.vm, '$emit');
vm.onClickCollapsedIcon(); wrapper.vm.onClickCollapsedIcon();
expect(vm.$emit).toHaveBeenCalledWith('toggleSidebar'); expect(spy).toHaveBeenCalledWith('toggleSidebar');
spy.mockRestore();
}); });
describe('given project emails are disabled', () => { describe('given project emails are disabled', () => {
const subscribeDisabledDescription = 'Notifications have been disabled'; const subscribeDisabledDescription = 'Notifications have been disabled';
beforeEach(() => { beforeEach(() => {
vm = mountComponent(Subscriptions, { wrapper = mountComponent({
subscribed: false, subscribed: false,
projectEmailsDisabled: true, projectEmailsDisabled: true,
subscribeDisabledDescription, subscribeDisabledDescription,
...@@ -89,12 +93,14 @@ describe('Subscriptions', function() { ...@@ -89,12 +93,14 @@ describe('Subscriptions', function() {
}); });
it('sets the correct display text', () => { it('sets the correct display text', () => {
expect(vm.$el.textContent).toContain(subscribeDisabledDescription); expect(wrapper.find('.issuable-header-text').text()).toContain(subscribeDisabledDescription);
expect(vm.$refs.tooltip.dataset.originalTitle).toBe(subscribeDisabledDescription); expect(wrapper.find({ ref: 'tooltip' }).attributes('data-original-title')).toBe(
subscribeDisabledDescription,
);
}); });
it('does not render the toggle button', () => { it('does not render the toggle button', () => {
expect(vm.$refs.toggleButton).toBeUndefined(); expect(wrapper.contains('.js-issuable-subscribe-button')).toBe(false);
}); });
}); });
}); });
import Vue from 'vue';
import mountComponent from 'spec/helpers/vue_mount_component_helper';
import editFormButtons from '~/sidebar/components/lock/edit_form_buttons.vue';
describe('EditFormButtons', () => {
let vm1;
let vm2;
beforeEach(() => {
const Component = Vue.extend(editFormButtons);
const toggleForm = () => {};
const updateLockedAttribute = () => {};
vm1 = mountComponent(Component, {
isLocked: true,
toggleForm,
updateLockedAttribute,
});
vm2 = mountComponent(Component, {
isLocked: false,
toggleForm,
updateLockedAttribute,
});
});
it('renders unlock or lock text based on locked state', () => {
expect(vm1.$el.innerHTML.includes('Unlock')).toBe(true);
expect(vm2.$el.innerHTML.includes('Lock')).toBe(true);
});
});
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