fix(design): distinguish saved video settings from preparation needs

This commit is contained in:
brother7 committed 2026-09-27 16:32:38 +08:00
1 parent 0eed70fa63
commit bbea6eba82
6 files changed
+203 -28

No files matched your search

+46 -3
View File
@@ -3,7 +3,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest';
import { DesignPlanHistory } from '@/pages/ImageCanvas/DesignPlanHistory';
import { YouthCreationCard } from '@/pages/ImageCanvas/YouthCreationCard';
import { useImageWorkspaceStore } from '@/stores/image-workspace';
import type { DesignGenerationTask } from '../../shared/image-workspace';
import type { DesignCompilationIssue, DesignGenerationTask } from '../../shared/image-workspace';
import {
designCapabilitiesFixture,
designFormFixture,
@@ -58,7 +58,7 @@ function taskFixture(overrides: Partial<DesignGenerationTask> = {}): DesignGener
};
}
function renderCard(workspace = designWorkspaceFixture()) {
function renderCard(workspace = designWorkspaceFixture(), quoteBlockers: DesignCompilationIssue[] = []) {
const actions = {
applyFieldOperations: vi.fn().mockResolvedValue(workspace),
prepareGeneration: vi.fn().mockResolvedValue(workspace),
@@ -74,7 +74,7 @@ function renderCard(workspace = designWorkspaceFixture()) {
render(
<YouthCreationCard
workspace={workspace}
quoteBlockers={[]}
quoteBlockers={quoteBlockers}
generationAvailable
generationOptions={designCapabilitiesFixture.generationOptions}
onQuoteOffered={vi.fn()}
@@ -123,6 +123,49 @@ describe('YouthCreationCard', () => {
useImageWorkspaceStore.getState().reset();
});
it('does not present a missing saved video duration as an already selected six seconds', () => {
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';
renderCard(workspace, [
{ code: 'video_duration_required', message: 'required', severity: 'blocker', path: 'video.total_duration_seconds' },
{ code: 'video_shots_required', message: 'required', severity: 'blocker', path: 'video.shots' },
]);
expect(screen.getByRole('combobox', { name: '时长' })).toHaveValue('');
expect(screen.getByRole('button', { name: '准备制作方案' })).toBeDisabled();
expect(screen.queryByRole('button', { name: '增加时长' })).not.toBeInTheDocument();
expect(screen.queryByText('至少写一个视频画面。')).not.toBeInTheDocument();
});
it('allows AI preparation without requiring the user to write internal video shots', 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';
workspace.form.specification.values.video.total_duration_seconds = 6;
const actions = renderCard(workspace, [
{ code: 'video_shots_required', message: 'required', severity: 'blocker', path: 'video.shots' },
]);
expect(screen.getByText('6 秒')).toBeInTheDocument();
expect(screen.queryByText('至少写一个视频画面。')).not.toBeInTheDocument();
expect(screen.getByRole('button', { name: '准备制作方案' })).toBeEnabled();
fireEvent.click(screen.getByRole('button', { name: '准备制作方案' }));
await waitFor(() => expect(actions.requestQuote).toHaveBeenCalledOnce());
});
it('restores the saved duration after a failed parameter edit', async () => {
const workspace = referenceWorkspace();
workspace.form.specification.values.intent.media = 'video';
workspace.form.specification.values.video.total_duration_seconds = 6;
const actions = renderCard(workspace);
actions.applyFieldOperations.mockRejectedValueOnce(new Error('save failed'));
fireEvent.click(screen.getByRole('button', { name: '增加时长' }));
await waitFor(() => expect(screen.getByText('方案需要重试')).toBeInTheDocument());
expect(screen.getByText('6 秒')).toBeInTheDocument();
expect(screen.queryByText('7 秒')).not.toBeInTheDocument();
});
it('persists the displayed supported duration when entering video mode', async () => {
const actions = renderCard();
fireEvent.change(screen.getByRole('combobox', { name: '类型' }), { target: { value: 'video' } });