통일 후 설문 응답과 유니크 보상 처리를 허용
통일 완료 상태의 설문 보상 명령만 데몬 큐에서 선점하도록 하고, 시계 중단·복구 경계와 유니크 지급을 검증한다.
This commit is contained in:
@@ -450,6 +450,33 @@ integration('database command queue', () => {
|
||||
}
|
||||
);
|
||||
|
||||
it.each([
|
||||
['SUSPENDED', 2, true],
|
||||
['COMPLETED', 2, true],
|
||||
['COMPLETED', 3, true],
|
||||
['SUSPENDED', 0, false],
|
||||
['RECONCILING', 2, false],
|
||||
] as const)('claims survey rewards in phase %s with unification state %i: %s', async (phase, united, allowed) => {
|
||||
await db.worldState.updateMany({ data: { clockPhase: phase, meta: { isunited: united } } });
|
||||
const requestId = `integration:engine:post-unification-vote:${phase}:${united}`;
|
||||
await db.inputEvent.create({
|
||||
data: {
|
||||
requestId,
|
||||
target: 'ENGINE',
|
||||
eventType: 'voteReward',
|
||||
actorUserId: 'user-7',
|
||||
payload: { type: 'voteReward', requestId, userId: 'user-7', voteId: 1, generalId: 7, selection: [0] },
|
||||
},
|
||||
});
|
||||
const commands = await new DatabaseTurnDaemonCommandQueue(db).drain();
|
||||
expect(commands.map((command) => command.type)).toEqual(allowed ? ['voteReward'] : []);
|
||||
expect(await db.inputEvent.findUniqueOrThrow({ where: { requestId } })).toMatchObject({
|
||||
status: allowed ? 'PROCESSING' : 'PENDING',
|
||||
attempts: allowed ? 1 : 0,
|
||||
processingGameTick: allowed ? 123n : null,
|
||||
});
|
||||
});
|
||||
|
||||
it('dequeues gameplay only in an executable phase and records the processing clock generation', async () => {
|
||||
const existingWorld = await db.worldState.findFirst({ orderBy: { id: 'asc' } });
|
||||
const world = existingWorld
|
||||
|
||||
@@ -414,6 +414,7 @@ describe('voteReward command', () => {
|
||||
it.each([
|
||||
['PREOPEN', new Date('2026-08-27T10:30:00.000Z'), 1, 'preopen-seed'],
|
||||
['OPEN', new Date('2026-08-27T11:00:05.000Z'), 2, 'open-seed'],
|
||||
['COMPLETED', new Date('2026-08-27T11:00:05.000Z'), 2, 'open-seed'],
|
||||
] as const)(
|
||||
'awards a survey unique from the Ref default pool at coefficient 1 during %s',
|
||||
async (_phase, wallNow, voteId, hiddenSeed) => {
|
||||
@@ -428,12 +429,14 @@ describe('voteReward command', () => {
|
||||
clockTick: 36_000_000,
|
||||
clockMode: 'realtime',
|
||||
clockWallAnchor: new Date('2026-08-27T11:00:00.000Z'),
|
||||
...(_phase === 'COMPLETED' ? { clockPhase: 'COMPLETED' as const } : {}),
|
||||
meta: {
|
||||
hiddenSeed,
|
||||
scenarioId: 0,
|
||||
initYear: 180,
|
||||
initMonth: 1,
|
||||
scenarioMeta: { startYear: 180 },
|
||||
...(_phase === 'COMPLETED' ? { isunited: 2, isUnited: 2 } : {}),
|
||||
preopenAt: '2026-08-27 19:30:00',
|
||||
opentime: '2026-08-27 20:00:00',
|
||||
},
|
||||
@@ -442,7 +445,7 @@ describe('voteReward command', () => {
|
||||
schedule: { entries: [{ startMinute: 0, tickMinutes: 10 }] },
|
||||
});
|
||||
const acceptedGameTick = world.dateToGameTick(world.getGameNow(wallNow));
|
||||
expect(acceptedGameTick).toBe(_phase === 'PREOPEN' ? 36_000_000 : 36_300_000);
|
||||
expect(acceptedGameTick).toBe(_phase === 'OPEN' ? 36_300_000 : 36_000_000);
|
||||
|
||||
const commandDb = {
|
||||
...actorBindingDb(),
|
||||
|
||||
Reference in New Issue
Block a user