Files
90CNServer/pvf/frontend/tests/item-creation-store.test.ts
T
hanfuit 645b64fe21 DNF90 服务端与启动器完整源码(含 GM 工具功能增强)
服务端(Go):
- GM 塞背包/带属性装备发放:在线角色推送 op14 增量物品行,背包实时刷新,无需回角色选择界面
- GM 改金币/改等级:去掉在线拒绝,落库后推送 op14 钱包/op37 等级状态,在线实时刷新
- 等级端点统一切换到新版 GMSetCharacterLevel(自带在线刷新)
- 无限/锁死疲劳模式 + 燃烧疲劳:每房间消耗 2 点、打怪与通关经验双倍
- 燃烧疲劳开关时给所有在线角色推送系统提示(op12 mode 0)
- 深渊史诗掉率:GM 全局倍率 + 城镇增益药剂窗口倍率,真实接入掉落结算

启动器(Python/JS):
- 标题栏自绘、窗口 1204x717、禁止拖拽改大小、仅最小化/关闭
- GM 工具:疲劳与燃烧、深渊史诗掉率、拍卖行上架(单一定价对齐)
- 拍卖行上架前端对齐服务端单一价格语义,修复 400 报错
2026-11-04 14:31:55 +08:00

47 lines
4.2 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from 'vitest';
import { createPinia, setActivePinia } from 'pinia';
import { nextTick } from 'vue';
import type { ItemCreateRequest } from '../bindings/pvfine/services/models';
const api=vi.hoisted(()=>({GetFileBasic:vi.fn(),GetFile:vi.fn(),GetAnnotations:vi.fn(),CreateItem:vi.fn(),refreshInfo:vi.fn(),events:new Map<string,Array<()=>void>>()}));
vi.mock('@wailsio/runtime',()=>({Events:{On:(name:string,fn:()=>void)=>api.events.set(name,[...(api.events.get(name)??[]),fn])}}));
vi.mock('../bindings/pvfine/services',()=>({EditorService:api,ArchiveService:api,FileGUIService:api}));
vi.mock('../src/stores/archive',()=>({useArchiveStore:()=>({refreshInfo:api.refreshInfo})}));
vi.mock('../src/stores/script',()=>({useScriptStore:()=>({})}));
vi.mock('../src/stores/explorer',()=>({useExplorerStore:()=>({getFilePath:()=>'',refreshTreeTags:vi.fn()})}));
import { useEditorStore } from '../src/stores/editor';
import { useFileGUIStore } from '../src/stores/fileGUI';
const meta=(index:number)=>({index,path:index===1?'stackable/stackable.lst':'stackable/source.stk',text:'original',editable:true,dataType:1,size:8,tags:[],annotations:[],modified:false});
const request:ItemCreateRequest={path:'stackable/new.stk',id:'999',name:'新物品',text:'[name]\n`copy`',revision:1,drafts:[]};
beforeEach(()=>{setActivePinia(createPinia());vi.resetAllMocks();api.events.clear();api.GetFileBasic.mockImplementation(async i=>meta(i));api.GetAnnotations.mockResolvedValue([]);api.GetFile.mockResolvedValue(null);});
describe('物品创建工作区',()=>{
it('提交包含所有未保存草稿,仅推进被消费列表的基线',async()=>{
const editor=useEditorStore();await editor.openGUIFile(1);await editor.openGUIFile(2);
editor.updateContent(1,'list draft');editor.updateContent(2,'source draft');
api.CreateItem.mockResolvedValue({fileIndex:3,path:request.path,id:'999',files:[{fileIndex:1,path:'stackable/stackable.lst',beforeText:'list draft',text:'registered list'}]});
await editor.createItem(request);
expect(api.CreateItem.mock.calls[0]![0].drafts).toEqual([{fileIndex:1,path:'stackable/stackable.lst',text:'list draft'},{fileIndex:2,path:'stackable/source.stk',text:'source draft'}]);
expect(editor.getFileDraft(1)).toMatchObject({text:'registered list',original:'registered list',modified:true});
expect(editor.getFileDraft(2)).toMatchObject({text:'source draft',original:'original'});
expect(editor.dirtyCount).toBe(1);expect(editor.saving).toBe(false);expect(editor.guiApplying).toBe(false);
});
it('创建期间锁定编辑,失败后保留草稿和状态',async()=>{
const editor=useEditorStore();await editor.openGUIFile(1);editor.updateContent(1,'draft');
let reject!:(e:Error)=>void;api.CreateItem.mockImplementation(()=>new Promise((_,r)=>{reject=r;}));
const work=editor.createItem(request);await nextTick();
expect(editor.guiApplying).toBe(true);editor.updateContent(1,'unexpected');expect(editor.getFileDraft(1)?.text).toBe('draft');
reject(new Error('ID conflict'));await expect(work).rejects.toThrow('ID conflict');
expect(editor.getFileDraft(1)).toMatchObject({text:'draft',original:'original'});expect(editor.guiApplying).toBe(false);
});
it('拒绝跨归档的旧返回值',async()=>{
const editor=useEditorStore(),gui=useFileGUIStore();await editor.openGUIFile(1);editor.updateContent(1,'draft');
let resolve!:(v:unknown)=>void;api.CreateItem.mockImplementation(()=>new Promise(r=>{resolve=r;}));
const work=editor.createItem(request);await nextTick();gui.epoch++;
resolve({fileIndex:3,path:request.path,id:'999',files:[{fileIndex:1,path:'stackable/stackable.lst',beforeText:'draft',text:'old response'}]});
await expect(work).rejects.toThrow('归档已切换');expect(editor.getFileDraft(1)?.text).toBe('draft');expect(editor.saving).toBe(false);
});
it('刷新失败仍返回已创建结果并保留提示,避免重复创建',async()=>{
const editor=useEditorStore();api.CreateItem.mockResolvedValue({fileIndex:3,path:request.path,id:'999',files:[]});api.refreshInfo.mockRejectedValue(new Error('refresh'));
expect((await editor.createItem(request)).fileIndex).toBe(3);expect(editor.guiRefreshWarning).toContain('已创建');
});
});