refactor: 收口创作恢复URL模型
This commit is contained in:
@@ -0,0 +1,224 @@
|
||||
import { describe, expect, test } from 'vitest';
|
||||
|
||||
import type { BarkBattleDraftConfig } from '../../../packages/shared/src/contracts/barkBattle';
|
||||
import type { BigFishSessionSnapshotResponse } from '../../../packages/shared/src/contracts/bigFish';
|
||||
import type { BabyObjectMatchDraft } from '../../../packages/shared/src/contracts/edutainmentBabyObject';
|
||||
import type { Match3DAgentSessionSnapshot } from '../../../packages/shared/src/contracts/match3dAgent';
|
||||
import type { PuzzleAgentSessionSnapshot } from '../../../packages/shared/src/contracts/puzzleAgentSession';
|
||||
import type { PuzzleWorkSummary } from '../../../packages/shared/src/contracts/puzzleWorkSummary';
|
||||
import type { SquareHoleSessionSnapshot } from '../../../packages/shared/src/contracts/squareHoleAgent';
|
||||
import type { VisualNovelAgentSessionSnapshot } from '../../../packages/shared/src/contracts/visualNovel';
|
||||
import type {
|
||||
JumpHopSessionSnapshotResponse,
|
||||
JumpHopWorkProfileResponse,
|
||||
} from '../../services/jump-hop/jumpHopClient';
|
||||
import type {
|
||||
WoodenFishSessionSnapshotResponse,
|
||||
WoodenFishWorkProfileResponse,
|
||||
} from '../../services/wooden-fish/woodenFishClient';
|
||||
import {
|
||||
buildBabyObjectMatchCreationUrlState,
|
||||
buildBarkBattleCreationUrlState,
|
||||
buildBigFishCreationUrlState,
|
||||
buildJumpHopCreationUrlState,
|
||||
buildMatch3DCreationUrlState,
|
||||
buildPuzzleCreationUrlState,
|
||||
buildPuzzleDraftRuntimeUrlState,
|
||||
buildPuzzlePublishedRuntimeUrlState,
|
||||
buildPuzzleRuntimeUrlStateKey,
|
||||
buildSquareHoleCreationUrlState,
|
||||
buildVisualNovelCreationUrlState,
|
||||
buildWoodenFishCreationUrlState,
|
||||
hasCreationUrlStateValue,
|
||||
hasPuzzleRuntimeUrlStateValue,
|
||||
normalizeCreationUrlValue,
|
||||
} from './platformCreationUrlStateModel';
|
||||
|
||||
describe('platformCreationUrlStateModel', () => {
|
||||
test('normalizes private creation url state values', () => {
|
||||
expect(normalizeCreationUrlValue(' session-1 ')).toBe('session-1');
|
||||
expect(normalizeCreationUrlValue(' ')).toBeNull();
|
||||
expect(
|
||||
hasCreationUrlStateValue({
|
||||
sessionId: ' ',
|
||||
profileId: null,
|
||||
draftId: undefined,
|
||||
workId: 'work-1',
|
||||
}),
|
||||
).toBe(true);
|
||||
expect(hasCreationUrlStateValue({})).toBe(false);
|
||||
});
|
||||
|
||||
test('builds creation restore state for core session based plays', () => {
|
||||
expect(
|
||||
buildBigFishCreationUrlState({
|
||||
sessionId: ' big-fish-session-1 ',
|
||||
} as BigFishSessionSnapshotResponse),
|
||||
).toEqual({
|
||||
sessionId: 'big-fish-session-1',
|
||||
workId: 'big-fish-work-big-fish-session-1',
|
||||
});
|
||||
|
||||
expect(
|
||||
buildMatch3DCreationUrlState({
|
||||
sessionId: 'match3d-session-1',
|
||||
draft: { profileId: 'match3d-profile-draft' },
|
||||
} as Match3DAgentSessionSnapshot),
|
||||
).toEqual({
|
||||
sessionId: 'match3d-session-1',
|
||||
profileId: 'match3d-profile-draft',
|
||||
workId: 'match3d-profile-draft',
|
||||
});
|
||||
|
||||
expect(
|
||||
buildSquareHoleCreationUrlState({
|
||||
sessionId: 'square-session-1',
|
||||
publishedProfileId: 'square-profile-published',
|
||||
} as SquareHoleSessionSnapshot),
|
||||
).toEqual({
|
||||
sessionId: 'square-session-1',
|
||||
profileId: 'square-profile-published',
|
||||
workId: 'square-profile-published',
|
||||
});
|
||||
|
||||
expect(
|
||||
buildVisualNovelCreationUrlState({
|
||||
sessionId: 'visual-session-1',
|
||||
draft: { profileId: 'visual-profile-1' },
|
||||
} as VisualNovelAgentSessionSnapshot),
|
||||
).toEqual({
|
||||
sessionId: 'visual-session-1',
|
||||
profileId: 'visual-profile-1',
|
||||
workId: 'visual-profile-1',
|
||||
});
|
||||
});
|
||||
|
||||
test('builds puzzle creation and runtime query state', () => {
|
||||
expect(
|
||||
buildPuzzleCreationUrlState({
|
||||
sessionId: 'puzzle-session-ocean',
|
||||
} as PuzzleAgentSessionSnapshot),
|
||||
).toEqual({
|
||||
sessionId: 'puzzle-session-ocean',
|
||||
profileId: 'puzzle-profile-ocean',
|
||||
workId: 'puzzle-work-ocean',
|
||||
});
|
||||
|
||||
const draftRuntime = buildPuzzleDraftRuntimeUrlState(
|
||||
buildPuzzleWork({
|
||||
profileId: 'puzzle-profile-ocean',
|
||||
sourceSessionId: null,
|
||||
}),
|
||||
'level-2',
|
||||
);
|
||||
expect(draftRuntime).toEqual({
|
||||
mode: 'draft',
|
||||
runtimeSessionId: 'puzzle-session-ocean',
|
||||
runtimeProfileId: 'puzzle-profile-ocean',
|
||||
runtimeLevelId: 'level-2',
|
||||
});
|
||||
expect(hasPuzzleRuntimeUrlStateValue(draftRuntime)).toBe(true);
|
||||
expect(buildPuzzleRuntimeUrlStateKey(draftRuntime)).toBe(
|
||||
'draft|puzzle-session-ocean|puzzle-profile-ocean|level-2|',
|
||||
);
|
||||
|
||||
const publishedRuntime = buildPuzzlePublishedRuntimeUrlState(
|
||||
buildPuzzleWork({ profileId: 'puzzle-profile-ocean' }),
|
||||
);
|
||||
expect(publishedRuntime.mode).toBe('published');
|
||||
expect(publishedRuntime.runtimeProfileId).toBe('puzzle-profile-ocean');
|
||||
expect(publishedRuntime.publicWorkCode).toMatch(/^PZ-/u);
|
||||
});
|
||||
|
||||
test('builds creation state for work backed plays with work id priority', () => {
|
||||
expect(
|
||||
buildJumpHopCreationUrlState({
|
||||
session: {
|
||||
sessionId: 'jump-session-1',
|
||||
draft: { profileId: 'jump-profile-draft' },
|
||||
} as JumpHopSessionSnapshotResponse,
|
||||
work: {
|
||||
summary: {
|
||||
profileId: 'jump-profile-work',
|
||||
workId: 'jump-work-1',
|
||||
},
|
||||
} as JumpHopWorkProfileResponse,
|
||||
}),
|
||||
).toEqual({
|
||||
sessionId: 'jump-session-1',
|
||||
profileId: 'jump-profile-work',
|
||||
workId: 'jump-work-1',
|
||||
});
|
||||
|
||||
expect(
|
||||
buildWoodenFishCreationUrlState({
|
||||
session: {
|
||||
sessionId: 'wood-session-1',
|
||||
draft: { profileId: 'wood-profile-draft' },
|
||||
} as WoodenFishSessionSnapshotResponse,
|
||||
work: {
|
||||
summary: {
|
||||
profileId: 'wood-profile-work',
|
||||
workId: 'wood-work-1',
|
||||
},
|
||||
} as WoodenFishWorkProfileResponse,
|
||||
}),
|
||||
).toEqual({
|
||||
sessionId: 'wood-session-1',
|
||||
profileId: 'wood-profile-work',
|
||||
draftId: 'wood-profile-work',
|
||||
workId: 'wood-work-1',
|
||||
});
|
||||
});
|
||||
|
||||
test('builds creation state for draft backed local plays', () => {
|
||||
expect(
|
||||
buildBarkBattleCreationUrlState({
|
||||
draftId: 'bark-draft-1',
|
||||
workId: 'bark-work-1',
|
||||
} as BarkBattleDraftConfig),
|
||||
).toEqual({
|
||||
draftId: 'bark-draft-1',
|
||||
workId: 'bark-work-1',
|
||||
});
|
||||
|
||||
expect(
|
||||
buildBabyObjectMatchCreationUrlState({
|
||||
draftId: 'baby-draft-1',
|
||||
profileId: 'baby-profile-1',
|
||||
} as BabyObjectMatchDraft),
|
||||
).toEqual({
|
||||
profileId: 'baby-profile-1',
|
||||
draftId: 'baby-draft-1',
|
||||
workId: 'baby-profile-1',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function buildPuzzleWork(
|
||||
overrides: Partial<PuzzleWorkSummary> = {},
|
||||
): PuzzleWorkSummary {
|
||||
return {
|
||||
workId: 'puzzle-work-base',
|
||||
profileId: 'puzzle-profile-base',
|
||||
ownerUserId: 'user-1',
|
||||
sourceSessionId: 'puzzle-session-base',
|
||||
authorDisplayName: '测试作者',
|
||||
workTitle: '潮雾拼图',
|
||||
workDescription: '潮雾港口拼图。',
|
||||
levelName: '潮雾拼图',
|
||||
summary: '潮雾港口拼图。',
|
||||
themeTags: [],
|
||||
coverImageSrc: null,
|
||||
coverAssetId: null,
|
||||
publicationStatus: 'draft',
|
||||
updatedAt: '2026-06-03T08:00:00.000Z',
|
||||
publishedAt: null,
|
||||
playCount: 0,
|
||||
remixCount: 0,
|
||||
likeCount: 0,
|
||||
publishReady: false,
|
||||
levels: [],
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user