feat: implement scheduled cleanup job for expired data
This commit is contained in:
111
src/modules/system/cleanup.service.test.ts
Normal file
111
src/modules/system/cleanup.service.test.ts
Normal file
@@ -0,0 +1,111 @@
|
||||
import { describe, it, expect, mock, beforeEach, spyOn } from "bun:test";
|
||||
import { cleanupService } from "./cleanup.service";
|
||||
import { lootdrops, userTimers, userQuests } from "@/db/schema";
|
||||
import { config } from "@/lib/config";
|
||||
|
||||
const mockDelete = mock();
|
||||
const mockReturning = mock();
|
||||
const mockWhere = mock();
|
||||
const mockFindMany = mock();
|
||||
|
||||
mockDelete.mockReturnValue({ where: mockWhere });
|
||||
mockWhere.mockReturnValue({ returning: mockReturning });
|
||||
|
||||
// Mock DrizzleClient
|
||||
mock.module("@/lib/DrizzleClient", () => ({
|
||||
DrizzleClient: {
|
||||
delete: mockDelete,
|
||||
query: {
|
||||
userTimers: {
|
||||
findMany: mockFindMany
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
// Mock AuroraClient
|
||||
mock.module("@/lib/BotClient", () => ({
|
||||
AuroraClient: {
|
||||
guilds: {
|
||||
fetch: mock().mockResolvedValue({
|
||||
members: {
|
||||
fetch: mock().mockResolvedValue({
|
||||
user: { tag: "TestUser#1234" },
|
||||
roles: { remove: mock().mockResolvedValue({}) }
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
// Mock Config
|
||||
mock.module("@/lib/config", () => ({
|
||||
config: {
|
||||
system: {
|
||||
cleanup: {
|
||||
intervalMs: 86400000,
|
||||
questArchiveDays: 30
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
describe("cleanupService", () => {
|
||||
beforeEach(() => {
|
||||
mockDelete.mockClear();
|
||||
mockWhere.mockClear();
|
||||
mockReturning.mockClear();
|
||||
mockFindMany.mockClear();
|
||||
});
|
||||
|
||||
it("cleanupLootdrops should delete expired unclaimed lootdrops", async () => {
|
||||
mockReturning.mockResolvedValue([{ id: "msg1" }, { id: "msg2" }]);
|
||||
|
||||
const count = await cleanupService.cleanupLootdrops();
|
||||
|
||||
expect(count).toBe(2);
|
||||
expect(mockDelete).toHaveBeenCalledWith(lootdrops);
|
||||
});
|
||||
|
||||
it("cleanupTimers should delete expired timers and handle roles", async () => {
|
||||
// Mock findMany for expired ACCESS timers
|
||||
mockFindMany.mockResolvedValue([
|
||||
{ userId: 123n, type: 'ACCESS', key: 'role_456', metadata: { roleId: '456' } }
|
||||
]);
|
||||
|
||||
// Mock returning for bulk delete
|
||||
mockReturning.mockResolvedValue([{ userId: 789n }]); // One other timer
|
||||
|
||||
const count = await cleanupService.cleanupTimers();
|
||||
|
||||
// 1 from findMany + 1 from bulk delete (simplified mock behavior)
|
||||
expect(count).toBe(2);
|
||||
expect(mockDelete).toHaveBeenCalledWith(userTimers);
|
||||
});
|
||||
|
||||
it("cleanupQuests should delete old completed quests", async () => {
|
||||
mockReturning.mockResolvedValue([{ userId: 123n }]);
|
||||
|
||||
const count = await cleanupService.cleanupQuests();
|
||||
|
||||
expect(count).toBe(1);
|
||||
expect(mockDelete).toHaveBeenCalledWith(userQuests);
|
||||
});
|
||||
|
||||
it("runAll should run all cleanup tasks and log stats", async () => {
|
||||
const spyLootdrops = spyOn(cleanupService, 'cleanupLootdrops').mockResolvedValue(1);
|
||||
const spyTimers = spyOn(cleanupService, 'cleanupTimers').mockResolvedValue(2);
|
||||
const spyQuests = spyOn(cleanupService, 'cleanupQuests').mockResolvedValue(3);
|
||||
|
||||
await cleanupService.runAll();
|
||||
|
||||
expect(spyLootdrops).toHaveBeenCalled();
|
||||
expect(spyTimers).toHaveBeenCalled();
|
||||
expect(spyQuests).toHaveBeenCalled();
|
||||
|
||||
spyLootdrops.mockRestore();
|
||||
spyTimers.mockRestore();
|
||||
spyQuests.mockRestore();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user