import { describe, test, expect, beforeEach, mock, afterEach } from "bun:test"; import { getClientStats, clearStatsCache } from "./clientStats"; // Mock AuroraClient mock.module("./BotClient", () => ({ AuroraClient: { guilds: { cache: { size: 5, }, }, ws: { ping: 42, }, users: { cache: { size: 100, }, }, commands: { size: 20, }, lastCommandTimestamp: 1641481200000, }, })); describe("clientStats", () => { beforeEach(() => { clearStatsCache(); }); test("should return client stats", () => { const stats = getClientStats(); expect(stats.guilds).toBe(5); expect(stats.ping).toBe(42); expect(stats.cachedUsers).toBe(100); expect(stats.commandsRegistered).toBe(20); expect(typeof stats.uptime).toBe("number"); // Can't mock process.uptime easily expect(stats.lastCommandTimestamp).toBe(1641481200000); }); test("should cache stats for 30 seconds", () => { const stats1 = getClientStats(); const stats2 = getClientStats(); // Should return same object (cached) expect(stats1).toBe(stats2); }); test("should refresh cache after TTL expires", async () => { const stats1 = getClientStats(); // Wait for cache to expire (simulate by clearing and waiting) await new Promise(resolve => setTimeout(resolve, 35)); clearStatsCache(); const stats2 = getClientStats(); // Should be different objects (new fetch) expect(stats1).not.toBe(stats2); // But values should be the same (mocked client) expect(stats1.guilds).toBe(stats2.guilds); }); test("clearStatsCache should invalidate cache", () => { const stats1 = getClientStats(); clearStatsCache(); const stats2 = getClientStats(); // Should be different objects expect(stats1).not.toBe(stats2); }); });