feat: add edutainment drawing and visual package flows
This commit is contained in:
102
src/services/edutainment-baby-drawing/babyDrawingClient.test.ts
Normal file
102
src/services/edutainment-baby-drawing/babyDrawingClient.test.ts
Normal file
@@ -0,0 +1,102 @@
|
||||
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';
|
||||
|
||||
import { requestJson } from '../apiClient';
|
||||
import {
|
||||
createBabyLoveDrawingMagicImage,
|
||||
listLocalBabyLoveDrawings,
|
||||
saveBabyLoveDrawing,
|
||||
} from './babyDrawingClient';
|
||||
|
||||
vi.mock('../apiClient', () => ({
|
||||
requestJson: vi.fn(),
|
||||
}));
|
||||
|
||||
const requestJsonMock = vi.mocked(requestJson);
|
||||
|
||||
describe('babyDrawingClient', () => {
|
||||
beforeEach(() => {
|
||||
const store = new Map<string, string>();
|
||||
vi.stubGlobal('window', {
|
||||
localStorage: {
|
||||
getItem: (key: string) => store.get(key) ?? null,
|
||||
setItem: (key: string, value: string) => {
|
||||
store.set(key, value);
|
||||
},
|
||||
},
|
||||
});
|
||||
vi.stubGlobal('crypto', {
|
||||
randomUUID: () => '11111111-2222-3333-4444-555555555555',
|
||||
});
|
||||
vi.useFakeTimers();
|
||||
vi.setSystemTime(new Date('2026-05-13T08:00:00.000Z'));
|
||||
requestJsonMock.mockReset();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.useRealTimers();
|
||||
vi.unstubAllGlobals();
|
||||
});
|
||||
|
||||
test('saves original drawing only when magic image is absent', () => {
|
||||
const response = saveBabyLoveDrawing({
|
||||
originalImageSrc: 'data:image/png;base64,original',
|
||||
magicImageSrc: null,
|
||||
strokeTrace: [],
|
||||
});
|
||||
|
||||
expect(response.record).toMatchObject({
|
||||
templateName: '宝贝爱画',
|
||||
originalImageSrc: 'data:image/png;base64,original',
|
||||
magicImageSrc: null,
|
||||
saveMode: 'original-only',
|
||||
themeTags: ['寓教于乐', '宝贝爱画'],
|
||||
});
|
||||
expect(listLocalBabyLoveDrawings()).toHaveLength(1);
|
||||
});
|
||||
|
||||
test('saves original and magic image together after magic generation', () => {
|
||||
const response = saveBabyLoveDrawing({
|
||||
originalImageSrc: 'data:image/png;base64,original',
|
||||
magicImageSrc: 'data:image/png;base64,magic',
|
||||
strokeTrace: [
|
||||
{
|
||||
strokeId: 'stroke-1',
|
||||
tool: 'brush',
|
||||
color: '#ef4444',
|
||||
points: [{ x: 0.1, y: 0.2, t: 1 }],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
expect(response.record.saveMode).toBe('original-and-magic');
|
||||
expect(response.record.magicImageSrc).toBe('data:image/png;base64,magic');
|
||||
expect(listLocalBabyLoveDrawings()[0]?.strokeTrace).toHaveLength(1);
|
||||
});
|
||||
|
||||
test('creates magic image through backend image-2 proxy', async () => {
|
||||
requestJsonMock.mockResolvedValueOnce({
|
||||
magicImageSrc: 'data:image/png;base64,magic',
|
||||
generationProvider: 'vector-engine-gpt-image-2',
|
||||
prompt: '绘本风格',
|
||||
});
|
||||
|
||||
const payload = {
|
||||
originalImageSrc: 'data:image/png;base64,original',
|
||||
strokeTrace: [],
|
||||
};
|
||||
const response = await createBabyLoveDrawingMagicImage(payload);
|
||||
|
||||
expect(response.magicImageSrc).toContain('magic');
|
||||
expect(requestJsonMock).toHaveBeenCalledWith(
|
||||
'/api/creation/edutainment/baby-love-drawing/magic',
|
||||
expect.objectContaining({
|
||||
method: 'POST',
|
||||
body: JSON.stringify(payload),
|
||||
}),
|
||||
'生成宝贝爱画魔法图片失败',
|
||||
expect.objectContaining({
|
||||
timeoutMs: 180000,
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user