refactor: 收口公开详情编辑意图

This commit is contained in:
2026-06-04 01:00:09 +08:00
parent e1134cc9ec
commit 7349c6df4f
6 changed files with 516 additions and 117 deletions

View File

@@ -6,10 +6,14 @@ import type { JumpHopGalleryCardResponse } from '../../../packages/shared/src/co
import type { Match3DWorkSummary } from '../../../packages/shared/src/contracts/match3dWorks';
import type { PuzzleRunSnapshot } from '../../../packages/shared/src/contracts/puzzleRuntimeSession';
import type { PuzzleWorkSummary } from '../../../packages/shared/src/contracts/puzzleWorkSummary';
import type { CustomWorldGalleryCard } from '../../../packages/shared/src/contracts/runtime';
import type {
CustomWorldGalleryCard,
CustomWorldLibraryEntry,
} from '../../../packages/shared/src/contracts/runtime';
import type { SquareHoleWorkSummary } from '../../../packages/shared/src/contracts/squareHoleWorks';
import type { VisualNovelWorkSummary } from '../../../packages/shared/src/contracts/visualNovel';
import type { WoodenFishGalleryCardResponse } from '../../../packages/shared/src/contracts/woodenFish';
import type { CustomWorldProfile } from '../../types';
import {
EDUTAINMENT_BABY_OBJECT_MATCH_TEMPLATE_ID,
EDUTAINMENT_BABY_OBJECT_MATCH_TEMPLATE_NAME,
@@ -31,11 +35,13 @@ import {
mapWoodenFishWorkToPublicWorkDetail,
type PlatformPublicWorkDetailKind,
type PlatformPublicWorkDetailOpenStrategy,
type PlatformPublicWorkEditIntentDeps,
type PlatformPublicWorkStartIntentDeps,
resolveActivePlatformPublicWorkAuthorEntry,
resolvePlatformPublicWorkActionMode,
resolvePlatformPublicWorkDetailOpenDecision,
resolvePlatformPublicWorkDetailOpenStrategy,
resolvePlatformPublicWorkEditIntent,
resolvePlatformPublicWorkLikeIntent,
resolvePlatformPublicWorkRemixIntent,
resolvePlatformPublicWorkStartIntent,
@@ -88,6 +94,18 @@ function buildRpgEntry(
};
}
function buildRpgLibraryEntry(
overrides: Partial<CustomWorldLibraryEntry<CustomWorldProfile>> = {},
): CustomWorldLibraryEntry<CustomWorldProfile> {
return {
...buildRpgEntry(overrides),
profile: {
id: overrides.profileId ?? 'rpg-profile',
} as unknown as CustomWorldProfile,
...overrides,
};
}
function buildTypedEntry<TSourceType extends PlatformGallerySourceType>(
sourceType: TSourceType,
overrides: TypedPlatformPublicGalleryCardOverrides<TSourceType> = {},
@@ -410,6 +428,20 @@ function buildStartIntentDeps(
};
}
function buildEditIntentDeps(
overrides: Partial<PlatformPublicWorkEditIntentDeps> = {},
): PlatformPublicWorkEditIntentDeps {
return {
selectedPuzzleDetail: null,
selectedRpgDetailEntry: null,
visualNovelWorks: [],
barkBattleGalleryEntries: [],
barkBattleWorks: [],
mapMatch3DWork: () => buildMatch3DWork(),
...overrides,
};
}
test('platform public work detail flow resolves detail kind for every play kind', () => {
const cases: Array<
[sourceType: PlatformGallerySourceType, kind: PlatformPublicWorkDetailKind]
@@ -435,7 +467,7 @@ test('platform public work detail flow resolves detail kind for every play kind'
});
test('platform public work detail flow resolves open strategy', () => {
const rpgEntry = buildRpgEntry();
const rpgEntry = buildRpgLibraryEntry();
const cases: Array<
[
entry: PlatformPublicGalleryCard,
@@ -522,7 +554,7 @@ test('platform public work detail flow resolves open strategy', () => {
});
test('platform public work detail flow maps work summaries to detail entries', () => {
const rpgEntry = buildRpgEntry();
const rpgEntry = buildRpgLibraryEntry();
expect(mapRpgGalleryCardToPublicWorkDetail(rpgEntry)).toBe(rpgEntry);
expect(mapPuzzleWorkToPublicWorkDetail(buildPuzzleWork())).toMatchObject({
@@ -843,6 +875,205 @@ test('platform public work detail flow resolves remix intent', () => {
});
});
test('platform public work detail flow resolves edit intent for draft-backed works', () => {
const bigFishEntry = buildTypedEntry('big-fish');
expect(resolvePlatformPublicWorkEditIntent(bigFishEntry, buildEditIntentDeps()))
.toEqual({
type: 'edit-big-fish',
work: mapPublicWorkDetailToBigFishWork(bigFishEntry),
});
const selectedPuzzleDetail = buildPuzzleWork({
profileId: 'puzzle-profile',
sourceSessionId: 'selected-puzzle-session',
});
expect(
resolvePlatformPublicWorkEditIntent(
buildTypedEntry('puzzle'),
buildEditIntentDeps({ selectedPuzzleDetail }),
),
).toEqual({
type: 'edit-puzzle',
work: selectedPuzzleDetail,
});
const puzzleEntry = buildTypedEntry('puzzle', {
profileId: 'fallback-puzzle-profile',
sourceSessionId: 'fallback-puzzle-session',
});
expect(
resolvePlatformPublicWorkEditIntent(
puzzleEntry,
buildEditIntentDeps({
selectedPuzzleDetail: buildPuzzleWork({ profileId: 'stale-profile' }),
}),
),
).toEqual({
type: 'edit-puzzle',
work: mapPublicWorkDetailToPuzzleWork(puzzleEntry),
});
expect(
resolvePlatformPublicWorkEditIntent(
buildTypedEntry('puzzle', { sourceSessionId: null }),
buildEditIntentDeps(),
),
).toEqual({
type: 'blocked',
errorMessage: '这份拼图作品缺少原草稿会话,暂时无法编辑。',
});
});
test('platform public work detail flow resolves edit intent for mapper-backed works', () => {
const match3DEntry = buildTypedEntry('match3d');
const match3DWork = buildMatch3DWork({ workId: 'editable-match3d-work' });
expect(
resolvePlatformPublicWorkEditIntent(
match3DEntry,
buildEditIntentDeps({
mapMatch3DWork: (entry) =>
entry === match3DEntry ? match3DWork : null,
}),
),
).toEqual({
type: 'edit-match3d',
work: match3DWork,
forceDraft: true,
});
expect(
resolvePlatformPublicWorkEditIntent(
match3DEntry,
buildEditIntentDeps({
mapMatch3DWork: () => buildMatch3DWork({ sourceSessionId: ' ' }),
}),
),
).toEqual({
type: 'blocked',
errorMessage: '这份抓大鹅作品缺少原草稿会话,暂时无法编辑。',
});
const squareHoleEntry = buildTypedEntry('square-hole', {
sourceSessionId: 'square-hole-session',
});
expect(
resolvePlatformPublicWorkEditIntent(squareHoleEntry, buildEditIntentDeps()),
).toEqual({
type: 'edit-square-hole',
work: mapPublicWorkDetailToSquareHoleWork(squareHoleEntry),
forceDraft: true,
});
expect(
resolvePlatformPublicWorkEditIntent(
buildTypedEntry('square-hole', { sourceSessionId: null }),
buildEditIntentDeps(),
),
).toEqual({
type: 'blocked',
errorMessage: '这份方洞挑战作品缺少原草稿会话,暂时无法编辑。',
});
});
test('platform public work detail flow resolves edit intent for cached work lookups', () => {
const visualNovelWork = buildVisualNovelWork();
expect(
resolvePlatformPublicWorkEditIntent(
buildTypedEntry('visual-novel'),
buildEditIntentDeps({ visualNovelWorks: [visualNovelWork] }),
),
).toEqual({
type: 'edit-visual-novel',
work: visualNovelWork,
forceDraft: true,
});
expect(
resolvePlatformPublicWorkEditIntent(
buildTypedEntry('visual-novel'),
buildEditIntentDeps(),
),
).toEqual({
type: 'blocked',
errorMessage: '这份视觉小说缺少可编辑草稿。',
});
const entry = buildTypedEntry('bark-battle');
const galleryWork = buildBarkBattleWork({
workId: 'bark-battle-work',
draftId: 'gallery-draft',
});
const loadedWork = buildBarkBattleWork({
workId: 'bark-battle-work',
draftId: 'loaded-draft',
});
expect(
resolvePlatformPublicWorkEditIntent(
entry,
buildEditIntentDeps({
barkBattleGalleryEntries: [galleryWork],
barkBattleWorks: [loadedWork],
}),
),
).toEqual({
type: 'edit-bark-battle',
work: loadedWork,
forceDraft: true,
});
expect(
resolvePlatformPublicWorkEditIntent(
buildTypedEntry('bark-battle', { sourceSessionId: null }),
buildEditIntentDeps(),
),
).toEqual({
type: 'blocked',
errorMessage: '这份汪汪声浪缺少可编辑草稿。',
});
});
test('platform public work detail flow resolves edit intent for unsupported and deferred works', () => {
expect(
resolvePlatformPublicWorkEditIntent(
buildTypedEntry('jump-hop'),
buildEditIntentDeps(),
),
).toEqual({
type: 'blocked',
errorMessage: '这份跳一跳作品暂时请从作品架编辑。',
});
expect(
resolvePlatformPublicWorkEditIntent(
buildTypedEntry('wooden-fish'),
buildEditIntentDeps(),
),
).toEqual({
type: 'blocked',
errorMessage: '这份敲木鱼作品暂时请从作品架编辑。',
});
const edutainmentEntry = buildTypedEntry('edutainment');
expect(
resolvePlatformPublicWorkEditIntent(edutainmentEntry, buildEditIntentDeps()),
).toEqual({
type: 'resolve-edutainment-draft',
entry: edutainmentEntry,
});
const rpgEntry = buildRpgLibraryEntry();
expect(
resolvePlatformPublicWorkEditIntent(
rpgEntry,
buildEditIntentDeps({ selectedRpgDetailEntry: rpgEntry }),
),
).toEqual({
type: 'edit-rpg-gallery',
entry: rpgEntry,
});
expect(
resolvePlatformPublicWorkEditIntent(rpgEntry, buildEditIntentDeps()),
).toEqual({
type: 'blocked',
errorMessage: '作品详情尚未读取完成。',
});
});
test('platform public work detail flow resolves start intent for direct launches', () => {
const bigFishEntry = buildTypedEntry('big-fish');
expect(