1
This commit is contained in:
@@ -5,9 +5,11 @@ import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import type { CustomWorldAgentSessionSnapshot } from '../../../packages/shared/src/contracts/customWorldAgent';
|
||||
import type { CustomWorldWorkSummary } from '../../../packages/shared/src/contracts/customWorldWorkSummary';
|
||||
import type { RpgCreationResultView } from '../../../packages/shared/src/contracts/rpgCreationResultView';
|
||||
import { WorldType, type CustomWorldProfile } from '../../types';
|
||||
import {
|
||||
executeRpgCreationAction,
|
||||
getRpgCreationOperation,
|
||||
upsertRpgWorldProfile,
|
||||
} from '../../services/rpg-creation';
|
||||
import { useRpgCreationResultAutosave } from './useRpgCreationResultAutosave';
|
||||
@@ -109,16 +111,42 @@ function buildSession(
|
||||
};
|
||||
}
|
||||
|
||||
function buildResultView(
|
||||
overrides: Partial<RpgCreationResultView> = {},
|
||||
): RpgCreationResultView {
|
||||
const session = overrides.session ?? buildSession();
|
||||
return {
|
||||
session,
|
||||
profile: null,
|
||||
profileSource: 'none',
|
||||
targetStage: 'agent-workspace',
|
||||
generationViewSource: null,
|
||||
resultViewSource: null,
|
||||
canAutosaveLibrary: false,
|
||||
canSyncResultProfile: false,
|
||||
publishReady: false,
|
||||
canEnterWorld: false,
|
||||
blockerCount: 0,
|
||||
recoveryAction: 'continue_agent',
|
||||
recoveryReason: null,
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
describe('RPG Agent 草稿恢复', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it('作品摘要已有对象数量但 session 没有 draftProfile 时恢复 Agent 页面', async () => {
|
||||
const syncAgentSessionSnapshot = vi.fn(async () =>
|
||||
buildSession({
|
||||
stage: 'clarifying',
|
||||
draftProfile: null,
|
||||
const syncAgentCreationResultView = vi.fn(async () =>
|
||||
buildResultView({
|
||||
session: buildSession({
|
||||
stage: 'clarifying',
|
||||
draftProfile: null,
|
||||
}),
|
||||
targetStage: 'agent-workspace',
|
||||
recoveryAction: 'continue_agent',
|
||||
}),
|
||||
);
|
||||
const setSelectionStage = vi.fn();
|
||||
@@ -150,9 +178,9 @@ describe('RPG Agent 草稿恢复', () => {
|
||||
refreshCustomWorldWorks: vi.fn(async () => []),
|
||||
refreshPublishedGallery: vi.fn(async () => []),
|
||||
persistAgentUiState,
|
||||
syncAgentSessionSnapshot,
|
||||
buildDraftResultProfile: (session) =>
|
||||
(session?.draftProfile as CustomWorldProfile | null) ?? null,
|
||||
syncAgentCreationResultView,
|
||||
buildDraftResultProfile: (view) =>
|
||||
(view?.profile as CustomWorldProfile | null) ?? null,
|
||||
suppressAgentDraftResultAutoOpen,
|
||||
releaseAgentDraftResultAutoOpenSuppression: vi.fn(),
|
||||
resetAutoSaveTrackingToIdle: vi.fn(),
|
||||
@@ -183,7 +211,7 @@ describe('RPG Agent 草稿恢复', () => {
|
||||
});
|
||||
});
|
||||
|
||||
expect(syncAgentSessionSnapshot).toHaveBeenCalledWith('agent-session-1');
|
||||
expect(syncAgentCreationResultView).toHaveBeenCalledWith('agent-session-1');
|
||||
expect(suppressAgentDraftResultAutoOpen).toHaveBeenCalled();
|
||||
expect(persistAgentUiState).toHaveBeenCalledWith('agent-session-1', null);
|
||||
expect(setGeneratedCustomWorldProfile).toHaveBeenLastCalledWith(null);
|
||||
@@ -192,7 +220,7 @@ describe('RPG Agent 草稿恢复', () => {
|
||||
expect(setSelectionStage).not.toHaveBeenCalledWith('custom-world-result');
|
||||
});
|
||||
|
||||
it('Agent 结果页自动保存只刷新 session draftProfile,不触发 sync_result_profile', async () => {
|
||||
it('Agent 结果页自动保存先回写 session,再保存后端 result-view profile', async () => {
|
||||
const oldProfile = buildProfile('旧前端快照');
|
||||
const latestProfile = {
|
||||
...buildProfile('服务端草稿快照'),
|
||||
@@ -203,6 +231,36 @@ describe('RPG Agent 草稿恢复', () => {
|
||||
draftProfile: latestProfile as unknown as Record<string, unknown>,
|
||||
});
|
||||
const syncAgentSessionSnapshot = vi.fn(async () => latestSession);
|
||||
const syncAgentCreationResultView = vi.fn(async () =>
|
||||
buildResultView({
|
||||
session: latestSession,
|
||||
profile: latestProfile,
|
||||
profileSource: 'result_preview',
|
||||
targetStage: 'custom-world-result',
|
||||
resultViewSource: 'agent-draft',
|
||||
canAutosaveLibrary: true,
|
||||
canSyncResultProfile: true,
|
||||
recoveryAction: 'open_result',
|
||||
}),
|
||||
);
|
||||
vi.mocked(executeRpgCreationAction).mockResolvedValue({
|
||||
operation: {
|
||||
operationId: 'operation-sync-result',
|
||||
type: 'sync_result_profile',
|
||||
status: 'running',
|
||||
phaseLabel: '结果页同步中',
|
||||
phaseDetail: '正在同步结果页。',
|
||||
progress: 50,
|
||||
},
|
||||
});
|
||||
vi.mocked(getRpgCreationOperation).mockResolvedValue({
|
||||
operationId: 'operation-sync-result',
|
||||
type: 'sync_result_profile',
|
||||
status: 'completed',
|
||||
phaseLabel: '结果页已同步',
|
||||
phaseDetail: '结果页已同步。',
|
||||
progress: 100,
|
||||
});
|
||||
|
||||
vi.mocked(upsertRpgWorldProfile).mockResolvedValue({
|
||||
entry: {
|
||||
@@ -230,16 +288,6 @@ describe('RPG Agent 草稿恢复', () => {
|
||||
useRpgCreationResultAutosave({
|
||||
selectionStage: 'custom-world-result',
|
||||
activeAgentSessionId: 'agent-session-1',
|
||||
agentSession: buildSession({
|
||||
stage: 'object_refining',
|
||||
draftProfile: oldProfile as unknown as Record<string, unknown>,
|
||||
resultPreview: {
|
||||
publishReady: false,
|
||||
blockers: [],
|
||||
qualityFindings: [],
|
||||
sourceLabel: '旧预览',
|
||||
} as never,
|
||||
}),
|
||||
generatedCustomWorldProfile: oldProfile,
|
||||
isAgentDraftResultView: true,
|
||||
userId: 'user-1',
|
||||
@@ -250,8 +298,9 @@ describe('RPG Agent 草稿恢复', () => {
|
||||
refreshCustomWorldWorks: vi.fn(async () => []),
|
||||
persistAgentUiState: vi.fn(),
|
||||
syncAgentSessionSnapshot,
|
||||
buildDraftResultProfile: (session) =>
|
||||
(session?.draftProfile as CustomWorldProfile | null) ?? null,
|
||||
syncAgentCreationResultView,
|
||||
buildDraftResultProfile: (view) =>
|
||||
(view?.profile as CustomWorldProfile | null) ?? null,
|
||||
});
|
||||
|
||||
return null;
|
||||
@@ -266,13 +315,23 @@ describe('RPG Agent 草稿恢复', () => {
|
||||
vi.useRealTimers();
|
||||
|
||||
expect(syncAgentSessionSnapshot).toHaveBeenCalledWith('agent-session-1');
|
||||
expect(upsertRpgWorldProfile).toHaveBeenCalledWith(latestProfile, {
|
||||
sourceAgentSessionId: 'agent-session-1',
|
||||
expect(syncAgentCreationResultView).toHaveBeenCalledWith('agent-session-1');
|
||||
expect(executeRpgCreationAction).toHaveBeenCalledWith('agent-session-1', {
|
||||
action: 'sync_result_profile',
|
||||
profile: expect.objectContaining({
|
||||
id: oldProfile.id,
|
||||
name: oldProfile.name,
|
||||
}),
|
||||
});
|
||||
expect(
|
||||
vi.mocked(executeRpgCreationAction).mock.calls.some(
|
||||
([, payload]) => payload?.action === 'sync_result_profile',
|
||||
),
|
||||
).toBe(false);
|
||||
expect(upsertRpgWorldProfile).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
id: latestProfile.id,
|
||||
name: latestProfile.name,
|
||||
summary: latestProfile.summary,
|
||||
}),
|
||||
{
|
||||
sourceAgentSessionId: 'agent-session-1',
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user