114 lines
3.3 KiB
TypeScript
114 lines
3.3 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
import {
|
|
buildHomeWorkspaceLaunchTarget,
|
|
createHomeProjectLaunch,
|
|
} from '@/lib/home/create-project-launch'
|
|
|
|
function buildJsonResponse(body: unknown, status = 200): Response {
|
|
return new Response(JSON.stringify(body), {
|
|
status,
|
|
headers: { 'Content-Type': 'application/json' },
|
|
})
|
|
}
|
|
|
|
describe('createHomeProjectLaunch', () => {
|
|
beforeEach(() => {
|
|
vi.restoreAllMocks()
|
|
})
|
|
|
|
it('creates project, config, first episode, and returns an auto-run workspace target', async () => {
|
|
const apiFetch = vi
|
|
.fn<(
|
|
input: string,
|
|
init?: RequestInit,
|
|
) => Promise<Response>>()
|
|
.mockResolvedValueOnce(buildJsonResponse({
|
|
project: { id: 'project-1' },
|
|
}, 201))
|
|
.mockResolvedValueOnce(buildJsonResponse({ success: true }, 200))
|
|
.mockResolvedValueOnce(buildJsonResponse({
|
|
episode: { id: 'episode-1' },
|
|
}, 201))
|
|
|
|
const result = await createHomeProjectLaunch({
|
|
apiFetch,
|
|
projectName: '开场白',
|
|
storyText: '第一章内容',
|
|
videoRatio: '9:16',
|
|
artStyle: 'american-comic',
|
|
episodeName: '第 1 集',
|
|
})
|
|
|
|
expect(apiFetch).toHaveBeenNthCalledWith(1, '/api/projects', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
name: '开场白',
|
|
}),
|
|
})
|
|
expect(apiFetch).toHaveBeenNthCalledWith(2, '/api/novel-promotion/project-1', {
|
|
method: 'PATCH',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
videoRatio: '9:16',
|
|
artStyle: 'american-comic',
|
|
}),
|
|
})
|
|
expect(apiFetch).toHaveBeenNthCalledWith(3, '/api/novel-promotion/project-1/episodes', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
name: '第 1 集',
|
|
novelText: '第一章内容',
|
|
}),
|
|
})
|
|
expect(result).toEqual({
|
|
projectId: 'project-1',
|
|
episodeId: 'episode-1',
|
|
target: {
|
|
pathname: '/workspace/project-1',
|
|
query: {
|
|
episode: 'episode-1',
|
|
autoRun: 'storyToScript',
|
|
},
|
|
},
|
|
})
|
|
})
|
|
|
|
it('fails explicitly when first episode creation does not return an episode id', async () => {
|
|
const apiFetch = vi
|
|
.fn<(
|
|
input: string,
|
|
init?: RequestInit,
|
|
) => Promise<Response>>()
|
|
.mockResolvedValueOnce(buildJsonResponse({
|
|
project: { id: 'project-1' },
|
|
}, 201))
|
|
.mockResolvedValueOnce(buildJsonResponse({ success: true }, 200))
|
|
.mockResolvedValueOnce(buildJsonResponse({
|
|
episode: {},
|
|
}, 201))
|
|
|
|
await expect(createHomeProjectLaunch({
|
|
apiFetch,
|
|
projectName: '开场白',
|
|
storyText: '第一章内容',
|
|
videoRatio: '9:16',
|
|
artStyle: 'american-comic',
|
|
episodeName: '第 1 集',
|
|
})).rejects.toThrow('Episode creation response missing episode id')
|
|
})
|
|
})
|
|
|
|
describe('buildHomeWorkspaceLaunchTarget', () => {
|
|
it('points workspace launch to the created episode and auto-runs story-to-script', () => {
|
|
expect(buildHomeWorkspaceLaunchTarget('project-9', 'episode-4')).toEqual({
|
|
pathname: '/workspace/project-9',
|
|
query: {
|
|
episode: 'episode-4',
|
|
autoRun: 'storyToScript',
|
|
},
|
|
})
|
|
})
|
|
})
|