fix(design): connect video preparation and playable history

This commit is contained in:
brother7 committed 2026-09-16 15:42:39 +08:00
1 parent 4321c77613
commit 1acca836fe
21 files changed
+900 -115

No files matched your search

+39
View File
@@ -5,6 +5,7 @@ import { YouthCreationCard } from '@/pages/ImageCanvas/YouthCreationCard';
import { useImageWorkspaceStore } from '@/stores/image-workspace';
import type { DesignGenerationTask } from '../../shared/image-workspace';
import {
designCapabilitiesFixture,
designFormFixture,
designQuoteFixture,
designValuesFixture,
@@ -60,6 +61,7 @@ function taskFixture(overrides: Partial<DesignGenerationTask> = {}): DesignGener
function renderCard(workspace = designWorkspaceFixture()) {
const actions = {
applyFieldOperations: vi.fn().mockResolvedValue(workspace),
prepareGeneration: vi.fn().mockResolvedValue(workspace),
requestQuote: vi.fn().mockResolvedValue(workspace),
confirmGeneration: vi.fn().mockResolvedValue(workspace),
};
@@ -74,6 +76,7 @@ function renderCard(workspace = designWorkspaceFixture()) {
workspace={workspace}
quoteBlockers={[]}
generationAvailable
generationOptions={designCapabilitiesFixture.generationOptions}
onQuoteOffered={vi.fn()}
/>,
);
@@ -120,6 +123,42 @@ describe('YouthCreationCard', () => {
useImageWorkspaceStore.getState().reset();
});
it('persists the displayed supported duration when entering video mode', async () => {
const actions = renderCard();
fireEvent.change(screen.getByRole('combobox', { name: '类型' }), { target: { value: 'video' } });
await waitFor(() => expect(actions.prepareGeneration).toHaveBeenCalledWith([
{ kind: 'set', path: 'intent.media', value: 'video' },
{ kind: 'set', path: 'video.total_duration_seconds', value: 6 },
]));
expect(actions.confirmGeneration).not.toHaveBeenCalled();
});
it('does not invent generation capabilities while the capability response is missing', () => {
render(<YouthCreationCard workspace={designWorkspaceFixture()} quoteBlockers={[]} generationAvailable />);
expect(screen.getByRole('button', { name: '准备制作方案' })).toBeDisabled();
expect(screen.getByRole('option', { name: '视频' })).toBeDisabled();
});
it('restores the saved medium if conversion cannot be prepared', async () => {
const actions = renderCard();
actions.prepareGeneration.mockRejectedValueOnce(new Error('preparation failed'));
fireEvent.change(screen.getByRole('combobox', { name: '类型' }), { target: { value: 'video' } });
await waitFor(() => expect(screen.getByRole('combobox', { name: '类型' })).toHaveValue('image'));
expect(screen.getByText('方案需要重试')).toBeInTheDocument();
});
it('unbinds the starting picture when its reference is explicitly removed', async () => {
const workspace = referenceWorkspace();
workspace.form.specification.values.intent.media = 'video';
workspace.form.specification.values.video.first_frame_asset_id = 'asset-reference';
workspace.form.specification.values.references[0].role = 'first_frame';
const actions = renderCard(workspace);
fireEvent.click(screen.getByRole('button', { name: '删除参考图 1' }));
await waitFor(() => expect(actions.applyFieldOperations).toHaveBeenCalledWith(expect.arrayContaining([
{ kind: 'clear', path: 'video.first_frame_asset_id' },
])));
});
it('keeps the editable prompt and visible parameters in a lightweight inline plan', () => {
renderCard();