1
This commit is contained in:
@@ -452,6 +452,104 @@ describe('storyChoiceRuntime', () => {
|
||||
expect(setGameState).toHaveBeenLastCalledWith(finalState);
|
||||
});
|
||||
|
||||
it('routes server defeat outcomes into death and revive flow instead of victory settlement', async () => {
|
||||
const gameState = createState({
|
||||
worldType: 'WUXIA',
|
||||
inBattle: true,
|
||||
playerHp: 6,
|
||||
playerMaxHp: 30,
|
||||
playerMana: 10,
|
||||
playerMaxMana: 10,
|
||||
currentScenePreset: {
|
||||
id: 'wuxia-bamboo-road',
|
||||
name: '竹林古道',
|
||||
description: '风穿竹影,路面狭长。',
|
||||
imageSrc: '/scene-a.png',
|
||||
connectedSceneIds: [],
|
||||
connections: [],
|
||||
forwardSceneId: null,
|
||||
treasureHints: [],
|
||||
npcs: [],
|
||||
},
|
||||
sceneHostileNpcs: [
|
||||
{
|
||||
id: 'wolf',
|
||||
name: '山狼',
|
||||
action: '逼近',
|
||||
description: '山狼',
|
||||
animation: 'idle',
|
||||
xMeters: 3,
|
||||
yOffset: 0,
|
||||
facing: 'left',
|
||||
attackRange: 1,
|
||||
speed: 1,
|
||||
hp: 4,
|
||||
maxHp: 18,
|
||||
},
|
||||
],
|
||||
});
|
||||
const finalState = createState({
|
||||
...gameState,
|
||||
inBattle: false,
|
||||
playerHp: 0,
|
||||
currentEncounter: null,
|
||||
sceneHostileNpcs: [],
|
||||
currentNpcBattleOutcome: 'fight_defeat',
|
||||
});
|
||||
const setGameState = vi.fn();
|
||||
const setCurrentStory = vi.fn();
|
||||
|
||||
resolveServerRuntimeChoiceMock.mockResolvedValueOnce({
|
||||
response: {
|
||||
presentation: {
|
||||
battle: {
|
||||
targetId: 'wolf',
|
||||
damageDealt: 22,
|
||||
damageTaken: 8,
|
||||
outcome: 'defeat',
|
||||
},
|
||||
resultText: '你在山狼的反扑下倒地。',
|
||||
},
|
||||
},
|
||||
hydratedSnapshot: {
|
||||
gameState: finalState,
|
||||
},
|
||||
nextStory: createStory('不会进入胜利文本'),
|
||||
});
|
||||
|
||||
await runServerRuntimeChoiceAction({
|
||||
gameState,
|
||||
currentStory: createStory('当前故事'),
|
||||
option: createOption('battle_all_in_crush'),
|
||||
character: createCharacter(),
|
||||
setBattleReward: vi.fn(),
|
||||
setAiError: vi.fn(),
|
||||
setIsLoading: vi.fn(),
|
||||
setGameState,
|
||||
setCurrentStory: setCurrentStory as (story: StoryMoment) => void,
|
||||
buildFallbackStoryForState: () => createStory('fallback'),
|
||||
turnVisualMs: 1,
|
||||
});
|
||||
|
||||
expect(setGameState).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
playerHp: 0,
|
||||
animationState: 'die',
|
||||
inBattle: false,
|
||||
}),
|
||||
);
|
||||
expect(setCurrentStory).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
text: expect.stringContaining('重新醒来'),
|
||||
}),
|
||||
);
|
||||
expect(setCurrentStory).not.toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
text: '不会进入胜利文本',
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('commits server-returned next-scene state after idle_travel_next_scene resolution', async () => {
|
||||
const gameState = createState({
|
||||
currentScenePreset: {
|
||||
|
||||
Reference in New Issue
Block a user