Add more tests
This commit is contained in:
parent
544b30c830
commit
47207476ff
@ -107,9 +107,8 @@
|
||||
"setupTestFrameworkScriptFile": "<rootDir>/resources/assets/tests/setup.js",
|
||||
"coveragePathIgnorePatterns": [
|
||||
"/node_modules/",
|
||||
"setup",
|
||||
"utils",
|
||||
"assets/src/js"
|
||||
"<rootDir>/resources/assets/tests/setup",
|
||||
"<rootDir>/resources/assets/tests/utils"
|
||||
],
|
||||
"testRegex": "resources/assets/tests/.*\\.(spec|test)\\.js"
|
||||
},
|
||||
|
@ -1,9 +1,8 @@
|
||||
import Vue from 'vue';
|
||||
import { emit } from './event';
|
||||
import { queryStringify } from './utils';
|
||||
import { showAjaxError } from './notify';
|
||||
|
||||
const csrfField = document.querySelector('meta[name="csrf-token"]');
|
||||
|
||||
const empty = Object.create(null);
|
||||
/** @type Request */
|
||||
export const init = {
|
||||
@ -11,11 +10,19 @@ export const init = {
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-TOKEN': csrfField && csrfField.content
|
||||
}
|
||||
};
|
||||
|
||||
function retrieveToken() {
|
||||
const csrfField = document.querySelector('meta[name="csrf-token"]');
|
||||
return csrfField && csrfField.content;
|
||||
}
|
||||
|
||||
export async function walkFetch(request) {
|
||||
request.headers['X-CSRF-TOKEN'] = retrieveToken();
|
||||
|
||||
emit('beforeFetch', request);
|
||||
|
||||
try {
|
||||
const response = await fetch(request);
|
||||
if (response.ok) {
|
||||
|
@ -11,7 +11,7 @@ import { trans } from './i18n';
|
||||
* @return {void}
|
||||
*/
|
||||
export function showMsg(msg, type = 'info') {
|
||||
$('[id=msg]')
|
||||
$('#msg')
|
||||
.removeClass()
|
||||
.addClass('callout')
|
||||
.addClass(`callout-${type}`)
|
||||
@ -30,7 +30,7 @@ export function showAjaxError(error) {
|
||||
}
|
||||
|
||||
const message = typeof error === 'string' ? error : error.message;
|
||||
showModal(message.replace(/\n/g, '<br />'), trans('general.fatalError'), 'danger');
|
||||
showModal(message.replace(/\n/g, '<br>'), trans('general.fatalError'), 'danger');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -68,7 +68,7 @@ export function showModal(msg, title = 'Message', type = 'default', options = {}
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
$(dom).on('hidden.bs.modal', function () {
|
||||
$(dom).on('hidden.bs.modal', /* istanbul ignore next */ function () {
|
||||
destroyOnClose && $(this).remove();
|
||||
}).modal(options);
|
||||
}
|
||||
|
78
resources/assets/tests/js/net.test.js
Normal file
78
resources/assets/tests/js/net.test.js
Normal file
@ -0,0 +1,78 @@
|
||||
import * as net from '@/js/net';
|
||||
import { on } from '@/js/event';
|
||||
import { showAjaxError } from '@/js/notify';
|
||||
|
||||
jest.mock('@/js/notify');
|
||||
|
||||
test('the GET method', async () => {
|
||||
const json = jest.fn().mockResolvedValue({});
|
||||
window.fetch = jest.fn().mockResolvedValue({
|
||||
ok: true,
|
||||
json
|
||||
});
|
||||
window.Request = jest.fn(function (url, init) {
|
||||
this.url = url;
|
||||
Object.keys(init).forEach(key => this[key] = init[key]);
|
||||
});
|
||||
|
||||
await net.get('/abc', { a: 'b' });
|
||||
expect(window.fetch.mock.calls[0][0].url).toBe('/abc?a=b');
|
||||
expect(json).toBeCalled();
|
||||
|
||||
await net.get('/abc');
|
||||
expect(window.fetch.mock.calls[1][0].url).toBe('/abc');
|
||||
});
|
||||
|
||||
test('the POST method', async () => {
|
||||
window.fetch = jest.fn().mockResolvedValue({
|
||||
ok: true,
|
||||
json: () => Promise.resolve({})
|
||||
});
|
||||
window.Request = jest.fn(function (url, init) {
|
||||
this.url = url;
|
||||
Object.keys(init).forEach(key => this[key] = init[key]);
|
||||
});
|
||||
|
||||
const meta = document.createElement('meta');
|
||||
meta.name = 'csrf-token';
|
||||
meta.content = 'token';
|
||||
document.head.appendChild(meta);
|
||||
|
||||
await net.post('/abc', { a: 'b' });
|
||||
const request = window.fetch.mock.calls[0][0];
|
||||
expect(request.url).toBe('/abc');
|
||||
expect(request.method).toBe('POST');
|
||||
expect(request.body).toBe(JSON.stringify({ a: 'b' }));
|
||||
expect(request.headers['X-CSRF-TOKEN']).toBe('token');
|
||||
|
||||
await net.post('/abc');
|
||||
expect(window.fetch.mock.calls[1][0].body).toBe('{}');
|
||||
});
|
||||
|
||||
test('low level fetch', async () => {
|
||||
const json = jest.fn().mockResolvedValue({});
|
||||
window.fetch = jest.fn()
|
||||
.mockRejectedValueOnce(new Error)
|
||||
.mockResolvedValueOnce({
|
||||
ok: false,
|
||||
text: () => Promise.resolve('404')
|
||||
})
|
||||
.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
json
|
||||
});
|
||||
|
||||
const stub = jest.fn();
|
||||
on('beforeFetch', stub);
|
||||
const request = { headers: {} };
|
||||
|
||||
await net.walkFetch(request);
|
||||
expect(showAjaxError.mock.calls[0][0]).toBeInstanceOf(Error);
|
||||
expect(stub).toBeCalledWith(request);
|
||||
|
||||
await net.walkFetch(request);
|
||||
expect(showAjaxError).toBeCalledWith('404');
|
||||
|
||||
await net.walkFetch(request);
|
||||
expect(json).toBeCalled();
|
||||
});
|
35
resources/assets/tests/js/notify.test.js
Normal file
35
resources/assets/tests/js/notify.test.js
Normal file
@ -0,0 +1,35 @@
|
||||
import $ from 'jquery';
|
||||
import * as notify from '@/js/notify';
|
||||
|
||||
test('show message', () => {
|
||||
document.body.innerHTML = '<div id=msg class="callout-x"></div>';
|
||||
notify.showMsg('hi');
|
||||
|
||||
const element = $('#msg');
|
||||
expect(element.hasClass('callout')).toBeTrue();
|
||||
expect(element.hasClass('callout-info')).toBeTrue();
|
||||
expect(element.html()).toBe('hi');
|
||||
});
|
||||
|
||||
test('show AJAX error', () => {
|
||||
notify.showAjaxError(); // Can be no arguments
|
||||
|
||||
$.fn.modal = function () {
|
||||
document.body.innerHTML = this.html();
|
||||
};
|
||||
notify.showAjaxError('error\nerror');
|
||||
expect(document.body.innerHTML).toContain('error<br>error');
|
||||
|
||||
notify.showAjaxError(new Error('an-error'));
|
||||
expect(document.body.innerHTML).toContain('an-error');
|
||||
});
|
||||
|
||||
test('show modal', () => {
|
||||
notify.showModal('message');
|
||||
expect($('.modal-title').html()).toBe('Message');
|
||||
|
||||
notify.showModal('message', '', 'default', {
|
||||
callback: () => undefined,
|
||||
destroyOnClose: false
|
||||
});
|
||||
});
|
23
resources/assets/tests/js/utils.test.js
Normal file
23
resources/assets/tests/js/utils.test.js
Normal file
@ -0,0 +1,23 @@
|
||||
import * as utils from '@/js/utils';
|
||||
|
||||
test('debounce', () => {
|
||||
const stub = jest.fn();
|
||||
const debounced = utils.debounce(stub, 2000);
|
||||
|
||||
debounced();
|
||||
debounced();
|
||||
expect(stub).not.toBeCalled();
|
||||
jest.runAllTimers();
|
||||
expect(stub).toBeCalledTimes(1);
|
||||
});
|
||||
|
||||
test('queryString', () => {
|
||||
history.pushState({}, 'page', 'about:blank?key=value');
|
||||
expect(utils.queryString('key')).toBe('value');
|
||||
expect(utils.queryString('a')).toBeUndefined();
|
||||
expect(utils.queryString('a', 'b')).toBe('b');
|
||||
});
|
||||
|
||||
test('queryStringify', () => {
|
||||
expect(utils.queryStringify({ a: 'b', c: 'd' })).toBe('a=b&c=d');
|
||||
});
|
Loading…
Reference in New Issue
Block a user