Fix prop confirmation bug, add Wan 2.7 model, refine multiple UI details, improve prop generation quality and aspect ratio, remove text overlays from Asset Center created images, and optimize prop filtering logic
This commit is contained in:
127
tests/unit/assets/project-location-backed-selection.test.ts
Normal file
127
tests/unit/assets/project-location-backed-selection.test.ts
Normal file
@@ -0,0 +1,127 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
const deleteObjectMock = vi.hoisted(() => vi.fn())
|
||||
const resolveStorageKeyFromMediaValueMock = vi.hoisted(() => vi.fn())
|
||||
const prismaMock = vi.hoisted(() => ({
|
||||
novelPromotionLocation: {
|
||||
findUnique: vi.fn(),
|
||||
update: vi.fn(),
|
||||
},
|
||||
locationImage: {
|
||||
update: vi.fn(),
|
||||
deleteMany: vi.fn(),
|
||||
},
|
||||
$transaction: vi.fn(),
|
||||
}))
|
||||
|
||||
vi.mock('@/lib/prisma', () => ({
|
||||
prisma: prismaMock,
|
||||
}))
|
||||
|
||||
vi.mock('@/lib/storage', () => ({
|
||||
deleteObject: deleteObjectMock,
|
||||
}))
|
||||
|
||||
vi.mock('@/lib/media/service', () => ({
|
||||
resolveStorageKeyFromMediaValue: resolveStorageKeyFromMediaValueMock,
|
||||
}))
|
||||
|
||||
describe('project location-backed selection service', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
prismaMock.$transaction.mockImplementation(async (
|
||||
callback: (tx: {
|
||||
locationImage: {
|
||||
update: typeof prismaMock.locationImage.update
|
||||
deleteMany: typeof prismaMock.locationImage.deleteMany
|
||||
}
|
||||
novelPromotionLocation: {
|
||||
update: typeof prismaMock.novelPromotionLocation.update
|
||||
}
|
||||
}) => Promise<void>,
|
||||
) => callback({
|
||||
locationImage: prismaMock.locationImage,
|
||||
novelPromotionLocation: prismaMock.novelPromotionLocation,
|
||||
}))
|
||||
resolveStorageKeyFromMediaValueMock.mockImplementation(async (value: string) => `key:${value}`)
|
||||
deleteObjectMock.mockResolvedValue(undefined)
|
||||
prismaMock.locationImage.deleteMany.mockResolvedValue({ count: 1 })
|
||||
prismaMock.locationImage.update.mockResolvedValue(undefined)
|
||||
prismaMock.novelPromotionLocation.update.mockResolvedValue(undefined)
|
||||
})
|
||||
|
||||
it('confirms a prop selection by keeping only the selected render', async () => {
|
||||
prismaMock.novelPromotionLocation.findUnique.mockResolvedValue({
|
||||
id: 'prop-1',
|
||||
selectedImageId: 'prop-image-2',
|
||||
images: [
|
||||
{
|
||||
id: 'prop-image-1',
|
||||
imageIndex: 0,
|
||||
imageUrl: 'https://example.com/prop-1.png',
|
||||
isSelected: false,
|
||||
},
|
||||
{
|
||||
id: 'prop-image-2',
|
||||
imageIndex: 1,
|
||||
imageUrl: 'https://example.com/prop-2.png',
|
||||
isSelected: true,
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
const mod = await import('@/lib/assets/services/project-location-backed-selection')
|
||||
|
||||
const result = await mod.confirmProjectLocationBackedSelection('prop-1')
|
||||
|
||||
expect(result).toEqual({ success: true })
|
||||
expect(resolveStorageKeyFromMediaValueMock).toHaveBeenCalledWith('https://example.com/prop-1.png')
|
||||
expect(deleteObjectMock).toHaveBeenCalledWith('key:https://example.com/prop-1.png')
|
||||
expect(prismaMock.locationImage.deleteMany).toHaveBeenCalledWith({
|
||||
where: {
|
||||
locationId: 'prop-1',
|
||||
id: { not: 'prop-image-2' },
|
||||
},
|
||||
})
|
||||
expect(prismaMock.locationImage.update).toHaveBeenCalledWith({
|
||||
where: { id: 'prop-image-2' },
|
||||
data: {
|
||||
imageIndex: 0,
|
||||
isSelected: true,
|
||||
},
|
||||
})
|
||||
expect(prismaMock.novelPromotionLocation.update).toHaveBeenCalledWith({
|
||||
where: { id: 'prop-1' },
|
||||
data: { selectedImageId: 'prop-image-2' },
|
||||
})
|
||||
})
|
||||
|
||||
it('fails explicitly when confirming without a selected prop render', async () => {
|
||||
prismaMock.novelPromotionLocation.findUnique.mockResolvedValue({
|
||||
id: 'prop-1',
|
||||
selectedImageId: null,
|
||||
images: [
|
||||
{
|
||||
id: 'prop-image-1',
|
||||
imageIndex: 0,
|
||||
imageUrl: 'https://example.com/prop-1.png',
|
||||
isSelected: false,
|
||||
},
|
||||
{
|
||||
id: 'prop-image-2',
|
||||
imageIndex: 1,
|
||||
imageUrl: 'https://example.com/prop-2.png',
|
||||
isSelected: false,
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
const mod = await import('@/lib/assets/services/project-location-backed-selection')
|
||||
|
||||
await expect(mod.confirmProjectLocationBackedSelection('prop-1')).rejects.toMatchObject({
|
||||
code: 'INVALID_PARAMS',
|
||||
})
|
||||
expect(prismaMock.locationImage.deleteMany).not.toHaveBeenCalled()
|
||||
expect(deleteObjectMock).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user