Files
Genarrative/src/components/image-editor/useCanvasGenerationDialogs.test.tsx
T
kdletters 37a738e271 拆分图片画布生成对象注册表
新增画布生成对象 dialog 管理 hook
补充生成对象注册表 hook 单测
调整 Lovart 式画布背景色板弹层
更新图片画布前端拆分跟踪文档
2026-06-17 05:29:04 +08:00

178 lines
5.7 KiB
TypeScript

/* @vitest-environment jsdom */
import { act, render, screen } from '@testing-library/react';
import { describe, expect, it, vi } from 'vitest';
import type { CanvasGenerationDialogState } from './ImageCanvasEditorTypes';
import { useCanvasGenerationDialogs } from './useCanvasGenerationDialogs';
function createDialog(
mode: CanvasGenerationDialogState['mode'],
prompt: string,
): Omit<CanvasGenerationDialogState, 'id'> {
return {
mode,
prompt,
status: 'idle',
composerOpen: true,
placeholder: {
x: mode === 'character' ? 30 : 10,
y: mode === 'character' ? 40 : 20,
width: 320,
height: 240,
originalWidth: 320,
originalHeight: 240,
},
};
}
function GenerationDialogsHarness({ onActivate }: { onActivate: () => void }) {
const dialogs = useCanvasGenerationDialogs({ onActivate });
const activeId = dialogs.activeCanvasGenerationDialog?.id ?? '-';
const activePrompt = dialogs.activeCanvasGenerationDialog?.prompt ?? '-';
const inactiveIds = dialogs.inactiveGenerateDialogs
.map((dialog) => `${dialog.id}:${dialog.prompt}:${dialog.composerOpen}`)
.join('|');
const allPrompts = dialogs.canvasGenerationDialogs
.map((dialog) => dialog.prompt)
.join(',');
return (
<div>
<span data-testid="active-id">{activeId}</span>
<span data-testid="active-prompt">{activePrompt}</span>
<span data-testid="inactive">{inactiveIds}</span>
<span data-testid="all-prompts">{allPrompts}</span>
<span data-testid="placeholder-x">
{String(
dialogs.getGeneratingDialogPlaceholder(
dialogs.activeCanvasGenerationDialog ?? {
mode: 'generate',
prompt: 'fallback',
status: 'idle',
},
)?.x ?? '-',
)}
</span>
<button
type="button"
onClick={() => dialogs.openCanvasGenerationDialog(createDialog('generate', 'first'))}
>
open first
</button>
<button
type="button"
onClick={() => dialogs.openCanvasGenerationDialog(createDialog('character', 'second'))}
>
open second
</button>
<button
type="button"
onClick={() => {
const target = dialogs.inactiveGenerateDialogs[0];
if (target) {
dialogs.activateCanvasGenerationDialog(target);
}
}}
>
activate inactive
</button>
<button
type="button"
onClick={() => {
const target = dialogs.activeCanvasGenerationDialog;
if (target) {
dialogs.updateCanvasGenerationDialogById(target.id, (dialog) => ({
...dialog,
status: 'generating',
placeholder: dialog.placeholder
? {
...dialog.placeholder,
x: 99,
}
: dialog.placeholder,
}));
}
}}
>
update active
</button>
<button
type="button"
onClick={() => {
const target = dialogs.activeCanvasGenerationDialog;
if (target) {
dialogs.removeCanvasGenerationDialogById(target.id);
}
}}
>
remove active
</button>
<button
type="button"
onClick={() => {
const target = dialogs.activeCanvasGenerationDialog;
if (target) {
dialogs.updateCanvasGenerationDialogById(target.id, (dialog) => ({
...dialog,
sourceLayerId: 'layer-a',
}));
}
}}
>
bind layer
</button>
<button
type="button"
onClick={() => dialogs.removeCanvasGenerationDialogsByLayerId('layer-a')}
>
remove layer dialogs
</button>
</div>
);
}
describe('useCanvasGenerationDialogs', () => {
it('archives, activates, updates, and removes canvas generation dialogs', () => {
const onActivate = vi.fn();
render(<GenerationDialogsHarness onActivate={onActivate} />);
act(() => screen.getByRole('button', { name: 'open first' }).click());
expect(screen.getByTestId('active-prompt').textContent).toBe('first');
expect(screen.getByTestId('all-prompts').textContent).toBe('first');
act(() => screen.getByRole('button', { name: 'open second' }).click());
expect(screen.getByTestId('active-prompt').textContent).toBe('second');
expect(screen.getByTestId('inactive').textContent).toContain(
'generation-dialog-1:first:false',
);
expect(screen.getByTestId('all-prompts').textContent).toBe(
'first,second',
);
act(() =>
screen.getByRole('button', { name: 'activate inactive' }).click(),
);
expect(onActivate).toHaveBeenCalledTimes(1);
expect(screen.getByTestId('active-prompt').textContent).toBe('first');
expect(screen.getByTestId('inactive').textContent).toContain(
'generation-dialog-2:second:false',
);
act(() => screen.getByRole('button', { name: 'update active' }).click());
expect(screen.getByTestId('placeholder-x').textContent).toBe('99');
act(() => screen.getByRole('button', { name: 'bind layer' }).click());
act(() =>
screen.getByRole('button', { name: 'remove layer dialogs' }).click(),
);
expect(screen.getByTestId('active-prompt').textContent).toBe('-');
expect(screen.getByTestId('inactive').textContent).toContain('second');
act(() => screen.getByRole('button', { name: 'activate inactive' }).click());
act(() => screen.getByRole('button', { name: 'remove active' }).click());
expect(screen.getByTestId('active-prompt').textContent).toBe('-');
expect(screen.getByTestId('inactive').textContent).toBe('');
});
});