Add unit test for JavaScript files
This commit is contained in:
parent
a8ac404c98
commit
d1faaf64f5
|
|
@ -25,9 +25,14 @@ module.exports = {
|
|||
"getQueryString": false,
|
||||
"TexturePreview": false
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2017
|
||||
},
|
||||
"env":{
|
||||
"commonjs": true,
|
||||
"es6": true,
|
||||
"browser": true,
|
||||
"jest": true,
|
||||
"jquery": true
|
||||
}
|
||||
};
|
||||
|
|
|
|||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1,5 +1,6 @@
|
|||
.env
|
||||
.sass-cache
|
||||
coverage
|
||||
vendor/*
|
||||
plugins/*
|
||||
storage/textures/*
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@
|
|||
"scripts": {
|
||||
"build": "gulp build",
|
||||
"release": "gulp release",
|
||||
"test": "jest --silent",
|
||||
"test:watch": "jest --silent --watch",
|
||||
"test:cover": "jest --silent --coverage",
|
||||
"dev": "gulp watch"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
@ -27,6 +30,7 @@
|
|||
"gulp-sass": "^3.1.0",
|
||||
"gulp-uglify": "^3.0.0",
|
||||
"gulp-zip": "^4.0.0",
|
||||
"jest": "^20.0.4",
|
||||
"run-sequence": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
@ -41,5 +45,8 @@
|
|||
"jquery": "^3.2.1",
|
||||
"sweetalert2": "^6.6.5",
|
||||
"toastr": "^2.1.2"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@types/jest": "^20.0.2"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
823
resources/assets/src/js/__tests__/admin.test.js
Normal file
823
resources/assets/src/js/__tests__/admin.test.js
Normal file
|
|
@ -0,0 +1,823 @@
|
|||
const $ = require('jquery');
|
||||
window.$ = window.jQuery = $;
|
||||
|
||||
describe('tests for "customize" module', () => {
|
||||
const modulePath = '../admin/customize';
|
||||
|
||||
it('change skin preview after switching color', () => {
|
||||
window.current_skin = 'skin-blue';
|
||||
document.body.className = window.current_skin;
|
||||
document.body.innerHTML = `
|
||||
<div id="layout-skins-list">
|
||||
<a data-skin="skin-purple"></a>
|
||||
</div>`;
|
||||
|
||||
require(modulePath);
|
||||
$('#layout-skins-list [data-skin]').click();
|
||||
|
||||
expect($('body').hasClass('skin-blue')).toBe(false);
|
||||
expect($('body').hasClass('skin-purple')).toBe(true);
|
||||
expect(window.current_skin).toBe('skin-purple');
|
||||
});
|
||||
|
||||
it('submit information of skin', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 0, msg: 'success' }))
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 1, msg: 'warning' }));
|
||||
const url = jest.fn(path => path);
|
||||
const toastr = {
|
||||
success: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
window.fetch = fetch;
|
||||
window.url = url;
|
||||
window.toastr = toastr;
|
||||
window.current_skin = '';
|
||||
|
||||
document.body.innerHTML = '<button id="color-submit">submit</button>';
|
||||
const submitColor = require(modulePath);
|
||||
|
||||
await submitColor();
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'admin/customize?action=color',
|
||||
dataType: 'json',
|
||||
data: { color_scheme: '' }
|
||||
});
|
||||
expect(toastr.warning).not.toBeCalled();
|
||||
expect(toastr.success).toBeCalledWith('success');
|
||||
|
||||
await submitColor();
|
||||
expect(toastr.warning).toBeCalledWith('warning');
|
||||
});
|
||||
});
|
||||
|
||||
describe('tests for "players" module', () => {
|
||||
const modulePath = '../admin/players';
|
||||
|
||||
it('change player reference', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 0, msg: 'success' }))
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 1, msg: 'warning' }));
|
||||
const url = jest.fn(path => path);
|
||||
const toastr = {
|
||||
success: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
window.fetch = fetch;
|
||||
window.url = url;
|
||||
window.toastr = toastr;
|
||||
|
||||
document.body.innerHTML = `
|
||||
<div id="1">
|
||||
<div><select>
|
||||
<option value="default" selected></option>
|
||||
<option value="slim"></option>
|
||||
</select></div>
|
||||
</div>
|
||||
`;
|
||||
$('select').on('change', require(modulePath).changePreference);
|
||||
|
||||
await $('select').val('slim').trigger('change');
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'admin/players?action=preference',
|
||||
dataType: 'json',
|
||||
data: {
|
||||
pid: '1',
|
||||
preference: 'slim'
|
||||
}
|
||||
});
|
||||
expect(toastr.warning).not.toBeCalled();
|
||||
expect(toastr.success).toBeCalledWith('success');
|
||||
|
||||
await $('select').trigger('change');
|
||||
expect(toastr.warning).toBeCalledWith('warning');
|
||||
});
|
||||
|
||||
it('submit changed texture information', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 0, msg: 'success' }))
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 1, msg: 'warning' }));
|
||||
const url = jest.fn(path => path);
|
||||
const toastr = {
|
||||
success: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
const modal = jest.fn();
|
||||
window.fetch = fetch;
|
||||
window.url = url;
|
||||
window.toastr = toastr;
|
||||
window.$.fn.modal = modal;
|
||||
|
||||
document.body.innerHTML = `
|
||||
<div class="modal" style="display: none" id="shouldBeRemoved"></div>
|
||||
<div class="modal" id="shouldNotBeRemoved"></div>
|
||||
<input id="model" value="default" />
|
||||
<input id="tid" value="1" />
|
||||
<img id="1-default" src="" />
|
||||
`;
|
||||
const ajaxChangeTexture = require(modulePath).ajaxChangeTexture;
|
||||
|
||||
await ajaxChangeTexture(1);
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'admin/players?action=texture',
|
||||
dataType: 'json',
|
||||
data: { pid: 1, model: 'default', tid: '1' }
|
||||
});
|
||||
expect(document.getElementById('shouldBeRemoved')).toBeNull();
|
||||
expect(document.getElementById('shouldNotBeRemoved')).not.toBeNull();
|
||||
expect(modal).toBeCalledWith('hide');
|
||||
expect(toastr.warning).not.toBeCalled();
|
||||
expect(toastr.success).toBeCalledWith('success');
|
||||
expect($('img').attr('src')).toBe('preview/64/1.png');
|
||||
|
||||
await ajaxChangeTexture(1);
|
||||
expect(toastr.warning).toBeCalledWith('warning');
|
||||
});
|
||||
|
||||
it('change player name', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValue(Promise.resolve({ errno: 0, msg: 'success' }));
|
||||
const url = jest.fn(path => path);
|
||||
const toastr = {
|
||||
success: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
const trans = jest.fn(key => key);
|
||||
const swal = jest.fn(options => {
|
||||
options.inputValidator('newName');
|
||||
return Promise.resolve('newName');
|
||||
});
|
||||
window.fetch = fetch;
|
||||
window.url = url;
|
||||
window.toastr = toastr;
|
||||
window.trans = trans;
|
||||
window.swal = swal;
|
||||
|
||||
document.body.innerHTML = `
|
||||
<table>
|
||||
<thead></thead>
|
||||
<tbody>
|
||||
<tr id="1">
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
`;
|
||||
const changePlayerName = require(modulePath).changePlayerName;
|
||||
|
||||
await changePlayerName(1, 'oldName');
|
||||
expect(swal).toBeCalledWith(expect.objectContaining({
|
||||
text: 'admin.changePlayerNameNotice',
|
||||
input: 'text',
|
||||
inputValue: 'oldName'
|
||||
}));
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'admin/players?action=name',
|
||||
dataType: 'json',
|
||||
data: { pid: 1, name: 'newName' }
|
||||
});
|
||||
await changePlayerName(1, 'oldName');
|
||||
expect($('tr#1 > td:nth-child(3)').text()).toBe('newName');
|
||||
expect(toastr.warning).not.toBeCalled();
|
||||
expect(toastr.success).toBeCalledWith('success');
|
||||
});
|
||||
|
||||
it('change owner', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 0, msg: 'success' }))
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 1, msg: 'warning' }));
|
||||
const url = jest.fn(path => path);
|
||||
const toastr = {
|
||||
success: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
const trans = jest.fn(key => key);
|
||||
const swal = jest.fn().mockReturnValue(Promise.resolve(2));
|
||||
const debounce = jest.fn(fn => fn);
|
||||
window.fetch = fetch;
|
||||
window.url = url;
|
||||
window.toastr = toastr;
|
||||
window.trans = trans;
|
||||
window.swal = swal;
|
||||
window.debounce = debounce;
|
||||
|
||||
document.body.innerHTML = `
|
||||
<table>
|
||||
<thead></thead>
|
||||
<tbody>
|
||||
<tr id="1">
|
||||
<td></td>
|
||||
<td>1</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div>
|
||||
<input class="swal2-input" />
|
||||
<div class="swal2-content"></div>
|
||||
</div>
|
||||
`;
|
||||
const changeOwner = require(modulePath).changeOwner;
|
||||
|
||||
await changeOwner(1, 'oldName');
|
||||
expect(debounce).toBeCalled();
|
||||
expect(swal).toBeCalledWith({
|
||||
html: 'admin.changePlayerOwner<br><small> </small>',
|
||||
input: 'number',
|
||||
inputValue: '1',
|
||||
showCancelButton: true
|
||||
});
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'admin/players?action=owner',
|
||||
dataType: 'json',
|
||||
data: { pid: 1, uid: 2 }
|
||||
});
|
||||
await changeOwner(1, 'oldName');
|
||||
expect($('tr#1 > td:nth-child(2)').text()).toBe((2).toString());
|
||||
expect(toastr.warning).not.toBeCalled();
|
||||
expect(toastr.success).toBeCalledWith('success');
|
||||
});
|
||||
|
||||
it('delete player', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 0, msg: 'success' }))
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 1, msg: 'warning' }));
|
||||
const url = jest.fn(path => path);
|
||||
const toastr = {
|
||||
success: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
const trans = jest.fn(key => key);
|
||||
const swal = jest.fn().mockReturnValue(Promise.resolve('newName'));
|
||||
window.fetch = fetch;
|
||||
window.url = url;
|
||||
window.toastr = toastr;
|
||||
window.trans = trans;
|
||||
window.swal = swal;
|
||||
|
||||
document.body.innerHTML = `
|
||||
<table>
|
||||
<thead></thead>
|
||||
<tbody>
|
||||
<tr id="1">
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
`;
|
||||
const deletePlayer = require(modulePath).deletePlayer;
|
||||
|
||||
await deletePlayer(1);
|
||||
expect(swal).toBeCalledWith({
|
||||
text: 'admin.deletePlayerNotice',
|
||||
type: 'warning',
|
||||
showCancelButton: true
|
||||
});
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'admin/players?action=delete',
|
||||
dataType: 'json',
|
||||
data: { pid: 1 }
|
||||
});
|
||||
await deletePlayer(1);
|
||||
expect(document.getElementById('1')).toBeNull();
|
||||
expect(toastr.warning).not.toBeCalled();
|
||||
expect(toastr.success).toBeCalledWith('success');
|
||||
});
|
||||
});
|
||||
|
||||
describe('tests for "plugins" module', () => {
|
||||
const modulePath = '../admin/plugins';
|
||||
|
||||
it('enable a plugin', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 0, msg: 'success' }))
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 1, msg: 'warning' }));
|
||||
const url = jest.fn(path => path);
|
||||
const toastr = {
|
||||
success: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
const reloadTable = jest.fn();
|
||||
window.fetch = fetch;
|
||||
window.url = url;
|
||||
window.toastr = toastr;
|
||||
$.pluginsTable = {
|
||||
ajax: {
|
||||
reload: reloadTable
|
||||
}
|
||||
};
|
||||
|
||||
const enablePlugin = require(modulePath).enablePlugin;
|
||||
|
||||
await enablePlugin('plugin');
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'admin/plugins?action=enable&name=plugin',
|
||||
dataType: 'json'
|
||||
});
|
||||
expect(toastr.warning).not.toBeCalled();
|
||||
expect(toastr.success).toBeCalledWith('success');
|
||||
expect(reloadTable).toBeCalledWith(null, false);
|
||||
|
||||
await enablePlugin('plugin');
|
||||
expect(toastr.warning).toBeCalledWith('warning');
|
||||
});
|
||||
|
||||
it('disable a plugin', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 0, msg: 'success' }))
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 1, msg: 'warning' }));
|
||||
const url = jest.fn(path => path);
|
||||
const toastr = {
|
||||
success: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
const reloadTable = jest.fn();
|
||||
window.fetch = fetch;
|
||||
window.url = url;
|
||||
window.toastr = toastr;
|
||||
$.pluginsTable = {
|
||||
ajax: {
|
||||
reload: reloadTable
|
||||
}
|
||||
};
|
||||
|
||||
const disablePlugin = require(modulePath).disablePlugin;
|
||||
|
||||
await disablePlugin('plugin');
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'admin/plugins?action=disable&name=plugin',
|
||||
dataType: 'json'
|
||||
});
|
||||
expect(toastr.warning).not.toBeCalled();
|
||||
expect(toastr.success).toBeCalledWith('success');
|
||||
expect(reloadTable).toBeCalledWith(null, false);
|
||||
|
||||
await disablePlugin('plugin');
|
||||
expect(toastr.warning).toBeCalledWith('warning');
|
||||
});
|
||||
|
||||
it('delete a plugin', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValue(Promise.resolve({ errno: 0, msg: 'success' }));
|
||||
const url = jest.fn(path => path);
|
||||
const toastr = {
|
||||
success: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
const reloadTable = jest.fn();
|
||||
const swal = jest.fn().mockReturnValue(Promise.resolve());
|
||||
window.fetch = fetch;
|
||||
window.url = url;
|
||||
window.toastr = toastr;
|
||||
$.pluginsTable = {
|
||||
ajax: {
|
||||
reload: reloadTable
|
||||
}
|
||||
};
|
||||
window.swal = swal;
|
||||
|
||||
const deletePlugin = require(modulePath).deletePlugin;
|
||||
|
||||
await deletePlugin('plugin');
|
||||
expect(swal).toBeCalledWith({
|
||||
text: 'admin.confirmDeletion',
|
||||
type: 'warning',
|
||||
showCancelButton: true
|
||||
});
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'admin/plugins?action=delete&name=plugin',
|
||||
dataType: 'json'
|
||||
});
|
||||
await deletePlugin('plugin');
|
||||
expect(toastr.warning).not.toBeCalled();
|
||||
expect(toastr.success).toBeCalledWith('success');
|
||||
expect(reloadTable).toBeCalledWith(null, false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('tests for "update" module', () => {
|
||||
it('download updates', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValueOnce(Promise.resolve({
|
||||
file_size: 5000
|
||||
}))
|
||||
.mockReturnValueOnce(Promise.resolve());
|
||||
const url = jest.fn(path => path);
|
||||
const toastr = {
|
||||
success: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
const modal = jest.fn();
|
||||
window.fetch = fetch;
|
||||
window.url = url;
|
||||
window.toastr = toastr;
|
||||
$.fn.modal = modal;
|
||||
|
||||
document.body.innerHTML = `
|
||||
<div id="file-size"></div>
|
||||
<div id="modal-start-download"></div>
|
||||
`;
|
||||
|
||||
await require('../admin/update')();
|
||||
expect(fetch).toBeCalledWith(expect.objectContaining({
|
||||
url: 'admin/update/download?action=prepare-download',
|
||||
type: 'GET',
|
||||
dataType: 'json',
|
||||
}));
|
||||
expect($('#file-size').html()).toBe('5000');
|
||||
expect(modal).toBeCalledWith({
|
||||
backdrop: 'static',
|
||||
keyboard: false
|
||||
});
|
||||
expect(fetch).toBeCalledWith({
|
||||
url: 'admin/update/download?action=start-download',
|
||||
type: 'POST',
|
||||
dataType: 'json'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('tests for "users" module', () => {
|
||||
const modulePath = '../admin/users';
|
||||
|
||||
it('change user email', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValue(Promise.resolve({ errno: 0, msg: 'success' }));
|
||||
const url = jest.fn(path => path);
|
||||
const toastr = {
|
||||
success: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
const trans = jest.fn(key => key);
|
||||
const swal = jest.fn(options => {
|
||||
options.inputValidator('a@b.c');
|
||||
return Promise.resolve('a@b.c');
|
||||
});
|
||||
window.fetch = fetch;
|
||||
window.url = url;
|
||||
window.toastr = toastr;
|
||||
window.trans = trans;
|
||||
window.swal = swal;
|
||||
|
||||
document.body.innerHTML = `
|
||||
<table>
|
||||
<tbody>
|
||||
<tr id="user-1">
|
||||
<td></td>
|
||||
<td>d@e.f</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
`;
|
||||
const changeUserEmail = require(modulePath).changeUserEmail;
|
||||
|
||||
await changeUserEmail(1);
|
||||
expect(swal).toBeCalledWith(expect.objectContaining({
|
||||
text: 'admin.newUserEmail',
|
||||
showCancelButton: true,
|
||||
input: 'text',
|
||||
inputValue: 'd@e.f'
|
||||
}));
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'admin/users?action=email',
|
||||
dataType: 'json',
|
||||
data: { uid: 1, email: 'a@b.c' }
|
||||
});
|
||||
await changeUserEmail(1);
|
||||
expect($('tr > td:nth-child(2)').text()).toBe('a@b.c');
|
||||
expect(toastr.success).toBeCalledWith('success');
|
||||
});
|
||||
|
||||
it('change user nick name', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValue(Promise.resolve({ errno: 0, msg: 'success' }));
|
||||
const url = jest.fn(path => path);
|
||||
const toastr = {
|
||||
success: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
const trans = jest.fn(key => key);
|
||||
const swal = jest.fn(options => {
|
||||
options.inputValidator('foo');
|
||||
return Promise.resolve('foo');
|
||||
});
|
||||
window.fetch = fetch;
|
||||
window.url = url;
|
||||
window.toastr = toastr;
|
||||
window.trans = trans;
|
||||
window.swal = swal;
|
||||
|
||||
document.body.innerHTML = `
|
||||
<table>
|
||||
<tbody>
|
||||
<tr id="user-1">
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td>hhh</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
`;
|
||||
const changeUserNickName = require(modulePath).changeUserNickName;
|
||||
|
||||
await changeUserNickName(1);
|
||||
expect(swal).toBeCalledWith(expect.objectContaining({
|
||||
text: 'admin.newUserNickname',
|
||||
showCancelButton: true,
|
||||
input: 'text',
|
||||
inputValue: 'hhh'
|
||||
}));
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'admin/users?action=nickname',
|
||||
dataType: 'json',
|
||||
data: { uid: 1, nickname: 'foo' }
|
||||
});
|
||||
await changeUserNickName(1);
|
||||
expect($('tr > td:nth-child(3)').text()).toBe('foo');
|
||||
expect(toastr.success).toBeCalledWith('success');
|
||||
});
|
||||
|
||||
it('change user password', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValue(Promise.resolve({ errno: 0, msg: 'success' }));
|
||||
const url = jest.fn(path => path);
|
||||
const toastr = {
|
||||
success: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
const trans = jest.fn(key => key);
|
||||
const swal = jest.fn().mockReturnValue(Promise.resolve('secret'));
|
||||
window.fetch = fetch;
|
||||
window.url = url;
|
||||
window.toastr = toastr;
|
||||
window.trans = trans;
|
||||
window.swal = swal;
|
||||
|
||||
const changeUserPwd = require(modulePath).changeUserPwd;
|
||||
|
||||
await changeUserPwd(1);
|
||||
expect(swal).toBeCalledWith(expect.objectContaining({
|
||||
text: 'admin.newUserPassword',
|
||||
showCancelButton: true,
|
||||
input: 'password',
|
||||
}));
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'admin/users?action=password',
|
||||
dataType: 'json',
|
||||
data: { uid: 1, password: 'secret' }
|
||||
});
|
||||
await changeUserPwd(1);
|
||||
expect(toastr.success).toBeCalledWith('success');
|
||||
});
|
||||
|
||||
it('change user score', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 0, msg: 'success' }))
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 1, msg: 'warning' }));
|
||||
const url = jest.fn(path => path);
|
||||
const toastr = {
|
||||
success: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
window.fetch = fetch;
|
||||
window.url = url;
|
||||
window.toastr = toastr;
|
||||
|
||||
document.body.innerHTML = `
|
||||
<table>
|
||||
<tbody>
|
||||
<tr id="user-1">
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
`;
|
||||
const changeUserScore = require(modulePath).changeUserScore;
|
||||
|
||||
await changeUserScore('user-1', 50);
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'admin/users?action=score',
|
||||
dataType: 'json',
|
||||
data: { uid: '1', score: 50 }
|
||||
});
|
||||
expect(toastr.warning).not.toBeCalled();
|
||||
expect(toastr.success).toBeCalledWith('success');
|
||||
|
||||
await changeUserScore('user-1', 50);
|
||||
expect(toastr.warning).toBeCalledWith('warning');
|
||||
});
|
||||
|
||||
it('change ban status', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValueOnce(Promise.resolve({
|
||||
errno: 0,
|
||||
msg: 'success',
|
||||
permission: 0
|
||||
}))
|
||||
.mockReturnValueOnce(Promise.resolve({
|
||||
errno: 0,
|
||||
msg: 'success',
|
||||
permission: -1
|
||||
}))
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 1, msg: 'warning' }));
|
||||
const url = jest.fn(path => path);
|
||||
const toastr = {
|
||||
success: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
const trans = jest.fn(key => key);
|
||||
window.fetch = fetch;
|
||||
window.url = url;
|
||||
window.toastr = toastr;
|
||||
window.trans = trans;
|
||||
|
||||
document.body.innerHTML = `
|
||||
<table>
|
||||
<tbody>
|
||||
<tr id="user-1">
|
||||
<td class="status"></td>
|
||||
<td id="ban-1" data="banned"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
`;
|
||||
await require(modulePath).changeBanStatus(1);
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'admin/users?action=ban',
|
||||
dataType: 'json',
|
||||
data: { uid: 1 }
|
||||
});
|
||||
expect($('#ban-1').attr('data')).toBe('normal');
|
||||
expect($('#ban-1').text()).toBe('admin.ban');
|
||||
expect($('.status').text()).toBe('admin.normal');
|
||||
expect(toastr.warning).not.toBeCalled();
|
||||
expect(toastr.success).toBeCalledWith('success');
|
||||
|
||||
document.body.innerHTML = `
|
||||
<table>
|
||||
<tbody>
|
||||
<tr id="user-1">
|
||||
<td class="status"></td>
|
||||
<td id="ban-1" data="normal"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
`;
|
||||
await require(modulePath).changeBanStatus(1);
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'admin/users?action=ban',
|
||||
dataType: 'json',
|
||||
data: { uid: 1 }
|
||||
});
|
||||
expect($('#ban-1').attr('data')).toBe('banned');
|
||||
expect($('#ban-1').text()).toBe('admin.unban');
|
||||
expect($('.status').text()).toBe('admin.banned');
|
||||
|
||||
await require(modulePath).changeBanStatus(1);
|
||||
expect(toastr.warning).toBeCalledWith('warning');
|
||||
});
|
||||
|
||||
it('change admin status', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValueOnce(Promise.resolve({
|
||||
errno: 0,
|
||||
msg: 'success',
|
||||
permission: 0
|
||||
}))
|
||||
.mockReturnValueOnce(Promise.resolve({
|
||||
errno: 0,
|
||||
msg: 'success',
|
||||
permission: 1
|
||||
}))
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 1, msg: 'warning' }));
|
||||
const url = jest.fn(path => path);
|
||||
const toastr = {
|
||||
success: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
const trans = jest.fn(key => key);
|
||||
window.fetch = fetch;
|
||||
window.url = url;
|
||||
window.toastr = toastr;
|
||||
window.trans = trans;
|
||||
|
||||
document.body.innerHTML = `
|
||||
<table>
|
||||
<tbody>
|
||||
<tr id="user-1">
|
||||
<td class="status"></td>
|
||||
<td id="admin-1" data="admin"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
`;
|
||||
await require(modulePath).changeAdminStatus(1);
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'admin/users?action=admin',
|
||||
dataType: 'json',
|
||||
data: { uid: 1 }
|
||||
});
|
||||
expect($('#admin-1').attr('data')).toBe('normal');
|
||||
expect($('#admin-1').text()).toBe('admin.setAdmin');
|
||||
expect($('.status').text()).toBe('admin.normal');
|
||||
expect(toastr.warning).not.toBeCalled();
|
||||
expect(toastr.success).toBeCalledWith('success');
|
||||
|
||||
document.body.innerHTML = `
|
||||
<table>
|
||||
<tbody>
|
||||
<tr id="user-1">
|
||||
<td class="status"></td>
|
||||
<td id="admin-1" data="normal"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
`;
|
||||
await require(modulePath).changeAdminStatus(1);
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'admin/users?action=admin',
|
||||
dataType: 'json',
|
||||
data: { uid: 1 }
|
||||
});
|
||||
expect($('#admin-1').attr('data')).toBe('admin');
|
||||
expect($('#admin-1').text()).toBe('admin.unsetAdmin');
|
||||
expect($('.status').text()).toBe('admin.admin');
|
||||
|
||||
await require(modulePath).changeAdminStatus(1);
|
||||
expect(toastr.warning).toBeCalledWith('warning');
|
||||
});
|
||||
|
||||
it('delete a user', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValue(Promise.resolve({ errno: 0, msg: 'success' }));
|
||||
const url = jest.fn(path => path);
|
||||
const toastr = {
|
||||
success: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
const trans = jest.fn(key => key);
|
||||
const swal = jest.fn().mockReturnValue(Promise.resolve());
|
||||
window.fetch = fetch;
|
||||
window.url = url;
|
||||
window.toastr = toastr;
|
||||
window.trans = trans;
|
||||
window.swal = swal;
|
||||
|
||||
document.body.innerHTML = '<tr id="user-1"></tr>';
|
||||
const deleteUserAccount = require(modulePath).deleteUserAccount;
|
||||
|
||||
await deleteUserAccount(1);
|
||||
expect(swal).toBeCalledWith({
|
||||
text: 'admin.deleteUserNotice',
|
||||
type: 'warning',
|
||||
showCancelButton: true
|
||||
});
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'admin/users?action=delete',
|
||||
dataType: 'json',
|
||||
data: { uid: 1 }
|
||||
});
|
||||
await deleteUserAccount(1);
|
||||
expect(document.getElementById('user-1')).toBeNull();
|
||||
});
|
||||
|
||||
it('"input" element should be focused out when press enter key', () => {
|
||||
document.body.innerHTML = `
|
||||
<div id="user-1">
|
||||
<div>
|
||||
<input class="score" type="number" value="0" />
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
require(modulePath);
|
||||
|
||||
$('.score').focus();
|
||||
const event = $.Event('keypress');
|
||||
event.which = 13;
|
||||
$('.score').trigger(event);
|
||||
|
||||
expect($('.score').is(':focus')).toBe(false);
|
||||
});
|
||||
});
|
||||
368
resources/assets/src/js/__tests__/auth.test.js
Normal file
368
resources/assets/src/js/__tests__/auth.test.js
Normal file
|
|
@ -0,0 +1,368 @@
|
|||
const $ = require('jquery');
|
||||
window.$ = window.jQuery = $;
|
||||
|
||||
describe('tests for "captcha" module', () => {
|
||||
it('refresh captcha', async () => {
|
||||
const url = jest.fn(path => path);
|
||||
window.url = url;
|
||||
|
||||
document.body.innerHTML = `
|
||||
<img class="captcha" src="" />
|
||||
<input id="captcha" value="old" />
|
||||
`;
|
||||
|
||||
require('../auth/captcha')();
|
||||
|
||||
expect($('.captcha').attr('src')).toEqual(expect.stringContaining('auth/captcha?'));
|
||||
expect($('#captcha').val()).toBe('');
|
||||
});
|
||||
});
|
||||
|
||||
describe('tests for "login" module', () => {
|
||||
const modulePath = '../auth/login';
|
||||
|
||||
it('login', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockImplementationOnce(option => {
|
||||
option.beforeSend();
|
||||
return Promise.resolve({ errno: 0, msg: 'success' });
|
||||
})
|
||||
.mockImplementationOnce(() => Promise.resolve(
|
||||
{ errno: 1, msg: 'warning1', login_fails: 1 }
|
||||
))
|
||||
.mockImplementationOnce(() => Promise.resolve(
|
||||
{ errno: 1, msg: 'warning2', login_fails: 4 }
|
||||
));
|
||||
const trans = jest.fn(key => key);
|
||||
const url = jest.fn(path => path);
|
||||
const swal = jest.fn();
|
||||
const refreshCaptcha = jest.fn();
|
||||
window.fetch = fetch;
|
||||
window.trans = trans;
|
||||
window.url = url;
|
||||
window.swal = swal;
|
||||
window.showMsg = jest.fn();
|
||||
window.refreshCaptcha = refreshCaptcha;
|
||||
|
||||
document.body.innerHTML = `
|
||||
<input id="identification" />
|
||||
<input id="password" />
|
||||
<div id="captcha-form"></div>
|
||||
<input id="captcha" />
|
||||
<input id="keep" checked />
|
||||
<button id="login-button"></button>
|
||||
`;
|
||||
|
||||
require(modulePath);
|
||||
|
||||
$('button').click();
|
||||
expect(trans).toBeCalledWith('auth.emptyIdentification');
|
||||
expect($('#identification').is(':focus')).toBe(true);
|
||||
|
||||
$('#identification').val('username');
|
||||
$('button').click();
|
||||
expect(trans).toBeCalledWith('auth.emptyPassword');
|
||||
expect($('#password').is(':focus')).toBe(true);
|
||||
|
||||
$('#password').val('password');
|
||||
$('button').click();
|
||||
expect(trans).toBeCalledWith('auth.emptyCaptcha');
|
||||
expect($('#captcha').is(':focus')).toBe(true);
|
||||
|
||||
$('#captcha').val('captcha');
|
||||
await $('button').click();
|
||||
expect(fetch).toBeCalledWith(expect.objectContaining({
|
||||
type: 'POST',
|
||||
url: 'auth/login',
|
||||
dataType: 'json',
|
||||
data: {
|
||||
identification: 'username',
|
||||
password: 'password',
|
||||
keep: true,
|
||||
captcha: 'captcha'
|
||||
}
|
||||
}));
|
||||
expect($('button').html()).toBe(
|
||||
'<i class="fa fa-spinner fa-spin"></i> auth.loggingIn'
|
||||
);
|
||||
expect($('button').prop('disabled')).toBe(true);
|
||||
expect(swal).toBeCalledWith({ type: 'success', html: 'success' });
|
||||
|
||||
$('#captcha-form').css('display', 'none');
|
||||
await $('button').click();
|
||||
expect($('#captcha-form').css('display')).toBe('none');
|
||||
expect(refreshCaptcha).toBeCalled();
|
||||
expect(showMsg).toBeCalledWith('warning1', 'warning');
|
||||
expect($('button').html()).toBe('auth.login');
|
||||
expect($('button').prop('disabled')).toBe(false);
|
||||
|
||||
await $('button').click();
|
||||
expect(swal).toBeCalledWith({ type: 'error', html: 'auth.tooManyFails' });
|
||||
expect($('#captcha-form').css('display')).not.toBe('none');
|
||||
expect(showMsg).toBeCalledWith('warning2', 'warning');
|
||||
});
|
||||
});
|
||||
|
||||
describe('tests for "register" module', () => {
|
||||
const modulePath = '../auth/register';
|
||||
|
||||
it('register', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockImplementationOnce(option => {
|
||||
option.beforeSend();
|
||||
return Promise.resolve({ errno: 0, msg: 'success' });
|
||||
})
|
||||
.mockImplementationOnce(() => Promise.resolve(
|
||||
{ errno: 1, msg: 'warning' }
|
||||
));
|
||||
const trans = jest.fn(key => key);
|
||||
const url = jest.fn(path => path);
|
||||
const swal = jest.fn();
|
||||
const showMsg = jest.fn();
|
||||
const refreshCaptcha = jest.fn();
|
||||
window.fetch = fetch;
|
||||
window.trans = trans;
|
||||
window.url = url;
|
||||
window.swal = swal;
|
||||
window.showMsg = showMsg;
|
||||
window.refreshCaptcha = refreshCaptcha;
|
||||
|
||||
document.body.innerHTML = `
|
||||
<input id="email" />
|
||||
<input id="nickname" />
|
||||
<input id="password" />
|
||||
<input id="confirm-pwd" />
|
||||
<div id="captcha-form"></div>
|
||||
<input id="captcha" />
|
||||
<button id="register-button"></button>
|
||||
`;
|
||||
|
||||
require(modulePath);
|
||||
|
||||
$('button').click();
|
||||
expect(trans).toBeCalledWith('auth.emptyEmail');
|
||||
expect($('#email').is(':focus')).toBe(true);
|
||||
|
||||
$('#email').val('email');
|
||||
$('button').click();
|
||||
expect(trans).toBeCalledWith('auth.invalidEmail');
|
||||
expect(showMsg).toBeCalledWith('auth.invalidEmail', 'warning');
|
||||
expect($('#email').is(':focus')).toBe(true);
|
||||
|
||||
$('#email').val('a@b.c');
|
||||
$('button').click();
|
||||
expect(trans).toBeCalledWith('auth.emptyPassword');
|
||||
expect($('#password').is(':focus')).toBe(true);
|
||||
|
||||
$('#password').val('secret');
|
||||
$('button').click();
|
||||
expect(trans).toBeCalledWith('auth.invalidPassword');
|
||||
expect(showMsg).toBeCalledWith('auth.invalidPassword', 'warning');
|
||||
expect($('#password').is(':focus')).toBe(true);
|
||||
|
||||
$('#password').val('too_long_password');
|
||||
$('#password').blur();
|
||||
$('button').click();
|
||||
expect(trans).toBeCalledWith('auth.invalidPassword');
|
||||
expect(showMsg).toBeCalledWith('auth.invalidPassword', 'warning');
|
||||
expect($('#password').is(':focus')).toBe(true);
|
||||
|
||||
$('#password').val('password');
|
||||
$('button').click();
|
||||
expect(trans).toBeCalledWith('auth.emptyConfirmPwd');
|
||||
expect($('#confirm-pwd').is(':focus')).toBe(true);
|
||||
|
||||
$('#confirm-pwd').val('not_same');
|
||||
$('button').click();
|
||||
expect(trans).toBeCalledWith('auth.invalidConfirmPwd');
|
||||
expect(showMsg).toBeCalledWith('auth.invalidConfirmPwd', 'warning');
|
||||
expect($('#confirm-pwd').is(':focus')).toBe(true);
|
||||
|
||||
$('#confirm-pwd').val('password');
|
||||
$('button').click();
|
||||
expect(trans).toBeCalledWith('auth.emptyNickname');
|
||||
expect($('#nickname').is(':focus')).toBe(true);
|
||||
|
||||
$('#nickname').val('nickname');
|
||||
$('button').click();
|
||||
expect(trans).toBeCalledWith('auth.emptyCaptcha');
|
||||
expect($('#captcha').is(':focus')).toBe(true);
|
||||
|
||||
$('#captcha').val('captcha');
|
||||
await $('button').click();
|
||||
expect(fetch).toBeCalledWith(expect.objectContaining({
|
||||
type: 'POST',
|
||||
url: 'auth/register',
|
||||
dataType: 'json',
|
||||
data: {
|
||||
email: 'a@b.c',
|
||||
nickname: 'nickname',
|
||||
password: 'password',
|
||||
captcha: 'captcha'
|
||||
}
|
||||
}));
|
||||
expect($('button').html()).toBe(
|
||||
'<i class="fa fa-spinner fa-spin"></i> auth.registering'
|
||||
);
|
||||
expect($('button').prop('disabled')).toBe(true);
|
||||
expect(swal).toBeCalledWith({ type: 'success', html: 'success' });
|
||||
|
||||
await $('button').click();
|
||||
expect(refreshCaptcha).toBeCalled();
|
||||
expect(showMsg).toBeCalledWith('warning', 'warning');
|
||||
expect($('button').html()).toBe('auth.register');
|
||||
});
|
||||
});
|
||||
|
||||
describe('tests for "forgot" module', () => {
|
||||
const modulePath = '../auth/forgot';
|
||||
|
||||
it('forgot password', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockImplementationOnce(option => {
|
||||
option.beforeSend();
|
||||
return Promise.resolve({ errno: 0, msg: 'success' });
|
||||
})
|
||||
.mockImplementationOnce(() => Promise.resolve(
|
||||
{ errno: 1, msg: 'warning' }
|
||||
));
|
||||
const trans = jest.fn(key => key);
|
||||
const url = jest.fn(path => path);
|
||||
const swal = jest.fn();
|
||||
const showMsg = jest.fn();
|
||||
const refreshCaptcha = jest.fn();
|
||||
window.fetch = fetch;
|
||||
window.trans = trans;
|
||||
window.url = url;
|
||||
window.swal = swal;
|
||||
window.showMsg = showMsg;
|
||||
window.refreshCaptcha = refreshCaptcha;
|
||||
|
||||
document.body.innerHTML = `
|
||||
<input id="email" />
|
||||
<div id="captcha-form"></div>
|
||||
<input id="captcha" />
|
||||
<button id="forgot-button"></button>
|
||||
`;
|
||||
|
||||
require(modulePath);
|
||||
|
||||
$('button').click();
|
||||
expect(trans).toBeCalledWith('auth.emptyEmail');
|
||||
expect($('#email').is(':focus')).toBe(true);
|
||||
|
||||
$('#email').val('email');
|
||||
$('button').click();
|
||||
expect(trans).toBeCalledWith('auth.invalidEmail');
|
||||
expect(showMsg).toBeCalledWith('auth.invalidEmail', 'warning');
|
||||
expect($('#email').is(':focus')).toBe(true);
|
||||
|
||||
$('#email').val('a@b.c');
|
||||
$('button').click();
|
||||
expect(trans).toBeCalledWith('auth.emptyCaptcha');
|
||||
expect($('#captcha').is(':focus')).toBe(true);
|
||||
|
||||
$('#captcha').val('captcha');
|
||||
await $('button').click();
|
||||
expect(fetch).toBeCalledWith(expect.objectContaining({
|
||||
type: 'POST',
|
||||
url: 'auth/forgot',
|
||||
dataType: 'json',
|
||||
data: {
|
||||
email: 'a@b.c',
|
||||
captcha: 'captcha'
|
||||
}
|
||||
}));
|
||||
expect($('button').html()).toBe('auth.send');
|
||||
expect($('button').prop('disabled')).toBe(true);
|
||||
expect(showMsg).toBeCalledWith('success', 'success');
|
||||
|
||||
await $('button').click();
|
||||
expect(refreshCaptcha).toBeCalled();
|
||||
expect(showMsg).toBeCalledWith('warning', 'warning');
|
||||
expect($('button').html()).toBe('auth.send');
|
||||
});
|
||||
});
|
||||
|
||||
describe('tests for "reset" module', () => {
|
||||
const modulePath = '../auth/reset';
|
||||
|
||||
it('reset password', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockImplementationOnce(option => {
|
||||
option.beforeSend();
|
||||
return Promise.resolve({ errno: 0, msg: 'success' });
|
||||
})
|
||||
.mockImplementationOnce(() => Promise.resolve(
|
||||
{ errno: 1, msg: 'warning' }
|
||||
));
|
||||
const trans = jest.fn(key => key);
|
||||
const url = jest.fn(path => path);
|
||||
const swal = jest.fn().mockReturnValue(Promise.resolve());
|
||||
const showMsg = jest.fn();
|
||||
window.fetch = fetch;
|
||||
window.trans = trans;
|
||||
window.url = url;
|
||||
window.swal = swal;
|
||||
window.showMsg = showMsg;
|
||||
window.refreshCaptcha = jest.fn();
|
||||
|
||||
document.body.innerHTML = `
|
||||
<input id="uid" value="1" />
|
||||
<input id="password" />
|
||||
<input id="confirm-pwd" />
|
||||
<button id="reset-button"></button>
|
||||
`;
|
||||
|
||||
require(modulePath);
|
||||
|
||||
$('button').click();
|
||||
expect(trans).toBeCalledWith('auth.emptyPassword');
|
||||
expect($('#password').is(':focus')).toBe(true);
|
||||
|
||||
$('#password').val('secret');
|
||||
$('button').click();
|
||||
expect(trans).toBeCalledWith('auth.invalidPassword');
|
||||
expect(showMsg).toBeCalledWith('auth.invalidPassword', 'warning');
|
||||
expect($('#password').is(':focus')).toBe(true);
|
||||
|
||||
$('#password').val('too_long_password');
|
||||
$('#password').blur();
|
||||
$('button').click();
|
||||
expect(trans).toBeCalledWith('auth.invalidPassword');
|
||||
expect(showMsg).toBeCalledWith('auth.invalidPassword', 'warning');
|
||||
expect($('#password').is(':focus')).toBe(true);
|
||||
|
||||
$('#password').val('password');
|
||||
$('button').click();
|
||||
expect(trans).toBeCalledWith('auth.emptyConfirmPwd');
|
||||
expect($('#confirm-pwd').is(':focus')).toBe(true);
|
||||
|
||||
$('#confirm-pwd').val('not_same');
|
||||
$('button').click();
|
||||
expect(trans).toBeCalledWith('auth.invalidConfirmPwd');
|
||||
expect(showMsg).toBeCalledWith('auth.invalidConfirmPwd', 'warning');
|
||||
expect($('#confirm-pwd').is(':focus')).toBe(true);
|
||||
|
||||
$('#confirm-pwd').val('password');
|
||||
await $('button').click();
|
||||
expect(fetch).toBeCalledWith(expect.objectContaining({
|
||||
type: 'POST',
|
||||
url: 'auth/reset',
|
||||
dataType: 'json',
|
||||
data: {
|
||||
uid: '1',
|
||||
password: 'password'
|
||||
}
|
||||
}));
|
||||
expect($('button').html()).toBe(
|
||||
'<i class="fa fa-spinner fa-spin"></i> auth.resetting'
|
||||
);
|
||||
expect($('button').prop('disabled')).toBe(true);
|
||||
expect(swal).toBeCalledWith({ type: 'success', html: 'success' });
|
||||
|
||||
await $('button').click();
|
||||
expect(showMsg).toBeCalledWith('warning', 'warning');
|
||||
expect($('button').html()).toBe('auth.reset');
|
||||
});
|
||||
});
|
||||
179
resources/assets/src/js/__tests__/common.test.js
Normal file
179
resources/assets/src/js/__tests__/common.test.js
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
const $ = require('jquery');
|
||||
window.jQuery = window.$ = $;
|
||||
|
||||
describe('tests for "i18n" module', () => {
|
||||
const modulePath = '../common/i18n';
|
||||
|
||||
it('load locales', () => {
|
||||
window.isEmpty = obj => !obj; // Just for test
|
||||
const loadLocales = require(modulePath).loadLocales;
|
||||
|
||||
$.locales = {
|
||||
en: { text: 'text', nested: { sth: ':sth here!' } }
|
||||
};
|
||||
|
||||
loadLocales();
|
||||
expect($.currentLocale).toEqual({ text: 'text', nested: { sth: ':sth here!' } });
|
||||
});
|
||||
|
||||
it('get translated text', () => {
|
||||
const trans = require(modulePath).trans;
|
||||
|
||||
expect(trans('text')).toBe('text');
|
||||
expect(trans('text.nothing')).toBe('text.nothing');
|
||||
expect(trans('nested.sth')).toBe(':sth here!');
|
||||
expect(trans('nested.sth', { sth: 'abc' })).toBe('abc here!');
|
||||
});
|
||||
});
|
||||
|
||||
describe('tests for "logout" module', () => {
|
||||
const modulePath = '../common/logout';
|
||||
|
||||
it('logout', async () => {
|
||||
const swal = jest.fn().mockReturnValue(Promise.resolve());
|
||||
const trans = jest.fn(key => key);
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValue(Promise.resolve({ msg: 'success' }));
|
||||
window.swal = swal;
|
||||
window.trans = trans;
|
||||
window.fetch = fetch;
|
||||
window.url = jest.fn(path => path);
|
||||
|
||||
document.body.innerHTML = '<button id="logout-button"></button>';
|
||||
require(modulePath);
|
||||
|
||||
await $('button').click();
|
||||
expect(swal).toBeCalledWith({
|
||||
text: 'general.confirmLogout',
|
||||
type: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'general.confirm',
|
||||
cancelButtonText: 'general.cancel'
|
||||
});
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'auth/logout',
|
||||
dataType: 'json'
|
||||
});
|
||||
await $('button').click();
|
||||
expect(swal).toBeCalledWith({ type: 'success', html: 'success' });
|
||||
});
|
||||
});
|
||||
|
||||
describe('tests for "notify" module', () => {
|
||||
const modulePath = '../common/notify';
|
||||
|
||||
it('show message', () => {
|
||||
document.body.innerHTML = '<div id="msg" class="a-class"></div>';
|
||||
|
||||
const showMsg = require(modulePath).showMsg;
|
||||
|
||||
showMsg('msg1');
|
||||
expect($('div').hasClass('a-class')).toBe(false);
|
||||
expect($('div').hasClass('callout')).toBe(true);
|
||||
expect($('div').hasClass('callout-info')).toBe(true);
|
||||
expect($('div').html()).toBe('msg1');
|
||||
|
||||
showMsg('msg2', 'warning');
|
||||
expect($('div').hasClass('callout-info')).toBe(false);
|
||||
expect($('div').hasClass('callout')).toBe(true);
|
||||
expect($('div').hasClass('callout-warning')).toBe(true);
|
||||
expect($('div').html()).toBe('msg2');
|
||||
});
|
||||
|
||||
it('show ajax error', () => {
|
||||
const warn = jest.fn();
|
||||
window.console.warn = warn;
|
||||
window.trans = jest.fn(key => key);
|
||||
|
||||
const showAjaxError = require(modulePath).showAjaxError;
|
||||
|
||||
showAjaxError('error');
|
||||
expect(warn).toBeCalledWith('error');
|
||||
|
||||
showAjaxError({});
|
||||
expect(warn).toBeCalledWith('Empty Ajax response body.');
|
||||
});
|
||||
|
||||
it('show modal dialog', () => {
|
||||
const modal = jest.fn();
|
||||
$.fn.modal = modal;
|
||||
|
||||
const showModal = require(modulePath).showModal;
|
||||
showModal('');
|
||||
expect(modal).toBeCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('tests for "polyfill" module', () => {
|
||||
const modulePath = '../common/polyfill';
|
||||
|
||||
String.prototype.includes = undefined;
|
||||
String.prototype.endsWith = undefined;
|
||||
require(modulePath);
|
||||
|
||||
it('String#includes', () => {
|
||||
expect('blessing-skin'.includes('skin')).toBe(true);
|
||||
expect('blessing-skin'.includes('server')).toBe(false);
|
||||
expect('blessing-skin'.includes('skin', 9)).toBe(true);
|
||||
expect('blessing-skin'.includes('blessing', 9)).toBe(false);
|
||||
});
|
||||
|
||||
it('String#endsWith', () => {
|
||||
expect('blessing-skin'.endsWith('skin')).toBe(true);
|
||||
expect('blessing-skin'.endsWith('server')).toBe(false);
|
||||
expect('blessing-skin'.endsWith('blessing', 8)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('tests for "utils" module', () => {
|
||||
const modulePath = '../common/utils';
|
||||
|
||||
window.blessing = {
|
||||
version: ''
|
||||
};
|
||||
|
||||
it('check a variable if it is empty', () => {
|
||||
const isEmpty = require(modulePath).isEmpty;
|
||||
|
||||
expect(isEmpty()).toBe(true);
|
||||
expect(isEmpty(null)).toBe(true);
|
||||
expect(isEmpty(undefined)).toBe(true);
|
||||
expect(isEmpty(0)).toBe(false);
|
||||
expect(isEmpty(false)).toBe(false);
|
||||
expect(isEmpty('')).toBe(true);
|
||||
expect(isEmpty({})).toBe(true);
|
||||
expect(isEmpty({ sth: '' })).toBe(false);
|
||||
});
|
||||
|
||||
it('fake fetch', () => {
|
||||
$.ajax = jest.fn();
|
||||
const fetch = require(modulePath).fetch;
|
||||
const xhr = fetch({ type: 'GET' });
|
||||
|
||||
expect($.ajax).toBeCalledWith({ type: 'GET' });
|
||||
expect(Object.getPrototypeOf(xhr)).toBe(Promise.prototype);
|
||||
});
|
||||
|
||||
it('make a debounced function', done => {
|
||||
const func = jest.fn();
|
||||
const debounced = require(modulePath).debounce(func, 100);
|
||||
|
||||
debounced();
|
||||
debounced();
|
||||
|
||||
setTimeout(() => {
|
||||
expect(func.mock.calls.length).toBe(1);
|
||||
done();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
it('get a absolute url', () => {
|
||||
window.blessing = { base_url: 'http://localhost' };
|
||||
const url = require(modulePath).url;
|
||||
|
||||
expect(url()).toBe('http://localhost/');
|
||||
expect(url('test')).toBe('http://localhost/test');
|
||||
expect(url('/test')).toBe('http://localhost/test');
|
||||
});
|
||||
});
|
||||
490
resources/assets/src/js/__tests__/skinlib.test.js
Normal file
490
resources/assets/src/js/__tests__/skinlib.test.js
Normal file
|
|
@ -0,0 +1,490 @@
|
|||
const $ = require('jquery');
|
||||
window.$ = window.jQuery = $;
|
||||
|
||||
window.getQueryString = jest.fn((key, defaultValue) => defaultValue);
|
||||
|
||||
describe('tests for "index" module', () => {
|
||||
const modulePath = '../skinlib/index';
|
||||
|
||||
it('render skin library', () => {
|
||||
const trans = jest.fn(key => key);
|
||||
const url = jest.fn(path => path);
|
||||
const jqPaginator = jest.fn();
|
||||
window.trans = trans;
|
||||
window.url = url;
|
||||
$.fn.jqPaginator = jqPaginator;
|
||||
|
||||
document.body.innerHTML = `
|
||||
<div class="overlay"></div>
|
||||
<div id="skinlib-container"></div>
|
||||
<div id="skinlib-paginator"></div>
|
||||
`;
|
||||
const renderSkinlib = require(modulePath).renderSkinlib;
|
||||
|
||||
renderSkinlib([]);
|
||||
expect($('#skinlib-container').html()).toBe(
|
||||
'<p style="text-align: center; margin: 30px 0;">general.noResult</p>'
|
||||
);
|
||||
expect($('#skinlib-paginator').css('display')).toBe('none');
|
||||
expect($('.overlay').css('display')).toBe('none');
|
||||
|
||||
renderSkinlib([{
|
||||
tid: 1,
|
||||
name: 'name',
|
||||
type: 'steve',
|
||||
public: 0
|
||||
}]);
|
||||
expect($('#skinlib-paginator').css('display')).not.toBe('none');
|
||||
expect($('.item').attr('tid')).toBe('1');
|
||||
expect($('.item-body > img').attr('src')).toBe('preview/1.png');
|
||||
expect($('.texture-name > span').attr('title')).toBe('name');
|
||||
expect($('.texture-name > span > small').text()).toBe('skinlib.filter.steve');
|
||||
expect($('a.more.like').attr('title')).toBe('skinlib.anonymous');
|
||||
expect($('a.more.like').hasClass('liked')).toBe(false);
|
||||
expect($('a.more.like').hasClass('anonymous')).toBe(true);
|
||||
expect($('small.more').hasClass('hide')).toBe(false);
|
||||
expect($('small.private-label').text().trim()).toBe('skinlib.private');
|
||||
|
||||
renderSkinlib([{
|
||||
tid: 1,
|
||||
name: 'name',
|
||||
type: 'steve',
|
||||
public: 0,
|
||||
liked: true
|
||||
}]);
|
||||
expect($('a.more.like').attr('title')).toBe('skinlib.removeFromCloset');
|
||||
expect($('a.more.like').hasClass('liked')).toBe(true);
|
||||
expect($('a.more.like').hasClass('anonymous')).toBe(false);
|
||||
expect($('small.more').hasClass('hide')).toBe(false);
|
||||
expect($('small.private-label').text().trim()).toBe('skinlib.private');
|
||||
|
||||
renderSkinlib([{
|
||||
tid: 1,
|
||||
name: 'name',
|
||||
type: 'steve',
|
||||
public: 0,
|
||||
liked: false
|
||||
}]);
|
||||
expect($('a.more.like').attr('title')).toBe('skinlib.addToCloset');
|
||||
expect($('a.more.like').hasClass('liked')).toBe(false);
|
||||
expect($('a.more.like').hasClass('anonymous')).toBe(false);
|
||||
expect($('small.more').hasClass('hide')).toBe(false);
|
||||
expect($('small.private-label').text().trim()).toBe('skinlib.private');
|
||||
|
||||
renderSkinlib([{
|
||||
tid: 1,
|
||||
name: 'name',
|
||||
type: 'steve',
|
||||
public: 1,
|
||||
liked: false
|
||||
}]);
|
||||
expect($('small.more').hasClass('hide')).toBe(true);
|
||||
});
|
||||
|
||||
it('update paginator', () => {
|
||||
const trans = jest.fn(key => key);
|
||||
const jqPaginator = jest.fn();
|
||||
window.trans = trans;
|
||||
$.fn.jqPaginator = jqPaginator;
|
||||
|
||||
document.body.innerHTML = `
|
||||
<p class="pagination"></p>
|
||||
<div id="skinlib-paginator"></div>
|
||||
<select class="pagination"></select>
|
||||
`;
|
||||
const updatePaginator = require(modulePath).updatePaginator;
|
||||
|
||||
updatePaginator(2, 2);
|
||||
expect(trans).toBeCalledWith('general.pagination', { page: 2, total: 2 });
|
||||
expect(jqPaginator).toBeCalledWith(expect.objectContaining({
|
||||
currentPage: 2,
|
||||
totalPages: 2
|
||||
}));
|
||||
expect($('option').length).toBe(2);
|
||||
expect($('option[value=1]').prop('selected')).toBe(false);
|
||||
expect($('option[value=2]').prop('selected')).toBe(true);
|
||||
|
||||
$('#skinlib-paginator').html('something');
|
||||
updatePaginator(2, 2);
|
||||
expect(jqPaginator).toBeCalledWith('option', {
|
||||
currentPage: 2,
|
||||
totalPages: 2
|
||||
});
|
||||
});
|
||||
|
||||
it('update breadcrumb', () => {
|
||||
const trans = jest.fn(key => key);
|
||||
const jqPaginator = jest.fn();
|
||||
window.trans = trans;
|
||||
$.fn.jqPaginator = jqPaginator;
|
||||
|
||||
document.body.innerHTML = `
|
||||
<div id="filter-indicator"></div>
|
||||
<div id="uploader-indicator"></div>
|
||||
<div id="sort-indicator"></div>
|
||||
<div id="search-indicator"></div>
|
||||
<input id="navbar-search-input" />
|
||||
`;
|
||||
const updateBreadCrumb = require(modulePath).updateBreadCrumb;
|
||||
|
||||
updateBreadCrumb();
|
||||
expect($('#filter-indicator').html().replace(/\s/g, '')).toBe(
|
||||
'general.skin<small>skinlib.filter.skin</small>'
|
||||
);
|
||||
|
||||
$.skinlib.filter = 'cape';
|
||||
updateBreadCrumb();
|
||||
expect($('#filter-indicator').html()).toBe('general.cape');
|
||||
|
||||
expect($('#uploader-indicator').html()).toBe('skinlib.filter.allUsers');
|
||||
$.skinlib.uploader = 1;
|
||||
updateBreadCrumb();
|
||||
expect(trans).toBeCalledWith('skinlib.filter.uploader', { uid: 1 });
|
||||
expect($('#uploader-indicator').html()).toBe('skinlib.filter.uploader');
|
||||
|
||||
expect($('#sort-indicator').html()).toBe('skinlib.sort.time');
|
||||
|
||||
$.skinlib.keyword = '%20q';
|
||||
updateBreadCrumb();
|
||||
expect(trans).lastCalledWith(
|
||||
'general.searchResult',
|
||||
{ keyword: ' q' }
|
||||
);
|
||||
expect($('#search-indicator').html()).toBe('general.searchResult');
|
||||
expect($('#navbar-search-input').val()).toBe(' q');
|
||||
});
|
||||
|
||||
it('reload skin library', async () => {
|
||||
const fetch = jest.fn().mockReturnValue(Promise.resolve({
|
||||
items: []
|
||||
}));
|
||||
const url = jest.fn(path => path);
|
||||
window.fetch = fetch;
|
||||
window.url = url;
|
||||
window.showAjaxError = jest.fn();
|
||||
document.body.innerHTML = `
|
||||
<div id="skinlib-paginator"></div>
|
||||
`;
|
||||
const reloadSkinlib = require(modulePath).reloadSkinlib;
|
||||
window.history.pushState = jest.fn();
|
||||
|
||||
await reloadSkinlib();
|
||||
expect(fetch).toBeCalledWith(expect.objectContaining({
|
||||
type: 'GET',
|
||||
url: 'skinlib/data',
|
||||
dataType: 'json',
|
||||
data: {
|
||||
page: 2,
|
||||
filter: 'cape',
|
||||
sort: 'time',
|
||||
uploader: 1,
|
||||
keyword: '%20q'
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
it('update query string', () => {
|
||||
const url = jest.fn(path => path);
|
||||
window.url = url;
|
||||
document.body.innerHTML = `
|
||||
<ul>
|
||||
<li class="locale" data-code="zh_CN"><a></a></li>
|
||||
<li class="locale" data-code="en"><a></a></li>
|
||||
</ul>
|
||||
`;
|
||||
const updateUrlQueryString = require(modulePath).updateUrlQueryString;
|
||||
window.history.pushState = jest.fn();
|
||||
|
||||
const query = 'page=2&filter=cape&sort=time&uploader=1&keyword=%2520q';
|
||||
|
||||
updateUrlQueryString();
|
||||
expect(window.history.pushState).toBeCalledWith(
|
||||
null,
|
||||
null,
|
||||
'skinlib?' + query);
|
||||
expect($('li[data-code=zh_CN] > a').prop('href')).toBe(`?lang=zh_CN&${query}`);
|
||||
expect($('li[data-code=en] > a').prop('href')).toBe(`?lang=en&${query}`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('tests for "operations" module', () => {
|
||||
const modulePath = '../skinlib/operations';
|
||||
|
||||
it('add to closet', async () => {
|
||||
const url = jest.fn(path => path);
|
||||
window.url = url;
|
||||
const trans = jest.fn(key => key);
|
||||
window.trans = trans;
|
||||
const swal = jest.fn(option => {
|
||||
option.inputValidator('custom');
|
||||
return Promise.resolve('custom');
|
||||
});
|
||||
window.swal = swal;
|
||||
$.getJSON = jest.fn((option, cb) => {
|
||||
cb({ name: 'name' });
|
||||
});
|
||||
|
||||
const addToCloset = require(modulePath).addToCloset;
|
||||
|
||||
await addToCloset(1);
|
||||
expect($.getJSON.mock.calls[0][0]).toBe('skinlib/info/1');
|
||||
expect(swal).toBeCalledWith(expect.objectContaining({
|
||||
title: 'skinlib.setItemName',
|
||||
inputValue: 'name',
|
||||
input: 'text',
|
||||
showCancelButton: true,
|
||||
}));
|
||||
});
|
||||
|
||||
it('add to closet (by ajax)', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 0, msg: 'success' }))
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 1, msg: 'warning' }));
|
||||
window.fetch = fetch;
|
||||
const url = jest.fn(path => path);
|
||||
window.url = url;
|
||||
const trans = jest.fn(key => key);
|
||||
window.trans = trans;
|
||||
const swal = jest.fn().mockReturnValue(Promise.resolve());
|
||||
window.swal = swal;
|
||||
const modal = jest.fn();
|
||||
const toastr = {
|
||||
success: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
window.toastr = toastr;
|
||||
$.fn.modal = modal;
|
||||
|
||||
document.body.innerHTML = `
|
||||
<div class="modal" style="display: none" id="shouldBeRemoved"></div>
|
||||
<div class="modal" id="shouldNotBeRemoved"></div>
|
||||
`;
|
||||
const ajaxAddToCloset = require(modulePath).ajaxAddToCloset;
|
||||
|
||||
await ajaxAddToCloset(1, 'name');
|
||||
expect(document.getElementById('shouldBeRemoved')).toBeNull();
|
||||
expect(document.getElementById('shouldNotBeRemoved')).not.toBeNull();
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'user/closet/add',
|
||||
dataType: 'json',
|
||||
data: { tid: 1, name: 'name' }
|
||||
});
|
||||
expect(swal).toBeCalledWith({ type: 'success', html: 'success' });
|
||||
expect(modal).toBeCalledWith('hide');
|
||||
|
||||
await ajaxAddToCloset(1, 'name');
|
||||
expect(toastr.warning).toBeCalledWith('warning');
|
||||
});
|
||||
|
||||
it('remove from closet', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValue(Promise.resolve({ errno: 0, msg: 'success' }));
|
||||
window.fetch = fetch;
|
||||
const url = jest.fn(path => path);
|
||||
window.url = url;
|
||||
const trans = jest.fn(key => key);
|
||||
window.trans = trans;
|
||||
const swal = jest.fn().mockReturnValue(Promise.resolve());
|
||||
window.swal = swal;
|
||||
const modal = jest.fn();
|
||||
const toastr = {
|
||||
success: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
window.toastr = toastr;
|
||||
|
||||
const removeFromCloset = require(modulePath).removeFromCloset;
|
||||
|
||||
await removeFromCloset(1);
|
||||
expect(swal).toBeCalledWith({
|
||||
text: 'user.removeFromClosetNotice',
|
||||
type: 'warning',
|
||||
showCancelButton: true,
|
||||
cancelButtonColor: '#3085d6',
|
||||
confirmButtonColor: '#d33'
|
||||
});
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: '/user/closet/remove',
|
||||
dataType: 'json',
|
||||
data: { tid: 1 }
|
||||
});
|
||||
await removeFromCloset(1);
|
||||
expect(swal).toBeCalledWith({ type: 'success', html: 'success' });
|
||||
});
|
||||
|
||||
it('change texture name', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValue(Promise.resolve({ errno: 0, msg: 'success' }));
|
||||
window.fetch = fetch;
|
||||
const url = jest.fn(path => path);
|
||||
window.url = url;
|
||||
const trans = jest.fn(key => key);
|
||||
window.trans = trans;
|
||||
const swal = jest.fn(option => {
|
||||
option.inputValidator('new-name');
|
||||
return Promise.resolve('new-name');
|
||||
});
|
||||
window.swal = swal;
|
||||
const modal = jest.fn();
|
||||
const toastr = {
|
||||
success: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
window.toastr = toastr;
|
||||
|
||||
document.body.innerHTML = '<div id="name"></div>';
|
||||
const changeTextureName = require(modulePath).changeTextureName;
|
||||
|
||||
await changeTextureName(1, 'oldName');
|
||||
expect(swal).toBeCalledWith(expect.objectContaining({
|
||||
text: 'skinlib.setNewTextureName',
|
||||
input: 'text',
|
||||
inputValue: 'oldName',
|
||||
showCancelButton: true,
|
||||
}));
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'skinlib/rename',
|
||||
dataType: 'json',
|
||||
data: { tid: 1, new_name: 'new-name' }
|
||||
});
|
||||
await changeTextureName(1, 'oldName');
|
||||
expect($('div').text()).toBe('new-name');
|
||||
expect(toastr.success).toBeCalledWith('success');
|
||||
});
|
||||
|
||||
it('update texture status', () => {
|
||||
window.trans = jest.fn(key => key);
|
||||
document.body.innerHTML = `
|
||||
<div id="likes">5</div>
|
||||
<a tid="1"></a>
|
||||
<a id="1"></a>
|
||||
`;
|
||||
const updateTextureStatus = require(modulePath).updateTextureStatus;
|
||||
|
||||
updateTextureStatus(1, 'add');
|
||||
expect($('a[tid=1]').attr('href')).toBe('javascript:removeFromCloset(1);');
|
||||
expect($('a[tid=1]').attr('title')).toBe('skinlib.removeFromCloset');
|
||||
expect($('a[tid=1]').hasClass('liked')).toBe(true);
|
||||
expect($('#1').attr('href')).toBe('javascript:removeFromCloset(1);');
|
||||
expect($('#1').html()).toBe('skinlib.removeFromCloset');
|
||||
expect($('div').html()).toBe('6');
|
||||
|
||||
updateTextureStatus(1, 'remove');
|
||||
expect($('a[tid=1]').attr('href')).toBe('javascript:addToCloset(1);');
|
||||
expect($('a[tid=1]').attr('title')).toBe('skinlib.addToCloset');
|
||||
expect($('a[tid=1]').hasClass('liked')).toBe(false);
|
||||
expect($('#1').attr('href')).toBe('javascript:addToCloset(1);');
|
||||
expect($('#1').html()).toBe('skinlib.addToCloset');
|
||||
expect($('div').html()).toBe('5');
|
||||
});
|
||||
|
||||
it('click changing privacy button', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValue(Promise.resolve({ errno: 0, msg: 'success' }));
|
||||
window.fetch = fetch;
|
||||
const url = jest.fn(path => path);
|
||||
window.url = url;
|
||||
const trans = jest.fn(key => key);
|
||||
window.trans = trans;
|
||||
const swal = jest.fn().mockReturnValue(Promise.resolve());
|
||||
window.swal = swal;
|
||||
const modal = jest.fn();
|
||||
const toastr = {
|
||||
success: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
window.toastr = toastr;
|
||||
|
||||
document.body.innerHTML = '<a class="private-label"></a>';
|
||||
require(modulePath);
|
||||
|
||||
await $('a').click();
|
||||
expect(swal).toBeCalledWith({
|
||||
text: 'skinlib.setPublicNotice',
|
||||
type: 'warning',
|
||||
showCancelButton: true
|
||||
});
|
||||
expect(document.getElementsByTagName('a').length).toBe(0);
|
||||
});
|
||||
|
||||
it('change privacy', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 0, msg: 'success', public: '0' }))
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 0, msg: 'success' }))
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 1, msg: 'warning' }));
|
||||
window.fetch = fetch;
|
||||
const url = jest.fn(path => path);
|
||||
window.url = url;
|
||||
const trans = jest.fn(key => key);
|
||||
window.trans = trans;
|
||||
const swal = jest.fn().mockReturnValue(Promise.resolve());
|
||||
window.swal = swal;
|
||||
const modal = jest.fn();
|
||||
const toastr = {
|
||||
success: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
window.toastr = toastr;
|
||||
|
||||
document.body.innerHTML = `
|
||||
<a id="1">skinlib.setAsPrivate</a>
|
||||
<a id="2">skinlib.setAsPublic</a>
|
||||
`;
|
||||
const changePrivacy = require(modulePath).changePrivacy;
|
||||
|
||||
await changePrivacy(1);
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'skinlib/privacy',
|
||||
dataType: 'json',
|
||||
data: { tid: 1 }
|
||||
});
|
||||
expect(toastr.warning).not.toBeCalled();
|
||||
expect(toastr.success).toBeCalledWith('success');
|
||||
expect($('#1').html()).toBe('skinlib.setAsPublic');
|
||||
|
||||
await changePrivacy(1);
|
||||
expect($('#2').html()).toBe('skinlib.setAsPrivate');
|
||||
|
||||
await changePrivacy(1);
|
||||
expect(toastr.warning).toBeCalledWith('warning');
|
||||
});
|
||||
|
||||
it('delete texture', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValue(Promise.resolve({ errno: 0, msg: 'success' }));
|
||||
window.fetch = fetch;
|
||||
const url = jest.fn(path => path);
|
||||
window.url = url;
|
||||
const trans = jest.fn(key => key);
|
||||
window.trans = trans;
|
||||
const swal = jest.fn().mockReturnValue(Promise.resolve());
|
||||
window.swal = swal;
|
||||
const modal = jest.fn();
|
||||
const toastr = {
|
||||
success: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
window.toastr = toastr;
|
||||
|
||||
const deleteTexture = require(modulePath).deleteTexture;
|
||||
|
||||
await deleteTexture(1);
|
||||
expect(swal).toBeCalledWith({
|
||||
text: 'skinlib.deleteNotice',
|
||||
type: 'warning',
|
||||
showCancelButton: true
|
||||
});
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'skinlib/delete',
|
||||
dataType: 'json',
|
||||
data: { tid: 1 }
|
||||
});
|
||||
await deleteTexture(1);
|
||||
expect(swal).toBeCalledWith({ type: 'success', html: 'success' });
|
||||
});
|
||||
});
|
||||
868
resources/assets/src/js/__tests__/user.test.js
Normal file
868
resources/assets/src/js/__tests__/user.test.js
Normal file
|
|
@ -0,0 +1,868 @@
|
|||
const $ = require('jquery');
|
||||
window.$ = window.jQuery = $;
|
||||
|
||||
describe('tests for "closet" module', () => {
|
||||
const modulePath = '../user/closet';
|
||||
|
||||
$.fn.jqPaginator = jest.fn();
|
||||
|
||||
it('preview textures', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValueOnce(Promise.resolve({ type: 'skin', hash: 1 }))
|
||||
.mockReturnValueOnce(Promise.resolve({ type: 'cape', hash: 2 }));
|
||||
const trans = jest.fn(key => key);
|
||||
const url = jest.fn(path => path);
|
||||
const MSP = {
|
||||
changeSkin: jest.fn(),
|
||||
changeCape: jest.fn()
|
||||
};
|
||||
window.fetch = fetch;
|
||||
window.trans = trans;
|
||||
window.url = url;
|
||||
window.MSP = MSP;
|
||||
|
||||
document.body.innerHTML = `
|
||||
<div id="textures-indicator"></div>
|
||||
<div id="prev" class="item-selected">
|
||||
<div class="item-body item-selected"></div>
|
||||
</div>
|
||||
<div id="next" tid="1">
|
||||
<div class="item-body"></div>
|
||||
</div>
|
||||
`;
|
||||
require(modulePath);
|
||||
|
||||
await $('#next > .item-body').click();
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'skinlib/info/1',
|
||||
dataType: 'json'
|
||||
});
|
||||
expect($('#next').hasClass('item-selected')).toBe(true);
|
||||
expect(MSP.changeSkin).toBeCalledWith('textures/1');
|
||||
expect($('#textures-indicator').text()).toBe('general.skin');
|
||||
|
||||
document.body.innerHTML = `
|
||||
<div id="textures-indicator"></div>
|
||||
<div id="prev" class="item-selected">
|
||||
<div class="item-body item-selected"></div>
|
||||
</div>
|
||||
<div id="next" tid="2">
|
||||
<div class="item-body"></div>
|
||||
</div>
|
||||
`;
|
||||
window.selectedTextures = [];
|
||||
|
||||
await $('#next > .item-body').click();
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'skinlib/info/2',
|
||||
dataType: 'json'
|
||||
});
|
||||
expect($('#next').hasClass('item-selected')).toBe(true);
|
||||
expect(MSP.changeCape).toBeCalledWith('textures/2');
|
||||
expect($('#textures-indicator').text()).toBe('general.skin & general.cape');
|
||||
});
|
||||
|
||||
it('render closet', () => {
|
||||
const trans = jest.fn(key => key);
|
||||
const url = jest.fn(path => path);
|
||||
window.trans = trans;
|
||||
window.url = url;
|
||||
|
||||
document.body.innerHTML = `
|
||||
<input name="q" />
|
||||
<div id="skin-category"></div>
|
||||
<div id="closet-paginator"></div>
|
||||
`;
|
||||
const renderCloset = require(modulePath).renderCloset;
|
||||
|
||||
renderCloset([], 'skin');
|
||||
expect($('#closet-paginator').css('display')).toBe('none');
|
||||
expect(trans).toBeCalledWith('user.emptyClosetMsg', { url: 'skinlib?filter=skin' });
|
||||
expect($('#skin-category').html()).toBe(
|
||||
'<div class="empty-msg">user.emptyClosetMsg</div>'
|
||||
);
|
||||
|
||||
$('input').val('q');
|
||||
renderCloset([], 'skin');
|
||||
expect($('#skin-category').html()).toBe(
|
||||
'<div class="empty-msg">general.noResult</div>'
|
||||
);
|
||||
|
||||
renderCloset([{ tid: 1, name: 'name', type: 'steve' }], 'skin');
|
||||
expect($('#closet-paginator').css('display')).not.toBe('none');
|
||||
expect($('.item').attr('tid')).toBe('1');
|
||||
expect($('img').attr('src')).toBe('/preview/1.png');
|
||||
expect($('.texture-name').html().trim()).toBe(
|
||||
'<span title="name">name <small>(steve)</small></span>'
|
||||
);
|
||||
expect($('a.more').attr('href')).toBe('/skinlib/show/1');
|
||||
expect($('a.more').attr('title')).toBe('user.viewInSkinlib');
|
||||
});
|
||||
|
||||
it('reload closet', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValue(Promise.resolve({
|
||||
items: [],
|
||||
category: 'skin',
|
||||
total_pages: 1
|
||||
}));
|
||||
const trans = jest.fn(key => key);
|
||||
const url = jest.fn(path => path);
|
||||
const swal = jest.fn().mockReturnValue(Promise.resolve('name'));
|
||||
const toastr = {
|
||||
success: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
const MSP = {
|
||||
changeSkin: jest.fn(),
|
||||
changeCape: jest.fn()
|
||||
};
|
||||
window.fetch = fetch;
|
||||
window.trans = trans;
|
||||
window.url = url;
|
||||
window.swal = swal;
|
||||
window.toastr = toastr;
|
||||
|
||||
document.body.innerHTML = `
|
||||
<div id="skin-category">
|
||||
<div tid="1">
|
||||
<div class="item-footer">
|
||||
<div class="texture-name">
|
||||
<span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="closet-paginator" last-skin-page="0"></div>
|
||||
`;
|
||||
const reloadCloset = require(modulePath).reloadCloset;
|
||||
|
||||
await reloadCloset('skin', 1, 'q');
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'GET',
|
||||
url: url('user/closet-data'),
|
||||
dataType: 'json',
|
||||
data: {
|
||||
category: 'skin',
|
||||
page: 1,
|
||||
q: 'q'
|
||||
}
|
||||
});
|
||||
expect($('#closet-paginator').attr('last-skin-page')).toBe('1');
|
||||
});
|
||||
|
||||
it('rename item', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValue(Promise.resolve({ errno: 0, msg: 'success' }));
|
||||
const trans = jest.fn(key => key);
|
||||
const url = jest.fn(path => path);
|
||||
const swal = jest.fn().mockReturnValue(Promise.resolve('name'));
|
||||
const toastr = {
|
||||
success: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
const MSP = {
|
||||
changeSkin: jest.fn(),
|
||||
changeCape: jest.fn()
|
||||
};
|
||||
window.fetch = fetch;
|
||||
window.trans = trans;
|
||||
window.url = url;
|
||||
window.swal = swal;
|
||||
window.toastr = toastr;
|
||||
|
||||
document.body.innerHTML = `
|
||||
<div id="skin-category">
|
||||
<div tid="1">
|
||||
<div class="item-footer">
|
||||
<div class="texture-name">
|
||||
<span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
const renameClosetItem = require(modulePath).renameClosetItem;
|
||||
|
||||
await renameClosetItem(1, 'oldName');
|
||||
expect(swal).toBeCalledWith(expect.objectContaining({
|
||||
title: trans('user.renameClosetItem'),
|
||||
input: 'text',
|
||||
inputValue: 'oldName',
|
||||
showCancelButton: true,
|
||||
}));
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'closet/rename',
|
||||
dataType: 'json',
|
||||
data: { tid: 1, new_name: 'name' }
|
||||
});
|
||||
|
||||
await renameClosetItem(1, 'oldName');
|
||||
expect(toastr.success).toBeCalledWith('success');
|
||||
expect($('span').html('name'));
|
||||
});
|
||||
|
||||
it('remove item from closet', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValue(Promise.resolve({ errno: 0, msg: 'success' }));
|
||||
const trans = jest.fn(key => key);
|
||||
const url = jest.fn(path => path);
|
||||
const swal = jest.fn().mockReturnValue(Promise.resolve());
|
||||
const toastr = {
|
||||
success: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
const MSP = {
|
||||
changeSkin: jest.fn(),
|
||||
changeCape: jest.fn()
|
||||
};
|
||||
window.fetch = fetch;
|
||||
window.trans = trans;
|
||||
window.url = url;
|
||||
window.swal = swal;
|
||||
window.toastr = toastr;
|
||||
|
||||
document.body.innerHTML = `
|
||||
<div id="skin-category">
|
||||
<div id="shouldBeRemoved" tid="1"></div>
|
||||
</div>
|
||||
`;
|
||||
const removeFromCloset = require(modulePath).removeFromCloset;
|
||||
|
||||
await removeFromCloset(1);
|
||||
expect(swal).toBeCalledWith({
|
||||
text: 'user.removeFromClosetNotice',
|
||||
type: 'warning',
|
||||
showCancelButton: true
|
||||
});
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'closet/remove',
|
||||
dataType: 'json',
|
||||
data: { tid: 1 }
|
||||
});
|
||||
|
||||
await removeFromCloset(1);
|
||||
expect(swal).toBeCalledWith({ type: 'success', html: 'success' });
|
||||
expect(document.getElementById('shouldBeRemoved')).toBeNull();
|
||||
expect(trans).toBeCalledWith('user.emptyClosetMsg', { url: url('skinlib?filter=skin') });
|
||||
expect($('#skin-category').html()).toBe(
|
||||
'<div class="empty-msg">user.emptyClosetMsg</div>'
|
||||
);
|
||||
});
|
||||
|
||||
it('set avatar', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValue(Promise.resolve({ errno: 0, msg: 'success' }));
|
||||
const trans = jest.fn(key => key);
|
||||
const url = jest.fn(path => path);
|
||||
const swal = jest.fn().mockReturnValue(Promise.resolve());
|
||||
const toastr = {
|
||||
success: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
const MSP = {
|
||||
changeSkin: jest.fn(),
|
||||
changeCape: jest.fn()
|
||||
};
|
||||
window.fetch = fetch;
|
||||
window.trans = trans;
|
||||
window.url = url;
|
||||
window.swal = swal;
|
||||
window.toastr = toastr;
|
||||
|
||||
document.body.innerHTML = `
|
||||
<img alt="User Image" src="src" />
|
||||
`;
|
||||
const setAsAvatar = require(modulePath).setAsAvatar;
|
||||
|
||||
await setAsAvatar(1);
|
||||
expect(swal).toBeCalledWith({
|
||||
title: 'user.setAvatar',
|
||||
text: 'user.setAvatarNotice',
|
||||
type: 'question',
|
||||
showCancelButton: true
|
||||
});
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'user/profile/avatar',
|
||||
dataType: 'json',
|
||||
data: { tid: 1 }
|
||||
});
|
||||
|
||||
await setAsAvatar(1);
|
||||
expect(toastr.success).toBeCalledWith('success');
|
||||
expect($('img').attr('src').endsWith('src')).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('tests for "player" module', () => {
|
||||
const modulePath = '../user/player';
|
||||
|
||||
it('show player texture preview', async () => {
|
||||
const url = jest.fn(path => path);
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValue(Promise.resolve({
|
||||
tid_steve: 1,
|
||||
tid_alex: 2,
|
||||
tid_cape: 3,
|
||||
preference: 'steve',
|
||||
player_name: 'name'
|
||||
}));
|
||||
window.url = url;
|
||||
window.fetch = fetch;
|
||||
window.TexturePreview = require('../common/texture-preview');
|
||||
window.MSP = {
|
||||
changeSkin: jest.fn(),
|
||||
changeCape: jest.fn(),
|
||||
setStatus: jest.fn(),
|
||||
getStatus: jest.fn()
|
||||
};
|
||||
|
||||
document.body.innerHTML = `
|
||||
<div id="1" class="player-selected player"></div>
|
||||
<div id="2" class="player"></div>
|
||||
`;
|
||||
require(modulePath);
|
||||
|
||||
await $('#2').click();
|
||||
expect($('#1').hasClass('player-selected')).toBe(false);
|
||||
expect($('#2').hasClass('player-selected')).toBe(true);
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'user/player/show',
|
||||
dataType: 'json',
|
||||
data: { pid: '2' }
|
||||
});
|
||||
});
|
||||
|
||||
it('change player reference', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 0, msg: 'success' }))
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 1, msg: 'warning' }));
|
||||
const url = jest.fn(path => path);
|
||||
const toastr = {
|
||||
success: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
window.fetch = fetch;
|
||||
window.url = url;
|
||||
window.toastr = toastr;
|
||||
|
||||
document.body.innerHTML = `
|
||||
<select id="preference" pid="1">
|
||||
<option value="default" selected></option>
|
||||
<option value="slim"></option>
|
||||
</select>
|
||||
`;
|
||||
$('select').on('change', require(modulePath).changePreference);
|
||||
|
||||
await $('select').val('slim').trigger('change');
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'user/player/preference',
|
||||
dataType: 'json',
|
||||
data: {
|
||||
pid: '1',
|
||||
preference: 'slim'
|
||||
}
|
||||
});
|
||||
expect(toastr.warning).not.toBeCalled();
|
||||
expect(toastr.success).toBeCalledWith('success');
|
||||
|
||||
await $('select').trigger('change');
|
||||
expect(toastr.warning).toBeCalledWith('warning');
|
||||
});
|
||||
|
||||
it('change player name', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValue(Promise.resolve({ errno: 0, msg: 'success' }));
|
||||
const url = jest.fn(path => path);
|
||||
const trans = jest.fn(key => key);
|
||||
const toastr = {
|
||||
success: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
const swal = jest.fn()
|
||||
.mockImplementationOnce(options => {
|
||||
options.inputValidator('name');
|
||||
return Promise.resolve('name');
|
||||
})
|
||||
.mockImplementation(() => Promise.resolve());
|
||||
window.fetch = fetch;
|
||||
window.url = url;
|
||||
window.trans = trans;
|
||||
window.toastr = toastr;
|
||||
window.swal = swal;
|
||||
|
||||
document.body.innerHTML = `
|
||||
<input id="player_name" placeholder="placeholder" />
|
||||
<table>
|
||||
<tbody>
|
||||
<td>1</td>
|
||||
<td id="player-name">old</td>
|
||||
</tbody>
|
||||
</table>
|
||||
`;
|
||||
const changePlayerName = require(modulePath).changePlayerName;
|
||||
|
||||
await changePlayerName(1);
|
||||
expect(swal).toBeCalledWith(expect.objectContaining({
|
||||
title: 'user.changePlayerName',
|
||||
text: 'placeholder',
|
||||
inputValue: 'old',
|
||||
input: 'text',
|
||||
showCancelButton: true
|
||||
}));
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'user/player/rename',
|
||||
dataType: 'json',
|
||||
data: { pid: 1, new_player_name: 'name' }
|
||||
});
|
||||
await changePlayerName(1);
|
||||
expect(swal).toBeCalledWith({ type: 'success', html: 'success' });
|
||||
expect($('#player-name').html()).toBe('name');
|
||||
});
|
||||
|
||||
it('submit clearing texture request', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 0, msg: 'success' }))
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 1, msg: 'warning' }));
|
||||
const url = jest.fn(path => path);
|
||||
const trans = jest.fn(key => key);
|
||||
const toastr = {
|
||||
success: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
const modal = jest.fn();
|
||||
window.fetch = fetch;
|
||||
window.url = url;
|
||||
window.trans = trans;
|
||||
window.toastr = toastr;
|
||||
$.fn.modal = modal;
|
||||
|
||||
document.body.innerHTML = `
|
||||
<div class="modal" id="shouldBeRemoved" style="display: none"></div>
|
||||
<div class="modal" id="shouldNotBeRemoved"></div>
|
||||
<input id="clear-steve">
|
||||
<input id="clear-alex">
|
||||
<input id="clear-cape">
|
||||
`;
|
||||
const ajaxClearTexture = require(modulePath).ajaxClearTexture;
|
||||
|
||||
ajaxClearTexture(1);
|
||||
expect(document.getElementById('shouldBeRemoved')).toBeNull();
|
||||
expect(document.getElementById('shouldNotBeRemoved')).not.toBeNull();
|
||||
expect(toastr.warning).toBeCalledWith('user.noClearChoice');
|
||||
|
||||
$('#clear-steve').prop('checked', true);
|
||||
await ajaxClearTexture(1);
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'user/player/texture/clear',
|
||||
dataType: 'json',
|
||||
data: { pid: 1, steve: 1, alex: 0, cape: 0 }
|
||||
});
|
||||
expect(swal).toBeCalledWith({ type: 'success', html: 'success' });
|
||||
expect(modal).toBeCalledWith('hide');
|
||||
|
||||
await ajaxClearTexture(1);
|
||||
expect(swal).lastCalledWith({ type: 'error', html: 'warning' });
|
||||
});
|
||||
|
||||
it('delete player', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValue(Promise.resolve({ errno: 0, msg: 'success' }));
|
||||
const url = jest.fn(path => path);
|
||||
const toastr = {
|
||||
success: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
const swal = jest.fn().mockReturnValue(Promise.resolve());
|
||||
window.fetch = fetch;
|
||||
window.url = url;
|
||||
window.toastr = toastr;
|
||||
window.swal = swal;
|
||||
|
||||
document.body.innerHTML = `
|
||||
<tr id="1"></tr>
|
||||
`;
|
||||
const deletePlayer = require(modulePath).deletePlayer;
|
||||
|
||||
await deletePlayer(1);
|
||||
expect(swal).toBeCalledWith({
|
||||
title: 'user.deletePlayer',
|
||||
text: 'user.deletePlayerNotice',
|
||||
type: 'warning',
|
||||
showCancelButton: true,
|
||||
cancelButtonColor: '#3085d6',
|
||||
confirmButtonColor: '#d33'
|
||||
});
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'user/player/delete',
|
||||
dataType: 'json',
|
||||
data: { pid: 1 }
|
||||
});
|
||||
|
||||
await deletePlayer(1);
|
||||
expect(swal).lastCalledWith({ type: 'success', html: 'success' });
|
||||
expect(document.getElementById('1')).toBeNull();
|
||||
});
|
||||
|
||||
it('add a new player', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 0, msg: 'success' }))
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 1, msg: 'warning' }));
|
||||
const url = jest.fn(path => path);
|
||||
const toastr = {
|
||||
success: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
const swal = jest.fn().mockReturnValue(Promise.resolve());
|
||||
const modal = jest.fn();
|
||||
window.fetch = fetch;
|
||||
window.url = url;
|
||||
window.toastr = toastr;
|
||||
window.swal = swal;
|
||||
$.fn.modal = modal;
|
||||
|
||||
document.body.innerHTML = `
|
||||
<input id="player_name" value="name" />
|
||||
`;
|
||||
const addNewPlayer = require(modulePath).addNewPlayer;
|
||||
|
||||
await addNewPlayer();
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'user/player/add',
|
||||
dataType: 'json',
|
||||
data: { player_name: 'name' }
|
||||
});
|
||||
expect(swal).toBeCalledWith({ type: 'success', html: 'success' });
|
||||
|
||||
await addNewPlayer();
|
||||
expect(toastr.warning).toBeCalledWith('warning');
|
||||
expect(modal.mock.calls.length).toBe(1);
|
||||
});
|
||||
|
||||
it('set texture', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 0, msg: 'success' }))
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 1, msg: 'warning' }));
|
||||
const url = jest.fn(path => path);
|
||||
const toastr = {
|
||||
success: jest.fn(),
|
||||
warning: jest.fn(),
|
||||
info: jest.fn()
|
||||
};
|
||||
const swal = jest.fn().mockReturnValue(Promise.resolve());
|
||||
const modal = jest.fn();
|
||||
window.fetch = fetch;
|
||||
window.url = url;
|
||||
window.toastr = toastr;
|
||||
window.swal = swal;
|
||||
$.fn.modal = modal;
|
||||
window.selectedTextures = {};
|
||||
|
||||
document.body.innerHTML = `
|
||||
<input name="player" id="1" />
|
||||
`;
|
||||
const setTexture = require(modulePath).setTexture;
|
||||
|
||||
setTexture();
|
||||
expect(toastr.info).toBeCalledWith('user.emptySelectedPlayer');
|
||||
|
||||
$('input').prop('checked', true);
|
||||
setTexture();
|
||||
expect(toastr.info).toBeCalledWith('user.emptySelectedTexture');
|
||||
|
||||
window.selectedTextures = { skin: 1, cape: 2 };
|
||||
await setTexture();
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'user/player/set',
|
||||
dataType: 'json',
|
||||
data: { 'pid': '1', 'tid[skin]': 1, 'tid[cape]': 2 }
|
||||
});
|
||||
expect(swal).toBeCalledWith({ type: 'success', html: 'success' });
|
||||
expect(modal).toBeCalledWith('hide');
|
||||
|
||||
await setTexture();
|
||||
expect(toastr.warning).toBeCalledWith('warning');
|
||||
expect(modal.mock.calls.length).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('tests for "profile" module', () => {
|
||||
const modulePath = '../user/profile';
|
||||
|
||||
it('change nickname', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValue(Promise.resolve({ errno: 0, msg: 'success' }));
|
||||
const swal = jest.fn().mockReturnValue(Promise.resolve());
|
||||
const trans = jest.fn(key => key);
|
||||
const url = jest.fn(path => path);
|
||||
window.fetch = fetch;
|
||||
window.swal = swal;
|
||||
window.trans = trans;
|
||||
window.url = url;
|
||||
window.debounce = jest.fn(fn => fn);
|
||||
|
||||
document.body.innerHTML = `
|
||||
<div class="nickname"></div>
|
||||
<input id="new-nickname" />
|
||||
`;
|
||||
const changeNickName = require(modulePath).changeNickName;
|
||||
|
||||
await changeNickName();
|
||||
expect(swal).toBeCalledWith({ type: 'error', html: 'user.emptyNewNickName' });
|
||||
|
||||
$('input').val('name');
|
||||
await changeNickName();
|
||||
expect(trans).toBeCalledWith('user.changeNickName', { new_nickname: 'name' });
|
||||
expect(swal).toBeCalledWith({
|
||||
text: 'user.changeNickName',
|
||||
type: 'question',
|
||||
showCancelButton: true
|
||||
});
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'user/profile?action=nickname',
|
||||
dataType: 'json',
|
||||
data: { new_nickname: 'name' }
|
||||
});
|
||||
|
||||
await changeNickName();
|
||||
expect($('.nickname').text()).toBe('name');
|
||||
expect(swal).toBeCalledWith({ type: 'success', html: 'success' });
|
||||
});
|
||||
|
||||
it('change password', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 0, msg: 'success' }))
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 1, msg: 'warning' }))
|
||||
.mockReturnValue(Promise.resolve({ errno: 0, msg: 'success' }));
|
||||
const swal = jest.fn().mockReturnValue(Promise.resolve());
|
||||
const trans = jest.fn(key => key);
|
||||
const url = jest.fn(path => path);
|
||||
const toastr = {
|
||||
info: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
window.fetch = fetch;
|
||||
window.swal = swal;
|
||||
window.trans = trans;
|
||||
window.url = url;
|
||||
window.toastr = toastr;
|
||||
window.logout = jest.fn().mockReturnValue(Promise.resolve({ errno: 0 }));
|
||||
|
||||
document.body.innerHTML = `
|
||||
<input id="password" />
|
||||
<input id="new-passwd" />
|
||||
<input id="confirm-pwd" />
|
||||
`;
|
||||
const changePassword = require(modulePath).changePassword;
|
||||
|
||||
changePassword();
|
||||
expect(toastr.info).toBeCalledWith('user.emptyPassword');
|
||||
expect($('#password').is(':focus')).toBe(true);
|
||||
|
||||
$('#password').val('password');
|
||||
changePassword();
|
||||
expect(toastr.info).toBeCalledWith('user.emptyNewPassword');
|
||||
expect($('#new-passwd').is(':focus')).toBe(true);
|
||||
|
||||
$('#new-passwd').val('new-password');
|
||||
changePassword();
|
||||
expect(toastr.info).toBeCalledWith('auth.emptyConfirmPwd');
|
||||
expect($('#confirm-pwd').is(':focus')).toBe(true);
|
||||
|
||||
$('#confirm-pwd').val('not-same').blur();
|
||||
changePassword();
|
||||
expect(toastr.warning).toBeCalledWith('auth.invalidConfirmPwd');
|
||||
expect($('#confirm-pwd').is(':focus')).toBe(true);
|
||||
|
||||
$('#confirm-pwd').val('new-password');
|
||||
await changePassword();
|
||||
expect(swal).toBeCalledWith({ text: 'success', type: 'success' });
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'user/profile?action=password',
|
||||
dataType: 'json',
|
||||
data: { current_password: 'password', new_password: 'new-password' }
|
||||
});
|
||||
|
||||
await changePassword();
|
||||
expect(swal).toBeCalledWith({ type: 'warning', text: 'warning' });
|
||||
|
||||
await changePassword();
|
||||
expect(logout).toBeCalled();
|
||||
});
|
||||
|
||||
it('change email', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 0, msg: 'success' }))
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 1, msg: 'warning' }));
|
||||
const swal = jest.fn().mockReturnValue(Promise.resolve());
|
||||
const trans = jest.fn(key => key);
|
||||
const url = jest.fn(path => path);
|
||||
const toastr = {
|
||||
info: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
window.fetch = fetch;
|
||||
window.swal = swal;
|
||||
window.trans = trans;
|
||||
window.url = url;
|
||||
window.toastr = toastr;
|
||||
window.logout = jest.fn().mockReturnValue(Promise.resolve({ errno: 0 }));
|
||||
|
||||
document.body.innerHTML = `
|
||||
<input id="new-email" />
|
||||
<input id="current-password" value="pwd" />
|
||||
`;
|
||||
const changeEmail = require(modulePath).changeEmail;
|
||||
|
||||
changeEmail();
|
||||
expect(swal).toBeCalledWith({ type: 'error', html: 'user.emptyNewEmail' });
|
||||
|
||||
$('#new-email').val('email');
|
||||
changeEmail();
|
||||
expect(swal).toBeCalledWith({ type: 'warning', html: 'auth.invalidEmail' });
|
||||
|
||||
$('#new-email').val('a@b.c');
|
||||
await changeEmail();
|
||||
expect(trans).toBeCalledWith('user.changeEmail', { new_email: 'a@b.c' });
|
||||
expect(swal).toBeCalledWith({
|
||||
text: 'user.changeEmail',
|
||||
type: 'question',
|
||||
showCancelButton: true
|
||||
});
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'user/profile?action=email',
|
||||
dataType: 'json',
|
||||
data: { new_email: 'a@b.c', password: 'pwd' }
|
||||
});
|
||||
});
|
||||
|
||||
it('delete account', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 0, msg: 'success' }))
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 1, msg: 'warning' }));
|
||||
const swal = jest.fn().mockReturnValue(Promise.resolve());
|
||||
const trans = jest.fn(key => key);
|
||||
const url = jest.fn(path => path);
|
||||
const toastr = {
|
||||
info: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
window.fetch = fetch;
|
||||
window.swal = swal;
|
||||
window.trans = trans;
|
||||
window.url = url;
|
||||
window.toastr = toastr;
|
||||
|
||||
document.body.innerHTML = `
|
||||
<div class="modal-body">
|
||||
<input id="password" />
|
||||
</div>
|
||||
`;
|
||||
const deleteAccount = require(modulePath).deleteAccount;
|
||||
|
||||
deleteAccount();
|
||||
expect(swal).toBeCalledWith({ type: 'warning', html: 'user.emptyDeletePassword' });
|
||||
|
||||
$('#password').val('password');
|
||||
await deleteAccount();
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'user/profile?action=delete',
|
||||
dataType: 'json',
|
||||
data: { password: 'password' }
|
||||
});
|
||||
expect(swal).toBeCalledWith({ type: 'success', html: 'success' });
|
||||
|
||||
await deleteAccount();
|
||||
expect(swal).toBeCalledWith({ type: 'warning', html: 'warning' });
|
||||
});
|
||||
});
|
||||
|
||||
describe('tests for "sign" module', () => {
|
||||
const modulePath = '../user/sign';
|
||||
|
||||
it('sign', async () => {
|
||||
const url = jest.fn(path => path);
|
||||
const toastr = {
|
||||
success: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
const trans = jest.fn(key => key);
|
||||
const swal = jest.fn().mockReturnValue(Promise.resolve());
|
||||
window.url = url;
|
||||
window.toastr = toastr;
|
||||
window.trans = trans;
|
||||
window.swal = swal;
|
||||
window.debounce = fn => fn;
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValueOnce(Promise.resolve({
|
||||
errno: 0,
|
||||
msg: 'success',
|
||||
score: 100,
|
||||
remaining_time: 24,
|
||||
storage: {
|
||||
used: 50,
|
||||
total: 100,
|
||||
percentage: 50
|
||||
}
|
||||
}))
|
||||
.mockReturnValueOnce(Promise.resolve({
|
||||
errno: 0,
|
||||
msg: 'success',
|
||||
score: 100,
|
||||
remaining_time: 24,
|
||||
storage: {
|
||||
used: 2000,
|
||||
total: 4000,
|
||||
percentage: 50
|
||||
}
|
||||
}))
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 1, msg: 'warning' }));
|
||||
window.fetch = fetch;
|
||||
|
||||
document.body.innerHTML = `
|
||||
<div id="score"></div>
|
||||
<a id="sign-button"></a>
|
||||
<div id="user-storage"></div>
|
||||
<div id="user-storage-bar"></div>
|
||||
`;
|
||||
const sign = require(modulePath);
|
||||
|
||||
await sign();
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'user/sign',
|
||||
dataType: 'json'
|
||||
});
|
||||
expect($('#score').html()).toBe('100');
|
||||
expect(trans).toBeCalledWith('user.signRemainingTime', { time: '24' });
|
||||
expect($('#sign-button').html()).toBe(
|
||||
'<i class="fa fa-calendar-check-o"></i> user.signRemainingTime'
|
||||
);
|
||||
expect($('#sign-button').attr('disabled')).toBe('disabled');
|
||||
expect($('#user-storage').html()).toBe('<b>50</b>/ 100 KB');
|
||||
expect($('#user-storage-bar').css('width')).toBe('50%');
|
||||
expect(swal).toBeCalledWith({ type: 'success', html: 'success' });
|
||||
|
||||
await sign();
|
||||
expect($('#user-storage').html()).toBe('<b>2</b>/ 4 MB');
|
||||
|
||||
await sign();
|
||||
expect(toastr.warning).toBeCalledWith('warning');
|
||||
});
|
||||
});
|
||||
|
|
@ -9,7 +9,7 @@ $('#layout-skins-list [data-skin]').click(function (e) {
|
|||
current_skin = skin_name;
|
||||
});
|
||||
|
||||
$('#color-submit').click(() => {
|
||||
function submitColor() {
|
||||
fetch({
|
||||
type: 'POST',
|
||||
url: url('admin/customize?action=color'),
|
||||
|
|
@ -18,4 +18,10 @@ $('#color-submit').click(() => {
|
|||
}).then(({ errno, msg }) => {
|
||||
(errno == 0) ? toastr.success(msg) : toastr.warning(msg);
|
||||
}).catch(err => showAjaxError(err));
|
||||
});
|
||||
}
|
||||
|
||||
$('#color-submit').click(submitColor);
|
||||
|
||||
if (typeof require !== 'undefined' && typeof module !== 'undefined') {
|
||||
module.exports = submitColor;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -162,3 +162,14 @@ function deletePlayer(pid) {
|
|||
}
|
||||
}).catch(err => showAjaxError(err));
|
||||
}
|
||||
|
||||
if (typeof require !== 'undefined' && typeof module !== 'undefined') {
|
||||
module.exports = {
|
||||
changePreference,
|
||||
changeTexture,
|
||||
ajaxChangeTexture,
|
||||
changePlayerName,
|
||||
changeOwner,
|
||||
deletePlayer
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ function disablePlugin(name) {
|
|||
dataType: 'json'
|
||||
}).then(({ errno, msg }) => {
|
||||
if (errno == 0) {
|
||||
toastr.warning(msg);
|
||||
toastr.success(msg);
|
||||
|
||||
$.pluginsTable.ajax.reload(null, false);
|
||||
} else {
|
||||
|
|
@ -53,3 +53,11 @@ function deletePlugin(name) {
|
|||
}
|
||||
}).catch(err => showAjaxError(err));
|
||||
}
|
||||
|
||||
if (typeof require !== 'undefined' && typeof module !== 'undefined') {
|
||||
module.exports = {
|
||||
enablePlugin,
|
||||
disablePlugin,
|
||||
deletePlugin
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,3 +89,7 @@ function downloadUpdates() {
|
|||
}).catch(err => showAjaxError(err));
|
||||
|
||||
}
|
||||
|
||||
if (typeof require !== 'undefined' && typeof module !== 'undefined') {
|
||||
module.exports = downloadUpdates;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -167,3 +167,15 @@ $('body').on('keypress', '.score', function(event){
|
|||
changeUserScore($(this).parent().parent().attr('id'), $(this).val());
|
||||
}
|
||||
});
|
||||
|
||||
if (typeof require !== 'undefined' && typeof module !== 'undefined') {
|
||||
module.exports = {
|
||||
changeUserEmail,
|
||||
changeUserNickName,
|
||||
changeUserPwd,
|
||||
changeUserScore,
|
||||
changeBanStatus,
|
||||
changeAdminStatus,
|
||||
deleteUserAccount
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,3 +9,7 @@ function refreshCaptcha() {
|
|||
}
|
||||
|
||||
$('.captcha').click(refreshCaptcha);
|
||||
|
||||
if (typeof require !== 'undefined' && typeof module !== 'undefined') {
|
||||
module.exports = refreshCaptcha;
|
||||
}
|
||||
|
|
|
|||
50
resources/assets/src/js/auth/forgot.js
Normal file
50
resources/assets/src/js/auth/forgot.js
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/* global refreshCaptcha */
|
||||
|
||||
'use strict';
|
||||
|
||||
$('#forgot-button').click(e => {
|
||||
e.preventDefault();
|
||||
|
||||
let data = {
|
||||
email: $('#email').val(),
|
||||
captcha: $('#captcha').val()
|
||||
};
|
||||
|
||||
(function validate({ email, captcha }, callback) {
|
||||
if (email == '') {
|
||||
showMsg(trans('auth.emptyEmail'));
|
||||
$('#email').focus();
|
||||
} else if (!/\S+@\S+\.\S+/.test(email)) {
|
||||
showMsg(trans('auth.invalidEmail'), 'warning');
|
||||
} else if (captcha == '') {
|
||||
showMsg(trans('auth.emptyCaptcha'));
|
||||
$('#captcha').focus();
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
})(data, () => {
|
||||
fetch({
|
||||
type: 'POST',
|
||||
url: url('auth/forgot'),
|
||||
dataType: 'json',
|
||||
data: data,
|
||||
beforeSend: () => {
|
||||
$('#forgot-button').html(
|
||||
'<i class="fa fa-spinner fa-spin"></i> ' + trans('auth.sending')
|
||||
).prop('disabled', 'disabled');
|
||||
}
|
||||
}).then(({ errno, msg }) => {
|
||||
if (errno == 0) {
|
||||
showMsg(msg, 'success');
|
||||
$('#forgot-button').html(trans('auth.send')).prop('disabled', 'disabled');
|
||||
} else {
|
||||
showMsg(msg, 'warning');
|
||||
refreshCaptcha();
|
||||
$('#forgot-button').html(trans('auth.send')).prop('disabled', '');
|
||||
}
|
||||
}).catch(err => {
|
||||
showAjaxError(err);
|
||||
$('#forgot-button').html(trans('auth.send')).prop('disabled', '');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -1,54 +1,5 @@
|
|||
/* global refreshCaptcha */
|
||||
|
||||
'use strict';
|
||||
|
||||
$('#forgot-button').click(e => {
|
||||
e.preventDefault();
|
||||
|
||||
let data = {
|
||||
email: $('#email').val(),
|
||||
captcha: $('#captcha').val()
|
||||
};
|
||||
|
||||
(function validate({ email, captcha }, callback) {
|
||||
if (email == '') {
|
||||
showMsg(trans('auth.emptyEmail'));
|
||||
$('#email').focus();
|
||||
} else if (!/\S+@\S+\.\S+/.test(email)) {
|
||||
showMsg(trans('auth.invalidEmail'), 'warning');
|
||||
} else if (captcha == '') {
|
||||
showMsg(trans('auth.emptyCaptcha'));
|
||||
$('#captcha').focus();
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
})(data, () => {
|
||||
fetch({
|
||||
type: 'POST',
|
||||
url: url('auth/forgot'),
|
||||
dataType: 'json',
|
||||
data: data,
|
||||
beforeSend: () => {
|
||||
$('#forgot-button').html(
|
||||
'<i class="fa fa-spinner fa-spin"></i> ' + trans('auth.sending')
|
||||
).prop('disabled', 'disabled');
|
||||
}
|
||||
}).then(({ errno, msg }) => {
|
||||
if (errno == 0) {
|
||||
showMsg(msg, 'success');
|
||||
$('#forgot-button').html(trans('auth.send')).prop('disabled', 'disabled');
|
||||
} else {
|
||||
showMsg(msg, 'warning');
|
||||
refreshCaptcha();
|
||||
$('#forgot-button').html(trans('auth.send')).prop('disabled', '');
|
||||
}
|
||||
}).catch(err => {
|
||||
showAjaxError(err);
|
||||
$('#forgot-button').html(trans('auth.send')).prop('disabled', '');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
$('#reset-button').click(e => {
|
||||
e.preventDefault();
|
||||
|
||||
|
|
|
|||
|
|
@ -49,3 +49,10 @@ function trans(key, parameters = {}) {
|
|||
|
||||
return temp;
|
||||
}
|
||||
|
||||
if (typeof require !== 'undefined' && typeof module !== 'undefined') {
|
||||
module.exports = {
|
||||
loadLocales,
|
||||
trans
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,3 +57,11 @@ function showModal(msg, title = 'Message', type = 'default', options = {}) {
|
|||
|
||||
$(dom).modal(options);
|
||||
}
|
||||
|
||||
if (typeof require !== 'undefined' && typeof module !== 'undefined') {
|
||||
module.exports = {
|
||||
showMsg,
|
||||
showAjaxError,
|
||||
showModal
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,3 +98,7 @@ $('.fa-pause').click(function () {
|
|||
|
||||
$('.fa-forward').click(() => MSP.setStatus('running', ! MSP.getStatus('running')));
|
||||
$('.fa-repeat' ).click(() => MSP.setStatus('rotation', ! MSP.getStatus('rotation')));
|
||||
|
||||
if (typeof require !== 'undefined' && typeof module !== 'undefined') {
|
||||
module.exports = TexturePreview;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ function getQueryString(key, defaultValue) {
|
|||
*/
|
||||
function debounce(func, delay, args = [], context = undefined) {
|
||||
if (isNaN(delay) || typeof func !== 'function') {
|
||||
throw new Error('Arguments type of function "debounce" is incorrent!');
|
||||
throw new Error('Arguments type of function "debounce" is incorrect!');
|
||||
}
|
||||
|
||||
let timer = null;
|
||||
|
|
@ -96,3 +96,12 @@ function url(relativeUri) {
|
|||
|
||||
return blessing.base_url + relativeUri;
|
||||
}
|
||||
|
||||
if (typeof require !== 'undefined' && typeof module !== 'undefined') {
|
||||
module.exports = {
|
||||
isEmpty,
|
||||
fetch,
|
||||
debounce,
|
||||
url
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,9 +63,11 @@ function renderSkinlib(items) {
|
|||
if (items.length === 0) {
|
||||
$('#skinlib-paginator').hide();
|
||||
|
||||
container.html(`<p style="text-align: center; margin: 30px 0;">
|
||||
${ trans('general.noResult') }
|
||||
</p>`);
|
||||
container.html(
|
||||
'<p style="text-align: center; margin: 30px 0;">' +
|
||||
trans('general.noResult') +
|
||||
'</p>'
|
||||
);
|
||||
} else {
|
||||
$('#skinlib-paginator').show();
|
||||
|
||||
|
|
@ -217,3 +219,13 @@ function updateBreadCrumb() {
|
|||
$('#navbar-search-input').val(decodeURI($.skinlib.keyword));
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof require !== 'undefined' && typeof module !== 'undefined') {
|
||||
module.exports = {
|
||||
renderSkinlib,
|
||||
reloadSkinlib,
|
||||
updatePaginator,
|
||||
updateUrlQueryString,
|
||||
updateBreadCrumb
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,16 +104,21 @@ function changeTextureName(tid, oldName) {
|
|||
/**
|
||||
* Update button action & likes of texture.
|
||||
*
|
||||
* @param {int} tid
|
||||
* @param {string} action add|remove
|
||||
* @param {number} tid
|
||||
* @param {'add'|'remove'} action
|
||||
* @return {null}
|
||||
*/
|
||||
function updateTextureStatus(tid, action) {
|
||||
let likes = parseInt($('#likes').html()) + (action == 'add' ? 1 : -1);
|
||||
action = (action == 'add') ? 'removeFromCloset' : 'addToCloset';
|
||||
|
||||
$(`a[tid=${tid}]`).attr('href', `javascript:${action}(${tid});`).attr('title', trans(`skinlib.${action}`)).toggleClass('liked');
|
||||
$(`#${tid}`).attr('href', `javascript:${action}(${tid});`).html(trans(`skinlib.${action}`));
|
||||
$(`a[tid=${tid}]`)
|
||||
.attr('href', `javascript:${action}(${tid});`)
|
||||
.attr('title', trans(`skinlib.${action}`))
|
||||
.toggleClass('liked');
|
||||
$(`#${tid}`)
|
||||
.attr('href', `javascript:${action}(${tid});`)
|
||||
.html(trans(`skinlib.${action}`));
|
||||
$('#likes').html(likes);
|
||||
}
|
||||
|
||||
|
|
@ -171,3 +176,15 @@ function deleteTexture(tid) {
|
|||
}
|
||||
}).catch(err => showAjaxError(err));
|
||||
}
|
||||
|
||||
if (typeof require !== 'undefined' && typeof module !== 'undefined') {
|
||||
module.exports = {
|
||||
addToCloset,
|
||||
ajaxAddToCloset,
|
||||
removeFromCloset,
|
||||
changeTextureName,
|
||||
updateTextureStatus,
|
||||
changePrivacy,
|
||||
deleteTexture
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -242,3 +242,13 @@ function setAsAvatar(tid) {
|
|||
}
|
||||
}).catch(err => showAjaxError(err));
|
||||
}
|
||||
|
||||
if (typeof require !== 'undefined' && typeof module !== 'undefined') {
|
||||
module.exports = {
|
||||
renderCloset,
|
||||
reloadCloset,
|
||||
renameClosetItem,
|
||||
removeFromCloset,
|
||||
setAsAvatar
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,13 +56,14 @@ $('body').on('change', '#preference', function () {
|
|||
}).catch(err => showAjaxError(err));
|
||||
});
|
||||
|
||||
function changePlayerName(pid, currentPlayerName) {
|
||||
function changePlayerName(pid) {
|
||||
let newPlayerName = '';
|
||||
const $playerName = $(`td:contains("${pid}")`).next();
|
||||
|
||||
swal({
|
||||
title: trans('user.changePlayerName'),
|
||||
text: $('#player_name').attr('placeholder'),
|
||||
inputValue: currentPlayerName,
|
||||
inputValue: $playerName.html(),
|
||||
input: 'text',
|
||||
showCancelButton: true,
|
||||
inputValidator: value => (new Promise((resolve, reject) => {
|
||||
|
|
@ -77,7 +78,7 @@ function changePlayerName(pid, currentPlayerName) {
|
|||
if (errno == 0) {
|
||||
swal({ type: 'success', html: msg });
|
||||
|
||||
$(`td:contains("${pid}")`).next().html(newPlayerName);
|
||||
$playerName.html(newPlayerName);
|
||||
} else {
|
||||
swal({ type: 'error', html: msg });
|
||||
}
|
||||
|
|
@ -207,3 +208,13 @@ function setTexture() {
|
|||
}).catch(err => showAjaxError(err));
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof require !== 'undefined' && typeof module !== 'undefined') {
|
||||
module.exports = {
|
||||
changePlayerName,
|
||||
ajaxClearTexture,
|
||||
deletePlayer,
|
||||
addNewPlayer,
|
||||
setTexture
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,8 +62,8 @@ function changePassword() {
|
|||
if (errno == 0) {
|
||||
return swal({
|
||||
type: 'success',
|
||||
text: msg }
|
||||
).then(() => {
|
||||
text: msg
|
||||
}).then(() => {
|
||||
return logout();
|
||||
}).then(({ errno }) => {
|
||||
if (errno == 0) {
|
||||
|
|
@ -151,3 +151,12 @@ function deleteAccount() {
|
|||
}
|
||||
}).catch(err => showAjaxError(err));
|
||||
}
|
||||
|
||||
if (typeof require !== 'undefined' && typeof module !== 'undefined') {
|
||||
module.exports = {
|
||||
changeNickName,
|
||||
changePassword,
|
||||
changeEmail,
|
||||
deleteAccount
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,9 @@ function sign() {
|
|||
$('#sign-button').attr('disabled', 'disabled').html(dom);
|
||||
|
||||
if (result.storage.used > 1024) {
|
||||
$('#user-storage').html(`<b>${Math.round(result.storage.used)}</b>/ ${Math.round(result.storage.total)} MB`);
|
||||
$('#user-storage').html(
|
||||
`<b>${Math.round(result.storage.used / 1024)}</b>/ ${Math.round(result.storage.total / 1024)} MB`
|
||||
);
|
||||
} else {
|
||||
$('#user-storage').html(`<b>${Math.round(result.storage.used)}</b>/ ${Math.round(result.storage.total)} KB`);
|
||||
}
|
||||
|
|
@ -26,3 +28,7 @@ function sign() {
|
|||
}
|
||||
}).catch(err => showAjaxError(err));
|
||||
}
|
||||
|
||||
if (typeof require !== 'undefined' && typeof module !== 'undefined') {
|
||||
module.exports = sign;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user