feat: add extensive test suite

This commit is contained in:
2026-08-30 11:33:53 +07:00 Unverified
parent 061cce00dc
commit 8359c7272e
131 changed files with 8717 additions and 2200 deletions
+144
View File
@@ -0,0 +1,144 @@
import { describe, expect, test } from "bun:test";
import {
adminExists,
decideCardFailure,
decideRubgramWebhook,
getScheduleDelay,
isDatabaseSeeded,
parseSubscriberMessage,
shouldRunDatabaseSeed,
} from "./logic";
describe("getScheduleDelay", () => {
const now = new Date("2026-01-01T00:00:00.000Z").getTime();
test("converts numeric seconds to milliseconds", () => {
expect(getScheduleDelay(0, now)).toBe(0);
expect(getScheduleDelay(60, now)).toBe(60_000);
expect(getScheduleDelay(0.5, now)).toBe(500);
});
test("polls in one minute when there are no target dates", () => {
expect(getScheduleDelay([], now)).toBe(60_000);
});
test("uses the nearest date regardless of input order", () => {
expect(
getScheduleDelay(
[
new Date(now + 30_000),
new Date(now + 10_000),
new Date(now + 20_000),
],
now,
),
).toBe(10_000);
});
test("retains immediate past deadlines and hourly polling for distant dates", () => {
expect(getScheduleDelay([new Date(now - 1)], now)).toBe(-1);
expect(getScheduleDelay([new Date(now + 7_200_000)], now)).toBe(3_600_000);
});
});
describe("database seed decisions", () => {
test("runs only in development", () => {
expect(shouldRunDatabaseSeed("development")).toBeTrue();
expect(shouldRunDatabaseSeed("production")).toBeFalse();
expect(shouldRunDatabaseSeed(undefined)).toBeFalse();
});
test("distinguishes empty query results from existing rows", () => {
expect(isDatabaseSeeded([])).toBeFalse();
expect(isDatabaseSeeded([{ id: true }])).toBeTrue();
expect(adminExists([])).toBeFalse();
expect(adminExists([{ id: "admin" }])).toBeTrue();
});
});
describe("decideCardFailure", () => {
test.each([
[
"The showcase for this UID is private",
"ผู้เล่นนี้ไม่มีโชว์เคส มองไม่เห็นตัวละครใดๆ",
true,
],
[
"Character not found in showcase",
"ตัวละครที่ผู้เล่นเลือก ไม่ได้อยู่ในโชว์เคส",
false,
],
["Invalid UID Provided", "ผู้เล่นนี้ไม่มีอยู่จริง โดนแบนไปแล้วรีเปล่า", false],
])("translates known card error %s", (input, error, stopRetrying) => {
expect(decideCardFailure(input, 500)).toEqual({ error, stopRetrying });
});
test("stops retrying all HTTP 400 responses", () => {
expect(decideCardFailure("bad request", 400)).toEqual({
error: "bad request",
stopRetrying: true,
});
});
test("uses a retry message for gateway failures and oversized bodies", () => {
const expected = {
error: "ไม่สามารถสร้างการ์ดได้ กำลังพยายามลองใหม่",
stopRetrying: false,
};
expect(decideCardFailure("upstream", 502)).toEqual(expected);
expect(decideCardFailure("x".repeat(2001), 500)).toEqual(expected);
expect(decideCardFailure("x".repeat(2000), 500).error).toHaveLength(2000);
});
test("stores only the first line of an unknown response", () => {
expect(decideCardFailure("first line\nstack trace", 500)).toEqual({
error: "first line",
stopRetrying: false,
});
});
});
describe("Redis subscriber decisions", () => {
test("parses a valid subscriber envelope", () => {
expect(
parseSubscriberMessage(
JSON.stringify({
event: "update",
data: { type: "submit", sub: "s1" },
}),
),
).toEqual({ event: "update", data: { type: "submit", sub: "s1" } });
});
test.each([
"not json",
"null",
"[]",
JSON.stringify({ event: "update" }),
JSON.stringify({ event: 1, data: {} }),
])("rejects malformed payload %s", (payload) => {
expect(parseSubscriberMessage(payload)).toBeNull();
});
test.each([
"submit",
"paid",
] as const)("allows configured %s updates", (type) => {
expect(
decideRubgramWebhook(
{ event: "update", data: { type, sub: "submission-1" } },
"https://webhook.test",
),
).toEqual({ type, sub: "submission-1" });
});
test.each([
[{ event: "other", data: { type: "submit", sub: "s1" } }, "url"],
[{ event: "update", data: { type: "cancel", sub: "s1" } }, "url"],
[{ event: "update", data: { type: "submit" } }, "url"],
[{ event: "update", data: null }, "url"],
[{ event: "update", data: { type: "submit", sub: "s1" } }, undefined],
] as const)("ignores ineligible message %#", (message, webhookUrl) => {
expect(decideRubgramWebhook(message, webhookUrl)).toBeNull();
});
});