test: add action-helper, send-currency, permission-ranks, catalog-tree, and audit test suites (77 files, 405 tests)
This commit is contained in:
1 parent
2e9db75eca
commit
ac3c42f308
4 files changed
+398
-75
No files matched your search
@@ -1,66 +1,141 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
vi.mock("@/lib/services/rcon", () => ({}));
|
||||
|
||||
import { sendCurrency } from "./send-currency";
|
||||
|
||||
function deps(delivered: boolean) {
|
||||
return {
|
||||
rcon: {
|
||||
giveCredits: vi.fn().mockResolvedValue(delivered),
|
||||
giveDuckets: vi.fn().mockResolvedValue(delivered),
|
||||
giveDiamonds: vi.fn().mockResolvedValue(delivered),
|
||||
givePointsGotw: vi.fn().mockResolvedValue(delivered),
|
||||
},
|
||||
db: {
|
||||
user: { update: vi.fn().mockResolvedValue(undefined) },
|
||||
usersCurrency: { upsert: vi.fn().mockResolvedValue(undefined) },
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
describe("sendCurrency", () => {
|
||||
it("rejects non-positive amounts", async () => {
|
||||
const d = deps(true);
|
||||
expect(await sendCurrency(d, 1, "credits", 0)).toBe(false);
|
||||
expect(await sendCurrency(d, 1, "credits", null)).toBe(false);
|
||||
expect(d.rcon.giveCredits).not.toHaveBeenCalled();
|
||||
it("returns false for non-positive amount", async () => {
|
||||
expect(await sendCurrency({} as any, 1, "credits", 0)).toBe(false);
|
||||
expect(await sendCurrency({} as any, 1, "credits", -5)).toBe(false);
|
||||
expect(await sendCurrency({} as any, 1, "credits", null)).toBe(false);
|
||||
expect(await sendCurrency({} as any, 1, "credits", undefined)).toBe(false);
|
||||
});
|
||||
|
||||
it("delivers credits via RCON when connected (no DB write)", async () => {
|
||||
const d = deps(true);
|
||||
expect(await sendCurrency(d, 7, "credits", 100)).toBe(true);
|
||||
expect(d.rcon.giveCredits).toHaveBeenCalledWith(7, 100);
|
||||
expect(d.db.user.update).not.toHaveBeenCalled();
|
||||
it("delivers credits via RCON", async () => {
|
||||
const rcon = {
|
||||
giveCredits: vi.fn().mockResolvedValue(true),
|
||||
giveDuckets: vi.fn(),
|
||||
giveDiamonds: vi.fn(),
|
||||
givePointsGotw: vi.fn(),
|
||||
};
|
||||
const result = await sendCurrency({ rcon, db: {} as any }, 1, "credits", 100);
|
||||
expect(result).toBe(true);
|
||||
expect(rcon.giveCredits).toHaveBeenCalledWith(1, 100);
|
||||
});
|
||||
|
||||
it("falls back to users.credits when RCON fails", async () => {
|
||||
const d = deps(false);
|
||||
await sendCurrency(d, 7, "credits", 100);
|
||||
expect(d.db.user.update).toHaveBeenCalledWith({
|
||||
where: { id: 7 },
|
||||
it("falls back to DB update when RCON fails for credits", async () => {
|
||||
const rcon = {
|
||||
giveCredits: vi.fn().mockResolvedValue(false),
|
||||
giveDuckets: vi.fn(),
|
||||
giveDiamonds: vi.fn(),
|
||||
givePointsGotw: vi.fn(),
|
||||
};
|
||||
const userUpdate = vi.fn().mockResolvedValue({});
|
||||
const result = await sendCurrency(
|
||||
{
|
||||
rcon,
|
||||
db: { user: { update: userUpdate } } as any,
|
||||
},
|
||||
1,
|
||||
"credits",
|
||||
100,
|
||||
);
|
||||
expect(result).toBe(true);
|
||||
expect(userUpdate).toHaveBeenCalledWith({
|
||||
where: { id: 1 },
|
||||
data: { credits: { increment: 100 } },
|
||||
});
|
||||
});
|
||||
|
||||
it("falls back to users_currency by type for diamonds", async () => {
|
||||
const d = deps(false);
|
||||
await sendCurrency(d, 7, "diamonds", 3);
|
||||
expect(d.db.usersCurrency.upsert).toHaveBeenCalledWith({
|
||||
where: { userId_type: { userId: 7, type: 5 } },
|
||||
update: { amount: { increment: 3 } },
|
||||
create: { userId: 7, type: 5, amount: 3 },
|
||||
});
|
||||
it("delivers duckets via RCON", async () => {
|
||||
const rcon = {
|
||||
giveCredits: vi.fn(),
|
||||
giveDuckets: vi.fn().mockResolvedValue(true),
|
||||
giveDiamonds: vi.fn(),
|
||||
givePointsGotw: vi.fn(),
|
||||
};
|
||||
const result = await sendCurrency({ rcon, db: {} as any }, 1, "duckets", 50);
|
||||
expect(result).toBe(true);
|
||||
expect(rcon.giveDuckets).toHaveBeenCalledWith(1, 50);
|
||||
});
|
||||
|
||||
it("uses the right type values (duckets=0, points=101)", async () => {
|
||||
const d = deps(false);
|
||||
await sendCurrency(d, 1, "duckets", 10);
|
||||
await sendCurrency(d, 1, "points", 20);
|
||||
expect(d.db.usersCurrency.upsert).toHaveBeenNthCalledWith(
|
||||
it("upserts duckets in DB when RCON fails", async () => {
|
||||
const rcon = {
|
||||
giveCredits: vi.fn(),
|
||||
giveDuckets: vi.fn().mockResolvedValue(false),
|
||||
giveDiamonds: vi.fn(),
|
||||
givePointsGotw: vi.fn(),
|
||||
};
|
||||
const upsert = vi.fn().mockResolvedValue({});
|
||||
await sendCurrency(
|
||||
{
|
||||
rcon,
|
||||
db: { usersCurrency: { upsert } } as any,
|
||||
},
|
||||
1,
|
||||
expect.objectContaining({ create: { userId: 1, type: 0, amount: 10 } }),
|
||||
"duckets",
|
||||
50,
|
||||
);
|
||||
expect(d.db.usersCurrency.upsert).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
expect.objectContaining({ create: { userId: 1, type: 101, amount: 20 } }),
|
||||
expect(upsert).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
where: expect.objectContaining({
|
||||
userId_type: expect.objectContaining({ userId: 1, type: 0 }),
|
||||
}),
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it("upserts diamonds in DB when RCON fails", async () => {
|
||||
const rcon = {
|
||||
giveCredits: vi.fn(),
|
||||
giveDuckets: vi.fn(),
|
||||
giveDiamonds: vi.fn().mockResolvedValue(false),
|
||||
givePointsGotw: vi.fn(),
|
||||
};
|
||||
const upsert = vi.fn().mockResolvedValue({});
|
||||
await sendCurrency(
|
||||
{
|
||||
rcon,
|
||||
db: { usersCurrency: { upsert } } as any,
|
||||
},
|
||||
1,
|
||||
"diamonds",
|
||||
10,
|
||||
);
|
||||
expect(upsert).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
where: expect.objectContaining({
|
||||
userId_type: expect.objectContaining({ userId: 1, type: 5 }),
|
||||
}),
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("upserts points in DB when RCON fails", async () => {
|
||||
const rcon = {
|
||||
giveCredits: vi.fn(),
|
||||
giveDuckets: vi.fn(),
|
||||
giveDiamonds: vi.fn(),
|
||||
givePointsGotw: vi.fn().mockResolvedValue(false),
|
||||
};
|
||||
const upsert = vi.fn().mockResolvedValue({});
|
||||
await sendCurrency(
|
||||
{
|
||||
rcon,
|
||||
db: { usersCurrency: { upsert } } as any,
|
||||
},
|
||||
1,
|
||||
"points",
|
||||
10,
|
||||
);
|
||||
expect(rcon.givePointsGotw).toHaveBeenCalled();
|
||||
expect(upsert).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
where: expect.objectContaining({
|
||||
userId_type: expect.objectContaining({ userId: 1, type: 101 }),
|
||||
}),
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user