diff --git a/resources/assets/src/components/mixins/addClosetItem.js b/resources/assets/src/components/mixins/addClosetItem.js new file mode 100644 index 00000000..e632084f --- /dev/null +++ b/resources/assets/src/components/mixins/addClosetItem.js @@ -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) + } + }, + }, +} diff --git a/resources/assets/src/components/mixins/removeClosetItem.js b/resources/assets/src/components/mixins/removeClosetItem.js new file mode 100644 index 00000000..ee635d5b --- /dev/null +++ b/resources/assets/src/components/mixins/removeClosetItem.js @@ -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) + } + }, + }, +} diff --git a/resources/assets/src/components/skinlib/Show.vue b/resources/assets/src/components/skinlib/Show.vue index b3228643..8171e387 100644 --- a/resources/assets/src/components/skinlib/Show.vue +++ b/resources/assets/src/components/skinlib/Show.vue @@ -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({ diff --git a/resources/assets/src/components/skinlib/SkinLibItem.vue b/resources/assets/src/components/skinlib/SkinLibItem.vue index d5f14cb1..b5fd7417 100644 --- a/resources/assets/src/components/skinlib/SkinLibItem.vue +++ b/resources/assets/src/components/skinlib/SkinLibItem.vue @@ -32,11 +32,15 @@ diff --git a/resources/assets/tests/components/skinlib/Show.test.js b/resources/assets/tests/components/skinlib/Show.test.js index ae10c909..7f427580 100644 --- a/resources/assets/tests/components/skinlib/Show.test.js +++ b/resources/assets/tests/components/skinlib/Show.test.js @@ -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() diff --git a/resources/assets/tests/components/skinlib/SkinLibItem.test.js b/resources/assets/tests/components/skinlib/SkinLibItem.test.js index 4b2eaf1e..ea563813 100644 --- a/resources/assets/tests/components/skinlib/SkinLibItem.test.js +++ b/resources/assets/tests/components/skinlib/SkinLibItem.test.js @@ -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]) })