优化
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
import { defineComponent, h } from 'vue'
|
||||
import { flushPromises, mount } from '@vue/test-utils'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { ApiResponseError } from '@/shared/api/http'
|
||||
import OwnedBusinessPhotosEditor from './OwnedBusinessPhotosEditor.vue'
|
||||
import { ownedBusinessFixture } from './OwnedBusinessFixtures'
|
||||
import type { OwnedBusinessPhoto } from '../ownedBusinessTypes'
|
||||
|
||||
const calls=vi.hoisted(()=>({upload:vi.fn(),bind:vi.fn(),command:vi.fn(),detail:vi.fn(),content:vi.fn(),actor:{user:{id:'actor'}},canUpload:true}))
|
||||
vi.mock('../api/ownedBusiness',()=>({uploadOwnedBusinessPhoto:calls.upload,bindOwnedBusinessPhoto:calls.bind,getOwnedBusinessCommand:calls.command,getOwnedBusiness:calls.detail,getOwnedBusinessPhotoContent:calls.content}))
|
||||
vi.mock('@/core/auth/auth',()=>({useAuthStore:()=>calls.actor}))
|
||||
vi.mock('@/core/access/accessPreview',()=>({useAccessPreviewStore:()=>({can:()=>calls.canUpload})}))
|
||||
vi.mock('@/core/unsaved-work/useUnsavedWorkRegistration',()=>({useUnsavedWorkRegistration:()=>({captureBaseline:vi.fn()})}))
|
||||
vi.mock('element-plus',()=>({ElMessage:{success:vi.fn()},ElMessageBox:{confirm:vi.fn()}}))
|
||||
const Frame=defineComponent({props:['modelValue','busy','beforeClose'],setup(_props,{slots}){return()=>h('div',Object.values(slots).map(slot=>slot?.()))}})
|
||||
const Button=defineComponent({props:['disabled'],template:'<button :disabled="disabled"><slot /></button>'})
|
||||
const global={stubs:{OwnedBusinessPhotosDialog:Frame,ElButton:Button,LoadErrorState:{props:['message'],template:'<div>{{message}}<slot name="details" /></div>'},ApiErrorMeta:true}}
|
||||
const photo:OwnedBusinessPhoto={slot:'LOADING_SCENE',category:'LOADING',fileId:'9007199254740993',fileName:'loading.png',contentType:'image/png',sizeBytes:'5',uploadedAt:'2026-10-20T10:00:00Z',savedAt:null}
|
||||
async function choose(wrapper:ReturnType<typeof mount>){const input=wrapper.find('input[type="file"]');Object.defineProperty(input.element,'files',{configurable:true,value:[new File(['image'],'loading.png',{type:'image/png'})]});await input.trigger('change');await flushPromises()}
|
||||
beforeEach(()=>{
|
||||
vi.clearAllMocks();sessionStorage.clear();calls.actor.user.id='actor';calls.canUpload=true
|
||||
calls.upload.mockResolvedValue(photo);calls.command.mockRejectedValue(new ApiResponseError('not found','A0404',404))
|
||||
const current=ownedBusinessFixture();current.row.recordVersion='1';current.photos=[{...photo,savedAt:'2026-10-20T10:01:00Z'}]
|
||||
calls.bind.mockResolvedValue(current);calls.detail.mockResolvedValue(current)
|
||||
})
|
||||
describe('owned business per-slot photo save',()=>{
|
||||
it('retains prepared file and original binding request through a failed bind without retransmitting the image',async()=>{
|
||||
calls.bind.mockRejectedValueOnce(new TypeError('network interrupted'))
|
||||
const wrapper=mount(OwnedBusinessPhotosEditor,{global,props:{modelValue:true,detail:ownedBusinessFixture()}});await choose(wrapper)
|
||||
expect(calls.upload).toHaveBeenCalledTimes(1);expect(calls.bind).toHaveBeenCalledTimes(1)
|
||||
expect(wrapper.text()).toContain('尚未确认绑定保存');expect(wrapper.emitted('saved')).toBeUndefined()
|
||||
const original=structuredClone(calls.bind.mock.calls[0]![2])
|
||||
await wrapper.findAll('button').find(button=>button.text()==='核对原结果并继续绑定')!.trigger('click');await flushPromises()
|
||||
expect(calls.upload).toHaveBeenCalledTimes(1);expect(calls.bind).toHaveBeenCalledTimes(2)
|
||||
expect(calls.bind.mock.calls[1]![2]).toEqual(original);expect(original.fileId).toBe(photo.fileId);expect(original.recordVersion).toBe('0')
|
||||
expect(wrapper.emitted('saved')).toHaveLength(1);wrapper.unmount()
|
||||
})
|
||||
it('does not offer a new upload after unknown upload or fabricate a saved photo',async()=>{
|
||||
calls.upload.mockRejectedValue(new TypeError('network interrupted'))
|
||||
const wrapper=mount(OwnedBusinessPhotosEditor,{global,props:{modelValue:true,detail:ownedBusinessFixture()}});await choose(wrapper)
|
||||
await wrapper.findAll('button').find(button=>button.text()==='核对原结果并继续绑定')!.trigger('click');await flushPromises()
|
||||
expect(calls.upload).toHaveBeenCalledTimes(1);expect(calls.bind).not.toHaveBeenCalled();expect(wrapper.emitted('saved')).toBeUndefined()
|
||||
expect(wrapper.find('input[type="file"]').attributes('disabled')).toBeDefined();expect(wrapper.text()).toContain('禁止重复上传');wrapper.unmount()
|
||||
})
|
||||
it('keeps saved metadata readable without upload permission and fetches image bytes only on explicit preview',async()=>{
|
||||
calls.canUpload=false
|
||||
const detail=ownedBusinessFixture();detail.photos=[{...photo,savedAt:'2026-10-20T10:01:00Z'}]
|
||||
const wrapper=mount(OwnedBusinessPhotosEditor,{global,props:{modelValue:true,detail}});await flushPromises()
|
||||
expect(wrapper.find('input[type="file"]').exists()).toBe(false);expect(wrapper.text()).toContain('已保存');expect(calls.content).not.toHaveBeenCalled()
|
||||
wrapper.unmount()
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user