Reuse common code

This commit is contained in:
Pig Fang 2019-03-17 15:26:12 +08:00
parent 70f5d059f0
commit 9633625e3d
7 changed files with 96 additions and 179 deletions

View File

@ -0,0 +1,31 @@
import toastr from 'toastr'
import { swal } from '../../js/notify'
export default {
methods: {
async addClosetItem() {
const { dismiss, value } = await swal({
title: this.$t('skinlib.setItemName'),
text: this.$t('skinlib.applyNotice'),
inputValue: this.name,
input: 'text',
showCancelButton: true,
inputValidator: val => !val && this.$t('skinlib.emptyItemName'),
})
if (dismiss) {
return
}
const { errno, msg } = await this.$http.post(
'/user/closet/add',
{ tid: this.tid, name: value }
)
if (errno === 0) {
swal({ type: 'success', text: msg })
this.$emit('like-toggled', true)
} else {
toastr.warning(msg)
}
},
},
}

View File

@ -0,0 +1,28 @@
import toastr from 'toastr'
import { swal } from '../../js/notify'
export default {
methods: {
async removeClosetItem() {
const { dismiss } = await swal({
text: this.$t('user.removeFromClosetNotice'),
type: 'warning',
showCancelButton: true,
})
if (dismiss) {
return
}
const { errno, msg } = await this.$http.post(
'/user/closet/remove',
{ tid: this.tid }
)
if (errno === 0) {
this.$emit('item-removed')
swal({ type: 'success', text: msg })
} else {
toastr.warning(msg)
}
},
},
}

View File

