Replace Element msgbox with Bootstrap modal
This commit is contained in:
parent
b1ae902091
commit
2da0a3576b
|
|
@ -43,6 +43,8 @@
|
|||
<script>
|
||||
import setAsAvatar from './mixins/setAsAvatar'
|
||||
import removeClosetItem from './mixins/removeClosetItem'
|
||||
import { showModal } from '../scripts/notify'
|
||||
import { truthy } from '../scripts/validators'
|
||||
|
||||
export default {
|
||||
name: 'ClosetItem',
|
||||
|
|
@ -82,12 +84,12 @@ export default {
|
|||
async rename() {
|
||||
let newTextureName
|
||||
try {
|
||||
({ value: newTextureName } = await this.$prompt(
|
||||
this.$t('user.renameClosetItem'),
|
||||
({ value: newTextureName } = await showModal(
|
||||
{
|
||||
inputValue: this.textureName,
|
||||
showCancelButton: true,
|
||||
inputValidator: value => !!value || this.$t('skinlib.emptyNewTextureName'),
|
||||
mode: 'prompt',
|
||||
text: this.$t('user.renameClosetItem'),
|
||||
input: this.textureName,
|
||||
validator: truthy(this.$t('skinlib.emptyNewTextureName')),
|
||||
},
|
||||
))
|
||||
} catch {
|
||||
|
|
|
|||
|
|
@ -29,7 +29,17 @@
|
|||
<div v-else-if="dangerousHTML" v-html="dangerousHTML" />
|
||||
<template v-if="mode === 'prompt'">
|
||||
<div class="form-group">
|
||||
<input v-model="value" type="text" class="form-control">
|
||||
<input
|
||||
v-model="value"
|
||||
:type="inputType"
|
||||
class="form-control"
|
||||
:placeholder="placeholder"
|
||||
@input="valid = true"
|
||||
>
|
||||
</div>
|
||||
<div v-if="!valid" class="alert alert-danger">
|
||||
<i class="icon far fa-times-circle" />
|
||||
{{ validatorMessage }}
|
||||
</div>
|
||||
</template>
|
||||
</slot>
|
||||
|
|
@ -91,6 +101,16 @@ export default {
|
|||
type: String,
|
||||
default: '',
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
},
|
||||
inputType: {
|
||||
type: String,
|
||||
default: 'text',
|
||||
},
|
||||
validator: {
|
||||
type: Function,
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'default',
|
||||
|
|
@ -128,6 +148,8 @@ export default {
|
|||
return {
|
||||
hidden: false,
|
||||
value: this.input,
|
||||
valid: true,
|
||||
validatorMessage: '',
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -154,6 +176,15 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
confirm() {
|
||||
if (typeof this.validator === 'function') {
|
||||
const result = this.validator(this.value)
|
||||
if (typeof result === 'string') {
|
||||
this.validatorMessage = result
|
||||
this.valid = false
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
this.hidden = true
|
||||
this.$emit('confirm', { value: this.value })
|
||||
$(this.$el).modal('hide')
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import Vue from 'vue'
|
||||
import { MessageBoxInputData } from 'element-ui/types/message-box'
|
||||
import { showModal } from '../../scripts/notify'
|
||||
import { truthy } from '../../scripts/validators'
|
||||
|
||||
export default Vue.extend<{
|
||||
name: string
|
||||
|
|
@ -9,15 +10,13 @@ export default Vue.extend<{
|
|||
async addClosetItem() {
|
||||
let value: string
|
||||
try {
|
||||
({ value } = await this.$prompt(
|
||||
this.$t('skinlib.applyNotice'),
|
||||
{
|
||||
title: this.$t('skinlib.setItemName'),
|
||||
inputValue: this.name,
|
||||
showCancelButton: true,
|
||||
inputValidator: val => !!val || this.$t('skinlib.emptyItemName'),
|
||||
},
|
||||
) as MessageBoxInputData)
|
||||
({ value } = await showModal({
|
||||
mode: 'prompt',
|
||||
title: this.$t('skinlib.setItemName'),
|
||||
text: this.$t('skinlib.applyNotice'),
|
||||
input: this.name,
|
||||
validator: truthy(this.$t('skinlib.emptyItemName')),
|
||||
}))
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import Vue from 'vue'
|
||||
import { showModal } from '../../scripts/notify'
|
||||
|
||||
export default Vue.extend({
|
||||
data: () => ({ plugins: [] }),
|
||||
|
|
@ -7,15 +8,15 @@ export default Vue.extend({
|
|||
name, dependencies: { all }, originalIndex,
|
||||
}: {
|
||||
name: string
|
||||
dependencies: { all: { [name: string]: string } }
|
||||
dependencies: { all: Record<string, string> }
|
||||
originalIndex: number
|
||||
}) {
|
||||
if (Object.keys(all).length === 0) {
|
||||
try {
|
||||
await this.$confirm(
|
||||
this.$t('admin.noDependenciesNotice'),
|
||||
{ type: 'warning' },
|
||||
)
|
||||
await showModal({
|
||||
text: this.$t('admin.noDependenciesNotice'),
|
||||
okButtonType: 'warning',
|
||||
})
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
|
|
@ -31,12 +32,21 @@ export default Vue.extend({
|
|||
this.$message.success(message)
|
||||
this.$set(this.plugins[originalIndex], 'enabled', true)
|
||||
} else {
|
||||
const h = this.$createElement
|
||||
const vnode = h('div', {}, [
|
||||
h('p', message),
|
||||
h('ul', {}, reason.map(item => h('li', item))),
|
||||
])
|
||||
this.$alert('', { message: vnode, type: 'warning' })
|
||||
const div = document.createElement('div')
|
||||
const p = document.createElement('p')
|
||||
p.textContent = message
|
||||
div.appendChild(p)
|
||||
const ul = document.createElement('ul')
|
||||
reason.forEach(item => {
|
||||
const li = document.createElement('li')
|
||||
li.textContent = item
|
||||
ul.appendChild(li)
|
||||
})
|
||||
div.appendChild(ul)
|
||||
showModal({
|
||||
mode: 'alert',
|
||||
dangerousHTML: div.outerHTML,
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import Vue from 'vue'
|
||||
import { showModal } from '../../scripts/notify'
|
||||
|
||||
export default Vue.extend<{
|
||||
name: string
|
||||
|
|
@ -7,10 +8,10 @@ export default Vue.extend<{
|
|||
methods: {
|
||||
async removeClosetItem() {
|
||||
try {
|
||||
await this.$confirm(
|
||||
this.$t('user.removeFromClosetNotice'),
|
||||
{ type: 'warning' },
|
||||
)
|
||||
await showModal({
|
||||
text: this.$t('user.removeFromClosetNotice'),
|
||||
okButtonType: 'danger',
|
||||
})
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import Vue from 'vue'
|
||||
import { showModal } from '../../scripts/notify'
|
||||
|
||||
export default Vue.extend<{
|
||||
tid: number
|
||||
|
|
@ -6,10 +7,10 @@ export default Vue.extend<{
|
|||
methods: {
|
||||
async setAsAvatar() {
|
||||
try {
|
||||
await this.$confirm(
|
||||
this.$t('user.setAvatarNotice'),
|
||||
this.$t('user.setAvatar'),
|
||||
)
|
||||
await showModal({
|
||||
title: this.$t('user.setAvatar'),
|
||||
text: this.$t('user.setAvatarNotice'),
|
||||
})
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +1,10 @@
|
|||
import Vue from 'vue'
|
||||
import {
|
||||
Button,
|
||||
Input,
|
||||
Message,
|
||||
MessageBox,
|
||||
} from 'element-ui'
|
||||
|
||||
Vue.use(Button)
|
||||
Vue.use(Input)
|
||||
import { Message } from 'element-ui'
|
||||
|
||||
Object.assign(Vue.prototype, {
|
||||
$message: Message,
|
||||
$msgbox: MessageBox,
|
||||
$alert: MessageBox.alert,
|
||||
$confirm: MessageBox.confirm,
|
||||
$prompt: MessageBox.prompt,
|
||||
})
|
||||
|
||||
blessing.ui = {
|
||||
message: Message,
|
||||
msgbox: MessageBox,
|
||||
alert: MessageBox.alert,
|
||||
confirm: MessageBox.confirm,
|
||||
prompt: MessageBox.prompt,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,10 @@ export interface ModalOptions {
|
|||
title?: string
|
||||
text?: string
|
||||
dangerousHTML?: string
|
||||
input?: boolean
|
||||
input?: string
|
||||
placeholder?: string
|
||||
inputType?: string
|
||||
validator?(value: any): string | boolean | void
|
||||
type?: string
|
||||
showHeader?: boolean
|
||||
center?: boolean
|
||||
|
|
@ -29,7 +32,7 @@ export function showModal(options: ModalOptions = {}): Promise<ModalResult> {
|
|||
|
||||
const instance = new Vue({
|
||||
render: h => h(Modal, {
|
||||
props: options,
|
||||
props: Object.assign({ center: true }, options),
|
||||
on: {
|
||||
confirm: resolve,
|
||||
dismiss: reject,
|
||||
|
|
|
|||
7
resources/assets/src/scripts/validators.ts
Normal file
7
resources/assets/src/scripts/validators.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
export function truthy(message: string) {
|
||||
return (value?: unknown): string | void => {
|
||||
if (!value) {
|
||||
return message
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1 @@
|
|||
@import '~element-theme-chalk/src/button.scss';
|
||||
@import '~element-theme-chalk/src/input.scss';
|
||||
@import '~element-theme-chalk/src/message.scss';
|
||||
@import '~element-theme-chalk/src/message-box.scss';
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ import 'vue-good-table/dist/vue-good-table.min.css'
|
|||
import enablePlugin from '../../components/mixins/enablePlugin'
|
||||
import tableOptions from '../../components/mixins/tableOptions'
|
||||
import emitMounted from '../../components/mixins/emitMounted'
|
||||
import { showModal } from '../../scripts/notify'
|
||||
|
||||
export default {
|
||||
name: 'Market',
|
||||
|
|
@ -149,11 +150,11 @@ export default {
|
|||
},
|
||||
async updatePlugin(plugin) {
|
||||
try {
|
||||
await this.$confirm(
|
||||
this.$t('admin.confirmUpdate', {
|
||||
await showModal({
|
||||
text: this.$t('admin.confirmUpdate', {
|
||||
plugin: plugin.title, old: plugin.installed, new: plugin.version,
|
||||
}),
|
||||
)
|
||||
})
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@
|
|||
<modal
|
||||
id="modal-change-texture"
|
||||
:title="$t('admin.changeTexture')"
|
||||
center
|
||||
@confirm="changeTexture"
|
||||
>
|
||||
<div class="form-group">
|
||||
|
|
@ -94,6 +95,8 @@ import Modal from '../../components/Modal.vue'
|
|||
import tableOptions from '../../components/mixins/tableOptions'
|
||||
import serverTable from '../../components/mixins/serverTable'
|
||||
import emitMounted from '../../components/mixins/emitMounted'
|
||||
import { showModal } from '../../scripts/notify'
|
||||
import { truthy } from '../../scripts/validators'
|
||||
|
||||
export default {
|
||||
name: 'PlayersManagement',
|
||||
|
|
@ -172,9 +175,11 @@ export default {
|
|||
async changeName(player) {
|
||||
let value
|
||||
try {
|
||||
({ value } = await this.$prompt(this.$t('admin.changePlayerNameNotice'), {
|
||||
inputValue: player.name,
|
||||
inputValidator: name => !!name || this.$t('admin.emptyPlayerName'),
|
||||
({ value } = await showModal({
|
||||
mode: 'prompt',
|
||||
text: this.$t('admin.changePlayerNameNotice'),
|
||||
input: player.name,
|
||||
validator: truthy(this.$t('admin.emptyPlayerName')),
|
||||
}))
|
||||
} catch {
|
||||
return
|
||||
|
|
@ -194,12 +199,15 @@ export default {
|
|||
async changeOwner(player) {
|
||||
let value
|
||||
try {
|
||||
({ value } = await this.$prompt(this.$t('admin.changePlayerOwner'), {
|
||||
inputValue: player.uid,
|
||||
({ value } = await showModal({
|
||||
mode: 'prompt',
|
||||
text: this.$t('admin.changePlayerOwner'),
|
||||
input: player.uid,
|
||||
}))
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
value = Number.parseInt(value)
|
||||
|
||||
const { code, message } = await this.$http.post(
|
||||
'/admin/players?action=owner',
|
||||
|
|
@ -214,8 +222,9 @@ export default {
|
|||
},
|
||||
async deletePlayer({ pid, originalIndex }) {
|
||||
try {
|
||||
await this.$confirm(this.$t('admin.deletePlayerNotice'), {
|
||||
type: 'warning',
|
||||
await showModal({
|
||||
text: this.$t('admin.deletePlayerNotice'),
|
||||
okButtonType: 'danger',
|
||||
})
|
||||
} catch {
|
||||
return
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ import 'vue-good-table/dist/vue-good-table.min.css'
|
|||
import enablePlugin from '../../components/mixins/enablePlugin'
|
||||
import tableOptions from '../../components/mixins/tableOptions'
|
||||
import emitMounted from '../../components/mixins/emitMounted'
|
||||
import { showModal } from '../../scripts/notify'
|
||||
|
||||
export default {
|
||||
name: 'Plugins',
|
||||
|
|
@ -141,9 +142,15 @@ export default {
|
|||
this.$message.warning(message)
|
||||
}
|
||||
},
|
||||
async deletePlugin({ name, originalIndex }) {
|
||||
async deletePlugin({
|
||||
name, title, originalIndex,
|
||||
}) {
|
||||
try {
|
||||
await this.$confirm(this.$t('admin.confirmDeletion'), { type: 'warning' })
|
||||
await showModal({
|
||||
title,
|
||||
text: this.$t('admin.confirmDeletion'),
|
||||
okButtonType: 'danger',
|
||||
})
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import { VueGoodTable } from 'vue-good-table'
|
|||
import 'vue-good-table/dist/vue-good-table.min.css'
|
||||
import tableOptions from '../../components/mixins/tableOptions'
|
||||
import emitMounted from '../../components/mixins/emitMounted'
|
||||
import { showModal } from '../../scripts/notify'
|
||||
|
||||
export default {
|
||||
name: 'Translations',
|
||||
|
|
@ -67,8 +68,10 @@ export default {
|
|||
async modify(line) {
|
||||
let text = null
|
||||
try {
|
||||
({ value: text } = await this.$prompt(this.$t('admin.i18n.updating'), {
|
||||
inputValue: line.text,
|
||||
({ value: text } = await showModal({
|
||||
mode: 'prompt',
|
||||
text: this.$t('admin.i18n.updating'),
|
||||
input: line.text,
|
||||
}))
|
||||
} catch {
|
||||
return
|
||||
|
|
@ -87,8 +90,9 @@ export default {
|
|||
},
|
||||
async remove({ id, originalIndex }) {
|
||||
try {
|
||||
await this.$confirm(this.$t('admin.i18n.confirmDelete'), {
|
||||
type: 'warning',
|
||||
await showModal({
|
||||
text: this.$t('admin.i18n.confirmDelete'),
|
||||
okButtonType: 'danger',
|
||||
})
|
||||
} catch {
|
||||
return
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
|
||||
<script>
|
||||
import emitMounted from '../../components/mixins/emitMounted'
|
||||
import { showModal } from '../../scripts/notify'
|
||||
|
||||
const POLLING_INTERVAL = 500
|
||||
|
||||
|
|
@ -73,10 +74,19 @@ export default {
|
|||
)
|
||||
this.updating = false
|
||||
if (code) {
|
||||
this.$alert(message, { type: 'error' })
|
||||
showModal({
|
||||
mode: 'alert',
|
||||
text: message,
|
||||
type: 'danger',
|
||||
okButtonType: 'outline-light',
|
||||
})
|
||||
return
|
||||
}
|
||||
await this.$alert(this.$t('admin.updateCompleted'), { type: 'success' })
|
||||
await showModal({
|
||||
mode: 'alert',
|
||||
text: this.$t('admin.updateCompleted'),
|
||||
okButtonType: 'success',
|
||||
})
|
||||
window.location = blessing.base_url
|
||||
},
|
||||
async polling() {
|
||||
|
|
|
|||
|
|
@ -45,8 +45,10 @@
|
|||
<a
|
||||
v-if="props.row.permission < 1 || (props.row.operations === 2 && props.row.permission < 2)"
|
||||
:title="$t('admin.changePermission')"
|
||||
data-toggle="modal"
|
||||
data-target="#modal-permission"
|
||||
data-test="permission"
|
||||
@click="changePermission(props.row)"
|
||||
@click="editingUser = props.row, permission = props.row.permission"
|
||||
>
|
||||
<i class="fas fa-edit btn-edit" />
|
||||
</a>
|
||||
|
|
@ -81,6 +83,40 @@
|
|||
<span v-else v-text="props.formattedRow[props.column.field]" />
|
||||
</template>
|
||||
</vue-good-table>
|
||||
<modal
|
||||
id="modal-permission"
|
||||
:title="$t(this.$t('admin.newPermission'))"
|
||||
center
|
||||
@confirm="changePermission"
|
||||
>
|
||||
<label class="mr-3">
|
||||
<input
|
||||
v-model="permission"
|
||||
type="radio"
|
||||
name="permission"
|
||||
:value="-1"
|
||||
>
|
||||
{{ $t('admin.banned') }}
|
||||
</label>
|
||||
<label class="mr-3">
|
||||
<input
|
||||
v-model="permission"
|
||||
type="radio"
|
||||
name="permission"
|
||||
:value="0"
|
||||
>
|
||||
{{ $t('admin.normal') }}
|
||||
</label>
|
||||
<label v-if="editingUser.operations === 2">
|
||||
<input
|
||||
v-model="permission"
|
||||
type="radio"
|
||||
name="permission"
|
||||
:value="1"
|
||||
>
|
||||
{{ $t('admin.admin') }}
|
||||
</label>
|
||||
</modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
@ -88,13 +124,17 @@
|
|||
import { VueGoodTable } from 'vue-good-table'
|
||||
import 'vue-good-table/dist/vue-good-table.min.css'
|
||||
import { trans } from '../../scripts/i18n'
|
||||
import Modal from '../../components/Modal.vue'
|
||||
import tableOptions from '../../components/mixins/tableOptions'
|
||||
import serverTable from '../../components/mixins/serverTable'
|
||||
import emitMounted from '../../components/mixins/emitMounted'
|
||||
import { showModal } from '../../scripts/notify'
|
||||
import { truthy } from '../../scripts/validators'
|
||||
|
||||
export default {
|
||||
name: 'UsersManagement',
|
||||
components: {
|
||||
Modal,
|
||||
VueGoodTable,
|
||||
},
|
||||
filters: {
|
||||
|
|
@ -149,6 +189,8 @@ export default {
|
|||
field: 'operations', label: this.$t('admin.operationsTitle'), sortable: false, globalSearchDisabled: true,
|
||||
},
|
||||
],
|
||||
editingUser: {},
|
||||
permission: 0,
|
||||
}
|
||||
},
|
||||
beforeMount() {
|
||||
|
|
@ -166,9 +208,11 @@ export default {
|
|||
async changeEmail(user) {
|
||||
let value
|
||||
try {
|
||||
({ value } = await this.$prompt(this.$t('admin.newUserEmail'), {
|
||||
inputValue: user.email,
|
||||
inputValidator: val => !!val || this.$t('auth.emptyEmail'),
|
||||
({ value } = await showModal({
|
||||
mode: 'prompt',
|
||||
text: this.$t('admin.newUserEmail'),
|
||||
input: user.email,
|
||||
validator: truthy(this.$t('auth.emptyEmail')),
|
||||
}))
|
||||
} catch {
|
||||
return
|
||||
|
|
@ -200,9 +244,11 @@ export default {
|
|||
async changeNickName(user) {
|
||||
let value
|
||||
try {
|
||||
({ value } = await this.$prompt(this.$t('admin.newUserNickname'), {
|
||||
inputValue: user.nickname,
|
||||
inputValidator: val => !!val || this.$t('auth.emptyNickname'),
|
||||
({ value } = await showModal({
|
||||
mode: 'prompt',
|
||||
text: this.$t('admin.newUserNickname'),
|
||||
input: user.nickname,
|
||||
validator: truthy(this.$t('auth.emptyNickname')),
|
||||
}))
|
||||
} catch {
|
||||
return
|
||||
|
|
@ -222,7 +268,9 @@ export default {
|
|||
async changePassword(user) {
|
||||
let value
|
||||
try {
|
||||
({ value } = await this.$prompt(this.$t('admin.newUserPassword'), {
|
||||
({ value } = await showModal({
|
||||
mode: 'prompt',
|
||||
text: this.$t('admin.newUserPassword'),
|
||||
inputType: 'password',
|
||||
}))
|
||||
} catch {
|
||||
|
|
@ -238,9 +286,11 @@ export default {
|
|||
async changeScore(user) {
|
||||
let value
|
||||
try {
|
||||
({ value } = await this.$prompt(this.$t('admin.newScore'), {
|
||||
({ value } = await showModal({
|
||||
mode: 'prompt',
|
||||
text: this.$t('admin.newScore'),
|
||||
input: user.score,
|
||||
inputType: 'number',
|
||||
inputValue: user.score,
|
||||
}))
|
||||
} catch {
|
||||
return
|
||||
|
|
@ -258,41 +308,14 @@ export default {
|
|||
this.$message.warning(message)
|
||||
}
|
||||
},
|
||||
async changePermission(user) {
|
||||
const operator = user.operations
|
||||
const options = [
|
||||
this.$t('admin.banned'),
|
||||
this.$t('admin.normal'),
|
||||
]
|
||||
if (operator === 2) {
|
||||
options.push(this.$t('admin.admin'))
|
||||
}
|
||||
const h = this.$createElement
|
||||
const vnode = h('div', null, [
|
||||
h('span', null, this.$t('admin.newPermission')),
|
||||
h(
|
||||
'select',
|
||||
{ attrs: { selectedIndex: 0 } },
|
||||
options.map(option => h('option', null, option)),
|
||||
),
|
||||
])
|
||||
|
||||
try {
|
||||
await this.$msgbox({
|
||||
message: vnode,
|
||||
showCancelButton: true,
|
||||
})
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
const value = vnode.children[1].elm.selectedIndex - 1
|
||||
|
||||
async changePermission() {
|
||||
const permission = Number.parseInt(this.permission)
|
||||
const { code, message } = await this.$http.post('/admin/users?action=permission', {
|
||||
uid: user.uid,
|
||||
permission: value,
|
||||
uid: this.editingUser.uid,
|
||||
permission,
|
||||
})
|
||||
if (code === 0) {
|
||||
user.permission = +value
|
||||
this.editingUser.permission = permission
|
||||
this.$message.success(message)
|
||||
} else {
|
||||
this.$message.warning(message)
|
||||
|
|
@ -300,8 +323,9 @@ export default {
|
|||
},
|
||||
async deleteUser({ uid, originalIndex }) {
|
||||
try {
|
||||
await this.$confirm(this.$t('admin.deleteUserNotice'), {
|
||||
type: 'warning',
|
||||
await showModal({
|
||||
text: this.$t('admin.deleteUserNotice'),
|
||||
okButtonType: 'danger',
|
||||
})
|
||||
} catch {
|
||||
return
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@
|
|||
<script>
|
||||
import Captcha from '../../components/Captcha.vue'
|
||||
import emitMounted from '../../components/mixins/emitMounted'
|
||||
import { showModal } from '../../scripts/notify'
|
||||
|
||||
export default {
|
||||
name: 'Login',
|
||||
|
|
@ -115,10 +116,16 @@ export default {
|
|||
if (loginFails > 3 && !this.tooManyFails) {
|
||||
if (this.recaptcha) {
|
||||
if (!this.invisible) {
|
||||
this.$alert(this.$t('auth.tooManyFails.recaptcha'), { type: 'error' })
|
||||
showModal({
|
||||
mode: 'alert',
|
||||
text: this.$t('auth.tooManyFails.recaptcha'),
|
||||
})
|
||||
}
|
||||
} else {
|
||||
this.$alert(this.$t('auth.tooManyFails.captcha'), { type: 'error' })
|
||||
showModal({
|
||||
mode: 'alert',
|
||||
text: this.$t('auth.tooManyFails.captcha'),
|
||||
})
|
||||
}
|
||||
this.tooManyFails = true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,7 +103,14 @@
|
|||
<span v-if="type === 'cape'">{{ $t('general.cape') }}</span>
|
||||
<span v-else>{{ type }}</span>
|
||||
<small v-if="hasEditPermission">
|
||||
<a v-t="'skinlib.show.edit'" href="#" @click="changeModel" />
|
||||
<a
|
||||
href="#"
|
||||
data-toggle="modal"
|
||||
data-target="#modal-type"
|
||||
@click="editingType = type"
|
||||
>
|
||||
{{ $t('skinlib.show.edit') }}
|
||||
</a>
|
||||
</small>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
@ -162,20 +169,59 @@
|
|||
:skin="type !== 'cape' ? tid : 0"
|
||||
:cape="type === 'cape' ? tid : 0"
|
||||
/>
|
||||
|
||||
<modal
|
||||
id="modal-type"
|
||||
:title="$t(this.$t('skinlib.setNewTextureModel'))"
|
||||
center
|
||||
@confirm="changeModel"
|
||||
>
|
||||
<label class="mr-3">
|
||||
<input
|
||||
v-model="editingType"
|
||||
type="radio"
|
||||
name="type"
|
||||
value="steve"
|
||||
>
|
||||
Steve
|
||||
</label>
|
||||
<label class="mr-3">
|
||||
<input
|
||||
v-model="editingType"
|
||||
type="radio"
|
||||
name="type"
|
||||
value="alex"
|
||||
>
|
||||
Alex
|
||||
</label>
|
||||
<label>
|
||||
<input
|
||||
v-model="editingType"
|
||||
type="radio"
|
||||
name="type"
|
||||
value="cape"
|
||||
>
|
||||
{{ $t('general.cape') }}
|
||||
</label>
|
||||
</modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Modal from '../../components/Modal.vue'
|
||||
import setAsAvatar from '../../components/mixins/setAsAvatar'
|
||||
import addClosetItem from '../../components/mixins/addClosetItem'
|
||||
import removeClosetItem from '../../components/mixins/removeClosetItem'
|
||||
import emitMounted from '../../components/mixins/emitMounted'
|
||||
import ApplyToPlayerDialog from '../../components/ApplyToPlayerDialog.vue'
|
||||
import { showModal } from '../../scripts/notify'
|
||||
import { truthy } from '../../scripts/validators'
|
||||
|
||||
export default {
|
||||
name: 'Show',
|
||||
components: {
|
||||
ApplyToPlayerDialog,
|
||||
Modal,
|
||||
Previewer: () => import('../../components/Previewer.vue'),
|
||||
},
|
||||
mixins: [
|
||||
|
|
@ -201,6 +247,7 @@ export default {
|
|||
size: 0,
|
||||
uploadAt: '',
|
||||
public: true,
|
||||
editingType: 'steve',
|
||||
liked: blessing.extra.inCloset,
|
||||
canBeDownloaded: blessing.extra.download,
|
||||
currentUid: blessing.extra.currentUid,
|
||||
|
|
@ -256,9 +303,11 @@ export default {
|
|||
async changeTextureName() {
|
||||
let value
|
||||
try {
|
||||
({ value } = await this.$prompt(this.$t('skinlib.setNewTextureName'), {
|
||||
inputValue: this.name,
|
||||
inputValidator: name => !!name || this.$t('skinlib.emptyNewTextureName'),
|
||||
({ value } = await showModal({
|
||||
mode: 'prompt',
|
||||
text: this.$t('skinlib.setNewTextureName'),
|
||||
input: this.name,
|
||||
validator: truthy(this.$t('skinlib.emptyNewTextureName')),
|
||||
}))
|
||||
} catch {
|
||||
return
|
||||
|
|
@ -276,31 +325,12 @@ export default {
|
|||
}
|
||||
},
|
||||
async changeModel() {
|
||||
const h = this.$createElement
|
||||
const vnode = h('div', null, [
|
||||
h('span', null, this.$t('skinlib.setNewTextureModel')),
|
||||
h('select', { attrs: { selectedIndex: 0 } }, [
|
||||
h('option', { attrs: { value: 'steve' } }, 'Steve'),
|
||||
h('option', { attrs: { value: 'alex' } }, 'Alex'),
|
||||
h('option', { attrs: { value: 'cape' } }, this.$t('general.cape')),
|
||||
]),
|
||||
])
|
||||
try {
|
||||
await this.$msgbox({
|
||||
message: vnode,
|
||||
showCancelButton: true,
|
||||
})
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
const value = ['steve', 'alex', 'cape'][vnode.children[1].elm.selectedIndex]
|
||||
|
||||
const { code, message } = await this.$http.post(
|
||||
'/skinlib/model',
|
||||
{ tid: this.tid, model: value },
|
||||
{ tid: this.tid, model: this.editingType },
|
||||
)
|
||||
if (code === 0) {
|
||||
this.type = value
|
||||
this.type = this.editingType
|
||||
this.$message.success(message)
|
||||
} else {
|
||||
this.$message.warning(message)
|
||||
|
|
@ -308,12 +338,11 @@ export default {
|
|||
},
|
||||
async togglePrivacy() {
|
||||
try {
|
||||
await this.$confirm(
|
||||
this.public
|
||||
await showModal({
|
||||
text: this.public
|
||||
? this.$t('skinlib.setPrivateNotice')
|
||||
: this.$t('skinlib.setPublicNotice'),
|
||||
{ type: 'warning' },
|
||||
)
|
||||
})
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
|
|
@ -331,10 +360,10 @@ export default {
|
|||
},
|
||||
async deleteTexture() {
|
||||
try {
|
||||
await this.$confirm(
|
||||
this.$t('skinlib.deleteNotice'),
|
||||
{ type: 'warning' },
|
||||
)
|
||||
await showModal({
|
||||
text: this.$t('skinlib.deleteNotice'),
|
||||
okButtonType: 'danger',
|
||||
})
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
|
|
@ -361,9 +390,11 @@ export default {
|
|||
})()
|
||||
let reason
|
||||
try {
|
||||
({ value: reason } = await this.$prompt(prompt, {
|
||||
({ value: reason } = await showModal({
|
||||
mode: 'prompt',
|
||||
title: this.$t('skinlib.report.title'),
|
||||
inputPlaceholder: this.$t('skinlib.report.reason'),
|
||||
text: prompt,
|
||||
placeholder: this.$t('skinlib.report.reason'),
|
||||
}))
|
||||
} catch {
|
||||
return
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
<script>
|
||||
import emitMounted from '../../components/mixins/emitMounted'
|
||||
import { showModal } from '../../scripts/notify'
|
||||
|
||||
export default {
|
||||
name: 'BindPlayer',
|
||||
|
|
@ -54,7 +55,7 @@ export default {
|
|||
async fetchPlayers() {
|
||||
const players = (await this.$http.get('/user/player/list')).data
|
||||
this.players = players.map(player => player.name)
|
||||
;[this.selected] = this.players
|
||||
this.selected = this.players[0]
|
||||
},
|
||||
async submit() {
|
||||
this.pending = true
|
||||
|
|
@ -64,7 +65,7 @@ export default {
|
|||
)
|
||||
this.pending = false
|
||||
if (code === 0) {
|
||||
await this.$alert(message)
|
||||
await showModal({ mode: 'alert', text: message })
|
||||
window.location.href = `${blessing.base_url}/user`
|
||||
} else {
|
||||
this.message = message
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ import Modal from '../../components/Modal.vue'
|
|||
import tableOptions from '../../components/mixins/tableOptions'
|
||||
import emitMounted from '../../components/mixins/emitMounted'
|
||||
import { walkFetch, init } from '../../scripts/net'
|
||||
import { showModal } from '../../scripts/notify'
|
||||
|
||||
export default {
|
||||
name: 'OAuthApps',
|
||||
|
|
@ -140,11 +141,11 @@ export default {
|
|||
async modifyName(client) {
|
||||
let name
|
||||
try {
|
||||
const { value } = await this.$prompt('', {
|
||||
({ value: name } = await showModal({
|
||||
mode: 'prompt',
|
||||
title: this.$t('user.oauth.name'),
|
||||
inputValue: client.name,
|
||||
})
|
||||
name = value
|
||||
input: client.name,
|
||||
}))
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
|
|
@ -153,11 +154,11 @@ export default {
|
|||
async modifyCallback(client) {
|
||||
let redirect
|
||||
try {
|
||||
const { value } = await this.$prompt('', {
|
||||
({ value: redirect } = await showModal({
|
||||
mode: 'prompt',
|
||||
title: this.$t('user.oauth.redirect'),
|
||||
inputValue: client.redirect,
|
||||
})
|
||||
redirect = value
|
||||
input: client.redirect,
|
||||
}))
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
|
|
@ -181,7 +182,10 @@ export default {
|
|||
},
|
||||
async remove(client) {
|
||||
try {
|
||||
await this.$confirm(this.$t('user.oauth.confirmRemove'), { type: 'warning' })
|
||||
await showModal({
|
||||
text: this.$t('user.oauth.confirmRemove'),
|
||||
okButtonType: 'danger',
|
||||
})
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -134,6 +134,8 @@
|
|||
import Modal from '../../components/Modal.vue'
|
||||
import AddPlayerDialog from '../../components/AddPlayerDialog.vue'
|
||||
import emitMounted from '../../components/mixins/emitMounted'
|
||||
import { showModal } from '../../scripts/notify'
|
||||
import { truthy } from '../../scripts/validators'
|
||||
|
||||
export default {
|
||||
name: 'Players',
|
||||
|
|
@ -206,9 +208,11 @@ export default {
|
|||
async changeName(player) {
|
||||
let value
|
||||
try {
|
||||
({ value } = await this.$prompt(this.$t('user.changePlayerName'), {
|
||||
inputValue: player.name,
|
||||
inputValidator: val => !!val || this.$t('user.emptyPlayerName'),
|
||||
({ value } = await showModal({
|
||||
mode: 'prompt',
|
||||
text: this.$t('user.changePlayerName'),
|
||||
input: player.name,
|
||||
validator: truthy(this.$t('user.emptyPlayerName')),
|
||||
}))
|
||||
} catch {
|
||||
return
|
||||
|
|
@ -246,9 +250,10 @@ export default {
|
|||
},
|
||||
async deletePlayer(player, index) {
|
||||
try {
|
||||
await this.$confirm(this.$t('user.deletePlayerNotice'), {
|
||||
await showModal({
|
||||
title: this.$t('user.deletePlayer'),
|
||||
type: 'warning',
|
||||
text: this.$t('user.deletePlayerNotice'),
|
||||
okButtonType: 'danger',
|
||||
})
|
||||
} catch {
|
||||
return
|
||||
|
|
|
|||
|
|
@ -196,6 +196,7 @@
|
|||
import EmailVerification from '../../components/EmailVerification.vue'
|
||||
import Modal from '../../components/Modal.vue'
|
||||
import emitMounted from '../../components/mixins/emitMounted'
|
||||
import { showModal } from '../../scripts/notify'
|
||||
|
||||
export default {
|
||||
name: 'Profile',
|
||||
|
|
@ -221,7 +222,7 @@ export default {
|
|||
nl2br: str => str.replace(/\n/g, '<br>'),
|
||||
async resetAvatar() {
|
||||
try {
|
||||
await this.$confirm(this.$t('user.resetAvatarConfirm'))
|
||||
await showModal({ text: this.$t('user.resetAvatarConfirm') })
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
|
|
@ -249,41 +250,29 @@ export default {
|
|||
'/user/profile?action=password',
|
||||
{ current_password: oldPassword, new_password: newPassword },
|
||||
)
|
||||
await showModal({ mode: 'alert', text: message })
|
||||
if (code === 0) {
|
||||
await this.$alert(message)
|
||||
return (window.location = `${blessing.base_url}/auth/login`)
|
||||
}
|
||||
return this.$alert(message, { type: 'warning' })
|
||||
},
|
||||
async changeNickName() {
|
||||
const { nickname } = this
|
||||
|
||||
try {
|
||||
await this.$confirm(this.$t('user.changeNickName', { new_nickname: nickname }))
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
|
||||
const { code, message } = await this.$http.post(
|
||||
'/user/profile?action=nickname',
|
||||
{ new_nickname: nickname },
|
||||
)
|
||||
if (code === 0) {
|
||||
Array.from(document.querySelectorAll('.nickname'))
|
||||
Array
|
||||
.from(document.querySelectorAll('[data-mark="nickname"]'))
|
||||
.forEach(el => (el.textContent = nickname))
|
||||
return this.$message.success(message)
|
||||
}
|
||||
return this.$alert(message, { type: 'warning' })
|
||||
showModal({ mode: 'alert', text: message })
|
||||
},
|
||||
async changeEmail() {
|
||||
const { email } = this
|
||||
|
||||
try {
|
||||
await this.$confirm(this.$t('user.changeEmail', { new_email: email }))
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
|
||||
const { code, message } = await this.$http.post(
|
||||
'/user/profile?action=email',
|
||||
{ new_email: email, password: this.currentPassword },
|
||||
|
|
@ -292,7 +281,7 @@ export default {
|
|||
await this.$message.success(message)
|
||||
return (window.location = `${blessing.base_url}/auth/login`)
|
||||
}
|
||||
return this.$alert(message, { type: 'warning' })
|
||||
showModal({ mode: 'alert', text: message })
|
||||
},
|
||||
async deleteAccount() {
|
||||
const { deleteConfirm: password } = this
|
||||
|
|
@ -301,11 +290,9 @@ export default {
|
|||
'/user/profile?action=delete',
|
||||
{ password },
|
||||
)
|
||||
await showModal({ mode: 'alert', text: message })
|
||||
if (code === 0) {
|
||||
await this.$alert(message, { type: 'success' })
|
||||
window.location = `${blessing.base_url}/auth/login`
|
||||
} else {
|
||||
return this.$alert(message, { type: 'warning' })
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
import Vue from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import { MessageBoxData } from 'element-ui/types/message-box'
|
||||
import { flushPromises } from '../utils'
|
||||
import { showModal } from '@/scripts/notify'
|
||||
import ClosetItem from '@/components/ClosetItem.vue'
|
||||
|
||||
jest.mock('@/scripts/notify')
|
||||
|
||||
function factory(opt = {}) {
|
||||
return {
|
||||
tid: 1,
|
||||
|
|
@ -43,14 +45,9 @@ test('rename texture', async () => {
|
|||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ code: 0 })
|
||||
.mockResolvedValueOnce({ code: 1 })
|
||||
Vue.prototype.$prompt.mockImplementationOnce(() => Promise.reject(new Error()))
|
||||
.mockImplementation((_, options) => {
|
||||
if (options.inputValidator) {
|
||||
options.inputValidator('name')
|
||||
options.inputValidator('')
|
||||
}
|
||||
return Promise.resolve({ value: 'new-name' } as MessageBoxData)
|
||||
})
|
||||
showModal
|
||||
.mockRejectedValueOnce(null)
|
||||
.mockResolvedValue({ value: 'new-name' })
|
||||
const wrapper = mount(ClosetItem, { propsData: factory() })
|
||||
const button = wrapper.findAll('.dropdown-item').at(0)
|
||||
|
||||
|
|
@ -58,6 +55,7 @@ test('rename texture', async () => {
|
|||
await flushPromises()
|
||||
expect(Vue.prototype.$http.post).not.toBeCalled()
|
||||
|
||||
// Warning message
|
||||
button.trigger('click')
|
||||
await flushPromises()
|
||||
|
||||
|
|
@ -74,9 +72,9 @@ test('remove texture', async () => {
|
|||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ code: 0 })
|
||||
.mockResolvedValueOnce({ code: 1 })
|
||||
Vue.prototype.$confirm
|
||||
.mockRejectedValueOnce({})
|
||||
.mockResolvedValue('confirm')
|
||||
showModal
|
||||
.mockRejectedValueOnce(null)
|
||||
.mockResolvedValue({ value: '' })
|
||||
|
||||
const wrapper = mount(ClosetItem, { propsData: factory() })
|
||||
const button = wrapper.findAll('.dropdown-item').at(1)
|
||||
|
|
@ -98,9 +96,9 @@ test('set as avatar', async () => {
|
|||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ code: 0 })
|
||||
.mockResolvedValueOnce({ code: 1 })
|
||||
Vue.prototype.$confirm
|
||||
.mockRejectedValueOnce({})
|
||||
.mockResolvedValue('confirm')
|
||||
showModal
|
||||
.mockRejectedValueOnce(null)
|
||||
.mockResolvedValue({ value: '' })
|
||||
|
||||
const wrapper = mount(ClosetItem, { propsData: factory() })
|
||||
const button = wrapper.findAll('.dropdown-item').at(3)
|
||||
|
|
|
|||
|
|
@ -77,6 +77,46 @@ test('prompt mode', () => {
|
|||
expect(wrapper.emitted().confirm[0][0]).toStrictEqual({ value: 'hazuki' })
|
||||
})
|
||||
|
||||
test('input placeholder', () => {
|
||||
const wrapper = mount(Modal, {
|
||||
propsData: {
|
||||
mode: 'prompt',
|
||||
placeholder: 'hibike',
|
||||
},
|
||||
})
|
||||
expect(wrapper.find('input').attributes('placeholder')).toBe('hibike')
|
||||
})
|
||||
|
||||
test('validate input', () => {
|
||||
const stub = jest.fn()
|
||||
.mockReturnValueOnce(false)
|
||||
.mockReturnValueOnce('invalid')
|
||||
|
||||
const wrapper = mount(Modal, {
|
||||
propsData: {
|
||||
mode: 'prompt',
|
||||
validator: stub,
|
||||
},
|
||||
})
|
||||
const button = wrapper.find('.btn-primary')
|
||||
|
||||
button.trigger('click')
|
||||
expect(wrapper.find('.alert').exists()).toBeFalse()
|
||||
|
||||
button.trigger('click')
|
||||
expect(wrapper.find('.alert').text()).toContain('invalid')
|
||||
})
|
||||
|
||||
test('input type', () => {
|
||||
const wrapper = mount(Modal, {
|
||||
propsData: {
|
||||
mode: 'prompt',
|
||||
inputType: 'password',
|
||||
},
|
||||
})
|
||||
expect(wrapper.find('[type=password]').exists()).toBeTrue()
|
||||
})
|
||||
|
||||
test('modal type', () => {
|
||||
const wrapper = mount(Modal, {
|
||||
propsData: {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
import Vue from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import SkinLibItem from '@/components/SkinLibItem.vue'
|
||||
import { MessageBoxData } from 'element-ui/types/message-box'
|
||||
import { flushPromises } from '../utils'
|
||||
import { showModal } from '@/scripts/notify'
|
||||
import SkinLibItem from '@/components/SkinLibItem.vue'
|
||||
|
||||
jest.mock('@/scripts/notify')
|
||||
|
||||
test('urls', () => {
|
||||
const wrapper = mount(SkinLibItem, {
|
||||
|
|
@ -60,7 +62,7 @@ test('liked state', () => {
|
|||
|
||||
test('remove from closet', async () => {
|
||||
Vue.prototype.$http.post.mockResolvedValue({ code: 0 })
|
||||
Vue.prototype.$confirm.mockResolvedValue('confirm')
|
||||
showModal.mockResolvedValue({ value: '' })
|
||||
const wrapper = mount(SkinLibItem, {
|
||||
propsData: {
|
||||
tid: 1, liked: true, anonymous: false,
|
||||
|
|
@ -75,15 +77,9 @@ test('add to closet', async () => {
|
|||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ code: 1, message: '1' })
|
||||
.mockResolvedValue({ code: 0 })
|
||||
Vue.prototype.$prompt
|
||||
.mockImplementationOnce(() => Promise.reject())
|
||||
.mockImplementation((_, { inputValidator }) => {
|
||||
if (inputValidator) {
|
||||
inputValidator('')
|
||||
inputValidator('name')
|
||||
}
|
||||
return Promise.resolve({ value: 'name' } as MessageBoxData)
|
||||
})
|
||||
showModal
|
||||
.mockRejectedValueOnce(null)
|
||||
.mockResolvedValue({ value: 'name' })
|
||||
const wrapper = mount(SkinLibItem, {
|
||||
propsData: {
|
||||
tid: 1, liked: false, anonymous: false,
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ jest.mock('@/scripts/notify')
|
|||
|
||||
test('log out', async () => {
|
||||
showModal
|
||||
.mockRejectedValueOnce({})
|
||||
.mockRejectedValueOnce(null)
|
||||
.mockResolvedValueOnce({ value: '' })
|
||||
post.mockResolvedValue({ message: '' })
|
||||
|
||||
|
|
|
|||
12
resources/assets/tests/scripts/validators.test.ts
Normal file
12
resources/assets/tests/scripts/validators.test.ts
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import * as validators from '@/scripts/validators'
|
||||
|
||||
test('truthy', () => {
|
||||
const validator = validators.truthy('invalid')
|
||||
expect(validator()).toBe('invalid')
|
||||
expect(validator(null)).toBe('invalid')
|
||||
expect(validator(undefined)).toBe('invalid')
|
||||
expect(validator(0)).toBe('invalid')
|
||||
expect(validator('')).toBe('invalid')
|
||||
expect(validator([])).toBeUndefined()
|
||||
expect(validator({})).toBeUndefined()
|
||||
})
|
||||
|
|
@ -74,8 +74,3 @@ Vue.prototype.$message = {
|
|||
warning: jest.fn(),
|
||||
error: jest.fn(),
|
||||
}
|
||||
// @ts-ignore
|
||||
Vue.prototype.$msgbox = jest.fn()
|
||||
Vue.prototype.$alert = jest.fn()
|
||||
Vue.prototype.$confirm = jest.fn()
|
||||
Vue.prototype.$prompt = jest.fn()
|
||||
|
|
|
|||
4
resources/assets/tests/shims.d.ts
vendored
4
resources/assets/tests/shims.d.ts
vendored
|
|
@ -17,10 +17,6 @@ declare module 'vue/types/vue' {
|
|||
warning: jest.Mock<ReturnType<typeof Message>, Parameters<typeof Message>>
|
||||
error: jest.Mock<ReturnType<typeof Message>, Parameters<typeof Message>>
|
||||
}
|
||||
$msgbox: jest.Mock<ReturnType<typeof MessageBox>, [ElMessageBoxOptions]>
|
||||
$alert: jest.Mock<ReturnType<typeof MessageBox>, [string, ElMessageBoxOptions]>
|
||||
$confirm: jest.Mock<ReturnType<typeof MessageBox>, [string, ElMessageBoxOptions]>
|
||||
$prompt: jest.Mock<ReturnType<typeof MessageBox>, [string, ElMessageBoxOptions]>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
import Vue from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import Market from '@/views/admin/Market.vue'
|
||||
import { flushPromises } from '../../utils'
|
||||
import { showModal } from '@/scripts/notify'
|
||||
import Market from '@/views/admin/Market.vue'
|
||||
|
||||
jest.mock('@/scripts/notify')
|
||||
|
||||
test('render dependencies', async () => {
|
||||
Vue.prototype.$http.get.mockResolvedValue([
|
||||
|
|
@ -82,9 +85,9 @@ test('update plugin', async () => {
|
|||
])
|
||||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ code: 1, message: '1' })
|
||||
Vue.prototype.$confirm
|
||||
.mockRejectedValueOnce('')
|
||||
.mockResolvedValue('confirm')
|
||||
showModal
|
||||
.mockRejectedValueOnce(null)
|
||||
.mockResolvedValue({ value: '' })
|
||||
const wrapper = mount(Market)
|
||||
await flushPromises()
|
||||
const button = wrapper.find('button')
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
import Vue from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import { MessageBoxData } from 'element-ui/types/message-box'
|
||||
import { flushPromises } from '../../utils'
|
||||
import { showModal } from '@/scripts/notify'
|
||||
import Modal from '@/components/Modal.vue'
|
||||
import Players from '@/views/admin/Players.vue'
|
||||
|
||||
jest.mock('@/scripts/notify')
|
||||
|
||||
test('fetch data after initializing', () => {
|
||||
Vue.prototype.$http.get.mockResolvedValue({ data: [] })
|
||||
mount(Players)
|
||||
|
|
@ -55,15 +57,9 @@ test('change player name', async () => {
|
|||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ code: 1, message: '1' })
|
||||
.mockResolvedValueOnce({ code: 0, message: '0' })
|
||||
Vue.prototype.$prompt
|
||||
.mockImplementationOnce(() => Promise.reject())
|
||||
.mockImplementation((_, options) => {
|
||||
if (options.inputValidator) {
|
||||
options.inputValidator('')
|
||||
options.inputValidator('new')
|
||||
}
|
||||
return Promise.resolve({ value: 'new' } as MessageBoxData)
|
||||
})
|
||||
showModal
|
||||
.mockRejectedValueOnce(null)
|
||||
.mockResolvedValue({ value: 'new' })
|
||||
const wrapper = mount(Players)
|
||||
await flushPromises()
|
||||
const button = wrapper.find('[data-test="name"]')
|
||||
|
|
@ -91,9 +87,9 @@ test('change owner', async () => {
|
|||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ code: 1, message: '1' })
|
||||
.mockResolvedValueOnce({ code: 0, message: '0' })
|
||||
Vue.prototype.$prompt
|
||||
.mockRejectedValueOnce('')
|
||||
.mockResolvedValue({ value: '3' } as MessageBoxData)
|
||||
showModal
|
||||
.mockRejectedValueOnce(null)
|
||||
.mockResolvedValue({ value: '3' })
|
||||
|
||||
const wrapper = mount(Players)
|
||||
await flushPromises()
|
||||
|
|
@ -106,7 +102,7 @@ test('change owner', async () => {
|
|||
await flushPromises()
|
||||
expect(Vue.prototype.$http.post).toBeCalledWith(
|
||||
'/admin/players?action=owner',
|
||||
{ pid: 1, uid: '3' },
|
||||
{ pid: 1, uid: 3 },
|
||||
)
|
||||
button.trigger('click')
|
||||
await flushPromises()
|
||||
|
|
@ -122,9 +118,9 @@ test('delete player', async () => {
|
|||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ code: 1, message: '1' })
|
||||
.mockResolvedValueOnce({ code: 0, message: '0' })
|
||||
Vue.prototype.$confirm
|
||||
.mockRejectedValueOnce('')
|
||||
.mockResolvedValue('confirm')
|
||||
showModal
|
||||
.mockRejectedValueOnce(null)
|
||||
.mockResolvedValue({ value: '' })
|
||||
|
||||
const wrapper = mount(Players)
|
||||
await flushPromises()
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import Vue from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import Plugins from '@/views/admin/Plugins.vue'
|
||||
import { flushPromises } from '../../utils'
|
||||
import { showModal } from '@/scripts/notify'
|
||||
import Plugins from '@/views/admin/Plugins.vue'
|
||||
|
||||
jest.mock('@/scripts/notify')
|
||||
|
||||
|
|
@ -60,22 +61,27 @@ test('enable plugin', async () => {
|
|||
code: 1, message: '1', data: { reason: ['abc'] },
|
||||
})
|
||||
.mockResolvedValue({ code: 0, message: '0' })
|
||||
Vue.prototype.$confirm
|
||||
.mockRejectedValueOnce('')
|
||||
.mockResolvedValue('confirm')
|
||||
showModal
|
||||
.mockRejectedValueOnce(null)
|
||||
.mockResolvedValue({ value: '' })
|
||||
const wrapper = mount(Plugins)
|
||||
await flushPromises()
|
||||
|
||||
wrapper.findAll('.actions').at(0)
|
||||
wrapper
|
||||
.findAll('.actions')
|
||||
.at(0)
|
||||
.find('a')
|
||||
.trigger('click')
|
||||
await flushPromises()
|
||||
expect(Vue.prototype.$confirm).toBeCalledWith('admin.noDependenciesNotice', {
|
||||
type: 'warning',
|
||||
expect(showModal).toBeCalledWith({
|
||||
text: 'admin.noDependenciesNotice',
|
||||
okButtonType: 'warning',
|
||||
})
|
||||
expect(Vue.prototype.$http.post).not.toBeCalled()
|
||||
|
||||
wrapper.findAll('.actions').at(0)
|
||||
wrapper
|
||||
.findAll('.actions')
|
||||
.at(0)
|
||||
.find('a')
|
||||
.trigger('click')
|
||||
await flushPromises()
|
||||
|
|
@ -83,12 +89,14 @@ test('enable plugin', async () => {
|
|||
'/admin/plugins/manage',
|
||||
{ action: 'enable', name: 'a' },
|
||||
)
|
||||
expect(Vue.prototype.$alert).toBeCalledWith('', ({
|
||||
type: 'warning',
|
||||
message: expect.anything(),
|
||||
}))
|
||||
expect(showModal).toBeCalledWith({
|
||||
mode: 'alert',
|
||||
dangerousHTML: expect.stringContaining('<li>abc</li>'),
|
||||
})
|
||||
|
||||
wrapper.findAll('.actions').at(1)
|
||||
wrapper
|
||||
.findAll('.actions')
|
||||
.at(1)
|
||||
.find('a')
|
||||
.trigger('click')
|
||||
await flushPromises()
|
||||
|
|
@ -123,15 +131,18 @@ test('disable plugin', async () => {
|
|||
test('delete plugin', async () => {
|
||||
Vue.prototype.$http.get.mockResolvedValue([
|
||||
{
|
||||
name: 'a', dependencies: { all: {}, unsatisfied: {} }, enabled: false,
|
||||
name: 'a',
|
||||
title: 'My Plugin',
|
||||
dependencies: { all: {}, unsatisfied: {} },
|
||||
enabled: false,
|
||||
},
|
||||
])
|
||||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ code: 1, message: '1' })
|
||||
.mockResolvedValue({ code: 0, message: '0' })
|
||||
Vue.prototype.$confirm
|
||||
.mockRejectedValueOnce('')
|
||||
.mockResolvedValue('confirm')
|
||||
showModal
|
||||
.mockRejectedValueOnce(null)
|
||||
.mockResolvedValue({ value: '' })
|
||||
const wrapper = mount(Plugins)
|
||||
await flushPromises()
|
||||
const button = wrapper.find('.actions').findAll('a')
|
||||
|
|
@ -139,8 +150,10 @@ test('delete plugin', async () => {
|
|||
|
||||
button.trigger('click')
|
||||
await flushPromises()
|
||||
expect(Vue.prototype.$confirm).toBeCalledWith('admin.confirmDeletion', {
|
||||
type: 'warning',
|
||||
expect(showModal).toBeCalledWith({
|
||||
title: 'My Plugin',
|
||||
text: 'admin.confirmDeletion',
|
||||
okButtonType: 'danger',
|
||||
})
|
||||
expect(Vue.prototype.$http.post).not.toBeCalled()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
import Vue from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import { MessageBoxData } from 'element-ui/types/message-box'
|
||||
import { flushPromises } from '../../utils'
|
||||
import { showModal } from '@/scripts/notify'
|
||||
import Translations from '@/views/admin/Translations.vue'
|
||||
|
||||
jest.mock('@/scripts/notify')
|
||||
|
||||
test('fetch data', async () => {
|
||||
Vue.prototype.$http.get.mockResolvedValue([
|
||||
{
|
||||
|
|
@ -26,10 +28,10 @@ test('modify line', async () => {
|
|||
Vue.prototype.$http.put
|
||||
.mockResolvedValueOnce({ code: 1, message: 'failed' })
|
||||
.mockResolvedValueOnce({ code: 0, message: 'ok' })
|
||||
Vue.prototype.$prompt
|
||||
showModal
|
||||
.mockRejectedValueOnce(null)
|
||||
.mockResolvedValueOnce({ value: '' } as MessageBoxData)
|
||||
.mockResolvedValueOnce({ value: 'wanshengwei' } as MessageBoxData)
|
||||
.mockResolvedValueOnce({ value: '' })
|
||||
.mockResolvedValueOnce({ value: 'wanshengwei' })
|
||||
|
||||
const wrapper = mount(Translations)
|
||||
await flushPromises()
|
||||
|
|
@ -65,9 +67,9 @@ test('delete line', async () => {
|
|||
},
|
||||
])
|
||||
Vue.prototype.$http.del.mockResolvedValueOnce({ message: 'ok' })
|
||||
Vue.prototype.$confirm
|
||||
showModal
|
||||
.mockRejectedValueOnce(null)
|
||||
.mockResolvedValueOnce('confirm')
|
||||
.mockResolvedValueOnce({ value: '' })
|
||||
|
||||
const wrapper = mount(Translations)
|
||||
await flushPromises()
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
import Vue from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import { flushPromises } from '../../utils'
|
||||
import { showModal } from '@/scripts/notify'
|
||||
import Update from '@/views/admin/Update.vue'
|
||||
|
||||
jest.mock('@/scripts/notify')
|
||||
|
||||
afterEach(() => {
|
||||
window.blessing.extra = { canUpdate: true }
|
||||
})
|
||||
|
|
@ -24,12 +27,16 @@ test('perform update', async () => {
|
|||
|
||||
button.trigger('click')
|
||||
await flushPromises()
|
||||
expect(Vue.prototype.$alert).toBeCalledWith('fail', { type: 'error' })
|
||||
expect(showModal).toBeCalledWith({
|
||||
mode: 'alert',
|
||||
text: 'fail',
|
||||
type: 'danger',
|
||||
okButtonType: 'outline-light',
|
||||
})
|
||||
|
||||
button.trigger('click')
|
||||
jest.runOnlyPendingTimers()
|
||||
await flushPromises()
|
||||
expect($).toBeCalled()
|
||||
expect(Vue.prototype.$http.get).toBeCalledWith(
|
||||
'/admin/update/download',
|
||||
{ action: 'progress' },
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
import Vue from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import Users from '@/views/admin/Users.vue'
|
||||
import '@/scripts/i18n'
|
||||
import { MessageBoxData } from 'element-ui/types/message-box'
|
||||
import { flushPromises } from '../../utils'
|
||||
import '@/scripts/i18n'
|
||||
import Modal from '@/components/Modal.vue'
|
||||
import { showModal } from '@/scripts/notify'
|
||||
import Users from '@/views/admin/Users.vue'
|
||||
|
||||
jest.mock('@/scripts/i18n', () => ({
|
||||
trans: (key: string) => key,
|
||||
}))
|
||||
jest.mock('@/scripts/notify')
|
||||
|
||||
test('fetch data after initializing', () => {
|
||||
Vue.prototype.$http.get.mockResolvedValue({ data: [] })
|
||||
|
|
@ -236,15 +238,9 @@ test('change email', async () => {
|
|||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ code: 1, message: '1' })
|
||||
.mockResolvedValueOnce({ code: 0, message: '0' })
|
||||
Vue.prototype.$prompt
|
||||
.mockImplementationOnce(() => Promise.reject())
|
||||
.mockImplementation((_, options) => {
|
||||
if (options.inputValidator) {
|
||||
options.inputValidator('')
|
||||
options.inputValidator('value')
|
||||
}
|
||||
return Promise.resolve({ value: 'd@e.f' } as MessageBoxData)
|
||||
})
|
||||
showModal
|
||||
.mockRejectedValueOnce(null)
|
||||
.mockResolvedValue({ value: 'd@e.f' })
|
||||
const wrapper = mount(Users)
|
||||
await flushPromises()
|
||||
const button = wrapper.find('[data-test="email"]')
|
||||
|
|
@ -299,15 +295,9 @@ test('change nickname', async () => {
|
|||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ code: 1, message: '1' })
|
||||
.mockResolvedValueOnce({ code: 0, message: '0' })
|
||||
Vue.prototype.$prompt
|
||||
.mockImplementationOnce(() => Promise.reject())
|
||||
.mockImplementation((_, options) => {
|
||||
if (options.inputValidator) {
|
||||
options.inputValidator('')
|
||||
options.inputValidator('value')
|
||||
}
|
||||
return Promise.resolve({ value: 'new' } as MessageBoxData)
|
||||
})
|
||||
showModal
|
||||
.mockRejectedValueOnce(null)
|
||||
.mockResolvedValue({ value: 'new' })
|
||||
const wrapper = mount(Users)
|
||||
await flushPromises()
|
||||
const button = wrapper.find('[data-test="nickname"]')
|
||||
|
|
@ -337,9 +327,9 @@ test('change password', async () => {
|
|||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ code: 0, message: '0' })
|
||||
.mockResolvedValueOnce({ code: 1, message: '1' })
|
||||
Vue.prototype.$prompt
|
||||
.mockRejectedValueOnce('')
|
||||
.mockResolvedValue({ value: 'password' }as MessageBoxData)
|
||||
showModal
|
||||
.mockRejectedValueOnce(null)
|
||||
.mockResolvedValue({ value: 'password' })
|
||||
|
||||
const wrapper = mount(Users)
|
||||
await flushPromises()
|
||||
|
|
@ -372,9 +362,9 @@ test('change score', async () => {
|
|||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ code: 1, message: '1' })
|
||||
.mockResolvedValueOnce({ code: 0, message: '0' })
|
||||
Vue.prototype.$prompt
|
||||
.mockRejectedValueOnce('')
|
||||
.mockResolvedValue({ value: '45' }as MessageBoxData)
|
||||
showModal
|
||||
.mockRejectedValueOnce(null)
|
||||
.mockResolvedValue({ value: '45' })
|
||||
|
||||
const wrapper = mount(Users)
|
||||
await flushPromises()
|
||||
|
|
@ -397,70 +387,48 @@ test('change score', async () => {
|
|||
})
|
||||
|
||||
test('change permission', async () => {
|
||||
Vue.prototype.$http.get
|
||||
.mockResolvedValueOnce({
|
||||
data: [
|
||||
{
|
||||
uid: 1, permission: 0, operations: 2,
|
||||
},
|
||||
],
|
||||
})
|
||||
.mockResolvedValueOnce({
|
||||
data: [
|
||||
{
|
||||
uid: 1, permission: 0, operations: 1,
|
||||
},
|
||||
],
|
||||
})
|
||||
Vue.prototype.$http.get.mockResolvedValue({
|
||||
data: [
|
||||
{
|
||||
uid: 1, permission: 0, operations: 2,
|
||||
},
|
||||
{
|
||||
uid: 2, permission: 0, operations: 1,
|
||||
},
|
||||
],
|
||||
})
|
||||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ code: 1, message: '1' })
|
||||
.mockResolvedValue({ code: 0, message: '0' })
|
||||
Vue.prototype.$msgbox
|
||||
.mockImplementationOnce(() => Promise.reject())
|
||||
.mockImplementationOnce(options => {
|
||||
if (options.message) {
|
||||
const vnode = options.message as Vue.VNode
|
||||
const elm = document.createElement('select')
|
||||
elm.appendChild(document.createElement('option'))
|
||||
elm.appendChild(document.createElement('option'))
|
||||
elm.appendChild(document.createElement('option'))
|
||||
elm.selectedIndex = 2
|
||||
;(vnode.children as Vue.VNode[])[1].elm = elm
|
||||
}
|
||||
return Promise.resolve({} as MessageBoxData)
|
||||
})
|
||||
.mockImplementation(options => {
|
||||
if (options.message) {
|
||||
const vnode = options.message as Vue.VNode
|
||||
const elm = document.createElement('select')
|
||||
elm.appendChild(document.createElement('option'))
|
||||
elm.appendChild(document.createElement('option'))
|
||||
elm.selectedIndex = 0
|
||||
;(vnode.children as Vue.VNode[])[1].elm = elm
|
||||
}
|
||||
return Promise.resolve({} as MessageBoxData)
|
||||
})
|
||||
|
||||
let wrapper = mount(Users)
|
||||
const wrapper = mount(Users)
|
||||
await flushPromises()
|
||||
let button = wrapper.find('[data-test=permission]')
|
||||
|
||||
button.trigger('click')
|
||||
expect(Vue.prototype.$http.post).not.toBeCalled()
|
||||
wrapper
|
||||
.findAll('[data-test=permission]')
|
||||
.at(0)
|
||||
.trigger('click')
|
||||
expect(wrapper.findAll('[type=radio]')).toHaveLength(3)
|
||||
|
||||
wrapper
|
||||
.findAll('[data-test=permission]')
|
||||
.at(1)
|
||||
.trigger('click')
|
||||
expect(wrapper.findAll('[type=radio]')).toHaveLength(2)
|
||||
|
||||
const button = wrapper.findAll('[data-test=permission]').at(1)
|
||||
button.trigger('click')
|
||||
wrapper.find('[type=radio]:nth-child(1)').setChecked()
|
||||
wrapper.find(Modal).vm.$emit('confirm')
|
||||
await flushPromises()
|
||||
expect(Vue.prototype.$http.post).toBeCalledWith(
|
||||
'/admin/users?action=permission',
|
||||
{ uid: 1, permission: 1 },
|
||||
{ uid: 2, permission: -1 },
|
||||
)
|
||||
expect(wrapper.text()).toContain('admin.normal')
|
||||
|
||||
wrapper = mount(Users)
|
||||
await flushPromises()
|
||||
button = wrapper.find('[data-test=permission]')
|
||||
|
||||
button.trigger('click')
|
||||
wrapper.find('[type=radio]:nth-child(1)').setChecked()
|
||||
wrapper.find(Modal).vm.$emit('confirm')
|
||||
await flushPromises()
|
||||
expect(wrapper.text()).toContain('admin.banned')
|
||||
})
|
||||
|
|
@ -474,9 +442,9 @@ test('delete user', async () => {
|
|||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ code: 1, message: '1' })
|
||||
.mockResolvedValue({ code: 0, message: '0' })
|
||||
Vue.prototype.$confirm
|
||||
.mockRejectedValueOnce('')
|
||||
.mockResolvedValue('confirm')
|
||||
showModal
|
||||
.mockRejectedValueOnce(null)
|
||||
.mockResolvedValue({ value: '' })
|
||||
|
||||
const wrapper = mount(Users)
|
||||
await flushPromises()
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
import Vue from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import { flushPromises } from '../../utils'
|
||||
import { showModal } from '@/scripts/notify'
|
||||
import Login from '@/views/auth/Login.vue'
|
||||
|
||||
jest.mock('@/scripts/notify')
|
||||
|
||||
const Captcha = Vue.extend({
|
||||
methods: {
|
||||
execute() {
|
||||
|
|
@ -47,7 +50,10 @@ test('login', async () => {
|
|||
|
||||
form.trigger('submit')
|
||||
await flushPromises()
|
||||
expect(Vue.prototype.$alert).toBeCalledWith('auth.tooManyFails.captcha', { type: 'error' })
|
||||
expect(showModal).toBeCalledWith({
|
||||
mode: 'alert',
|
||||
text: 'auth.tooManyFails.captcha',
|
||||
})
|
||||
expect(wrapper.find('img').exists()).toBeTrue()
|
||||
|
||||
wrapper.setData({
|
||||
|
|
@ -61,7 +67,10 @@ test('login', async () => {
|
|||
})
|
||||
form.trigger('submit')
|
||||
await flushPromises()
|
||||
expect(Vue.prototype.$alert).toBeCalledWith('auth.tooManyFails.recaptcha', { type: 'error' })
|
||||
expect(showModal).toBeCalledWith({
|
||||
mode: 'alert',
|
||||
text: 'auth.tooManyFails.recaptcha',
|
||||
})
|
||||
|
||||
wrapper.find('[type="checkbox"]').setChecked()
|
||||
form.trigger('submit')
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
import Vue from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import Show from '@/views/skinlib/Show.vue'
|
||||
import { MessageBoxData } from 'element-ui/types/message-box'
|
||||
import { flushPromises } from '../../utils'
|
||||
import { showModal } from '@/scripts/notify'
|
||||
import Show from '@/views/skinlib/Show.vue'
|
||||
|
||||
jest.mock('@/scripts/notify')
|
||||
|
||||
type Component = Vue & {
|
||||
liked: boolean
|
||||
|
|
@ -191,7 +193,7 @@ test('set as avatar', async () => {
|
|||
})
|
||||
await flushPromises()
|
||||
wrapper.find('[data-test="setAsAvatar"]').trigger('click')
|
||||
expect(Vue.prototype.$confirm).toBeCalled()
|
||||
expect(showModal).toBeCalled()
|
||||
})
|
||||
|
||||
test('hide "set avatar" button when texture is cape', async () => {
|
||||
|
|
@ -210,7 +212,7 @@ test('add to closet', async () => {
|
|||
Object.assign(window.blessing.extra, { currentUid: 1, inCloset: false })
|
||||
Vue.prototype.$http.get.mockResolvedValue({ data: { name: 'wow', likes: 2 } })
|
||||
Vue.prototype.$http.post.mockResolvedValue({ code: 0, message: '' })
|
||||
Vue.prototype.$prompt.mockResolvedValue({ value: 'a' } as MessageBoxData)
|
||||
showModal.mockResolvedValue({ value: 'a' })
|
||||
const wrapper = mount<Component>(Show, {
|
||||
mocks: {
|
||||
$route: ['/skinlib/show/1', '1'],
|
||||
|
|
@ -245,15 +247,9 @@ test('change texture name', async () => {
|
|||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ code: 1, message: '1' })
|
||||
.mockResolvedValue({ code: 0, message: '0' })
|
||||
Vue.prototype.$prompt
|
||||
.mockImplementationOnce(() => Promise.reject('cancel'))
|
||||
.mockImplementation((_, { inputValidator }) => {
|
||||
if (inputValidator) {
|
||||
inputValidator('')
|
||||
inputValidator('new-name')
|
||||
}
|
||||
return Promise.resolve({ value: 'new-name' } as MessageBoxData)
|
||||
})
|
||||
showModal
|
||||
.mockRejectedValueOnce(null)
|
||||
.mockResolvedValue({ value: 'new-name' })
|
||||
const wrapper = mount<Component>(Show, {
|
||||
mocks: {
|
||||
$route: ['/skinlib/show/1', '1'],
|
||||
|
|
@ -283,34 +279,24 @@ test('change texture model', async () => {
|
|||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ code: 1, message: '1' })
|
||||
.mockResolvedValue({ code: 0, message: '0' })
|
||||
Vue.prototype.$msgbox
|
||||
.mockImplementationOnce(() => Promise.reject())
|
||||
.mockImplementation(options => {
|
||||
if (options.message) {
|
||||
const vnode = options.message as Vue.VNode
|
||||
const elm = document.createElement('select')
|
||||
elm.appendChild(document.createElement('option'))
|
||||
elm.appendChild(document.createElement('option'))
|
||||
elm.selectedIndex = 1
|
||||
;(vnode.children as Vue.VNode[])[1].elm = elm
|
||||
}
|
||||
return Promise.resolve({} as MessageBoxData)
|
||||
})
|
||||
const wrapper = mount<Component>(Show, {
|
||||
mocks: {
|
||||
$route: ['/skinlib/show/1', '1'],
|
||||
},
|
||||
stubs: { previewer },
|
||||
})
|
||||
const modal = wrapper.find('#modal-type')
|
||||
const button = wrapper
|
||||
.findAll('small')
|
||||
.at(1)
|
||||
.find('a')
|
||||
|
||||
button.trigger('click')
|
||||
expect(Vue.prototype.$http.post).not.toBeCalled()
|
||||
|
||||
button.trigger('click')
|
||||
wrapper
|
||||
.findAll('[type=radio]')
|
||||
.at(1)
|
||||
.setChecked()
|
||||
modal.vm.$emit('confirm')
|
||||
await flushPromises()
|
||||
expect(Vue.prototype.$http.post).toBeCalledWith(
|
||||
'/skinlib/model',
|
||||
|
|
@ -319,6 +305,11 @@ test('change texture model', async () => {
|
|||
expect(Vue.prototype.$message.warning).toBeCalledWith('1')
|
||||
|
||||
button.trigger('click')
|
||||
wrapper
|
||||
.findAll('[type=radio]')
|
||||
.at(1)
|
||||
.setChecked()
|
||||
modal.vm.$emit('confirm')
|
||||
await flushPromises()
|
||||
expect(wrapper.vm.type).toBe('alex')
|
||||
})
|
||||
|
|
@ -328,9 +319,9 @@ test('toggle privacy', async () => {
|
|||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ code: 1, message: '1' })
|
||||
.mockResolvedValue({ code: 0, message: '0' })
|
||||
Vue.prototype.$confirm
|
||||
.mockRejectedValueOnce('')
|
||||
.mockResolvedValue('confirm')
|
||||
showModal
|
||||
.mockRejectedValueOnce(null)
|
||||
.mockResolvedValue({ value: '' })
|
||||
const wrapper = mount<Component>(Show, {
|
||||
mocks: {
|
||||
$route: ['/skinlib/show/1', '1'],
|
||||
|
|
@ -364,9 +355,9 @@ test('delete texture', async () => {
|
|||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ code: 1, message: '1' })
|
||||
.mockResolvedValue({ code: 0, message: '0' })
|
||||
Vue.prototype.$confirm
|
||||
.mockRejectedValueOnce('')
|
||||
.mockResolvedValue('confirm')
|
||||
showModal
|
||||
.mockRejectedValueOnce(null)
|
||||
.mockResolvedValue({ value: '' })
|
||||
const wrapper = mount(Show, {
|
||||
mocks: {
|
||||
$route: ['/skinlib/show/1', '1'],
|
||||
|
|
@ -397,10 +388,10 @@ test('report texture', async () => {
|
|||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ code: 1, message: 'duplicated' })
|
||||
.mockResolvedValue({ code: 0, message: 'success' })
|
||||
Vue.prototype.$prompt
|
||||
.mockRejectedValueOnce('')
|
||||
.mockRejectedValueOnce('')
|
||||
.mockResolvedValue({ value: 'reason' } as MessageBoxData)
|
||||
showModal
|
||||
.mockRejectedValueOnce(null)
|
||||
.mockRejectedValueOnce(null)
|
||||
.mockResolvedValue({ value: 'reason' })
|
||||
const wrapper = mount(Show, {
|
||||
mocks: {
|
||||
$route: ['/skinlib/show/1', '1'],
|
||||
|
|
@ -410,24 +401,30 @@ test('report texture', async () => {
|
|||
|
||||
const button = wrapper.find('[data-test=report]')
|
||||
button.trigger('click')
|
||||
expect(Vue.prototype.$prompt).toBeCalledWith('', {
|
||||
expect(showModal).toBeCalledWith({
|
||||
mode: 'prompt',
|
||||
title: 'skinlib.report.title',
|
||||
inputPlaceholder: 'skinlib.report.reason',
|
||||
text: '',
|
||||
placeholder: 'skinlib.report.reason',
|
||||
})
|
||||
expect(Vue.prototype.$http.post).not.toBeCalled()
|
||||
|
||||
wrapper.setData({ reportScore: -5 })
|
||||
button.trigger('click')
|
||||
expect(Vue.prototype.$prompt).toBeCalledWith('skinlib.report.negative', {
|
||||
expect(showModal).toBeCalledWith({
|
||||
mode: 'prompt',
|
||||
title: 'skinlib.report.title',
|
||||
inputPlaceholder: 'skinlib.report.reason',
|
||||
text: 'skinlib.report.negative',
|
||||
placeholder: 'skinlib.report.reason',
|
||||
})
|
||||
|
||||
wrapper.setData({ reportScore: 5 })
|
||||
button.trigger('click')
|
||||
expect(Vue.prototype.$prompt).toBeCalledWith('skinlib.report.positive', {
|
||||
expect(showModal).toBeCalledWith({
|
||||
mode: 'prompt',
|
||||
title: 'skinlib.report.title',
|
||||
inputPlaceholder: 'skinlib.report.reason',
|
||||
text: 'skinlib.report.positive',
|
||||
placeholder: 'skinlib.report.reason',
|
||||
})
|
||||
await flushPromises()
|
||||
expect(Vue.prototype.$http.post).toBeCalledWith(
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
import Vue from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import { flushPromises } from '../../utils'
|
||||
import { showModal } from '@/scripts/notify'
|
||||
import Bind from '@/views/user/Bind.vue'
|
||||
|
||||
jest.mock('@/scripts/notify')
|
||||
|
||||
test('list existed players', async () => {
|
||||
Vue.prototype.$http.get
|
||||
.mockResolvedValue({ data: [{ name: 'a' }, { name: 'b' }] })
|
||||
|
|
@ -36,5 +39,5 @@ test('submit', async () => {
|
|||
|
||||
form.trigger('submit')
|
||||
await flushPromises()
|
||||
expect(Vue.prototype.$alert).toBeCalledWith('ok')
|
||||
expect(showModal).toBeCalledWith({ mode: 'alert', text: 'ok' })
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
import Vue from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import { MessageBoxData } from 'element-ui/types/message-box'
|
||||
import { flushPromises } from '../../utils'
|
||||
import { walkFetch } from '@/scripts/net'
|
||||
import { showModal } from '@/scripts/notify'
|
||||
import Modal from '@/components/Modal.vue'
|
||||
import OAuth from '@/views/user/OAuth.vue'
|
||||
|
||||
jest.mock('@/scripts/notify')
|
||||
|
||||
jest.mock('@/scripts/net', () => ({
|
||||
walkFetch: jest.fn(),
|
||||
init: {},
|
||||
|
|
@ -55,9 +57,9 @@ test('modify name', async () => {
|
|||
walkFetch
|
||||
.mockResolvedValueOnce({ message: 'fail' })
|
||||
.mockResolvedValueOnce({ id: 1, name: 'new-name' })
|
||||
Vue.prototype.$prompt
|
||||
.mockRejectedValueOnce('')
|
||||
.mockResolvedValue({ value: 'new-name' } as MessageBoxData)
|
||||
showModal
|
||||
.mockRejectedValueOnce(null)
|
||||
.mockResolvedValue({ value: 'new-name' })
|
||||
const wrapper = mount(OAuth)
|
||||
await flushPromises()
|
||||
const button = wrapper.find('[data-test=name]')
|
||||
|
|
@ -89,9 +91,9 @@ test('modify redirect', async () => {
|
|||
walkFetch
|
||||
.mockResolvedValueOnce({ message: 'fail' })
|
||||
.mockResolvedValueOnce({ id: 1, redirect: 'https://example.net/' })
|
||||
Vue.prototype.$prompt
|
||||
.mockRejectedValueOnce('')
|
||||
.mockResolvedValue({ value: 'https://example.net/' } as MessageBoxData)
|
||||
showModal
|
||||
.mockRejectedValueOnce(null)
|
||||
.mockResolvedValue({ value: 'https://example.net/' })
|
||||
const wrapper = mount(OAuth)
|
||||
await flushPromises()
|
||||
const button = wrapper.find('[data-test=callback]')
|
||||
|
|
@ -120,9 +122,9 @@ test('remove app', async () => {
|
|||
Vue.prototype.$http.get.mockResolvedValue([
|
||||
{ id: 1, name: 'name' },
|
||||
])
|
||||
Vue.prototype.$confirm
|
||||
.mockRejectedValueOnce('cancel')
|
||||
.mockResolvedValue('confirm')
|
||||
showModal
|
||||
.mockRejectedValueOnce(null)
|
||||
.mockResolvedValue({ value: '' })
|
||||
|
||||
const wrapper = mount(OAuth)
|
||||
await flushPromises()
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
import Vue from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import { MessageBoxData } from 'element-ui/types/message-box'
|
||||
import { flushPromises } from '../../utils'
|
||||
import { showModal } from '@/scripts/notify'
|
||||
import Players from '@/views/user/Players.vue'
|
||||
|
||||
jest.mock('@/scripts/notify')
|
||||
|
||||
window.blessing.extra = {
|
||||
rule: 'rule',
|
||||
length: 'length',
|
||||
|
|
@ -90,14 +92,9 @@ test('change player name', async () => {
|
|||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ code: 1 })
|
||||
.mockResolvedValue({ code: 0 })
|
||||
Vue.prototype.$prompt.mockImplementationOnce(() => Promise.reject('cancel'))
|
||||
.mockImplementation((_, { inputValidator }) => {
|
||||
if (inputValidator) {
|
||||
inputValidator('')
|
||||
inputValidator('new-name')
|
||||
}
|
||||
return Promise.resolve({ value: 'new-name' } as MessageBoxData)
|
||||
})
|
||||
showModal
|
||||
.mockRejectedValueOnce(null)
|
||||
.mockResolvedValue({ value: 'new-name' })
|
||||
const wrapper = mount(Players)
|
||||
await flushPromises()
|
||||
const button = wrapper.find('.btn-default')
|
||||
|
|
@ -126,9 +123,9 @@ test('delete player', async () => {
|
|||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ code: 1 })
|
||||
.mockResolvedValue({ code: 0 })
|
||||
Vue.prototype.$confirm
|
||||
.mockRejectedValueOnce({})
|
||||
.mockResolvedValue('confirm')
|
||||
showModal
|
||||
.mockRejectedValueOnce(null)
|
||||
.mockResolvedValue({ value: '' })
|
||||
const wrapper = mount(Players)
|
||||
await flushPromises()
|
||||
const button = wrapper.findAll('.btn-danger')
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
import Vue from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import { flushPromises } from '../../utils'
|
||||
import { showModal } from '@/scripts/notify'
|
||||
import Profile from '@/views/user/Profile.vue'
|
||||
|
||||
jest.mock('@/scripts/notify')
|
||||
|
||||
window.blessing.extra = { unverified: false }
|
||||
|
||||
test('computed values', () => {
|
||||
|
|
@ -20,9 +23,9 @@ test('convert linebreak', () => {
|
|||
})
|
||||
|
||||
test('reset avatar', async () => {
|
||||
Vue.prototype.$confirm
|
||||
.mockRejectedValueOnce('close')
|
||||
.mockResolvedValue('confirm')
|
||||
showModal
|
||||
.mockRejectedValueOnce(null)
|
||||
.mockResolvedValue({ value: '' })
|
||||
Vue.prototype.$http.post.mockResolvedValue({ message: 'ok' })
|
||||
const wrapper = mount(Profile)
|
||||
const button = wrapper.find('[data-test=resetAvatar]')
|
||||
|
|
@ -63,29 +66,22 @@ test('change password', async () => {
|
|||
'/user/profile?action=password',
|
||||
{ current_password: '1', new_password: '1' },
|
||||
)
|
||||
expect(Vue.prototype.$alert).toBeCalledWith('w', { type: 'warning' })
|
||||
expect(showModal).toBeCalledWith({ mode: 'alert', text: 'w' })
|
||||
|
||||
form.trigger('submit')
|
||||
await flushPromises()
|
||||
expect(Vue.prototype.$alert).toBeCalledWith('o')
|
||||
expect(showModal).toBeCalledWith({ mode: 'alert', text: 'o' })
|
||||
})
|
||||
|
||||
test('change nickname', async () => {
|
||||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ code: 1, message: 'w' })
|
||||
.mockResolvedValue({ code: 0, message: 'o' })
|
||||
Vue.prototype.$confirm
|
||||
.mockRejectedValueOnce('close')
|
||||
.mockResolvedValue('confirm')
|
||||
const wrapper = mount(Profile)
|
||||
const form = wrapper.find('[data-test=changeNickName]')
|
||||
document.body.innerHTML += '<span class="nickname"></span>'
|
||||
document.body.innerHTML += '<span data-mark="nickname"></span>'
|
||||
|
||||
wrapper.setData({ nickname: 'nickname' })
|
||||
form.trigger('submit')
|
||||
expect(Vue.prototype.$http.post).not.toBeCalled()
|
||||
expect(Vue.prototype.$confirm).toBeCalledWith('user.changeNickName')
|
||||
|
||||
form.trigger('submit')
|
||||
await flushPromises()
|
||||
expect(Vue.prototype.$http.post).toBeCalledWith(
|
||||
|
|
@ -93,29 +89,22 @@ test('change nickname', async () => {
|
|||
{ new_nickname: 'nickname' },
|
||||
)
|
||||
await flushPromises()
|
||||
expect(Vue.prototype.$alert).toBeCalledWith('w', { type: 'warning' })
|
||||
expect(showModal).toBeCalledWith({ mode: 'alert', text: 'w' })
|
||||
|
||||
form.trigger('submit')
|
||||
await flushPromises()
|
||||
expect(Vue.prototype.$message.success).toBeCalledWith('o')
|
||||
expect(document.querySelector('.nickname')!.textContent).toBe('nickname')
|
||||
expect(document.querySelector('span')!.textContent).toBe('nickname')
|
||||
})
|
||||
|
||||
test('change email', async () => {
|
||||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ code: 1, message: 'w' })
|
||||
.mockResolvedValue({ code: 0, message: 'o' })
|
||||
Vue.prototype.$confirm
|
||||
.mockRejectedValueOnce('close')
|
||||
.mockResolvedValue('confirm')
|
||||
const wrapper = mount(Profile)
|
||||
const form = wrapper.find('[data-test=changeEmail]')
|
||||
|
||||
wrapper.setData({ email: 'a@b.c', currentPassword: 'abc' })
|
||||
form.trigger('submit')
|
||||
expect(Vue.prototype.$confirm).toBeCalledWith('user.changeEmail')
|
||||
expect(Vue.prototype.$http.post).not.toBeCalled()
|
||||
|
||||
form.trigger('submit')
|
||||
await flushPromises()
|
||||
expect(Vue.prototype.$http.post).toBeCalledWith(
|
||||
|
|
@ -123,7 +112,7 @@ test('change email', async () => {
|
|||
{ new_email: 'a@b.c', password: 'abc' },
|
||||
)
|
||||
await flushPromises()
|
||||
expect(Vue.prototype.$alert).toBeCalledWith('w', { type: 'warning' })
|
||||
expect(showModal).toBeCalledWith({ mode: 'alert', text: 'w' })
|
||||
|
||||
form.trigger('submit')
|
||||
await flushPromises()
|
||||
|
|
@ -145,9 +134,9 @@ test('delete account', async () => {
|
|||
{ password: 'abc' },
|
||||
)
|
||||
await flushPromises()
|
||||
expect(Vue.prototype.$alert).toBeCalledWith('w', { type: 'warning' })
|
||||
expect(showModal).toBeCalledWith({ mode: 'alert', text: 'w' })
|
||||
|
||||
form.trigger('submit')
|
||||
await flushPromises()
|
||||
expect(Vue.prototype.$alert).toBeCalledWith('o', { type: 'success' })
|
||||
expect(showModal).toBeCalledWith({ mode: 'alert', text: 'w' })
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
<li class="nav-item dropdown user-menu">
|
||||
<a href="#" class="nav-link" data-toggle="dropdown">
|
||||
<img src="{{ avatar }}" class="user-image img-circle elevation-2" alt="User Image">
|
||||
<span class="d-none d-md-inline d-sm-block">{{ user.nickname ?? user.email }}</span>
|
||||
<span class="d-none d-md-inline d-sm-block" data-mark="nickname">
|
||||
{{ user.nickname ?? user.email }}
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<div class="dropdown-menu dropdown-menu-lg dropdown-menu-right">
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<img src="{{ avatar }}" class="img-circle elevation-2" alt="User Image">
|
||||
</div>
|
||||
<div class="info">
|
||||
<a class="d-block">{{ user.nickname ?? user.email }}</a>
|
||||
<a class="d-block" data-mark="nickname">{{ user.nickname ?? user.email }}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user