blessing-skin-server/resources/assets/tests/components/user/Closet.test.js
2019-03-13 13:16:51 +08:00

299 lines
8.8 KiB
JavaScript

import Vue from 'vue';
import { mount } from '@vue/test-utils';
import Closet from '@/components/user/Closet';
import ClosetItem from '@/components/user/ClosetItem';
import Previewer from '@/components/common/Previewer';
import toastr from 'toastr';
import { swal } from '@/js/notify';
jest.mock('@/js/notify');
window.blessing.extra = { unverified: false };
test('fetch closet data before mount', () => {
Vue.prototype.$http.get.mockResolvedValue({});
mount(Closet);
jest.runAllTicks();
expect(Vue.prototype.$http.get).toBeCalledWith(
'/user/closet-data',
{
category: 'skin',
q: '',
page: 1,
}
);
});
test('switch tabs', () => {
Vue.prototype.$http.get.mockResolvedValue({
items: [],
category: 'skin',
total_pages: 1
}).mockResolvedValueOnce({
items: [],
category: 'cape',
total_pages: 1
});
const wrapper = mount(Closet);
const tabSkin = wrapper.findAll('.nav-tabs > li').at(0);
tabSkin.find('a').trigger('click');
jest.runAllTicks();
expect(Vue.prototype.$http.get).toBeCalledWith(
'/user/closet-data',
{
category: 'skin',
q: '',
page: 1,
}
);
const tabCape = wrapper.findAll('.nav-tabs > li').at(1);
tabCape.find('a').trigger('click');
jest.runAllTicks();
expect(Vue.prototype.$http.get).toBeCalledWith(
'/user/closet-data',
{
category: 'cape',
q: '',
page: 1,
}
);
});
test('different categories', () => {
Vue.prototype.$http.get.mockResolvedValue({});
const wrapper = mount(Closet);
expect(wrapper.findAll('.nav-tabs > li').at(0).classes('active')).toBeTrue();
expect(wrapper.find('#skin-category').classes('active')).toBeTrue();
wrapper.setData({ category: 'cape' });
expect(wrapper.findAll('.nav-tabs > li').at(1).classes('active')).toBeTrue();
expect(wrapper.find('#cape-category').classes('active')).toBeTrue();
});
test('search textures', () => {
Vue.prototype.$http.get.mockResolvedValue({});
const wrapper = mount(Closet);
const input = wrapper.find('input');
input.element.value = 'q';
input.trigger('input');
jest.runAllTimers();
jest.runAllTicks();
expect(Vue.prototype.$http.get).toBeCalledWith(
'/user/closet-data',
{
category: 'skin',
q: 'q',
page: 1,
}
);
});
test('empty closet', () => {
Vue.prototype.$http.get.mockResolvedValue({});
const wrapper = mount(Closet);
expect(wrapper.find('#skin-category').text()).toContain('user.emptyClosetMsg');
wrapper.setData({ category: 'cape' });
expect(wrapper.find('#cape-category').text()).toContain('user.emptyClosetMsg');
});
test('no matched search result', () => {
Vue.prototype.$http.get.mockResolvedValue({});
const wrapper = mount(Closet);
wrapper.setData({ query: 'q' });
expect(wrapper.find('#skin-category').text()).toContain('general.noResult');
wrapper.setData({ category: 'cape' });
expect(wrapper.find('#cape-category').text()).toContain('general.noResult');
});
test('render items', async () => {
Vue.prototype.$http.get.mockResolvedValue({
items: [
{ tid: 1 },
{ tid: 2 }
],
category: 'skin',
total_pages: 1
});
const wrapper = mount(Closet);
await wrapper.vm.$nextTick();
expect(wrapper.findAll(ClosetItem)).toHaveLength(2);
});
test('reload closet when page changed', () => {
Vue.prototype.$http.get.mockResolvedValue({});
const wrapper = mount(Closet);
wrapper.vm.pageChanged();
jest.runAllTicks();
expect(Vue.prototype.$http.get).toBeCalledTimes(2);
});
test('remove skin item', () => {
Vue.prototype.$http.get.mockResolvedValue({});
const wrapper = mount(Closet);
wrapper.setData({ skinItems: [{ tid: 1 }] });
wrapper.vm.removeSkinItem(0);
expect(wrapper.find('#skin-category').text()).toContain('user.emptyClosetMsg');
});
test('remove cape item', () => {
Vue.prototype.$http.get.mockResolvedValue({});
const wrapper = mount(Closet);
wrapper.setData({ capeItems: [{ tid: 1 }], category: 'cape' });
wrapper.vm.removeCapeItem(0);
expect(wrapper.find('#cape-category').text()).toContain('user.emptyClosetMsg');
});
test('compute avatar URL', () => {
Vue.prototype.$http.get.mockResolvedValue({});
const wrapper = mount(Closet);
const { avatarUrl } = wrapper.vm;
expect(avatarUrl({ tid_skin: 1 })).toBe('/avatar/35/1');
});
test('select texture', async () => {
Vue.prototype.$http.get
.mockResolvedValueOnce({})
.mockResolvedValueOnce({ type: 'steve', hash: 'a' })
.mockResolvedValueOnce({ type: 'cape', hash: 'b' });
const wrapper = mount(Closet);
wrapper.setData({ skinItems: [{ tid: 1 }] });
wrapper.find(ClosetItem).vm.$emit('select');
await wrapper.vm.$nextTick();
expect(Vue.prototype.$http.get).toBeCalledWith('/skinlib/info/1');
expect(wrapper.vm.skinUrl).toBe('/textures/a');
wrapper.setData({ skinItems: [], capeItems: [{ tid: 2 }], category: 'cape' });
wrapper.find(ClosetItem).vm.$emit('select');
await wrapper.vm.$nextTick();
expect(Vue.prototype.$http.get).toBeCalledWith('/skinlib/info/2');
expect(wrapper.vm.capeUrl).toBe('/textures/b');
});
test('apply texture', async () => {
window.$ = jest.fn(() => ({
iCheck: () => ({
on(evt, cb) {
cb();
},
}),
0: {
dispatchEvent: () => {}
}
}));
Vue.prototype.$http.get
.mockResolvedValueOnce({})
.mockResolvedValueOnce([])
.mockResolvedValueOnce([
{ pid: 1, name: 'name', tid_skin: 10 }
]);
const wrapper = mount(Closet);
const button = wrapper.find(Previewer).findAll('button').at(0);
button.trigger('click');
jest.runAllTicks();
expect(wrapper.find('.modal-body').text()).toContain('user.closet.use-as.empty');
button.trigger('click');
await wrapper.vm.$nextTick();
expect(wrapper.find('input[type="radio"]').attributes('value')).toBe('1');
expect(wrapper.find('.model-label > img').attributes('src')).toBe('/avatar/35/10');
expect(wrapper.find('.modal-body').text()).toContain('name');
jest.runAllTimers();
});
test('submit applying texture', async () => {
window.$ = jest.fn(() => ({ modal() {} }));
jest.spyOn(toastr, 'info');
Vue.prototype.$http.get.mockResolvedValue({});
Vue.prototype.$http.post.mockResolvedValueOnce({ errno: 1 })
.mockResolvedValue({ errno: 0, msg: 'ok' });
const wrapper = mount(Closet);
const button = wrapper.find('.modal-footer > a:nth-child(2)');
button.trigger('click');
expect(toastr.info).toBeCalledWith('user.emptySelectedPlayer');
wrapper.setData({ selectedPlayer: 1 });
button.trigger('click');
expect(toastr.info).toBeCalledWith('user.emptySelectedTexture');
wrapper.setData({ selectedSkin: 1 });
button.trigger('click');
expect(Vue.prototype.$http.post).toBeCalledWith(
'/user/player/set',
{
pid: 1,
tid: {
skin: 1,
cape: undefined
}
}
);
wrapper.setData({ selectedSkin: 0, selectedCape: 1 });
button.trigger('click');
expect(Vue.prototype.$http.post).toBeCalledWith(
'/user/player/set',
{
pid: 1,
tid: {
skin: undefined,
cape: 1
}
}
);
await wrapper.vm.$nextTick();
expect(swal).toBeCalledWith({ type: 'success', text: 'ok' });
});
test('reset selected texture', () => {
Vue.prototype.$http.get.mockResolvedValue({});
const wrapper = mount(Closet);
wrapper.setData({
selectedSkin: 1,
selectedCape: 2,
skinUrl: 'a',
capeUrl: 'b'
});
wrapper.find(Previewer).findAll('button').at(1).trigger('click');
expect(wrapper.vm).toEqual(expect.objectContaining({
selectedSkin: 0,
selectedCape: 0,
skinUrl: '',
capeUrl: ''
}));
});
test('select specified texture initially', async () => {
window.history.pushState({}, 'title', `${location.href}?tid=1`);
window.$ = jest.fn(() => ({
modal() {},
iCheck: () => ({
on(evt, cb) {
cb();
},
}),
0: {
dispatchEvent: () => {}
}
}));
Vue.prototype.$http.get
.mockResolvedValueOnce({
items: [],
category: 'skin',
total_pages: 1
})
.mockResolvedValueOnce({ type: 'cape', hash: '' })
.mockResolvedValueOnce([]);
const wrapper = mount(Closet);
jest.runAllTimers();
await wrapper.vm.$nextTick();
jest.unmock('@/js/utils');
});