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') })