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