fix(canvas): cap video duration choices

This commit is contained in:
2026-08-18 11:06:23 +08:00
parent 9e1e03f583
commit 566f99f5ed
4 changed files with 135 additions and 6 deletions

View File

@@ -510,6 +510,69 @@ describe('ImageCanvas Workspace-first design experience', () => {
expect(screen.getByRole('button', { name: '确认并开始生成' })).toBeEnabled();
});
it('limits legacy video durations to 2-6 seconds and preserves 6 seconds through confirmation', async () => {
const videoConversation = conversationFixture();
const videoQuote = videoConversation.messages[1].generationQuote!;
videoConversation.brief.medium = 'video';
videoQuote.medium = 'video';
videoQuote.generationParameters = {
...videoQuote.generationParameters,
durationSeconds: 10,
};
videoQuote.generationOptions.durations = [2, 6, 7, 15].map((value) => ({
value,
label: `${value}`,
default: value === 10,
disabled: false,
multiplier: 1,
}));
fetchImageWorkspaceConversationMock.mockResolvedValueOnce(videoConversation);
updateImageWorkspaceGenerationQuoteMock.mockImplementationOnce(async (
_workspaceId: string,
_quoteId: string,
finalPrompt: string,
generationParameters: DesignGenerationQuote['generationParameters'],
) => ({
...videoQuote,
finalPrompt,
generationParameters,
}));
render(<MemoryRouter><ImageCanvas /></MemoryRouter>);
const durationSelect = await screen.findByTestId('design-quote-duration');
expect(durationSelect).toHaveValue('');
expect(within(durationSelect).getAllByRole('option').map((option) => option.getAttribute('value')))
.toEqual(['', '2', '6']);
fireEvent.change(durationSelect, { target: { value: '6' } });
await waitFor(() => expect(updateImageWorkspaceGenerationQuoteMock).toHaveBeenCalledWith(
'workspace-cloud',
'quote-one',
videoQuote.finalPrompt,
{
...videoQuote.generationParameters,
durationSeconds: 6,
},
));
await waitFor(() => expect(screen.getByTestId('design-quote-duration')).toHaveValue('6'));
fireEvent.click(screen.getByRole('button', { name: '确认并开始生成' }));
await waitFor(() => expect(confirmImageWorkspaceGenerationMock).toHaveBeenCalledWith(
'workspace-cloud',
'conversation-cloud',
1,
'quote-one',
expect.stringMatching(/^turn-/),
videoQuote.finalPrompt,
{
...videoQuote.generationParameters,
durationSeconds: 6,
},
));
});
it('offers an actionable retry when re-quoting fails', async () => {
updateImageWorkspaceGenerationQuoteMock.mockRejectedValueOnce(
new ImageWorkspaceApiError(409, 'generation_quote_invalid', '当前生成方案已失效'),

View File

@@ -567,7 +567,7 @@ describe('Works Square AI design adapter', () => {
model: 'image-model-one',
resolution: '1024x1024',
aspectRatio: '16:9',
durationSeconds: null,
durationSeconds: 6,
},
})).resolves.toMatchObject({
quoteId: 'quote-one',
@@ -586,7 +586,7 @@ describe('Works Square AI design adapter', () => {
model: 'image-model-one',
resolution: '1024x1024',
aspect_ratio: '16:9',
duration_seconds: null,
duration_seconds: 6,
}),
}),
);