613 lines
17 KiB
JavaScript
613 lines
17 KiB
JavaScript
import Vue from 'vue'
|
|
import { mount } from '@vue/test-utils'
|
|
import { flushPromises } from '../../utils'
|
|
import Users from '@/components/admin/Users'
|
|
import toastr from 'toastr'
|
|
import { swal } from '@/js/notify'
|
|
import '@/js/i18n'
|
|
|
|
jest.mock('@/js/notify')
|
|
jest.mock('@/js/i18n', () => ({
|
|
trans: key => key,
|
|
}))
|
|
|
|
test('fetch data after initializing', () => {
|
|
Vue.prototype.$http.get.mockResolvedValue({ data: [] })
|
|
mount(Users)
|
|
expect(Vue.prototype.$http.get).toBeCalledWith(
|
|
'/admin/user-data',
|
|
{
|
|
page: 1, perPage: 10, search: '', sortField: 'uid', sortType: 'asc',
|
|
}
|
|
)
|
|
})
|
|
|
|
test('update tables', () => {
|
|
Vue.prototype.$http.get.mockResolvedValue({
|
|
data: Array.from({ length: 20 }).map((item, uid) => ({ uid })),
|
|
})
|
|
const wrapper = mount(Users)
|
|
|
|
wrapper.find('.vgt-input').setValue('abc')
|
|
expect(Vue.prototype.$http.get).toBeCalledWith(
|
|
'/admin/user-data',
|
|
{
|
|
page: 1, perPage: 10, search: 'abc', sortField: 'uid', sortType: 'asc',
|
|
}
|
|
)
|
|
wrapper.vm.onPageChange({ currentPage: 2 })
|
|
expect(Vue.prototype.$http.get).toBeCalledWith(
|
|
'/admin/user-data',
|
|
{
|
|
page: 2, perPage: 10, search: 'abc', sortField: 'uid', sortType: 'asc',
|
|
}
|
|
)
|
|
wrapper.vm.onPerPageChange({ currentPerPage: 5 })
|
|
expect(Vue.prototype.$http.get).toBeCalledWith(
|
|
'/admin/user-data',
|
|
{
|
|
page: 2, perPage: 5, search: 'abc', sortField: 'uid', sortType: 'asc',
|
|
}
|
|
)
|
|
wrapper.vm.onSortChange({ sortType: 'desc', columnIndex: 0 })
|
|
expect(Vue.prototype.$http.get).toBeCalledWith(
|
|
'/admin/user-data',
|
|
{
|
|
page: 2, perPage: 5, search: 'abc', sortField: 'uid', sortType: 'desc',
|
|
}
|
|
)
|
|
})
|
|
|
|
test('humanize permission', async () => {
|
|
Vue.prototype.$http.get.mockResolvedValue({
|
|
data: [
|
|
{ uid: 1, permission: -1 },
|
|
{ uid: 2, permission: 0 },
|
|
{ uid: 3, permission: 1 },
|
|
{ uid: 4, permission: 2 },
|
|
],
|
|
})
|
|
const wrapper = mount(Users)
|
|
await wrapper.vm.$nextTick()
|
|
const text = wrapper.find('.vgt-table').text()
|
|
expect(text).toContain('admin.banned')
|
|
expect(text).toContain('admin.normal')
|
|
expect(text).toContain('admin.admin')
|
|
expect(text).toContain('admin.superAdmin')
|
|
})
|
|
test('generate players page link', async () => {
|
|
Vue.prototype.$http.get.mockResolvedValue({
|
|
data: [
|
|
{ uid: 1, permission: 0 },
|
|
],
|
|
})
|
|
const wrapper = mount(Users)
|
|
await wrapper.vm.$nextTick()
|
|
expect(wrapper.find('[data-toggle="tooltip"]').attributes('href')).toBe('/admin/players?uid=1')
|
|
})
|
|
test('admin option should not be displayed for super admins', async () => {
|
|
Vue.prototype.$http.get.mockResolvedValue({
|
|
data: [
|
|
{ uid: 1, permission: 2 },
|
|
],
|
|
})
|
|
const wrapper = mount(Users)
|
|
await wrapper.vm.$nextTick()
|
|
const text = wrapper.find('.vgt-table').text()
|
|
expect(text).not.toContain('admin.setAdmin')
|
|
expect(text).not.toContain('admin.unsetAdmin')
|
|
})
|
|
test('banning option should not be displayed for super admins', async () => {
|
|
Vue.prototype.$http.get.mockResolvedValue({
|
|
data: [
|
|
{ uid: 1, permission: 2 },
|
|
],
|
|
})
|
|
const wrapper = mount(Users)
|
|
await wrapper.vm.$nextTick()
|
|
const text = wrapper.find('.vgt-table').text()
|
|
expect(text).not.toContain('admin.ban')
|
|
expect(text).not.toContain('admin.unban')
|
|
})
|
|
test('admin option should be displayed for admin as super admin', async () => {
|
|
Vue.prototype.$http.get.mockResolvedValue({
|
|
data: [
|
|
{
|
|
uid: 1, permission: 1, operations: 2,
|
|
},
|
|
],
|
|
})
|
|
const wrapper = mount(Users)
|
|
await wrapper.vm.$nextTick()
|
|
const text = wrapper.find('.vgt-table').text()
|
|
expect(text).toContain('admin.unsetAdmin')
|
|
expect(text).not.toContain('admin.setAdmin')
|
|
})
|
|
test('banning option should not be displayed for admin as super admin', async () => {
|
|
Vue.prototype.$http.get.mockResolvedValue({
|
|
data: [
|
|
{
|
|
uid: 1, permission: 1, operations: 2,
|
|
},
|
|
],
|
|
})
|
|
const wrapper = mount(Users)
|
|
await wrapper.vm.$nextTick()
|
|
const text = wrapper.find('.vgt-table').text()
|
|
expect(text).not.toContain('admin.ban')
|
|
expect(text).not.toContain('admin.unban')
|
|
})
|
|
test('admin option should be displayed for normal users as super admin', async () => {
|
|
Vue.prototype.$http.get.mockResolvedValue({
|
|
data: [
|
|
{
|
|
uid: 1, permission: 0, operations: 2,
|
|
},
|
|
],
|
|
})
|
|
const wrapper = mount(Users)
|
|
await wrapper.vm.$nextTick()
|
|
const text = wrapper.find('.vgt-table').text()
|
|
expect(text).toContain('admin.setAdmin')
|
|
expect(text).not.toContain('admin.unsetAdmin')
|
|
})
|
|
test('banning option should be displayed for normal users as super admin', async () => {
|
|
Vue.prototype.$http.get.mockResolvedValue({
|
|
data: [
|
|
{
|
|
uid: 1, permission: 0, operations: 2,
|
|
},
|
|
],
|
|
})
|
|
const wrapper = mount(Users)
|
|
await wrapper.vm.$nextTick()
|
|
const text = wrapper.find('.vgt-table').text()
|
|
expect(text).toContain('admin.ban')
|
|
expect(text).not.toContain('admin.unban')
|
|
})
|
|
test('admin option should not be displayed for banned users as super admin', async () => {
|
|
Vue.prototype.$http.get.mockResolvedValue({
|
|
data: [
|
|
{
|
|
uid: 1, permission: -1, operations: 2,
|
|
},
|
|
],
|
|
})
|
|
const wrapper = mount(Users)
|
|
await wrapper.vm.$nextTick()
|
|
const text = wrapper.find('.vgt-table').text()
|
|
expect(text).not.toContain('admin.setAdmin')
|
|
expect(text).not.toContain('admin.unsetAdmin')
|
|
})
|
|
test('banning option should be displayed for banned users as super admin', async () => {
|
|
Vue.prototype.$http.get.mockResolvedValue({
|
|
data: [
|
|
{
|
|
uid: 1, permission: -1, operations: 2,
|
|
},
|
|
],
|
|
})
|
|
const wrapper = mount(Users)
|
|
await wrapper.vm.$nextTick()
|
|
const text = wrapper.find('.vgt-table').text()
|
|
expect(text).toContain('admin.unban')
|
|
})
|
|
test('admin option should not be displayed for other admins as admin', async () => {
|
|
Vue.prototype.$http.get.mockResolvedValue({
|
|
data: [
|
|
{
|
|
uid: 1, permission: 1, operations: 1,
|
|
},
|
|
],
|
|
})
|
|
const wrapper = mount(Users)
|
|
await wrapper.vm.$nextTick()
|
|
const text = wrapper.find('.vgt-table').text()
|
|
expect(text).not.toContain('admin.setAdmin')
|
|
expect(text).not.toContain('admin.unsetAdmin')
|
|
})
|
|
test('banning option should not be displayed for other admins as admin', async () => {
|
|
Vue.prototype.$http.get.mockResolvedValue({
|
|
data: [
|
|
{
|
|
uid: 1, permission: 1, operations: 1,
|
|
},
|
|
],
|
|
})
|
|
const wrapper = mount(Users)
|
|
await wrapper.vm.$nextTick()
|
|
const text = wrapper.find('.vgt-table').text()
|
|
expect(text).not.toContain('admin.ban')
|
|
expect(text).not.toContain('admin.unban')
|
|
})
|
|
test('admin option should not be displayed for normal users as admin', async () => {
|
|
Vue.prototype.$http.get.mockResolvedValue({
|
|
data: [
|
|
{
|
|
uid: 1, permission: 0, operations: 1,
|
|
},
|
|
],
|
|
})
|
|
const wrapper = mount(Users)
|
|
await wrapper.vm.$nextTick()
|
|
const text = wrapper.find('.vgt-table').text()
|
|
expect(text).not.toContain('admin.setAdmin')
|
|
expect(text).not.toContain('admin.unsetAdmin')
|
|
})
|
|
test('banning option should be displayed for normal users as admin', async () => {
|
|
Vue.prototype.$http.get.mockResolvedValue({
|
|
data: [
|
|
{
|
|
uid: 1, permission: 0, operations: 1,
|
|
},
|
|
],
|
|
})
|
|
const wrapper = mount(Users)
|
|
await wrapper.vm.$nextTick()
|
|
const text = wrapper.find('.vgt-table').text()
|
|
expect(text).toContain('admin.ban')
|
|
expect(text).not.toContain('admin.unban')
|
|
})
|
|
test('admin option should not be displayed for banned users as admin', async () => {
|
|
Vue.prototype.$http.get.mockResolvedValue({
|
|
data: [
|
|
{
|
|
uid: 1, permission: -1, operations: 1,
|
|
},
|
|
],
|
|
})
|
|
const wrapper = mount(Users)
|
|
await wrapper.vm.$nextTick()
|
|
const text = wrapper.find('.vgt-table').text()
|
|
expect(text).not.toContain('admin.setAdmin')
|
|
expect(text).not.toContain('admin.unsetAdmin')
|
|
})
|
|
test('banning option should be displayed for banned users as admin', async () => {
|
|
Vue.prototype.$http.get.mockResolvedValue({
|
|
data: [
|
|
{
|
|
uid: 1, permission: -1, operations: 1,
|
|
},
|
|
],
|
|
})
|
|
const wrapper = mount(Users)
|
|
await wrapper.vm.$nextTick()
|
|
const text = wrapper.find('.vgt-table').text()
|
|
expect(text).toContain('admin.unban')
|
|
})
|
|
test('deletion button should not be displayed for super admins', async () => {
|
|
Vue.prototype.$http.get.mockResolvedValue({
|
|
data: [
|
|
{ uid: 1, permission: 2 },
|
|
],
|
|
})
|
|
const wrapper = mount(Users)
|
|
await wrapper.vm.$nextTick()
|
|
expect(wrapper.find('.btn-danger').attributes('disabled')).toBe('disabled')
|
|
})
|
|
test('deletion button should be displayed for admins as super admin', async () => {
|
|
Vue.prototype.$http.get.mockResolvedValue({
|
|
data: [
|
|
{
|
|
uid: 1, permission: 1, operations: 2,
|
|
},
|
|
],
|
|
})
|
|
const wrapper = mount(Users)
|
|
await wrapper.vm.$nextTick()
|
|
expect(wrapper.find('.btn-danger').attributes('disabled')).toBeNil()
|
|
})
|
|
test('deletion button should be displayed for normal users as super admin', async () => {
|
|
Vue.prototype.$http.get.mockResolvedValue({
|
|
data: [
|
|
{
|
|
uid: 1, permission: 0, operations: 2,
|
|
},
|
|
],
|
|
})
|
|
const wrapper = mount(Users)
|
|
await wrapper.vm.$nextTick()
|
|
expect(wrapper.find('.btn-danger').attributes('disabled')).toBeNil()
|
|
})
|
|
test('deletion button should be displayed for banned users as super admin', async () => {
|
|
Vue.prototype.$http.get.mockResolvedValue({
|
|
data: [
|
|
{
|
|
uid: 1, permission: -1, operations: 2,
|
|
},
|
|
],
|
|
})
|
|
const wrapper = mount(Users)
|
|
await wrapper.vm.$nextTick()
|
|
expect(wrapper.find('.btn-danger').attributes('disabled')).toBeNil()
|
|
})
|
|
test('deletion button should not be displayed for other admins as admin', async () => {
|
|
Vue.prototype.$http.get.mockResolvedValue({
|
|
data: [
|
|
{
|
|
uid: 1, permission: 1, operations: 1,
|
|
},
|
|
],
|
|
})
|
|
const wrapper = mount(Users)
|
|
await wrapper.vm.$nextTick()
|
|
expect(wrapper.find('.btn-danger').attributes('disabled')).toBe('disabled')
|
|
})
|
|
test('deletion button should be displayed for normal users as admin', async () => {
|
|
Vue.prototype.$http.get.mockResolvedValue({
|
|
data: [
|
|
{
|
|
uid: 1, permission: 0, operations: 1,
|
|
},
|
|
],
|
|
})
|
|
const wrapper = mount(Users)
|
|
await wrapper.vm.$nextTick()
|
|
expect(wrapper.find('.btn-danger').attributes('disabled')).toBeNil()
|
|
})
|
|
test('deletion button should be displayed for banned users as admin', async () => {
|
|
Vue.prototype.$http.get.mockResolvedValue({
|
|
data: [
|
|
{
|
|
uid: 1, permission: -1, operations: 1,
|
|
},
|
|
],
|
|
})
|
|
const wrapper = mount(Users)
|
|
await wrapper.vm.$nextTick()
|
|
expect(wrapper.find('.btn-danger').attributes('disabled')).toBeNil()
|
|
})
|
|
test('change email', async () => {
|
|
Vue.prototype.$http.get.mockResolvedValue({
|
|
data: [
|
|
{ uid: 1, email: 'a@b.c' },
|
|
],
|
|
})
|
|
Vue.prototype.$http.post
|
|
.mockResolvedValueOnce({ errno: 1, msg: '1' })
|
|
.mockResolvedValueOnce({ errno: 0, msg: '0' })
|
|
swal.mockImplementationOnce(() => ({ dismiss: 1 }))
|
|
.mockImplementation(options => {
|
|
options.inputValidator()
|
|
options.inputValidator('value')
|
|
return { value: 'd@e.f' }
|
|
})
|
|
const wrapper = mount(Users)
|
|
await wrapper.vm.$nextTick()
|
|
const button = wrapper.find('[data-test="email"]')
|
|
|
|
button.trigger('click')
|
|
expect(Vue.prototype.$http.post).not.toBeCalled()
|
|
|
|
button.trigger('click')
|
|
await wrapper.vm.$nextTick()
|
|
expect(Vue.prototype.$http.post).toBeCalledWith(
|
|
'/admin/users?action=email',
|
|
{ uid: 1, email: 'd@e.f' }
|
|
)
|
|
expect(wrapper.text()).toContain('a@b.c')
|
|
|
|
button.trigger('click')
|
|
await flushPromises()
|
|
expect(wrapper.text()).toContain('d@e.f')
|
|
})
|
|
test('toggle verification', async () => {
|
|
Vue.prototype.$http.get.mockResolvedValue({
|
|
data: [
|
|
{ uid: 1, verified: false },
|
|
],
|
|
})
|
|
Vue.prototype.$http.post
|
|
.mockResolvedValueOnce({ errno: 1, msg: '1' })
|
|
.mockResolvedValueOnce({ errno: 0, msg: '0' })
|
|
|
|
const wrapper = mount(Users)
|
|
await wrapper.vm.$nextTick()
|
|
const button = wrapper.find('[data-test="verification"')
|
|
|
|
button.trigger('click')
|
|
await wrapper.vm.$nextTick()
|
|
expect(Vue.prototype.$http.post).toBeCalledWith(
|
|
'/admin/users?action=verification',
|
|
{ uid: 1 }
|
|
)
|
|
button.trigger('click')
|
|
await flushPromises()
|
|
expect(wrapper.text()).toContain('admin.verified')
|
|
})
|
|
test('change nickname', async () => {
|
|
Vue.prototype.$http.get.mockResolvedValue({
|
|
data: [
|
|
{ uid: 1, nickname: 'old' },
|
|
],
|
|
})
|
|
Vue.prototype.$http.post
|
|
.mockResolvedValueOnce({ errno: 1, msg: '1' })
|
|
.mockResolvedValueOnce({ errno: 0, msg: '0' })
|
|
swal.mockImplementationOnce(() => ({ dismiss: 1 }))
|
|
.mockImplementation(options => {
|
|
options.inputValidator()
|
|
options.inputValidator('value')
|
|
return { value: 'new' }
|
|
})
|
|
const wrapper = mount(Users)
|
|
await wrapper.vm.$nextTick()
|
|
const button = wrapper.find('[data-test="nickname"]')
|
|
|
|
button.trigger('click')
|
|
expect(Vue.prototype.$http.post).not.toBeCalled()
|
|
|
|
button.trigger('click')
|
|
await wrapper.vm.$nextTick()
|
|
expect(Vue.prototype.$http.post).toBeCalledWith(
|
|
'/admin/users?action=nickname',
|
|
{ uid: 1, nickname: 'new' }
|
|
)
|
|
expect(wrapper.text()).toContain('old')
|
|
|
|
button.trigger('click')
|
|
await flushPromises()
|
|
expect(wrapper.text()).toContain('new')
|
|
})
|
|
test('change password', async () => {
|
|
jest.spyOn(toastr, 'success')
|
|
jest.spyOn(toastr, 'warning')
|
|
Vue.prototype.$http.get.mockResolvedValue({
|
|
data: [
|
|
{ uid: 1 },
|
|
],
|
|
})
|
|
Vue.prototype.$http.post
|
|
.mockResolvedValueOnce({ errno: 0, msg: '0' })
|
|
.mockResolvedValueOnce({ errno: 1, msg: '1' })
|
|
swal.mockResolvedValueOnce({ dismiss: 1 })
|
|
.mockResolvedValue({ value: 'password' })
|
|
|
|
const wrapper = mount(Users)
|
|
await wrapper.vm.$nextTick()
|
|
const button = wrapper.find('.operations-menu > li:nth-child(1) > a')
|
|
|
|
button.trigger('click')
|
|
expect(Vue.prototype.$http.post).not.toBeCalled()
|
|
|
|
button.trigger('click')
|
|
await wrapper.vm.$nextTick()
|
|
expect(Vue.prototype.$http.post).toBeCalledWith(
|
|
'/admin/users?action=password',
|
|
{ uid: 1, password: 'password' }
|
|
)
|
|
await flushPromises()
|
|
expect(toastr.success).toBeCalledWith('0')
|
|
|
|
|
|
button.trigger('click')
|
|
await flushPromises()
|
|
expect(toastr.warning).toBeCalledWith('1')
|
|
})
|
|
test('change score', async () => {
|
|
Vue.prototype.$http.get.mockResolvedValue({
|
|
data: [
|
|
{ uid: 1, score: 23 },
|
|
],
|
|
})
|
|
Vue.prototype.$http.post
|
|
.mockResolvedValueOnce({ errno: 1, msg: '1' })
|
|
.mockResolvedValueOnce({ errno: 0, msg: '0' })
|
|
swal.mockResolvedValueOnce({ dismiss: 1 })
|
|
.mockResolvedValue({ value: '45' })
|
|
|
|
const wrapper = mount(Users)
|
|
await wrapper.vm.$nextTick()
|
|
const button = wrapper.find('[data-test="score"]')
|
|
|
|
button.trigger('click')
|
|
expect(Vue.prototype.$http.post).not.toBeCalled()
|
|
|
|
button.trigger('click')
|
|
await wrapper.vm.$nextTick()
|
|
expect(Vue.prototype.$http.post).toBeCalledWith(
|
|
'/admin/users?action=score',
|
|
{ uid: 1, score: 45 }
|
|
)
|
|
expect(wrapper.text()).toContain('23')
|
|
|
|
button.trigger('click')
|
|
await flushPromises()
|
|
expect(wrapper.text()).toContain('45')
|
|
})
|
|
test('toggle admin', async () => {
|
|
Vue.prototype.$http.get.mockResolvedValue({
|
|
data: [
|
|
{
|
|
uid: 1, permission: 0, operations: 2,
|
|
},
|
|
],
|
|
})
|
|
Vue.prototype.$http.post
|
|
.mockResolvedValueOnce({ errno: 1, msg: '1' })
|
|
.mockResolvedValue({ errno: 0, msg: '0' })
|
|
|
|
const wrapper = mount(Users)
|
|
await wrapper.vm.$nextTick()
|
|
const button = wrapper.find('.operations-menu > li:nth-child(3) > a')
|
|
|
|
button.trigger('click')
|
|
await wrapper.vm.$nextTick()
|
|
expect(Vue.prototype.$http.post).toBeCalledWith(
|
|
'/admin/users?action=admin',
|
|
{ uid: 1 }
|
|
)
|
|
expect(wrapper.text()).toContain('admin.normal')
|
|
|
|
button.trigger('click')
|
|
await flushPromises()
|
|
expect(wrapper.text()).toContain('admin.admin')
|
|
|
|
button.trigger('click')
|
|
await flushPromises()
|
|
expect(wrapper.text()).toContain('admin.normal')
|
|
})
|
|
test('toggle ban', async () => {
|
|
Vue.prototype.$http.get.mockResolvedValue({
|
|
data: [
|
|
{
|
|
uid: 1, permission: 0, operations: 2,
|
|
},
|
|
],
|
|
})
|
|
Vue.prototype.$http.post
|
|
.mockResolvedValueOnce({ errno: 1, msg: '1' })
|
|
.mockResolvedValue({ errno: 0, msg: '0' })
|
|
|
|
const wrapper = mount(Users)
|
|
await wrapper.vm.$nextTick()
|
|
const button = wrapper.find('.operations-menu > li:nth-child(4) > a')
|
|
|
|
button.trigger('click')
|
|
await wrapper.vm.$nextTick()
|
|
expect(Vue.prototype.$http.post).toBeCalledWith(
|
|
'/admin/users?action=ban',
|
|
{ uid: 1 }
|
|
)
|
|
expect(wrapper.text()).toContain('admin.ban')
|
|
|
|
button.trigger('click')
|
|
await flushPromises()
|
|
expect(wrapper.text()).toContain('admin.banned')
|
|
|
|
button.trigger('click')
|
|
await flushPromises()
|
|
expect(wrapper.text()).toContain('admin.ban')
|
|
})
|
|
test('delete user', async () => {
|
|
Vue.prototype.$http.get.mockResolvedValue({
|
|
data: [
|
|
{ uid: 1, nickname: 'to-be-deleted' },
|
|
],
|
|
})
|
|
Vue.prototype.$http.post
|
|
.mockResolvedValueOnce({ errno: 1, msg: '1' })
|
|
.mockResolvedValue({ errno: 0, msg: '0' })
|
|
swal.mockResolvedValueOnce({ dismiss: 1 })
|
|
.mockResolvedValue({})
|
|
|
|
const wrapper = mount(Users)
|
|
await wrapper.vm.$nextTick()
|
|
const button = wrapper.find('.btn-danger')
|
|
|
|
button.trigger('click')
|
|
expect(Vue.prototype.$http.post).not.toBeCalled()
|
|
|
|
button.trigger('click')
|
|
await wrapper.vm.$nextTick()
|
|
expect(Vue.prototype.$http.post).toBeCalledWith(
|
|
'/admin/users?action=delete',
|
|
{ uid: 1 }
|
|
)
|
|
expect(wrapper.text()).toContain('to-be-deleted')
|
|
|
|
button.trigger('click')
|
|
await flushPromises()
|
|
expect(wrapper.text()).toContain('No data')
|
|
})
|