Commit 574b1058 authored by Paul Slaughter's avatar Paul Slaughter

Merge branch '194194-spec-js-badges-to-jest' into 'master'

Migrate spec/javascripts/badges/ to Jest

Closes #194194

See merge request gitlab-org/gitlab!25118
parents 3f5729cb c7cc41e8
import Vue from 'vue';
import MockAdapter from 'axios-mock-adapter';
import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
import { mountComponentWithStore } from 'helpers/vue_mount_component_helper';
import axios from '~/lib/utils/axios_utils';
import store from '~/badges/store';
import createEmptyBadge from '~/badges/empty_badge';
import BadgeForm from '~/badges/components/badge_form.vue';
import { DUMMY_IMAGE_URL, TEST_HOST } from '../../test_constants';
import { DUMMY_IMAGE_URL, TEST_HOST } from 'helpers/test_constants';
// avoid preview background process
BadgeForm.methods.debouncedPreview = () => {};
......@@ -41,7 +41,7 @@ describe('BadgeForm component', () => {
describe('onCancel', () => {
it('calls stopEditing', () => {
spyOn(vm, 'stopEditing');
jest.spyOn(vm, 'stopEditing').mockImplementation(() => {});
vm.onCancel();
......@@ -68,14 +68,14 @@ describe('BadgeForm component', () => {
const expectInvalidInput = inputElementSelector => {
const inputElement = vm.$el.querySelector(inputElementSelector);
expect(inputElement).toBeMatchedBy(':invalid');
expect(inputElement.checkValidity()).toBe(false);
const feedbackElement = vm.$el.querySelector(`${inputElementSelector} + .invalid-feedback`);
expect(feedbackElement).toBeVisible();
};
beforeEach(() => {
spyOn(vm, submitAction).and.returnValue(Promise.resolve());
beforeEach(done => {
jest.spyOn(vm, submitAction).mockReturnValue(Promise.resolve());
store.replaceState({
...store.state,
badgeInAddForm: createEmptyBadge(),
......@@ -83,9 +83,14 @@ describe('BadgeForm component', () => {
isSaving: false,
});
setValue(nameSelector, 'TestBadge');
setValue(linkUrlSelector, `${TEST_HOST}/link/url`);
setValue(imageUrlSelector, `${window.location.origin}${DUMMY_IMAGE_URL}`);
Vue.nextTick()
.then(() => {
setValue(nameSelector, 'TestBadge');
setValue(linkUrlSelector, `${TEST_HOST}/link/url`);
setValue(imageUrlSelector, `${window.location.origin}${DUMMY_IMAGE_URL}`);
})
.then(done)
.catch(done.fail);
});
it('returns immediately if imageUrl is empty', () => {
......@@ -131,8 +136,8 @@ describe('BadgeForm component', () => {
it(`calls ${submitAction}`, () => {
submitForm();
expect(findImageUrlElement()).toBeMatchedBy(':valid');
expect(findLinkUrlElement()).toBeMatchedBy(':valid');
expect(findImageUrlElement().checkValidity()).toBe(true);
expect(findLinkUrlElement().checkValidity()).toBe(true);
expect(vm[submitAction]).toHaveBeenCalled();
});
};
......
import $ from 'jquery';
import Vue from 'vue';
import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
import { mountComponentWithStore } from 'helpers/vue_mount_component_helper';
import { GROUP_BADGE, PROJECT_BADGE } from '~/badges/constants';
import store from '~/badges/store';
import BadgeListRow from '~/badges/components/badge_list_row.vue';
......@@ -40,15 +39,15 @@ describe('BadgeListRow component', () => {
});
it('renders the badge name', () => {
expect(vm.$el).toContainText(badge.name);
expect(vm.$el.innerText).toMatch(badge.name);
});
it('renders the badge link', () => {
expect(vm.$el).toContainText(badge.linkUrl);
expect(vm.$el.innerText).toMatch(badge.linkUrl);
});
it('renders the badge kind', () => {
expect(vm.$el).toContainText('Project Badge');
expect(vm.$el.innerText).toMatch('Project Badge');
});
it('shows edit and delete buttons', () => {
......@@ -66,7 +65,7 @@ describe('BadgeListRow component', () => {
});
it('calls editBadge when clicking then edit button', () => {
spyOn(vm, 'editBadge');
jest.spyOn(vm, 'editBadge').mockImplementation(() => {});
const editButton = vm.$el.querySelector('.table-button-footer button:first-of-type');
editButton.click();
......@@ -75,13 +74,17 @@ describe('BadgeListRow component', () => {
});
it('calls updateBadgeInModal and shows modal when clicking then delete button', done => {
spyOn(vm, 'updateBadgeInModal');
$('#delete-badge-modal').on('shown.bs.modal', () => done());
jest.spyOn(vm, 'updateBadgeInModal').mockImplementation(() => {});
const deleteButton = vm.$el.querySelector('.table-button-footer button:last-of-type');
deleteButton.click();
expect(vm.updateBadgeInModal).toHaveBeenCalled();
Vue.nextTick()
.then(() => {
expect(vm.updateBadgeInModal).toHaveBeenCalled();
})
.then(done)
.catch(done.fail);
});
describe('for a group badge', () => {
......@@ -94,7 +97,7 @@ describe('BadgeListRow component', () => {
});
it('renders the badge kind', () => {
expect(vm.$el).toContainText('Group Badge');
expect(vm.$el.innerText).toMatch('Group Badge');
});
it('hides edit and delete buttons', () => {
......
import Vue from 'vue';
import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
import { mountComponentWithStore } from 'helpers/vue_mount_component_helper';
import { GROUP_BADGE, PROJECT_BADGE } from '~/badges/constants';
import store from '~/badges/store';
import BadgeList from '~/badges/components/badge_list.vue';
......@@ -22,6 +22,10 @@ describe('BadgeList component', () => {
kind: PROJECT_BADGE,
isLoading: false,
});
// Can be removed once GlLoadingIcon no longer throws a warning
jest.spyOn(global.console, 'warn').mockImplementation(() => jest.fn());
vm = mountComponentWithStore(Component, {
el: '#dummy-element',
store,
......@@ -49,7 +53,7 @@ describe('BadgeList component', () => {
Vue.nextTick()
.then(() => {
expect(vm.$el).toContainText('This project has no badges');
expect(vm.$el.innerText).toMatch('This project has no badges');
})
.then(done)
.catch(done.fail);
......@@ -82,7 +86,7 @@ describe('BadgeList component', () => {
Vue.nextTick()
.then(() => {
expect(vm.$el).toContainText('This group has no badges');
expect(vm.$el.innerText).toMatch('This group has no badges');
})
.then(done)
.catch(done.fail);
......
import $ from 'jquery';
import Vue from 'vue';
import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
import { mountComponentWithStore } from 'helpers/vue_mount_component_helper';
import store from '~/badges/store';
import BadgeSettings from '~/badges/components/badge_settings.vue';
import { createDummyBadge } from '../dummy_badge';
......@@ -19,6 +18,10 @@ describe('BadgeSettings component', () => {
data-target="#delete-badge-modal"
>Show modal</button>
`);
// Can be removed once GlLoadingIcon no longer throws a warning
jest.spyOn(global.console, 'warn').mockImplementation(() => jest.fn());
vm = mountComponentWithStore(Component, {
el: '#dummy-element',
store,
......@@ -35,20 +38,16 @@ describe('BadgeSettings component', () => {
const modal = vm.$el.querySelector('#delete-badge-modal');
const button = document.getElementById('dummy-modal-button');
$(modal).on('shown.bs.modal', () => {
expect(modal).toContainText('Delete badge?');
const badgeElement = modal.querySelector('img.project-badge');
expect(badgeElement).not.toBe(null);
expect(badgeElement.getAttribute('src')).toBe(badge.renderedImageUrl);
done();
});
button.click();
Vue.nextTick()
.then(() => {
button.click();
expect(modal.innerText).toMatch('Delete badge?');
const badgeElement = modal.querySelector('img.project-badge');
expect(badgeElement).not.toBe(null);
expect(badgeElement.getAttribute('src')).toBe(badge.renderedImageUrl);
})
.then(done)
.catch(done.fail);
});
......@@ -67,7 +66,7 @@ describe('BadgeSettings component', () => {
expect(badgeListElement).not.toBe(null);
expect(badgeListElement).toBeVisible();
expect(badgeListElement).toContainText('Your badges');
expect(badgeListElement.innerText).toMatch('Your badges');
});
describe('when editing', () => {
......@@ -103,7 +102,7 @@ describe('BadgeSettings component', () => {
describe('methods', () => {
describe('onSubmitModal', () => {
it('triggers ', () => {
spyOn(vm, 'deleteBadge').and.callFake(() => Promise.resolve());
jest.spyOn(vm, 'deleteBadge').mockImplementation(() => Promise.resolve());
const modal = vm.$el.querySelector('#delete-badge-modal');
const deleteButton = modal.querySelector('.btn-danger');
......
import Vue from 'vue';
import mountComponent from 'spec/helpers/vue_mount_component_helper';
import mountComponent from 'helpers/vue_mount_component_helper';
import { DUMMY_IMAGE_URL, TEST_HOST } from 'spec/test_constants';
import Badge from '~/badges/components/badge.vue';
......@@ -23,9 +23,11 @@ describe('Badge component', () => {
const createComponent = (props, el = null) => {
vm = mountComponent(Component, props, el);
const { badgeImage } = findElements();
return new Promise(resolve => badgeImage.addEventListener('load', resolve)).then(() =>
Vue.nextTick(),
);
return new Promise(resolve => {
badgeImage.addEventListener('load', resolve);
// Manually dispatch load event as it is not triggered
badgeImage.dispatchEvent(new Event('load'));
}).then(() => Vue.nextTick());
};
afterEach(() => {
......@@ -111,7 +113,7 @@ describe('Badge component', () => {
expect(badgeImage).toBeVisible();
expect(loadingIcon).toBeHidden();
expect(reloadButton).toBeHidden();
expect(vm.$el.innerText).toBe('');
expect(vm.$el.querySelector('.btn-group')).toBeHidden();
});
it('shows a loading icon when loading', done => {
......@@ -124,7 +126,7 @@ describe('Badge component', () => {
expect(badgeImage).toBeHidden();
expect(loadingIcon).toBeVisible();
expect(reloadButton).toBeHidden();
expect(vm.$el.innerText).toBe('');
expect(vm.$el.querySelector('.btn-group')).toBeHidden();
})
.then(done)
.catch(done.fail);
......
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