feat: expose archived general histories
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
|
||||
import { asRecord } from '@sammo-ts/common';
|
||||
import { createGamePostgresConnector, type GamePrismaClient } from '@sammo-ts/infra';
|
||||
import { LogCategory, LogScope } from '@sammo-ts/logic';
|
||||
|
||||
import type { GeneralLifecycleEvent } from '../src/turn/inMemoryWorld.js';
|
||||
import { persistGeneralLifecycleEvents } from '../src/turn/generalTurnLifecyclePersistence.js';
|
||||
@@ -72,6 +74,7 @@ integration('general turn lifecycle persistence', () => {
|
||||
let close: (() => Promise<void>) | undefined;
|
||||
|
||||
const cleanup = async () => {
|
||||
await db.logEntry.deleteMany({ where: { generalId: { in: generalIds } } });
|
||||
await db.generalAccessLog.deleteMany({ where: { generalId: { in: generalIds } } });
|
||||
await db.rankData.deleteMany({ where: { generalId: { in: generalIds } } });
|
||||
await db.oldGeneral.deleteMany({ where: { serverId, generalNo: { in: generalIds } } });
|
||||
@@ -116,6 +119,26 @@ integration('general turn lifecycle persistence', () => {
|
||||
{ generalId: general.id, nationId: 0, type: 'firenum', value: 1 },
|
||||
],
|
||||
});
|
||||
await db.logEntry.createMany({
|
||||
data: [
|
||||
{
|
||||
scope: LogScope.GENERAL,
|
||||
category: LogCategory.HISTORY,
|
||||
year: 199,
|
||||
month: 12,
|
||||
generalId: general.id,
|
||||
text: '<C>●</>첫 기록',
|
||||
},
|
||||
{
|
||||
scope: LogScope.GENERAL,
|
||||
category: LogCategory.HISTORY,
|
||||
year: 200,
|
||||
month: 1,
|
||||
generalId: general.id,
|
||||
text: '<Y>●</>둘째 기록',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
await db.$transaction((tx) =>
|
||||
persistGeneralLifecycleEvents(
|
||||
@@ -127,7 +150,10 @@ integration('general turn lifecycle persistence', () => {
|
||||
);
|
||||
|
||||
expect(await db.generalAccessLog.findUnique({ where: { generalId: general.id } })).toBeNull();
|
||||
expect(await db.oldGeneral.findUnique({ where: { by_no: { serverId, generalNo: general.id } } })).not.toBeNull();
|
||||
const archived = await db.oldGeneral.findUniqueOrThrow({
|
||||
where: { by_no: { serverId, generalNo: general.id } },
|
||||
});
|
||||
expect(asRecord(archived.data).history).toEqual(['<Y>●</>둘째 기록', '<C>●</>첫 기록']);
|
||||
expect(
|
||||
await db.inheritancePoint.findUnique({
|
||||
where: { userId_key: { userId: general.userId!, key: 'previous' } },
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import type { GamePrisma } from '@sammo-ts/infra';
|
||||
import { LogCategory, LogScope } from '@sammo-ts/logic';
|
||||
|
||||
import { persistGeneralLifecycleEvents } from '../src/turn/generalTurnLifecyclePersistence.js';
|
||||
import type { GeneralLifecycleEvent } from '../src/turn/inMemoryWorld.js';
|
||||
import type { TurnGeneral } from '../src/turn/types.js';
|
||||
|
||||
const archivedGeneral = (): TurnGeneral => ({
|
||||
id: 91,
|
||||
userId: null,
|
||||
name: '기록장수',
|
||||
nationId: 0,
|
||||
cityId: 1,
|
||||
troopId: 0,
|
||||
stats: { leadership: 80, strength: 70, intelligence: 60 },
|
||||
experience: 1_000,
|
||||
dedication: 500,
|
||||
officerLevel: 0,
|
||||
role: {
|
||||
personality: null,
|
||||
specialDomestic: null,
|
||||
specialWar: null,
|
||||
items: { horse: null, weapon: null, book: null, item: null },
|
||||
},
|
||||
injury: 0,
|
||||
gold: 1_000,
|
||||
rice: 1_000,
|
||||
crew: 0,
|
||||
crewTypeId: 1,
|
||||
train: 0,
|
||||
atmos: 0,
|
||||
age: 70,
|
||||
npcState: 2,
|
||||
bornYear: 170,
|
||||
deadYear: 240,
|
||||
affinity: 50,
|
||||
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
|
||||
meta: { killturn: 0 },
|
||||
turnTime: new Date('0200-01-01T00:00:00.000Z'),
|
||||
});
|
||||
|
||||
describe('general lifecycle archive history', () => {
|
||||
it('stores the general history in descending log order when a general is deleted', async () => {
|
||||
const general = archivedGeneral();
|
||||
const upsert = vi.fn(async () => undefined);
|
||||
const prisma = {
|
||||
generalAccessLog: {
|
||||
updateMany: vi.fn(async () => ({ count: 1 })),
|
||||
deleteMany: vi.fn(async () => ({ count: 1 })),
|
||||
},
|
||||
logEntry: {
|
||||
findMany: vi.fn(async () => [{ text: '<Y>●</>둘째 기록' }, { text: '<C>●</>첫 기록' }]),
|
||||
},
|
||||
oldGeneral: { upsert },
|
||||
} as unknown as GamePrisma.TransactionClient;
|
||||
const event: GeneralLifecycleEvent = {
|
||||
generalId: general.id,
|
||||
outcome: 'deleted',
|
||||
before: general,
|
||||
year: 200,
|
||||
month: 1,
|
||||
};
|
||||
|
||||
await persistGeneralLifecycleEvents(prisma, [event], { serverId: 'archive-fixture' }, {});
|
||||
|
||||
expect(prisma.logEntry.findMany).toHaveBeenCalledWith({
|
||||
where: {
|
||||
generalId: general.id,
|
||||
scope: LogScope.GENERAL,
|
||||
category: LogCategory.HISTORY,
|
||||
},
|
||||
orderBy: { id: 'desc' },
|
||||
select: { text: true },
|
||||
});
|
||||
expect(upsert).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
create: expect.objectContaining({
|
||||
data: expect.objectContaining({
|
||||
history: ['<Y>●</>둘째 기록', '<C>●</>첫 기록'],
|
||||
}),
|
||||
}),
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user