- Created dashboard service with DB queries for users, economy, events - Added client stats provider with 30s caching for Discord metrics - Implemented /api/stats endpoint aggregating all dashboard data - Created useDashboardStats React hook with auto-refresh - Updated Dashboard.tsx to display real data with loading/error states - Added comprehensive test coverage (11 tests passing) - Replaced all mock values with live Discord and database metrics
75 lines
2.0 KiB
TypeScript
75 lines
2.0 KiB
TypeScript
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);
|
|
});
|
|
});
|