107
src/components/npcVisualEditorPersistence.test.ts
Normal file
107
src/components/npcVisualEditorPersistence.test.ts
Normal file
@@ -0,0 +1,107 @@
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import type { MedievalNpcVisualOverride } from '../data/medievalNpcVisuals';
|
||||
import type { EditableNpcVisualState } from './npcVisualEditorModel';
|
||||
import {
|
||||
NPC_LAYOUT_CONFIG_API_PATH,
|
||||
NPC_VISUAL_OVERRIDES_API_PATH,
|
||||
persistNpcLayoutConfig,
|
||||
persistNpcVisualOverrides,
|
||||
} from './npcVisualEditorPersistence';
|
||||
import type { NpcLayoutConfig } from './npcVisualShared';
|
||||
|
||||
function createEditorState(): EditableNpcVisualState {
|
||||
return {
|
||||
race: 'human',
|
||||
bodyColor: 'black',
|
||||
headIndex: 1,
|
||||
hairColorIndex: 1,
|
||||
hairStyleFrame: 0,
|
||||
facialHairEnabled: false,
|
||||
facialHairColorIndex: 1,
|
||||
facialHairStyleFrame: 0,
|
||||
headgearType: 'none',
|
||||
headgearFile: '',
|
||||
headgearFrame: 0,
|
||||
mainHandType: 'none',
|
||||
mainHandFile: '',
|
||||
mainHandFrame: 0,
|
||||
offHandType: 'none',
|
||||
offHandFile: '',
|
||||
offHandFrame: 0,
|
||||
};
|
||||
}
|
||||
|
||||
function createExistingOverride(): MedievalNpcVisualOverride {
|
||||
return {
|
||||
race: 'elf',
|
||||
bodySrc: '/body.png',
|
||||
headSrc: '/head.png',
|
||||
hairSrc: '/hair.png',
|
||||
handSrc: '/hand.png',
|
||||
bodyFrames: [0, 1, 2, 3],
|
||||
headFrame: 0,
|
||||
hairFrame: 1,
|
||||
handFrame: 0,
|
||||
};
|
||||
}
|
||||
|
||||
function createLayoutDraft(): NpcLayoutConfig {
|
||||
return {
|
||||
body: { x: 0, y: 0 },
|
||||
head: { x: 1, y: 2 },
|
||||
facialHair: { x: 3, y: 4 },
|
||||
hair: { x: 5, y: 6 },
|
||||
headgear: { x: 7, y: 8 },
|
||||
hand: { x: 9, y: 10 },
|
||||
mainHand: { x: 11, y: 12 },
|
||||
offHand: { x: 13, y: 14 },
|
||||
};
|
||||
}
|
||||
|
||||
describe('npcVisualEditorPersistence', () => {
|
||||
it('persists merged npc visual overrides and returns the writeback payload', async () => {
|
||||
const saveJson = vi.fn(async () => undefined);
|
||||
const result = await persistNpcVisualOverrides({
|
||||
overrideMap: {
|
||||
existing: createExistingOverride(),
|
||||
},
|
||||
npcId: 'npc-1',
|
||||
editorState: createEditorState(),
|
||||
saveJson,
|
||||
});
|
||||
|
||||
expect(saveJson).toHaveBeenCalledWith(
|
||||
NPC_VISUAL_OVERRIDES_API_PATH,
|
||||
expect.objectContaining({
|
||||
existing: createExistingOverride(),
|
||||
'npc-1': expect.objectContaining({
|
||||
race: 'human',
|
||||
bodyFrames: [0, 1, 2, 3],
|
||||
}),
|
||||
}),
|
||||
'保存角色形象覆盖配置失败',
|
||||
);
|
||||
expect(result.nextOverrideMap.existing).toEqual(createExistingOverride());
|
||||
expect(result.nextOverrideMap['npc-1']).toEqual(expect.objectContaining({ race: 'human' }));
|
||||
expect(result.saveMessage).toContain('npcVisualOverrides.json');
|
||||
});
|
||||
|
||||
it('persists layout config with a cloned payload for local writeback', async () => {
|
||||
const saveJson = vi.fn(async () => undefined);
|
||||
const layoutDraft = createLayoutDraft();
|
||||
const result = await persistNpcLayoutConfig({
|
||||
layoutDraft,
|
||||
saveJson,
|
||||
});
|
||||
|
||||
expect(saveJson).toHaveBeenCalledWith(
|
||||
NPC_LAYOUT_CONFIG_API_PATH,
|
||||
expect.objectContaining(layoutDraft),
|
||||
'保存角色布局配置失败',
|
||||
);
|
||||
expect(result.nextLayout).toEqual(layoutDraft);
|
||||
expect(result.nextLayout).not.toBe(layoutDraft);
|
||||
expect(result.saveMessage).toContain('角色布局');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user