feat: simplify AI design for young creators

This commit is contained in:
brother7 committed 2026-09-02 19:14:33 +08:00
1 parent 7552cf5952
commit 756638a28a
17 files changed
+3595 -297

No files matched your search

+46 -29
View File
@@ -53,7 +53,11 @@ function prepareWorkspace(overrides = {}) {
return { workspace, actions };
}
describe('Living Form Canvas page', () => {
function openMobileCreationCard() {
fireEvent.click(screen.getByRole('button', { name: /^我的创作/ }));
}
describe('youth AI Design Canvas page', () => {
beforeEach(() => {
vi.clearAllMocks();
useAuthStore.setState({
@@ -65,50 +69,61 @@ describe('Living Form Canvas page', () => {
useImageWorkspaceStore.getState().reset();
});
it('shows the persistent form beside the conversation from the first Workspace snapshot', () => {
it('starts with conversation and a concise Creation Card instead of a professional field matrix', () => {
prepareWorkspace();
render(<ImageCanvas />);
expect(screen.getByTestId('image-workspace-living-form')).toBeInTheDocument();
expect(screen.getByText('Living Form')).toBeInTheDocument();
expect(screen.getByText('目标与用途')).toBeInTheDocument();
expect(screen.getByText('内容与叙事')).toBeInTheDocument();
expect(screen.getByText('Agent 建议')).toBeInTheDocument();
expect(screen.getByTestId('image-workspace-conversation')).toBeInTheDocument();
expect(screen.getByRole('heading', { name: '一起做作品' })).toBeInTheDocument();
openMobileCreationCard();
const card = screen.getByTestId('youth-creation-card');
expect(card).toBeInTheDocument();
expect(within(card).getByRole('heading', { name: '我的创作' })).toBeInTheDocument();
expect(screen.getByText('做一张便携咖啡机的小红书主视觉')).toBeInTheDocument();
expect(screen.getByText('编译生成方案')).toBeInTheDocument();
expect(screen.queryByText('Living Form')).not.toBeInTheDocument();
expect(screen.queryByText('目标与用途')).not.toBeInTheDocument();
expect(screen.queryByText(/规格版本|编译器|生成策略|字段决策/)).not.toBeInTheDocument();
});
it('keeps form edits local until the user saves an explicit field operation', () => {
it('sends high-impact fine adjustments through the existing typed field operations', () => {
const { actions } = prepareWorkspace();
render(<ImageCanvas />);
const ratio = screen.getByDisplayValue('3:4');
fireEvent.change(ratio, { target: { value: '16:9' } });
expect(useImageWorkspaceStore.getState().fieldDrafts).toEqual({
'output.aspect_ratio': '16:9',
});
const field = screen.getByText('画幅比例').closest('.space-y-2');
expect(field).not.toBeNull();
fireEvent.click(within(field as HTMLElement).getByRole('button', { name: '保存' }));
openMobileCreationCard();
fireEvent.click(screen.getByRole('button', { name: '精细调整' }));
fireEvent.click(screen.getByRole('button', { name: '电脑横屏' }));
expect(actions.applyFieldOperations).toHaveBeenCalledWith(
[{ kind: 'set', path: 'output.aspect_ratio', value: '16:9' }],
['output.aspect_ratio'],
[
{ kind: 'set', path: 'output.aspect_ratio', value: '16:9' },
{ kind: 'set', path: 'output.orientation', value: 'landscape' },
],
[],
);
});
it('renders an immutable quote and confirms only its identity', () => {
it('shows a plain-language production confirmation and confirms only the Quote identity', () => {
const quote = designQuoteFixture();
quote.warnings = [{
code: 'reference_observation_fallback',
message: 'Reference observations were not reviewed by the frozen compiler.',
severity: 'warning',
path: 'references',
}];
const workspace = designWorkspaceFixture({
form: designFormFixture({ activeQuotes: [designQuoteFixture()] }),
form: designFormFixture({ activeQuotes: [quote] }),
});
const { actions } = prepareWorkspace(workspace);
render(<ImageCanvas />);
expect(screen.getByText('报价已冻结')).toBeInTheDocument();
openMobileCreationCard();
expect(screen.getByRole('heading', { name: '制作方案准备好了' })).toBeInTheDocument();
expect(screen.getByText('12')).toBeInTheDocument();
expect(screen.getByText('有张参考图还没检查完成,AI 会谨慎使用它。')).toBeInTheDocument();
expect(screen.queryByText(/frozen compiler/i)).not.toBeInTheDocument();
expect(screen.queryByDisplayValue(/prompt/i)).not.toBeInTheDocument();
fireEvent.click(screen.getByRole('button', { name: '确认生成' }));
expect(screen.queryByText(/规格版本|报价已冻结|生成方式|不可变/)).not.toBeInTheDocument();
fireEvent.click(screen.getByRole('button', { name: '花 12 设计点开始制作' }));
expect(actions.confirmGeneration).toHaveBeenCalledWith('quote-1');
});
@@ -123,13 +138,13 @@ describe('Living Form Canvas page', () => {
expect(actions.sendChat).not.toHaveBeenCalled();
});
it('explains and safely retries a command whose accepted result is unknown', () => {
it('explains an unknown accepted result without suggesting a second production', () => {
const { actions } = prepareWorkspace();
useImageWorkspaceStore.setState({
pendingOperations: {
'operation-1': {
id: 'operation-1',
label: '编译生成方案',
label: '准备制作方案',
command: {
kind: 'request_quote',
workspaceId: 'workspace-1',
@@ -147,8 +162,10 @@ describe('Living Form Canvas page', () => {
});
render(<ImageCanvas />);
expect(screen.getByText('有操作结果尚未确认')).toBeInTheDocument();
fireEvent.click(screen.getByRole('button', { name: '安全重试' }));
openMobileCreationCard();
expect(screen.getByText('还在确认刚才的操作')).toBeInTheDocument();
expect(screen.getByText(/不会重复制作或重复扣费/)).toBeInTheDocument();
fireEvent.click(screen.getByRole('button', { name: '查看原来的结果' }));
expect(actions.retryOperation).toHaveBeenCalledWith('operation-1');
});
@@ -165,7 +182,7 @@ describe('Living Form Canvas page', () => {
window.addEventListener('niancode:image-workspace:create-project', listener);
render(<ImageCanvas />);
fireEvent.click(screen.getByRole('button', { name: '新建设计项目' }));
fireEvent.click(screen.getByRole('button', { name: '开始第一个创作' }));
expect(listener).toHaveBeenCalledOnce();
window.removeEventListener('niancode:image-workspace:create-project', listener);
});