1
This commit is contained in:
607
src/services/customWorldAgentDraftResult.test.ts
Normal file
607
src/services/customWorldAgentDraftResult.test.ts
Normal file
@@ -0,0 +1,607 @@
|
||||
import { afterEach, expect, test } from 'vitest';
|
||||
|
||||
import type { CustomWorldAgentSessionSnapshot } from '../../packages/shared/src/contracts/customWorldAgent';
|
||||
import { buildCustomWorldRuntimeCharacters } from '../data/characterPresets';
|
||||
import { setRuntimeCustomWorldProfile } from '../data/customWorldRuntime';
|
||||
import { getScenePresetsByWorld } from '../data/scenePresets';
|
||||
import { WorldType } from '../types';
|
||||
import { buildCustomWorldProfileFromAgentDraft } from './customWorldAgentDraftResult';
|
||||
|
||||
afterEach(() => {
|
||||
setRuntimeCustomWorldProfile(null);
|
||||
});
|
||||
|
||||
const session: CustomWorldAgentSessionSnapshot = {
|
||||
sessionId: 'session-1',
|
||||
stage: 'object_refining',
|
||||
focusCardId: null,
|
||||
creatorIntent: {
|
||||
sourceMode: 'card',
|
||||
worldHook: '被海雾吞没的旧航路群岛',
|
||||
playerPremise: '玩家回到群岛调查沉船真相。',
|
||||
themeKeywords: ['海雾', '旧航路'],
|
||||
toneDirectives: ['压抑', '悬疑'],
|
||||
openingSituation: '首夜就有陌生船只闯入禁航区。',
|
||||
coreConflicts: ['航运公会与守灯会争夺航路控制权'],
|
||||
keyFactions: [],
|
||||
keyCharacters: [],
|
||||
keyLandmarks: [],
|
||||
iconicElements: ['会移动的海雾'],
|
||||
forbiddenDirectives: [],
|
||||
rawSettingText: '',
|
||||
},
|
||||
creatorIntentReadiness: {
|
||||
isReady: true,
|
||||
completedKeys: [],
|
||||
missingKeys: [],
|
||||
},
|
||||
anchorPack: {},
|
||||
lockState: {},
|
||||
draftProfile: {
|
||||
name: '潮雾列岛',
|
||||
subtitle: '旧灯塔与失控航路',
|
||||
summary: '第一版世界底稿已经整理完成。',
|
||||
tone: '压抑、潮湿、悬疑',
|
||||
playerGoal: '查清沉船与禁航区异动的真相。',
|
||||
majorFactions: ['守灯会', '航运公会'],
|
||||
coreConflicts: ['守灯会与航运公会争夺旧航路控制权'],
|
||||
playableNpcs: [
|
||||
{
|
||||
id: 'playable-1',
|
||||
name: '沈砺',
|
||||
title: '旧航路引路人',
|
||||
role: '关键同行者',
|
||||
publicIdentity: '最熟悉旧航路的人。',
|
||||
publicMask: '看上去像可靠旧友。',
|
||||
currentPressure: '他必须在两股势力间站队。',
|
||||
hiddenHook: '暗中替沉船商盟引路。',
|
||||
relationToPlayer: '旧友兼潜在背叛者',
|
||||
threadIds: ['thread-1'],
|
||||
summary: '他像旧友,但也像一把始终没收回鞘的刀。',
|
||||
},
|
||||
],
|
||||
storyNpcs: [
|
||||
{
|
||||
id: 'story-1',
|
||||
name: '顾潮音',
|
||||
title: '守灯会值夜人',
|
||||
role: '场景关键角色',
|
||||
publicIdentity: '负责夜间巡灯与封锁。',
|
||||
publicMask: '对外一直冷静克制。',
|
||||
currentPressure: '她知道更多禁航区真相。',
|
||||
hiddenHook: '曾亲眼见过失控海雾吞船。',
|
||||
relationToPlayer: '最早愿意交换线索的人',
|
||||
threadIds: ['thread-1'],
|
||||
summary: '她总像比所有人更早知道海雾会往哪一侧压下来。',
|
||||
},
|
||||
],
|
||||
landmarks: [
|
||||
{
|
||||
id: 'landmark-1',
|
||||
name: '回潮旧灯塔',
|
||||
purpose: '观察雾潮与往来船只',
|
||||
mood: '潮湿、压抑、风声不止',
|
||||
importance: '开局核心场景',
|
||||
characterIds: ['story-1'],
|
||||
threadIds: ['thread-1'],
|
||||
summary: '旧灯塔是整片群岛最先看见异动的地方。',
|
||||
},
|
||||
],
|
||||
factions: [],
|
||||
threads: [],
|
||||
chapters: [],
|
||||
worldHook: '被海雾吞没的旧航路群岛',
|
||||
playerPremise: '玩家回到群岛调查沉船真相。',
|
||||
openingSituation: '首夜就有陌生船只闯入禁航区。',
|
||||
iconicElements: ['会移动的海雾'],
|
||||
sourceAnchorSummary: '海雾、旧灯塔、失控航路。',
|
||||
},
|
||||
messages: [],
|
||||
draftCards: [],
|
||||
pendingClarifications: [],
|
||||
suggestedActions: [],
|
||||
recommendedReplies: [],
|
||||
qualityFindings: [],
|
||||
assetCoverage: {
|
||||
roleAssets: [],
|
||||
sceneAssets: [],
|
||||
allRoleAssetsReady: false,
|
||||
allSceneAssetsReady: false,
|
||||
},
|
||||
updatedAt: '2026-04-15T10:00:00.000Z',
|
||||
};
|
||||
|
||||
function buildBackstoryReveal(label: string) {
|
||||
return {
|
||||
publicSummary: `${label}的公开背景`,
|
||||
privateChatUnlockAffinity: 40,
|
||||
chapters: [
|
||||
{
|
||||
id: `${label}-surface`,
|
||||
title: '表层来意',
|
||||
affinityRequired: 15,
|
||||
teaser: `${label}先只肯说表面的来意。`,
|
||||
content: `${label}表面上只愿意谈当前局势。`,
|
||||
contextSnippet: `${label}表面上还在收着话。`,
|
||||
},
|
||||
{
|
||||
id: `${label}-scar`,
|
||||
title: '旧事裂痕',
|
||||
affinityRequired: 30,
|
||||
teaser: `${label}背后还有一段旧伤。`,
|
||||
content: `${label}曾在旧案里留下无法轻易揭开的伤口。`,
|
||||
contextSnippet: `${label}和旧案之间有一段没说开的裂痕。`,
|
||||
},
|
||||
{
|
||||
id: `${label}-hidden`,
|
||||
title: '隐藏执念',
|
||||
affinityRequired: 60,
|
||||
teaser: `${label}真正想追的不是表面那件事。`,
|
||||
content: `${label}真正挂着的是旧案里还没结的那条线。`,
|
||||
contextSnippet: `${label}真正执念指向旧案深处。`,
|
||||
},
|
||||
{
|
||||
id: `${label}-final`,
|
||||
title: '最终底牌',
|
||||
affinityRequired: 90,
|
||||
teaser: `${label}手里还压着最后一张牌。`,
|
||||
content: `${label}手里还握着能直接证明真相的关键证据。`,
|
||||
contextSnippet: `${label}最后的底牌足以改写局势。`,
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
function buildLegacyResultProfile() {
|
||||
return {
|
||||
id: 'legacy-profile-1',
|
||||
settingText: '被海雾吞没的旧航路群岛',
|
||||
name: '旧版完整结果',
|
||||
subtitle: '直接展示',
|
||||
summary: '优先使用服务端编译好的旧版 profile。',
|
||||
tone: '压抑',
|
||||
playerGoal: '查明真相',
|
||||
templateWorldType: WorldType.WUXIA,
|
||||
compatibilityTemplateWorldType: WorldType.WUXIA,
|
||||
majorFactions: ['守灯会', '航运公会'],
|
||||
coreConflicts: ['争夺航路控制权', '沉船真相'],
|
||||
attributeSchema: {
|
||||
id: 'schema:test',
|
||||
worldId: 'CUSTOM',
|
||||
schemaVersion: 1,
|
||||
schemaName: '测试',
|
||||
generatedFrom: {
|
||||
worldType: WorldType.CUSTOM,
|
||||
worldName: '旧版完整结果',
|
||||
settingSummary: '测试',
|
||||
tone: '测试',
|
||||
conflictCore: '测试',
|
||||
},
|
||||
slots: [],
|
||||
},
|
||||
playableNpcs: [
|
||||
{
|
||||
id: 'playable-1',
|
||||
name: '沈砺',
|
||||
title: '旧航路引路人',
|
||||
role: '关键同行者',
|
||||
description: '最熟悉旧航路的人。',
|
||||
backstory: '曾在沉船夜里带着半支船队逃出海雾。',
|
||||
personality: '表面沉稳,心里一直在算退路。',
|
||||
motivation: '想赶在守灯会封航前查清真相。',
|
||||
combatStyle: '借地形和潮路换位,先拉扯再压近。',
|
||||
initialAffinity: 18,
|
||||
relationshipHooks: ['旧友', '沉船旧案'],
|
||||
tags: ['潮路', '引路'],
|
||||
backstoryReveal: buildBackstoryReveal('沈砺'),
|
||||
skills: [
|
||||
{
|
||||
id: 'skill-playable-1',
|
||||
name: '潮行引路',
|
||||
summary: '踩着旧潮阶切线前压,替队伍打开角度。',
|
||||
style: '机动周旋',
|
||||
},
|
||||
{
|
||||
id: 'skill-playable-2',
|
||||
name: '回雾折返',
|
||||
summary: '借海雾遮住身位,再从侧线拉开。',
|
||||
style: '起手压制',
|
||||
},
|
||||
{
|
||||
id: 'skill-playable-3',
|
||||
name: '旧图定标',
|
||||
summary: '用旧潮图锁定退路和突入口。',
|
||||
style: '爆发终结',
|
||||
},
|
||||
],
|
||||
initialItems: [
|
||||
{
|
||||
id: 'item-playable-1',
|
||||
name: '旧潮短刃',
|
||||
category: '武器',
|
||||
quantity: 1,
|
||||
rarity: 'rare',
|
||||
description: '专门在湿滑甲板上近身换位用的短刃。',
|
||||
tags: ['潮路', '近战'],
|
||||
},
|
||||
{
|
||||
id: 'item-playable-2',
|
||||
name: '雾盐药包',
|
||||
category: '消耗品',
|
||||
quantity: 2,
|
||||
rarity: 'uncommon',
|
||||
description: '压住寒潮后遗症的随身药包。',
|
||||
tags: ['补给'],
|
||||
},
|
||||
{
|
||||
id: 'item-playable-3',
|
||||
name: '旧潮图残页',
|
||||
category: '专属物品',
|
||||
quantity: 1,
|
||||
rarity: 'rare',
|
||||
description: '只剩半页,但足够指向沉船夜的另一条线。',
|
||||
tags: ['线索', '真相'],
|
||||
},
|
||||
],
|
||||
attributeProfile: {
|
||||
schemaId: 'schema:test',
|
||||
values: { axis_a: 48, axis_b: 72, axis_c: 78 },
|
||||
topTraits: ['浪步', '舟识'],
|
||||
evidence: [
|
||||
{
|
||||
slotId: 'axis_b',
|
||||
reason: '长期依赖潮路换位与切线。',
|
||||
},
|
||||
],
|
||||
},
|
||||
narrativeProfile: {
|
||||
publicMask: '像个只想把旧路再走通一次的熟路人。',
|
||||
firstContactMask: '先别问太深,至少今晚这条路我还认得。',
|
||||
visibleLine: '他明面上只想护着队伍别再走错一次潮线。',
|
||||
hiddenLine: '真正让他回来的是沉船夜里被人卖掉的那条航线。',
|
||||
contradiction: '嘴上说只想带路,实际每一步都在找能对上旧案的证据。',
|
||||
debtOrBurden: '背着半支船队没能活着回来的旧债。',
|
||||
taboo: '最忌讳别人轻描淡写地提起那晚的失踪名单。',
|
||||
immediatePressure: '守灯会封航在即,他必须赶在封口前找到证据。',
|
||||
relatedThreadIds: ['thread-visible-1'],
|
||||
relatedScarIds: ['scar-1'],
|
||||
reactionHooks: ['沉船夜', '封航记录'],
|
||||
},
|
||||
templateCharacterId: 'archer-hero',
|
||||
},
|
||||
],
|
||||
storyNpcs: [
|
||||
{
|
||||
id: 'story-1',
|
||||
name: '顾潮音',
|
||||
title: '守灯会值夜人',
|
||||
role: '场景关键角色',
|
||||
description: '夜里巡灯与封锁禁航区的人。',
|
||||
backstory: '在失控海雾第一次吞船那夜,她是最后一个还留在灯塔顶的人。',
|
||||
personality: '冷静克制,但提到旧灯册时会显得过分警觉。',
|
||||
motivation: '想守住灯塔记录,也想找到谁先改动了禁航信号。',
|
||||
combatStyle: '借塔顶视角和风向压制,再用灯火错位扰乱。',
|
||||
initialAffinity: 8,
|
||||
relationshipHooks: ['禁航记录', '灯塔值夜'],
|
||||
tags: ['守灯会', '灯塔'],
|
||||
backstoryReveal: buildBackstoryReveal('顾潮音'),
|
||||
skills: [
|
||||
{
|
||||
id: 'skill-story-1',
|
||||
name: '夜潮灯语',
|
||||
summary: '借灯语与潮声干扰对方判断。',
|
||||
style: '起手压制',
|
||||
},
|
||||
{
|
||||
id: 'skill-story-2',
|
||||
name: '禁航暗潮',
|
||||
summary: '封住错误航线,把人逼回她熟悉的区域。',
|
||||
style: '机动周旋',
|
||||
},
|
||||
{
|
||||
id: 'skill-story-3',
|
||||
name: '回声巡线',
|
||||
summary: '借塔顶回声迅速锁定异动方向。',
|
||||
style: '爆发终结',
|
||||
},
|
||||
],
|
||||
initialItems: [
|
||||
{
|
||||
id: 'item-story-1',
|
||||
name: '值夜灯尺',
|
||||
category: '武器',
|
||||
quantity: 1,
|
||||
rarity: 'rare',
|
||||
description: '兼作警械和测灯尺的长柄器具。',
|
||||
tags: ['守灯会'],
|
||||
},
|
||||
{
|
||||
id: 'item-story-2',
|
||||
name: '防潮火折',
|
||||
category: '消耗品',
|
||||
quantity: 2,
|
||||
rarity: 'uncommon',
|
||||
description: '在潮雾里也能点亮的值夜火折。',
|
||||
tags: ['值夜'],
|
||||
},
|
||||
{
|
||||
id: 'item-story-3',
|
||||
name: '封灯令副本',
|
||||
category: '专属物品',
|
||||
quantity: 1,
|
||||
rarity: 'rare',
|
||||
description: '一份被她私下截留下来的封灯令副本。',
|
||||
tags: ['证据', '灯册'],
|
||||
},
|
||||
],
|
||||
imageSrc: '/custom/npcs/gu-chaoyin.png',
|
||||
attributeProfile: {
|
||||
schemaId: 'schema:test',
|
||||
values: { axis_a: 54, axis_c: 82, axis_f: 61 },
|
||||
topTraits: ['舟识', '回澜'],
|
||||
evidence: [
|
||||
{
|
||||
slotId: 'axis_c',
|
||||
reason: '长期依赖值夜观察和读灯判断局势。',
|
||||
},
|
||||
],
|
||||
},
|
||||
narrativeProfile: {
|
||||
publicMask: '守灯会值夜人,对外总像比别人更冷静一步。',
|
||||
firstContactMask: '想进塔就按规矩来,今晚谁都别想乱闯禁航区。',
|
||||
visibleLine: '她表面上只是在守灯和封线。',
|
||||
hiddenLine: '她真正盯着的是那本被改过的原始灯册。',
|
||||
contradiction: '越强调规矩,越像在掩住自己手里那份没上报的记录。',
|
||||
debtOrBurden: '她扛着第一次海雾吞船夜里没能及时点亮备用灯的旧责。',
|
||||
taboo: '最忌讳别人把那夜的失踪当成单纯天灾。',
|
||||
immediatePressure: '新的封航令马上要落下来,她必须先把旧灯册转出去。',
|
||||
relatedThreadIds: ['thread-visible-1'],
|
||||
relatedScarIds: ['scar-1'],
|
||||
reactionHooks: ['原始灯册', '封灯令'],
|
||||
},
|
||||
visual: {
|
||||
race: 'human',
|
||||
bodyColor: 'blue',
|
||||
headIndex: 2,
|
||||
hairColorIndex: 3,
|
||||
hairStyleFrame: 4,
|
||||
facialHairEnabled: false,
|
||||
facialHairColorIndex: 0,
|
||||
facialHairStyleFrame: 0,
|
||||
offHand: {
|
||||
type: 'magic',
|
||||
file: 'lantern.png',
|
||||
frameIndex: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
items: [
|
||||
{
|
||||
id: 'item-world-1',
|
||||
name: '潮雾罗盘',
|
||||
category: '饰品',
|
||||
rarity: 'rare',
|
||||
description: '会在假航灯附近偏转的旧罗盘。',
|
||||
tags: ['线索', '潮雾'],
|
||||
attributeResonance: {
|
||||
resonanceVector: { axis_c: 0.88, axis_e: 0.31 },
|
||||
explanation: '它会把持有者的判断力牵到潮雾最异常的地方。',
|
||||
},
|
||||
},
|
||||
],
|
||||
camp: {
|
||||
name: '回潮暂栖所',
|
||||
description: '能暂时收拢队伍、整理灯册与潮路线索的落脚点。',
|
||||
dangerLevel: 'low',
|
||||
imageSrc: '/custom/camp/huichao.png',
|
||||
},
|
||||
landmarks: [
|
||||
{
|
||||
id: 'landmark-1',
|
||||
name: '回潮旧灯塔',
|
||||
description: '被海雾啃旧的石塔仍在夜里维持着微弱灯火。',
|
||||
dangerLevel: 'high',
|
||||
imageSrc: '/custom/scenes/lighthouse.png',
|
||||
sceneNpcIds: ['story-1'],
|
||||
connections: [
|
||||
{
|
||||
targetLandmarkId: 'landmark-2',
|
||||
relativePosition: 'forward',
|
||||
summary: '沿着旧潮阶继续前压到雾栈尽头。',
|
||||
},
|
||||
],
|
||||
narrativeResidues: [
|
||||
{
|
||||
id: 'residue-1',
|
||||
title: '潮痕',
|
||||
visibleClue: '塔壁上有一圈不该出现在高处的潮痕。',
|
||||
linkedFactIds: ['fact-1'],
|
||||
linkedThreadIds: ['thread-visible-1'],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'landmark-2',
|
||||
name: '雾栈尽头',
|
||||
description: '旧栈桥尽头只剩断索、潮板和被抹掉的船名。',
|
||||
dangerLevel: 'high',
|
||||
imageSrc: '/custom/scenes/pier.png',
|
||||
sceneNpcIds: [],
|
||||
connections: [
|
||||
{
|
||||
targetLandmarkId: 'landmark-1',
|
||||
relativePosition: 'back',
|
||||
summary: '退回灯塔还能重新整理路线。',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
themePack: {
|
||||
id: 'theme-pack:tide',
|
||||
displayName: '潮雾悬疑',
|
||||
toneRange: ['压抑', '潮湿', '悬疑'],
|
||||
institutionLexicon: ['守灯会', '航运公会'],
|
||||
tabooLexicon: ['假航灯', '封灯令'],
|
||||
artifactClasses: ['旧潮图', '灯册', '罗盘'],
|
||||
actorArchetypes: ['引路人', '值夜人'],
|
||||
conflictForms: ['封航争夺', '旧案追查'],
|
||||
clueForms: ['灯册残页', '潮痕'],
|
||||
namingPatterns: ['潮', '雾', '灯'],
|
||||
revealStyles: ['试探式回应'],
|
||||
},
|
||||
storyGraph: {
|
||||
visibleThreads: [
|
||||
{
|
||||
id: 'thread-visible-1',
|
||||
title: '封航争夺',
|
||||
visibility: 'visible',
|
||||
summary: '守灯会与航运公会正在争夺旧航路的解释权。',
|
||||
conflictType: '控制权争夺',
|
||||
stakes: '谁能定义禁航区,就能决定谁能活着穿过去。',
|
||||
involvedFactionIds: ['faction-guard', 'faction-guild'],
|
||||
involvedActorIds: ['playable-1', 'story-1'],
|
||||
relatedLocationIds: ['landmark-1', 'landmark-2'],
|
||||
},
|
||||
],
|
||||
hiddenThreads: [
|
||||
{
|
||||
id: 'thread-hidden-1',
|
||||
title: '沉船旧案',
|
||||
visibility: 'hidden',
|
||||
summary: '沉船夜的航灯与灯册被人动过手脚。',
|
||||
conflictType: '真相遮蔽',
|
||||
stakes: '真相一旦坐实,守灯会内部会先崩。',
|
||||
involvedFactionIds: ['faction-guard'],
|
||||
involvedActorIds: ['playable-1', 'story-1'],
|
||||
relatedLocationIds: ['landmark-1'],
|
||||
},
|
||||
],
|
||||
scars: [
|
||||
{
|
||||
id: 'scar-1',
|
||||
title: '沉船夜',
|
||||
pastEvent: '假航灯把整支船队引进了死潮区。',
|
||||
publicResidue: '每逢潮夜,灯塔下总有人提起那晚的失踪名单。',
|
||||
hiddenTruth: '禁航记录和灯册都在事后被篡改过。',
|
||||
relatedActorIds: ['playable-1', 'story-1'],
|
||||
relatedLocationIds: ['landmark-1'],
|
||||
},
|
||||
],
|
||||
motifs: [
|
||||
{
|
||||
id: 'motif-1',
|
||||
label: '假航灯',
|
||||
semanticRole: 'technology',
|
||||
lexicalHints: ['假灯', '偏航', '禁航记录'],
|
||||
},
|
||||
],
|
||||
},
|
||||
knowledgeFacts: [
|
||||
{
|
||||
id: 'fact-1',
|
||||
title: '高处潮痕',
|
||||
content: '回潮旧灯塔的高处潮痕说明那晚海面高度异常。',
|
||||
ownerActorIds: ['story-1'],
|
||||
relatedThreadIds: ['thread-visible-1'],
|
||||
relatedScarIds: ['scar-1'],
|
||||
sourceType: 'scene',
|
||||
visibility: 'discoverable',
|
||||
sayability: 'indirect',
|
||||
},
|
||||
],
|
||||
threadContracts: [
|
||||
{
|
||||
id: 'contract-1',
|
||||
threadId: 'thread-visible-1',
|
||||
issuerActorId: 'story-1',
|
||||
narrativeType: 'investigation',
|
||||
currentStepId: 'contract-step-1',
|
||||
visibleStage: 1,
|
||||
steps: [
|
||||
{
|
||||
id: 'contract-step-1',
|
||||
title: '查灯塔',
|
||||
revealText: '先查清灯塔顶上的高处潮痕。',
|
||||
completionSignalIds: ['inspect_scene:landmark-1'],
|
||||
optionalFactIds: ['fact-1'],
|
||||
},
|
||||
],
|
||||
followupThreadIds: ['thread-hidden-1'],
|
||||
},
|
||||
],
|
||||
scenarioPackId: 'scenario-pack:tide',
|
||||
campaignPackId: 'campaign-pack:tide',
|
||||
generationMode: 'fast',
|
||||
generationStatus: 'key_only',
|
||||
};
|
||||
}
|
||||
|
||||
function buildProfileFromEmbeddedLegacyResult() {
|
||||
return buildCustomWorldProfileFromAgentDraft({
|
||||
...session,
|
||||
draftProfile: {
|
||||
...session.draftProfile,
|
||||
legacyResultProfile: buildLegacyResultProfile(),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
test('adapts agent draft profile into legacy custom world result profile', () => {
|
||||
const profile = buildCustomWorldProfileFromAgentDraft(session);
|
||||
|
||||
expect(profile?.name).toBe('潮雾列岛');
|
||||
expect(profile?.generationStatus).toBe('key_only');
|
||||
expect(profile?.playableNpcs[0]?.name).toBe('沈砺');
|
||||
expect(profile?.storyNpcs[0]?.name).toBe('顾潮音');
|
||||
expect(profile?.landmarks[0]?.name).toBe('回潮旧灯塔');
|
||||
});
|
||||
|
||||
test('prefers embedded legacy result profile without dropping compiled runtime fields', () => {
|
||||
const profile = buildProfileFromEmbeddedLegacyResult();
|
||||
|
||||
expect(profile?.name).toBe('旧版完整结果');
|
||||
expect(profile?.majorFactions).toEqual(['守灯会', '航运公会']);
|
||||
expect(profile?.coreConflicts).toEqual(['争夺航路控制权', '沉船真相']);
|
||||
expect(profile?.themePack?.id).toBe('theme-pack:tide');
|
||||
expect(profile?.storyGraph?.visibleThreads[0]?.id).toBe('thread-visible-1');
|
||||
expect(profile?.knowledgeFacts?.[0]?.id).toBe('fact-1');
|
||||
expect(profile?.threadContracts?.[0]?.id).toBe('contract-1');
|
||||
expect(profile?.scenarioPackId).toBe('scenario-pack:tide');
|
||||
expect(profile?.campaignPackId).toBe('campaign-pack:tide');
|
||||
expect(profile?.playableNpcs[0]?.attributeProfile?.schemaId).toBe(
|
||||
'schema:test',
|
||||
);
|
||||
expect(profile?.storyNpcs[0]?.narrativeProfile?.publicMask).toContain(
|
||||
'守灯会值夜人',
|
||||
);
|
||||
expect(profile?.items[0]?.attributeResonance?.explanation).toContain('潮雾');
|
||||
expect(profile?.landmarks[0]?.narrativeResidues?.[0]?.title).toBe('潮痕');
|
||||
});
|
||||
|
||||
test('embedded legacy result profile keeps result-page settings in runtime characters and scenes', () => {
|
||||
const profile = buildProfileFromEmbeddedLegacyResult();
|
||||
|
||||
expect(profile).toBeTruthy();
|
||||
|
||||
setRuntimeCustomWorldProfile(profile);
|
||||
|
||||
const runtimeCharacters = buildCustomWorldRuntimeCharacters(profile);
|
||||
const leadCharacter = runtimeCharacters.find(
|
||||
(character) => character.id === 'playable-1',
|
||||
);
|
||||
const lighthouseScene = getScenePresetsByWorld(WorldType.CUSTOM).find(
|
||||
(scene) => scene.name === '回潮旧灯塔',
|
||||
);
|
||||
const guardNpc = lighthouseScene?.npcs.find((npc) => npc.id === 'story-1');
|
||||
|
||||
expect(leadCharacter?.skills[0]?.name).toBe('潮行引路');
|
||||
expect(leadCharacter?.backstoryReveal?.publicSummary).toBe('沈砺的公开背景');
|
||||
expect(lighthouseScene?.connections[0]?.summary).toBe(
|
||||
'沿着旧潮阶继续前压到雾栈尽头。',
|
||||
);
|
||||
expect(lighthouseScene?.narrativeResidues?.[0]?.title).toBe('潮痕');
|
||||
expect(guardNpc?.narrativeProfile?.publicMask).toBe(
|
||||
'守灯会值夜人,对外总像比别人更冷静一步。',
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user