@ -142,13 +142,19 @@
import toastr from 'toastr'
import { swal } from '../../js/notify'
import setAsAvatar from '../mixins/setAsAvatar'
import addClosetItem from '../mixins/addClosetItem'
import removeClosetItem from '../mixins/removeClosetItem'
export default {
name: 'Show',
components: {
Previewer: () => import('../common/Previewer'),
},
mixins: [setAsAvatar],
mixins: [
addClosetItem,
removeClosetItem,
setAsAvatar,
],
props: {
baseUrl: {
type: String,
@ -200,53 +206,18 @@ export default {
this.public = !!data.public
},
async addToCloset() {
const { dismiss, value } = await swal({
title: this.$t('skinlib.setItemName'),
text: this.$t('skinlib.applyNotice'),
inputValue: this.name,
input: 'text',
showCancelButton: true,
inputValidator: val => !val && this.$t('skinlib.emptyItemName'),
})
if (dismiss) {
return
}
const { errno, msg } = await this.$http.post(
'/user/closet/add',
{ tid: this.tid, name: value }
)
if (errno === 0) {
this.$once('like-toggled', () => {
this.liked = true
this.likes += 1
swal({ type: 'success', text: msg })
} else {
toastr.warning(msg)
}
})
await this.addClosetItem()
},
async removeFromCloset() {
const { dismiss } = await swal({
text: this.$t('user.removeFromClosetNotice'),
type: 'warning',
showCancelButton: true,
cancelButtonColor: '#3085d6',
confirmButtonColor: '#d33',
})
if (dismiss) {
return
}
const { errno, msg } = await this.$http.post(
'/user/closet/remove',
{ tid: this.tid }
)
if (errno === 0) {
this.$once('item-removed', () => {
this.liked = false
this.likes -= 1
swal({ type: 'success', text: msg })
} else {
toastr.warning(msg)
}
})
await this.removeClosetItem()
},
async changeTextureName() {
const { dismiss, value } = await swal({

View File

@ -32,11 +32,15 @@
</template>
<script>
import toastr from 'toastr'
import { swal } from '../../js/notify'
import addClosetItem from '../mixins/addClosetItem'
import removeClosetItem from '../mixins/removeClosetItem'
export default {
name: 'SkinLibItem',
mixins: [
addClosetItem,
removeClosetItem,
],
props: {
tid: Number,
name: String,
@ -74,55 +78,12 @@ export default {
if (this.liked) {
this.removeFromCloset()
} else {
this.addToCloset()
}
},
async addToCloset() {
const { dismiss, value } = await swal({
title: this.$t('skinlib.setItemName'),
text: this.$t('skinlib.applyNotice'),
inputValue: this.name,
input: 'text',
showCancelButton: true,
inputValidator: val => !val && this.$t('skinlib.emptyItemName'),
})
if (dismiss) {
return
}
const { errno, msg } = await this.$http.post(
'/user/closet/add',
{ tid: this.tid, name: value }
)
if (errno === 0) {
swal({ type: 'success', text: msg })
this.$emit('like-toggled', true)
} else {
toastr.warning(msg)
this.addClosetItem()
}
},
async removeFromCloset() {
const { dismiss } = await swal({
text: this.$t('user.removeFromClosetNotice'),
type: 'warning',
showCancelButton: true,
cancelButtonColor: '#3085d6',
confirmButtonColor: '#d33',
})
if (dismiss) {
return
}
const { errno, msg } = await this.$http.post(
'/user/closet/remove',
{ tid: this.tid }
)
if (errno === 0) {
this.$emit('like-toggled', false)
swal({ type: 'success', text: msg })
} else {
toastr.warning(msg)
}
this.$once('item-removed', () => this.$emit('like-toggled', false))
await this.removeClosetItem()
},
},
}

View File

@ -25,7 +25,7 @@
<ul class="dropup dropdown-menu" aria-labelledby="more-button">
<li><a v-t="'user.renameItem'" @click="rename" /></li>
<li><a v-t="'user.removeItem'" @click="remove" /></li>
<li><a v-t="'user.removeItem'" @click="removeClosetItem" /></li>
<li><a v-if="type !== 'cape'" v-t="'user.setAsAvatar'" @click="setAsAvatar" /></li>
</ul>
</div>
@ -36,10 +36,14 @@
import toastr from 'toastr'
import { swal } from '../../js/notify'
import setAsAvatar from '../mixins/setAsAvatar'
import removeClosetItem from '../mixins/removeClosetItem'
export default {
name: 'ClosetItem',
mixins: [setAsAvatar],
mixins: [
removeClosetItem,
setAsAvatar,
],
props: {
tid: {
type: Number,
@ -92,27 +96,6 @@ export default {
toastr.warning(msg)
}
},
async remove() {
const { dismiss } = await swal({
text: this.$t('user.removeFromClosetNotice'),
type: 'warning',
showCancelButton: true,
})
if (dismiss) {
return
}
const { errno, msg } = await this.$http.post(
'/user/closet/remove',
{ tid: this.tid }
)
if (errno === 0) {
this.$emit('item-removed')
swal({ type: 'success', text: msg })
} else {
toastr.warning(msg)
}
},
},
}
</script>

View File

@ -163,38 +163,15 @@ test('set as avatar', () => {
test('add to closet', async () => {
Object.assign(window.blessing.extra, { currentUid: 1, inCloset: false })
Vue.prototype.$http.get.mockResolvedValue({ name: 'wow', likes: 2 })
Vue.prototype.$http.post
.mockResolvedValueOnce({ errno: 1, msg: '1' })
.mockResolvedValue({ errno: 0, msg: '' })
jest.spyOn(toastr, 'warning')
swal.mockImplementationOnce(() => ({ dismiss: 1 }))
.mockImplementation(({ inputValidator }) => {
if (inputValidator) {
inputValidator()
inputValidator('wow')
}
return { value: 'wow' }
})
Vue.prototype.$http.post.mockResolvedValue({ errno: 0, msg: '' })
swal.mockResolvedValue({})
const wrapper = mount(Show, {
mocks: {
$route: ['/skinlib/show/1', '1'],
},
stubs: { previewer },
})
const button = wrapper.find('.btn-primary')
button.trigger('click')
expect(Vue.prototype.$http.post).not.toBeCalled()
button.trigger('click')
await flushPromises()
expect(Vue.prototype.$http.post).toBeCalledWith(
'/user/closet/add',
{ tid: 1, name: 'wow' }
)
expect(toastr.warning).toBeCalledWith('1')
button.trigger('click')
wrapper.find('.btn-primary').trigger('click')
await flushPromises()
expect(wrapper.vm.likes).toBe(3)
expect(wrapper.vm.liked).toBeTrue()
@ -203,32 +180,15 @@ test('add to closet', async () => {
test('remove from closet', async () => {
Object.assign(window.blessing.extra, { currentUid: 1, inCloset: true })
Vue.prototype.$http.get.mockResolvedValue({ likes: 2 })
Vue.prototype.$http.post
.mockResolvedValueOnce({ errno: 1, msg: '1' })
.mockResolvedValue({ errno: 0, msg: '' })
jest.spyOn(toastr, 'warning')
swal.mockResolvedValueOnce({ dismiss: 1 })
.mockResolvedValue({})
Vue.prototype.$http.post.mockResolvedValue({ errno: 0 })
swal.mockResolvedValue({})
const wrapper = mount(Show, {
mocks: {
$route: ['/skinlib/show/1', '1'],
},
stubs: { previewer },
})
const button = wrapper.find('.btn-primary')
button.trigger('click')
expect(Vue.prototype.$http.post).not.toBeCalled()
button.trigger('click')
await flushPromises()
expect(Vue.prototype.$http.post).toBeCalledWith(
'/user/closet/remove',
{ tid: 1 }
)
expect(toastr.warning).toBeCalledWith('1')
button.trigger('click')
wrapper.find('.btn-primary').trigger('click')
await flushPromises()
expect(wrapper.vm.likes).toBe(1)
expect(wrapper.vm.liked).toBeFalse()

View File

@ -63,31 +63,14 @@ test('liked state', () => {
})
test('remove from closet', async () => {
Vue.prototype.$http.post
.mockResolvedValueOnce({ errno: 1, msg: '1' })
.mockResolvedValue({ errno: 0 })
swal.mockResolvedValueOnce({ dismiss: 1 })
.mockResolvedValue({})
jest.spyOn(toastr, 'warning')
Vue.prototype.$http.post.mockResolvedValue({ errno: 0 })
swal.mockResolvedValue({})
const wrapper = mount(SkinLibItem, {
propsData: {
tid: 1, liked: true, anonymous: false,
},
})
const button = wrapper.find('.like')
button.trigger('click')
expect(Vue.prototype.$http.post).not.toBeCalled()
button.trigger('click')
await flushPromises()
expect(Vue.prototype.$http.post).toBeCalledWith(
'/user/closet/remove',
{ tid: 1 }
)
expect(toastr.warning).toBeCalledWith('1')
button.trigger('click')
wrapper.find('.like').trigger('click')
await flushPromises()
expect(wrapper.emitted('like-toggled')[0]).toEqual([false])
})