Migrate to TypeScript
This commit is contained in:
parent
cfe419d41c
commit
d1d4c54818
@ -176,8 +176,8 @@
|
||||
],
|
||||
"moduleNameMapper": {
|
||||
"^@/(.*)$": "<rootDir>/resources/assets/src/$1",
|
||||
"\\.css$": "<rootDir>/resources/assets/tests/__mocks__/style.js",
|
||||
"\\.(png|jpg)$": "<rootDir>/resources/assets/tests/__mocks__/file.js"
|
||||
"\\.css$": "<rootDir>/resources/assets/tests/__mocks__/style.ts",
|
||||
"\\.(png|jpg)$": "<rootDir>/resources/assets/tests/__mocks__/file.ts"
|
||||
},
|
||||
"setupFilesAfterEnv": [
|
||||
"<rootDir>/resources/assets/tests/setup.js"
|
||||
|
@ -1,87 +1,87 @@
|
||||
export default [
|
||||
{
|
||||
path: 'user',
|
||||
component: () => import('./user/Dashboard'),
|
||||
component: () => import('./user/Dashboard.vue'),
|
||||
el: '#usage-box',
|
||||
},
|
||||
{
|
||||
path: 'user/closet',
|
||||
component: () => import('./user/Closet'),
|
||||
component: () => import('./user/Closet.vue'),
|
||||
el: '.content',
|
||||
},
|
||||
{
|
||||
path: 'user/player',
|
||||
component: () => import('./user/Players'),
|
||||
component: () => import('./user/Players.vue'),
|
||||
el: '.content',
|
||||
},
|
||||
{
|
||||
path: 'user/profile',
|
||||
component: () => import('./user/Profile'),
|
||||
component: () => import('./user/Profile.vue'),
|
||||
el: '.content',
|
||||
},
|
||||
{
|
||||
path: 'admin/users',
|
||||
component: () => import('./admin/Users'),
|
||||
component: () => import('./admin/Users.vue'),
|
||||
el: '.content',
|
||||
},
|
||||
{
|
||||
path: 'admin/players',
|
||||
component: () => import('./admin/Players'),
|
||||
component: () => import('./admin/Players.vue'),
|
||||
el: '.content',
|
||||
},
|
||||
{
|
||||
path: 'admin/customize',
|
||||
component: () => import('./admin/Customization'),
|
||||
component: () => import('./admin/Customization.vue'),
|
||||
el: '#change-color',
|
||||
},
|
||||
{
|
||||
path: 'admin/plugins/manage',
|
||||
component: () => import('./admin/Plugins'),
|
||||
component: () => import('./admin/Plugins.vue'),
|
||||
el: '.content',
|
||||
},
|
||||
{
|
||||
path: 'admin/plugins/market',
|
||||
component: () => import('./admin/Market'),
|
||||
component: () => import('./admin/Market.vue'),
|
||||
el: '.content',
|
||||
},
|
||||
{
|
||||
path: 'admin/update',
|
||||
component: () => import('./admin/Update'),
|
||||
component: () => import('./admin/Update.vue'),
|
||||
el: '#update-button',
|
||||
},
|
||||
{
|
||||
path: 'auth/login',
|
||||
component: () => import('./auth/Login'),
|
||||
component: () => import('./auth/Login.vue'),
|
||||
el: 'form',
|
||||
},
|
||||
{
|
||||
path: 'auth/register',
|
||||
component: () => import('./auth/Register'),
|
||||
component: () => import('./auth/Register.vue'),
|
||||
el: 'form',
|
||||
},
|
||||
{
|
||||
path: 'auth/forgot',
|
||||
component: () => import('./auth/Forgot'),
|
||||
component: () => import('./auth/Forgot.vue'),
|
||||
el: 'form',
|
||||
},
|
||||
{
|
||||
path: 'auth/reset/(\\d+)',
|
||||
component: () => import('./auth/Reset'),
|
||||
component: () => import('./auth/Reset.vue'),
|
||||
el: 'form',
|
||||
},
|
||||
{
|
||||
path: 'skinlib',
|
||||
component: () => import('./skinlib/List'),
|
||||
component: () => import('./skinlib/List.vue'),
|
||||
el: '.content-wrapper',
|
||||
},
|
||||
{
|
||||
path: 'skinlib/show/(\\d+)',
|
||||
component: () => import('./skinlib/Show'),
|
||||
component: () => import('./skinlib/Show.vue'),
|
||||
el: '.content > .row:nth-child(1)',
|
||||
},
|
||||
{
|
||||
path: 'skinlib/upload',
|
||||
component: () => import('./skinlib/Upload'),
|
||||
component: () => import('./skinlib/Upload.vue'),
|
||||
el: '.content',
|
||||
},
|
||||
]
|
@ -1,10 +1,26 @@
|
||||
/* eslint-disable max-params */
|
||||
/* eslint-disable max-classes-per-file */
|
||||
|
||||
export class SkinViewer {
|
||||
disposed: boolean
|
||||
|
||||
skinUrl: string
|
||||
|
||||
capeUrl: string
|
||||
|
||||
animationPaused: boolean
|
||||
|
||||
camera: { position: { z: number } }
|
||||
|
||||
constructor() {
|
||||
this.skinUrl = ''
|
||||
this.capeUrl = ''
|
||||
this.disposed = false
|
||||
this.animationPaused = false
|
||||
this.camera = {
|
||||
position: {},
|
||||
position: {
|
||||
z: 0,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,7 +30,7 @@ export class SkinViewer {
|
||||
}
|
||||
|
||||
export class CompositeAnimation {
|
||||
add(animation) {
|
||||
add(animation: any) {
|
||||
return animation
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
import Vue from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import Customization from '@/components/admin/Customization'
|
||||
import Customization from '@/components/admin/Customization.vue'
|
||||
|
||||
window.blessing.extra = { currentSkin: 'skin-blue' }
|
||||
|
@ -1,6 +1,6 @@
|
||||
import Vue from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import Market from '@/components/admin/Market'
|
||||
import Market from '@/components/admin/Market.vue'
|
||||
import { flushPromises } from '../../utils'
|
||||
import { swal } from '@/js/notify'
|
||||
|
@ -1,7 +1,7 @@
|
||||
import Vue from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import { flushPromises } from '../../utils'
|
||||
import Players from '@/components/admin/Players'
|
||||
import Players from '@/components/admin/Players.vue'
|
||||
import { swal } from '@/js/notify'
|
||||
|
||||
jest.mock('@/js/notify')
|
||||
@ -18,10 +18,16 @@ test('fetch data after initializing', () => {
|
||||
})
|
||||
|
||||
test('update tables', () => {
|
||||
interface Methods {
|
||||
onPageChange(options: { currentPage: number }): void
|
||||
onPerPageChange(options: { currentPerPage: number }): void
|
||||
onSortChange(options: { sortType: 'asc' | 'desc', columnIndex: number }): void
|
||||
}
|
||||
|
||||
Vue.prototype.$http.get.mockResolvedValue({
|
||||
data: Array.from({ length: 20 }).map((item, pid) => ({ pid })),
|
||||
data: Array.from({ length: 20 }).map((_, pid) => ({ pid })),
|
||||
})
|
||||
const wrapper = mount(Players)
|
||||
const wrapper = mount<Vue & Methods>(Players)
|
||||
|
||||
wrapper.find('.vgt-input').setValue('abc')
|
||||
expect(Vue.prototype.$http.get).toBeCalledWith(
|
||||
@ -83,7 +89,7 @@ test('change texture', async () => {
|
||||
button.trigger('click')
|
||||
await flushPromises()
|
||||
expect(wrapper.html()).toContain('/preview/64/5.png')
|
||||
expect(window.$).toBeCalledWith('.modal')
|
||||
expect($).toBeCalledWith('.modal')
|
||||
})
|
||||
|
||||
test('change player name', async () => {
|
||||
@ -95,11 +101,13 @@ test('change player name', async () => {
|
||||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ errno: 1, msg: '1' })
|
||||
.mockResolvedValueOnce({ errno: 0, msg: '0' })
|
||||
swal.mockImplementationOnce(() => ({ dismiss: 1 }))
|
||||
swal.mockImplementationOnce(() => Promise.resolve({ dismiss: 1 }))
|
||||
.mockImplementation(options => {
|
||||
options.inputValidator()
|
||||
options.inputValidator('new')
|
||||
return { value: 'new' }
|
||||
if (options.inputValidator) {
|
||||
options.inputValidator('')
|
||||
options.inputValidator('new')
|
||||
}
|
||||
return Promise.resolve({ value: 'new' })
|
||||
})
|
||||
const wrapper = mount(Players)
|
||||
await wrapper.vm.$nextTick()
|
@ -1,6 +1,6 @@
|
||||
import Vue from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import Plugins from '@/components/admin/Plugins'
|
||||
import Plugins from '@/components/admin/Plugins.vue'
|
||||
import toastr from 'toastr'
|
||||
import { flushPromises } from '../../utils'
|
||||
import { swal } from '@/js/notify'
|
@ -29,7 +29,7 @@ test('perform update', async () => {
|
||||
|
||||
button.trigger('click')
|
||||
await flushPromises()
|
||||
expect(window.$).not.toBeCalled()
|
||||
expect($).not.toBeCalled()
|
||||
expect(Vue.prototype.$http.post).toBeCalledWith(
|
||||
'/admin/update/download',
|
||||
{ action: 'prepare-download' }
|
||||
@ -37,7 +37,7 @@ test('perform update', async () => {
|
||||
button.trigger('click')
|
||||
jest.runOnlyPendingTimers()
|
||||
await flushPromises()
|
||||
expect(window.$).toBeCalled()
|
||||
expect($).toBeCalled()
|
||||
expect(Vue.prototype.$http.get).toBeCalledWith(
|
||||
'/admin/update/download',
|
||||
{ action: 'get-progress' }
|
@ -1,14 +1,14 @@
|
||||
import Vue from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import { flushPromises } from '../../utils'
|
||||
import Users from '@/components/admin/Users'
|
||||
import Users from '@/components/admin/Users.vue'
|
||||
import toastr from 'toastr'
|
||||
import { swal } from '@/js/notify'
|
||||
import '@/js/i18n'
|
||||
import { flushPromises } from '../../utils'
|
||||
|
||||
jest.mock('@/js/notify')
|
||||
jest.mock('@/js/i18n', () => ({
|
||||
trans: key => key,
|
||||
trans: (key: string) => key,
|
||||
}))
|
||||
|
||||
test('fetch data after initializing', () => {
|
||||
@ -23,10 +23,16 @@ test('fetch data after initializing', () => {
|
||||
})
|
||||
|
||||
test('update tables', () => {
|
||||
interface Methods {
|
||||
onPageChange(options: { currentPage: number }): void
|
||||
onPerPageChange(options: { currentPerPage: number }): void
|
||||
onSortChange(options: { sortType: 'asc' | 'desc', columnIndex: number }): void
|
||||
}
|
||||
|
||||
Vue.prototype.$http.get.mockResolvedValue({
|
||||
data: Array.from({ length: 20 }).map((item, uid) => ({ uid })),
|
||||
data: Array.from({ length: 20 }).map((_, uid) => ({ uid })),
|
||||
})
|
||||
const wrapper = mount(Users)
|
||||
const wrapper = mount<Vue & Methods>(Users)
|
||||
|
||||
wrapper.find('.vgt-input').setValue('abc')
|
||||
expect(Vue.prototype.$http.get).toBeCalledWith(
|
||||
@ -389,11 +395,13 @@ test('change email', async () => {
|
||||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ errno: 1, msg: '1' })
|
||||
.mockResolvedValueOnce({ errno: 0, msg: '0' })
|
||||
swal.mockImplementationOnce(() => ({ dismiss: 1 }))
|
||||
swal.mockImplementationOnce(() => Promise.resolve({ dismiss: 1 }))
|
||||
.mockImplementation(options => {
|
||||
options.inputValidator()
|
||||
options.inputValidator('value')
|
||||
return { value: 'd@e.f' }
|
||||
if (options.inputValidator) {
|
||||
options.inputValidator('')
|
||||
options.inputValidator('value')
|
||||
}
|
||||
return Promise.resolve({ value: 'd@e.f' })
|
||||
})
|
||||
const wrapper = mount(Users)
|
||||
await wrapper.vm.$nextTick()
|
||||
@ -449,11 +457,13 @@ test('change nickname', async () => {
|
||||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ errno: 1, msg: '1' })
|
||||
.mockResolvedValueOnce({ errno: 0, msg: '0' })
|
||||
swal.mockImplementationOnce(() => ({ dismiss: 1 }))
|
||||
swal.mockImplementationOnce(() => Promise.resolve({ dismiss: 1 }))
|
||||
.mockImplementation(options => {
|
||||
options.inputValidator()
|
||||
options.inputValidator('value')
|
||||
return { value: 'new' }
|
||||
if (options.inputValidator) {
|
||||
options.inputValidator('')
|
||||
options.inputValidator('value')
|
||||
}
|
||||
return Promise.resolve({ value: 'new' })
|
||||
})
|
||||
const wrapper = mount(Users)
|
||||
await wrapper.vm.$nextTick()
|
@ -1,6 +1,6 @@
|
||||
import Vue from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import Forgot from '@/components/auth/Forgot'
|
||||
import Forgot from '@/components/auth/Forgot.vue'
|
||||
|
||||
test('click to refresh captcha', () => {
|
||||
jest.spyOn(Date, 'now')
|
@ -1,6 +1,6 @@
|
||||
import Vue from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import Login from '@/components/auth/Login'
|
||||
import Login from '@/components/auth/Login.vue'
|
||||
import { swal } from '@/js/notify'
|
||||
|
||||
jest.mock('@/js/notify')
|
@ -1,6 +1,6 @@
|
||||
import Vue from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import Register from '@/components/auth/Register'
|
||||
import Register from '@/components/auth/Register.vue'
|
||||
import { swal } from '@/js/notify'
|
||||
|
||||
jest.mock('@/js/notify')
|
@ -1,6 +1,6 @@
|
||||
import Vue from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import Reset from '@/components/auth/Reset'
|
||||
import Reset from '@/components/auth/Reset.vue'
|
||||
import { swal } from '@/js/notify'
|
||||
|
||||
jest.mock('@/js/notify')
|
@ -1,32 +1,43 @@
|
||||
import Vue from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import Previewer from '@/components/common/Previewer'
|
||||
import Previewer from '@/components/common/Previewer.vue'
|
||||
import * as emitter from '@/js/event'
|
||||
import * as mockedSkinview3d from '../../__mocks__/skinview3d'
|
||||
|
||||
type Viewer = Vue & { viewer: mockedSkinview3d.SkinViewer }
|
||||
|
||||
interface Handles {
|
||||
handles: {
|
||||
run: { paused: boolean }
|
||||
walk: { paused: boolean }
|
||||
rotate: { paused: boolean }
|
||||
}
|
||||
}
|
||||
|
||||
test('initialize skinview3d', () => {
|
||||
const stub = jest.fn()
|
||||
emitter.on('skinViewerMounted', stub)
|
||||
|
||||
const wrapper = mount(Previewer)
|
||||
const wrapper = mount<Viewer>(Previewer)
|
||||
expect(wrapper.vm.viewer).toBeInstanceOf(mockedSkinview3d.SkinViewer)
|
||||
expect(wrapper.vm.viewer.camera.position.z).toBe(70)
|
||||
expect(stub).toBeCalledWith(expect.any(HTMLElement))
|
||||
})
|
||||
|
||||
test('dispose viewer before destroy', () => {
|
||||
const wrapper = mount(Previewer)
|
||||
const wrapper = mount<Viewer>(Previewer)
|
||||
wrapper.destroy()
|
||||
expect(wrapper.vm.viewer.disposed).toBeTrue()
|
||||
})
|
||||
|
||||
test('skin URL should be updated', () => {
|
||||
const wrapper = mount(Previewer)
|
||||
const wrapper = mount<Viewer>(Previewer)
|
||||
wrapper.setProps({ skin: 'abc' })
|
||||
expect(wrapper.vm.viewer.skinUrl).toBe('abc')
|
||||
})
|
||||
|
||||
test('cape URL should be updated', () => {
|
||||
const wrapper = mount(Previewer)
|
||||
const wrapper = mount<Viewer>(Previewer)
|
||||
wrapper.setProps({ cape: 'abc' })
|
||||
expect(wrapper.vm.viewer.capeUrl).toBe('abc')
|
||||
})
|
||||
@ -73,22 +84,24 @@ test('toggle pause', () => {
|
||||
})
|
||||
|
||||
test('toggle run', () => {
|
||||
const wrapper = mount(Previewer)
|
||||
const wrapper = mount<Vue & Handles>(Previewer)
|
||||
wrapper.find('.fa-forward').trigger('click')
|
||||
expect(wrapper.vm.handles.run.paused).toBeFalse()
|
||||
expect(wrapper.vm.handles.walk.paused).toBeTrue()
|
||||
})
|
||||
|
||||
test('toggle rotate', () => {
|
||||
const wrapper = mount(Previewer)
|
||||
const wrapper = mount<Vue & Handles>(Previewer)
|
||||
wrapper.find('.fa-redo-alt').trigger('click')
|
||||
expect(wrapper.vm.handles.rotate.paused).toBeTrue()
|
||||
})
|
||||
|
||||
test('reset', () => {
|
||||
mockedSkinview3d.SkinViewer.prototype.dispose = jest.fn(function () {
|
||||
this.disposed = true
|
||||
}.bind(mockedSkinview3d.SkinViewer))
|
||||
mockedSkinview3d.SkinViewer.prototype.dispose = jest.fn(
|
||||
function (this: mockedSkinview3d.SkinViewer) {
|
||||
this.disposed = true
|
||||
}.bind(new mockedSkinview3d.SkinViewer())
|
||||
)
|
||||
const wrapper = mount(Previewer)
|
||||
wrapper.find('.fa-stop').trigger('click')
|
||||
expect(mockedSkinview3d.SkinViewer.prototype.dispose).toBeCalled()
|
@ -1,6 +1,6 @@
|
||||
import Vue from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import List from '@/components/skinlib/List'
|
||||
import List from '@/components/skinlib/List.vue'
|
||||
|
||||
test('fetch data before mounting', () => {
|
||||
Vue.prototype.$http.get.mockResolvedValue({
|
||||
@ -169,7 +169,7 @@ test('is anonymous', () => {
|
||||
Vue.prototype.$http.get.mockResolvedValue({
|
||||
items: [], total_pages: 0, current_uid: 0,
|
||||
})
|
||||
const wrapper = mount(List)
|
||||
const wrapper = mount<Vue & { anonymous: boolean }>(List)
|
||||
expect(wrapper.vm.anonymous).toBeTrue()
|
||||
})
|
||||
|
||||
@ -177,7 +177,7 @@ test('on page changed', () => {
|
||||
Vue.prototype.$http.get.mockResolvedValue({
|
||||
items: [], total_pages: 0, current_uid: 0,
|
||||
})
|
||||
const wrapper = mount(List)
|
||||
const wrapper = mount<Vue & { pageChanged(page: number): void }>(List)
|
||||
jest.runAllTimers()
|
||||
wrapper.vm.pageChanged(2)
|
||||
expect(Vue.prototype.$http.get).toBeCalledWith(
|
||||
@ -196,7 +196,10 @@ test('on like toggled', async () => {
|
||||
total_pages: 1,
|
||||
current_uid: 0,
|
||||
})
|
||||
const wrapper = mount(List)
|
||||
const wrapper = mount<Vue & {
|
||||
onLikeToggled(tid: number, like: boolean): void,
|
||||
items: Array<{ liked: boolean, likes: number }>
|
||||
}>(List)
|
||||
await wrapper.vm.$nextTick()
|
||||
wrapper.vm.onLikeToggled(0, true)
|
||||
expect(wrapper.vm.items[0].liked).toBeTrue()
|
@ -1,12 +1,20 @@
|
||||
import Vue from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import Show from '@/components/skinlib/Show'
|
||||
import Show from '@/components/skinlib/Show.vue'
|
||||
import toastr from 'toastr'
|
||||
import { flushPromises } from '../../utils'
|
||||
import { swal } from '@/js/notify'
|
||||
|
||||
jest.mock('@/js/notify')
|
||||
|
||||
type Component = Vue & {
|
||||
liked: boolean
|
||||
likes: number
|
||||
public: boolean
|
||||
name: string
|
||||
type: 'steve' | 'alex' | 'cape'
|
||||
}
|
||||
|
||||
window.blessing.extra = {
|
||||
download: true,
|
||||
currentUid: 0,
|
||||
@ -15,12 +23,11 @@ window.blessing.extra = {
|
||||
inCloset: false,
|
||||
}
|
||||
|
||||
/** @type {import('Vue').ComponentOptions} */
|
||||
const previewer = {
|
||||
const previewer = Vue.extend({
|
||||
render(h) {
|
||||
return h('div', this.$slots.footer)
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
test('button for adding to closet should be disabled if not auth', () => {
|
||||
Vue.prototype.$http.get.mockResolvedValue({})
|
||||
@ -165,7 +172,7 @@ test('add to closet', async () => {
|
||||
Vue.prototype.$http.get.mockResolvedValue({ name: 'wow', likes: 2 })
|
||||
Vue.prototype.$http.post.mockResolvedValue({ errno: 0, msg: '' })
|
||||
swal.mockResolvedValue({})
|
||||
const wrapper = mount(Show, {
|
||||
const wrapper = mount<Component>(Show, {
|
||||
mocks: {
|
||||
$route: ['/skinlib/show/1', '1'],
|
||||
},
|
||||
@ -182,7 +189,7 @@ test('remove from closet', async () => {
|
||||
Vue.prototype.$http.get.mockResolvedValue({ likes: 2 })
|
||||
Vue.prototype.$http.post.mockResolvedValue({ errno: 0 })
|
||||
swal.mockResolvedValue({})
|
||||
const wrapper = mount(Show, {
|
||||
const wrapper = mount<Component>(Show, {
|
||||
mocks: {
|
||||
$route: ['/skinlib/show/1', '1'],
|
||||
},
|
||||
@ -201,13 +208,15 @@ test('change texture name', async () => {
|
||||
.mockResolvedValueOnce({ errno: 1, msg: '1' })
|
||||
.mockResolvedValue({ errno: 0, msg: '0' })
|
||||
jest.spyOn(toastr, 'warning')
|
||||
swal.mockImplementationOnce(() => ({ dismiss: 1 }))
|
||||
swal.mockImplementationOnce(() => Promise.resolve({ dismiss: 1 }))
|
||||
.mockImplementation(({ inputValidator }) => {
|
||||
inputValidator()
|
||||
inputValidator('new-name')
|
||||
return { value: 'new-name' }
|
||||
if (inputValidator) {
|
||||
inputValidator('')
|
||||
inputValidator('new-name')
|
||||
}
|
||||
return Promise.resolve({ value: 'new-name' })
|
||||
})
|
||||
const wrapper = mount(Show, {
|
||||
const wrapper = mount<Component>(Show, {
|
||||
mocks: {
|
||||
$route: ['/skinlib/show/1', '1'],
|
||||
},
|
||||
@ -239,7 +248,7 @@ test('change texture model', async () => {
|
||||
jest.spyOn(toastr, 'warning')
|
||||
swal.mockResolvedValueOnce({ dismiss: 1 })
|
||||
.mockResolvedValue({ value: 'alex' })
|
||||
const wrapper = mount(Show, {
|
||||
const wrapper = mount<Component>(Show, {
|
||||
mocks: {
|
||||
$route: ['/skinlib/show/1', '1'],
|
||||
},
|
||||
@ -272,7 +281,7 @@ test('toggle privacy', async () => {
|
||||
jest.spyOn(toastr, 'warning')
|
||||
swal.mockResolvedValueOnce({ dismiss: 1 })
|
||||
.mockResolvedValue({})
|
||||
const wrapper = mount(Show, {
|
||||
const wrapper = mount<Component>(Show, {
|
||||
mocks: {
|
||||
$route: ['/skinlib/show/1', '1'],
|
||||
},
|
@ -1,6 +1,6 @@
|
||||
import Vue from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import SkinLibItem from '@/components/skinlib/SkinLibItem'
|
||||
import SkinLibItem from '@/components/skinlib/SkinLibItem.vue'
|
||||
import toastr from 'toastr'
|
||||
import { flushPromises } from '../../utils'
|
||||
import { swal } from '@/js/notify'
|
||||
@ -79,13 +79,13 @@ test('add to closet', async () => {
|
||||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ errno: 1, msg: '1' })
|
||||
.mockResolvedValue({ errno: 0 })
|
||||
swal.mockImplementationOnce(() => ({ dismiss: 1 }))
|
||||
swal.mockImplementationOnce(() => Promise.resolve({ dismiss: 1 }))
|
||||
.mockImplementation(({ inputValidator }) => {
|
||||
if (inputValidator) {
|
||||
inputValidator()
|
||||
inputValidator('')
|
||||
inputValidator('name')
|
||||
}
|
||||
return { value: 'name' }
|
||||
return Promise.resolve({ value: 'name' })
|
||||
})
|
||||
jest.spyOn(toastr, 'warning')
|
||||
const wrapper = mount(SkinLibItem, {
|
@ -1,8 +1,7 @@
|
||||
/* eslint-disable accessor-pairs */
|
||||
/* eslint-disable no-invalid-this */
|
||||
import Vue from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import Upload from '@/components/skinlib/Upload'
|
||||
import Upload from '@/components/skinlib/Upload.vue'
|
||||
import { flushPromises } from '../../utils'
|
||||
import toastr from 'toastr'
|
||||
import { swal } from '@/js/notify'
|
||||
@ -32,14 +31,12 @@ test('display drap and drop notice', () => {
|
||||
})
|
||||
|
||||
test('button for removing texture', () => {
|
||||
const wrapper = mount(Upload, {
|
||||
const wrapper = mount<Vue & { texture: string }>(Upload, {
|
||||
stubs: ['file-upload'],
|
||||
})
|
||||
wrapper.vm.$refs = {
|
||||
upload: {
|
||||
clear: jest.fn(),
|
||||
},
|
||||
}
|
||||
Object.defineProperty(wrapper.vm.$refs.upload, 'clear', {
|
||||
get: () => jest.fn(),
|
||||
})
|
||||
const button = wrapper.find('.btn-default')
|
||||
expect(button.isVisible()).toBeFalse()
|
||||
wrapper.setData({ files: [{}] })
|
||||
@ -73,15 +70,15 @@ test('display score cost', () => {
|
||||
|
||||
test('process input file', () => {
|
||||
window.URL.createObjectURL = jest.fn().mockReturnValue('file-url')
|
||||
jest.spyOn(window, 'Image')
|
||||
.mockImplementationOnce(function () {
|
||||
;(window as Window & { Image: jest.Mock }).Image = jest.fn()
|
||||
.mockImplementationOnce(function (this: HTMLImageElement) {
|
||||
this.src = ''
|
||||
this.onload = null
|
||||
Object.defineProperty(this, 'onload', {
|
||||
set: fn => fn(),
|
||||
})
|
||||
})
|
||||
.mockImplementationOnce(function () {
|
||||
.mockImplementationOnce(function (this: HTMLImageElement) {
|
||||
this.src = ''
|
||||
this.width = 500
|
||||
this.onload = null
|
||||
@ -90,7 +87,12 @@ test('process input file', () => {
|
||||
})
|
||||
})
|
||||
const blob = new Blob()
|
||||
const wrapper = mount(Upload, {
|
||||
type Component = Vue & {
|
||||
name: string
|
||||
texture: string
|
||||
inputFile(attrs?: { file: Blob, name: string }): void
|
||||
}
|
||||
const wrapper = mount<Component>(Upload, {
|
||||
stubs: ['file-upload'],
|
||||
})
|
||||
|
||||
@ -109,18 +111,18 @@ test('process input file', () => {
|
||||
|
||||
expect(wrapper.vm.texture).toBe('file-url')
|
||||
|
||||
window.Image.mockRestore()
|
||||
;(window as Window & { Image: jest.Mock }).Image.mockRestore()
|
||||
})
|
||||
|
||||
test('upload file', async () => {
|
||||
window.Request = jest.fn()
|
||||
(window as Window & { Request: jest.Mock }).Request = jest.fn()
|
||||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ errno: 1, msg: '1' })
|
||||
.mockResolvedValueOnce({
|
||||
errno: 0, msg: '0', tid: 1,
|
||||
})
|
||||
jest.spyOn(toastr, 'info')
|
||||
swal.mockReturnValue()
|
||||
swal.mockReturnValue(Promise.resolve({}))
|
||||
|
||||
const wrapper = mount(Upload, {
|
||||
stubs: ['file-upload'],
|
@ -1,8 +1,8 @@
|
||||
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 Closet from '@/components/user/Closet.vue'
|
||||
import ClosetItem from '@/components/user/ClosetItem.vue'
|
||||
import Previewer from '@/components/common/Previewer.vue'
|
||||
import toastr from 'toastr'
|
||||
import { swal } from '@/js/notify'
|
||||
|
||||
@ -80,7 +80,7 @@ test('search textures', () => {
|
||||
|
||||
const wrapper = mount(Closet)
|
||||
const input = wrapper.find('input')
|
||||
input.element.value = 'q'
|
||||
;(input.element as HTMLInputElement).value = 'q'
|
||||
input.trigger('input')
|
||||
jest.runAllTimers()
|
||||
jest.runAllTicks()
|
||||
@ -127,7 +127,7 @@ test('render items', async () => {
|
||||
|
||||
test('reload closet when page changed', () => {
|
||||
Vue.prototype.$http.get.mockResolvedValue({})
|
||||
const wrapper = mount(Closet)
|
||||
const wrapper = mount<Vue & { pageChanged(): void }>(Closet)
|
||||
wrapper.vm.pageChanged()
|
||||
jest.runAllTicks()
|
||||
expect(Vue.prototype.$http.get).toBeCalledTimes(2)
|
||||
@ -135,7 +135,7 @@ test('reload closet when page changed', () => {
|
||||
|
||||
test('remove skin item', () => {
|
||||
Vue.prototype.$http.get.mockResolvedValue({})
|
||||
const wrapper = mount(Closet)
|
||||
const wrapper = mount<Vue & { removeSkinItem(tid: number): void }>(Closet)
|
||||
wrapper.setData({ skinItems: [{ tid: 1 }] })
|
||||
wrapper.vm.removeSkinItem(0)
|
||||
expect(wrapper.find('#skin-category').text()).toContain('user.emptyClosetMsg')
|
||||
@ -143,7 +143,7 @@ test('remove skin item', () => {
|
||||
|
||||
test('remove cape item', () => {
|
||||
Vue.prototype.$http.get.mockResolvedValue({})
|
||||
const wrapper = mount(Closet)
|
||||
const wrapper = mount<Vue & { removeCapeItem(tid: number): void }>(Closet)
|
||||
wrapper.setData({ capeItems: [{ tid: 1 }], category: 'cape' })
|
||||
wrapper.vm.removeCapeItem(0)
|
||||
expect(wrapper.find('#cape-category').text()).toContain('user.emptyClosetMsg')
|
||||
@ -151,7 +151,8 @@ test('remove cape item', () => {
|
||||
|
||||
test('compute avatar URL', () => {
|
||||
Vue.prototype.$http.get.mockResolvedValue({})
|
||||
const wrapper = mount(Closet)
|
||||
// eslint-disable-next-line camelcase
|
||||
const wrapper = mount<Vue & { avatarUrl(player: { tid_skin: number }): string }>(Closet)
|
||||
const { avatarUrl } = wrapper.vm
|
||||
expect(avatarUrl({ tid_skin: 1 })).toBe('/avatar/35/1')
|
||||
})
|
||||
@ -162,7 +163,7 @@ test('select texture', async () => {
|
||||
.mockResolvedValueOnce({ type: 'steve', hash: 'a' })
|
||||
.mockResolvedValueOnce({ type: 'cape', hash: 'b' })
|
||||
|
||||
const wrapper = mount(Closet)
|
||||
const wrapper = mount<Vue & { skinUrl: string, capeUrl: string }>(Closet)
|
||||
wrapper.setData({ skinItems: [{ tid: 1 }] })
|
||||
wrapper.find(ClosetItem).vm.$emit('select')
|
||||
await wrapper.vm.$nextTick()
|
||||
@ -181,7 +182,7 @@ test('select texture', async () => {
|
||||
test('apply texture', async () => {
|
||||
window.$ = jest.fn(() => ({
|
||||
iCheck: () => ({
|
||||
on(evt, cb) {
|
||||
on(_: Event, cb: CallableFunction) {
|
||||
cb()
|
||||
},
|
||||
}),
|
||||
@ -282,7 +283,7 @@ test('select specified texture initially', async () => {
|
||||
window.$ = jest.fn(() => ({
|
||||
modal() {},
|
||||
iCheck: () => ({
|
||||
on(evt, cb) {
|
||||
on(_: Event, cb: CallableFunction) {
|
||||
cb()
|
||||
},
|
||||
}),
|
@ -1,7 +1,7 @@
|
||||
import Vue from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import { flushPromises } from '../../utils'
|
||||
import ClosetItem from '@/components/user/ClosetItem'
|
||||
import ClosetItem from '@/components/user/ClosetItem.vue'
|
||||
import { swal } from '@/js/notify'
|
||||
|
||||
jest.mock('@/js/notify')
|
||||
@ -40,11 +40,13 @@ test('rename texture', async () => {
|
||||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ errno: 0 })
|
||||
.mockResolvedValueOnce({ errno: 1 })
|
||||
swal.mockImplementationOnce(() => ({ dismiss: 'cancel' }))
|
||||
swal.mockImplementationOnce(() => Promise.resolve({ dismiss: 1 }))
|
||||
.mockImplementation(options => {
|
||||
options.inputValidator('name')
|
||||
options.inputValidator()
|
||||
return { value: 'new-name' }
|
||||
if (options.inputValidator) {
|
||||
options.inputValidator('name')
|
||||
options.inputValidator('')
|
||||
}
|
||||
return Promise.resolve({ value: 'new-name' })
|
||||
})
|
||||
const wrapper = mount(ClosetItem, { propsData: factory() })
|
||||
const button = wrapper.findAll('.dropdown-menu > li').at(0)
|
||||
@ -71,7 +73,7 @@ test('remove texture', async () => {
|
||||
.mockResolvedValueOnce({ errno: 0 })
|
||||
.mockResolvedValueOnce({ errno: 1 })
|
||||
swal
|
||||
.mockResolvedValueOnce({ dismiss: 'cancel' })
|
||||
.mockResolvedValueOnce({ dismiss: 1 })
|
||||
.mockResolvedValue({})
|
||||
|
||||
const wrapper = mount(ClosetItem, { propsData: factory() })
|
||||
@ -96,7 +98,7 @@ test('set as avatar', async () => {
|
||||
.mockResolvedValueOnce({ errno: 0 })
|
||||
.mockResolvedValueOnce({ errno: 1 })
|
||||
swal
|
||||
.mockResolvedValueOnce({ dismiss: 'cancel' })
|
||||
.mockResolvedValueOnce({ dismiss: 1 })
|
||||
.mockResolvedValue({})
|
||||
|
||||
const wrapper = mount(ClosetItem, { propsData: factory() })
|
||||
@ -115,7 +117,7 @@ test('set as avatar', async () => {
|
||||
await flushPromises()
|
||||
await wrapper.vm.$nextTick()
|
||||
expect(Vue.prototype.$http.post).toBeCalledWith('/user/profile/avatar', { tid: 1 })
|
||||
expect(document.querySelector('img').src).toMatch(/\d+$/)
|
||||
expect(document.querySelector('img')!.src).toMatch(/\d+$/)
|
||||
})
|
||||
|
||||
test('no avatar option if texture is cape', () => {
|
@ -1,7 +1,7 @@
|
||||
/* eslint-disable no-mixed-operators */
|
||||
import Vue from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import Dashboard from '@/components/user/Dashboard'
|
||||
import Dashboard from '@/components/user/Dashboard.vue'
|
||||
import toastr from 'toastr'
|
||||
import { swal } from '@/js/notify'
|
||||
|
||||
@ -125,7 +125,7 @@ test('remaining time', async () => {
|
||||
|
||||
test('sign', async () => {
|
||||
jest.spyOn(toastr, 'warning')
|
||||
swal.mockResolvedValue()
|
||||
swal.mockResolvedValue({})
|
||||
Vue.prototype.$http.get.mockResolvedValue(scoreInfo({
|
||||
user: { lastSignAt: Date.now() - 30 * 3600 * 1000 },
|
||||
}))
|
@ -1,6 +1,6 @@
|
||||
import Vue from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import EmailVerification from '@/components/user/EmailVerification'
|
||||
import EmailVerification from '@/components/user/EmailVerification.vue'
|
||||
import { swal } from '@/js/notify'
|
||||
|
||||
jest.mock('@/js/notify')
|
@ -1,7 +1,7 @@
|
||||
import Vue from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import { flushPromises } from '../../utils'
|
||||
import Players from '@/components/user/Players'
|
||||
import Players from '@/components/user/Players.vue'
|
||||
import { swal } from '@/js/notify'
|
||||
|
||||
jest.mock('toastr')
|
||||
@ -67,13 +67,13 @@ test('change player name', async () => {
|
||||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ errno: 1 })
|
||||
.mockResolvedValue({ errno: 0 })
|
||||
swal.mockImplementationOnce(() => ({ dismiss: 1 }))
|
||||
swal.mockImplementationOnce(() => Promise.resolve({ dismiss: 1 }))
|
||||
.mockImplementation(({ inputValidator }) => {
|
||||
if (inputValidator) {
|
||||
inputValidator()
|
||||
inputValidator('')
|
||||
inputValidator('new-name')
|
||||
return { value: 'new-name' }
|
||||
}
|
||||
return Promise.resolve({ value: 'new-name' })
|
||||
})
|
||||
const wrapper = mount(Players)
|
||||
await wrapper.vm.$nextTick()
|
||||
@ -100,7 +100,7 @@ test('load iCheck', async () => {
|
||||
])
|
||||
window.$ = jest.fn(() => ({
|
||||
iCheck: () => ({
|
||||
on(evt, cb) {
|
||||
on(_: Event, cb: CallableFunction) {
|
||||
cb()
|
||||
},
|
||||
}),
|
@ -1,7 +1,7 @@
|
||||
import Vue from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import { flushPromises } from '../../utils'
|
||||
import Profile from '@/components/user/Profile'
|
||||
import Profile from '@/components/user/Profile.vue'
|
||||
import toastr from 'toastr'
|
||||
import { swal } from '@/js/notify'
|
||||
|
||||
@ -11,15 +11,15 @@ window.blessing.extra = { unverified: false }
|
||||
|
||||
test('computed values', () => {
|
||||
window.blessing.extra = { admin: true }
|
||||
const wrapper = mount(Profile)
|
||||
const wrapper = mount<Vue & { siteName: string, isAdmin: boolean }>(Profile)
|
||||
expect(wrapper.vm.siteName).toBe('Blessing Skin')
|
||||
expect(wrapper.vm.isAdmin).toBeTrue()
|
||||
window.blessing.extra = { admin: false }
|
||||
expect(mount(Profile).vm.isAdmin).toBeFalse()
|
||||
expect(mount<Vue & { isAdmin: boolean }>(Profile).vm.isAdmin).toBeFalse()
|
||||
})
|
||||
|
||||
test('convert linebreak', () => {
|
||||
const wrapper = mount(Profile)
|
||||
const wrapper = mount<Vue & { nl2br(input: string): string }>(Profile)
|
||||
expect(wrapper.vm.nl2br('a\nb\nc')).toBe('a<br>b<br>c')
|
||||
})
|
||||
|
||||
@ -44,7 +44,7 @@ test('reset avatar', async () => {
|
||||
)
|
||||
await flushPromises()
|
||||
expect(toastr.success).toBeCalledWith('ok')
|
||||
expect(document.querySelector('img').src).toMatch(/\d+$/)
|
||||
expect(document.querySelector('img')!.src).toMatch(/\d+$/)
|
||||
})
|
||||
|
||||
test('change password', async () => {
|
||||
@ -52,7 +52,7 @@ test('change password', async () => {
|
||||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ errno: 1, msg: 'w' })
|
||||
.mockResolvedValueOnce({ errno: 0, msg: 'o' })
|
||||
swal.mockResolvedValue()
|
||||
swal.mockResolvedValue({})
|
||||
const wrapper = mount(Profile)
|
||||
const button = wrapper.find('[data-test=changePassword]')
|
||||
|
||||
@ -125,7 +125,7 @@ test('change nickname', async () => {
|
||||
button.trigger('click')
|
||||
await flushPromises()
|
||||
expect(swal).toBeCalledWith({ type: 'success', text: 'o' })
|
||||
expect(document.querySelector('.nickname').textContent).toBe('nickname')
|
||||
expect(document.querySelector('.nickname')!.textContent).toBe('nickname')
|
||||
})
|
||||
|
||||
test('change email', async () => {
|
||||
@ -173,7 +173,7 @@ test('change email', async () => {
|
||||
|
||||
test('delete account', async () => {
|
||||
window.blessing.extra = { admin: true }
|
||||
swal.mockResolvedValue()
|
||||
swal.mockResolvedValue({})
|
||||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ errno: 1, msg: 'w' })
|
||||
.mockResolvedValue({ errno: 0, msg: 'o' })
|
3
resources/assets/tests/js/types.d.ts
vendored
3
resources/assets/tests/js/types.d.ts
vendored
@ -9,7 +9,10 @@ interface Window {
|
||||
|
||||
blessing: {
|
||||
i18n: object
|
||||
extra: object
|
||||
}
|
||||
|
||||
fetch: jest.Mock
|
||||
|
||||
$: jest.Mock
|
||||
}
|
||||
|
5
resources/assets/tests/vue.d.ts
vendored
Normal file
5
resources/assets/tests/vue.d.ts
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
declare module '*.vue' {
|
||||
import Vue from 'vue'
|
||||
|
||||
export default Vue
|
||||
}
|
@ -12,6 +12,9 @@
|
||||
"@/js/*": [
|
||||
"./resources/assets/tests/ts-shims/*",
|
||||
"./resources/assets/src/js/*"
|
||||
],
|
||||
"@/components/*": [
|
||||
"./resources/assets/src/components/*"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user