test: 경매 복구 fixture의 논리 시각과 mailbox를 교정한다
manual world의 game clock으로 만료 시각을 만들고 private mailbox 범위의 장수 ID를 사용한다. 연장 소진 뒤 invalid item 취소 결과도 durable input event와 함께 고정한다.
This commit is contained in:
@@ -62,8 +62,7 @@ liveDescribe('auction worker durable recovery', () => {
|
|||||||
await connector.disconnect();
|
await connector.disconnect();
|
||||||
});
|
});
|
||||||
|
|
||||||
const createAuction = async (status: 'OPEN' | 'FINALIZING') => {
|
const createAuction = async (status: 'OPEN' | 'FINALIZING', closeAt = new Date(Date.now() - 60_000)) => {
|
||||||
const closeAt = new Date(Date.now() - 60_000);
|
|
||||||
const auction = await connector.prisma.auction.create({
|
const auction = await connector.prisma.auction.create({
|
||||||
data: {
|
data: {
|
||||||
type: 'BUY_RICE',
|
type: 'BUY_RICE',
|
||||||
@@ -340,14 +339,14 @@ liveDescribe('auction worker durable recovery', () => {
|
|||||||
imageServer: 0,
|
imageServer: 0,
|
||||||
});
|
});
|
||||||
const host = buildGeneral({
|
const host = buildGeneral({
|
||||||
id: 992_032,
|
id: 8_032,
|
||||||
userId: 'auction-durable-host',
|
userId: 'auction-durable-host',
|
||||||
name: '경매주최자',
|
name: '경매주최자',
|
||||||
gold: 1_000,
|
gold: 1_000,
|
||||||
rice: 900,
|
rice: 900,
|
||||||
});
|
});
|
||||||
const bidder = buildGeneral({
|
const bidder = buildGeneral({
|
||||||
id: 992_033,
|
id: 8_033,
|
||||||
userId: 'auction-durable-bidder',
|
userId: 'auction-durable-bidder',
|
||||||
name: '경매입찰자',
|
name: '경매입찰자',
|
||||||
gold: 800,
|
gold: 800,
|
||||||
@@ -366,7 +365,7 @@ liveDescribe('auction worker durable recovery', () => {
|
|||||||
map,
|
map,
|
||||||
};
|
};
|
||||||
|
|
||||||
const lifecycleGeneralIds = [992_032, 992_033];
|
const lifecycleGeneralIds = [8_032, 8_033];
|
||||||
await connector.prisma.logEntry.deleteMany({ where: { generalId: { in: lifecycleGeneralIds } } });
|
await connector.prisma.logEntry.deleteMany({ where: { generalId: { in: lifecycleGeneralIds } } });
|
||||||
await connector.prisma.general.deleteMany({ where: { id: { in: lifecycleGeneralIds } } });
|
await connector.prisma.general.deleteMany({ where: { id: { in: lifecycleGeneralIds } } });
|
||||||
await connector.prisma.worldState.deleteMany({ where: { id: worldId } });
|
await connector.prisma.worldState.deleteMany({ where: { id: worldId } });
|
||||||
@@ -398,7 +397,8 @@ liveDescribe('auction worker durable recovery', () => {
|
|||||||
});
|
});
|
||||||
createdGeneralIds.push(general.id);
|
createdGeneralIds.push(general.id);
|
||||||
}
|
}
|
||||||
const auction = await createAuction('OPEN');
|
const logicalPastCloseAt = new Date(state.lastTurnTime.getTime() - 60_000);
|
||||||
|
const auction = await createAuction('OPEN', logicalPastCloseAt);
|
||||||
await connector.prisma.auction.update({
|
await connector.prisma.auction.update({
|
||||||
where: { id: auction.id },
|
where: { id: auction.id },
|
||||||
data: { hostGeneralId: host.id, hostName: host.name },
|
data: { hostGeneralId: host.id, hostName: host.name },
|
||||||
@@ -487,7 +487,7 @@ liveDescribe('auction worker durable recovery', () => {
|
|||||||
hostName: '(상인)',
|
hostName: '(상인)',
|
||||||
detail: { remainCloseDateExtensionCnt: 1 },
|
detail: { remainCloseDateExtensionCnt: 1 },
|
||||||
status: 'OPEN',
|
status: 'OPEN',
|
||||||
closeAt: new Date(Date.now() - 60_000),
|
closeAt: logicalPastCloseAt,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
extensionAuctionId = extensionAuction.id;
|
extensionAuctionId = extensionAuction.id;
|
||||||
@@ -528,8 +528,8 @@ liveDescribe('auction worker durable recovery', () => {
|
|||||||
expect(reopened).toMatchObject({ status: 'OPEN' });
|
expect(reopened).toMatchObject({ status: 'OPEN' });
|
||||||
expect(reopened!.closeAt.getTime()).toBeGreaterThan(extensionAuction.closeAt.getTime());
|
expect(reopened!.closeAt.getTime()).toBeGreaterThan(extensionAuction.closeAt.getTime());
|
||||||
|
|
||||||
const secondWallNow = new Date();
|
const secondGameNow = world.getGameNow(new Date());
|
||||||
const secondCloseAt = new Date(secondWallNow.getTime() - 1_000);
|
const secondCloseAt = new Date(secondGameNow.getTime() - 1_000);
|
||||||
const secondCloseTick = world.dateToGameTick(secondCloseAt);
|
const secondCloseTick = world.dateToGameTick(secondCloseAt);
|
||||||
await connector.prisma.auction.update({
|
await connector.prisma.auction.update({
|
||||||
where: { id: extensionAuction.id },
|
where: { id: extensionAuction.id },
|
||||||
@@ -546,8 +546,8 @@ liveDescribe('auction worker durable recovery', () => {
|
|||||||
timerKey: 'timer',
|
timerKey: 'timer',
|
||||||
historyKey: 'history',
|
historyKey: 'history',
|
||||||
id: String(extensionAuction.id),
|
id: String(extensionAuction.id),
|
||||||
nowMs: world.getGameNow(secondWallNow).getTime(),
|
nowMs: secondGameNow.getTime(),
|
||||||
nowTick: world.dateToGameTick(secondWallNow),
|
nowTick: world.dateToGameTick(secondGameNow),
|
||||||
});
|
});
|
||||||
|
|
||||||
for (let attempt = 0; attempt < 200; attempt += 1) {
|
for (let attempt = 0; attempt < 200; attempt += 1) {
|
||||||
@@ -558,6 +558,16 @@ liveDescribe('auction worker durable recovery', () => {
|
|||||||
if (event?.status === 'SUCCEEDED' && storedAuction?.status === 'CANCELED') break;
|
if (event?.status === 'SUCCEEDED' && storedAuction?.status === 'CANCELED') break;
|
||||||
await delay(25);
|
await delay(25);
|
||||||
}
|
}
|
||||||
|
const secondExtensionEvent = await connector.prisma.inputEvent.findUniqueOrThrow({
|
||||||
|
where: { requestId: secondExtensionRequestId },
|
||||||
|
});
|
||||||
|
expect(secondExtensionEvent).toMatchObject({ status: 'SUCCEEDED', error: null });
|
||||||
|
expect(secondExtensionEvent.result).toEqual({
|
||||||
|
type: 'auctionFinalize',
|
||||||
|
ok: false,
|
||||||
|
auctionId: extensionAuction.id,
|
||||||
|
reason: '아이템 키가 올바르지 않습니다.',
|
||||||
|
});
|
||||||
await expect(
|
await expect(
|
||||||
connector.prisma.auction.findUniqueOrThrow({ where: { id: extensionAuction.id } })
|
connector.prisma.auction.findUniqueOrThrow({ where: { id: extensionAuction.id } })
|
||||||
).resolves.toMatchObject({ status: 'CANCELED' });
|
).resolves.toMatchObject({ status: 'CANCELED' });
|
||||||
|
|||||||
Reference in New Issue
Block a user