import { describe, expect, test } from "bun:test"; import { createGuildProfileReader } from "@/lib/profile/guild-profile"; describe("Guild profile read module", () => { test("assembles independent sections and current voice scope", async () => { const reader = createGuildProfileReader({ getProfile: async () => ({ id: "member-1", username: "member", globalName: "Member", avatarUrl: null, avatarDecorationUrl: null, bannerUrl: null, accentColor: null, primaryGuild: null, roles: [], }), getXp: async () => ({ level: 2, totalXp: "1200", rank: 4 }), getCurrentVoiceChannels: async () => [ { id: "voice-1", name: "Lounge", type: 2, position: 1 }, { id: "stage-1", name: "Stage", type: 13, position: 2 }, ], getVoice: async (_discordId, channelIds) => ({ totalSeconds: channelIds.join(",") === "voice-1,stage-1" ? "90" : "0", rank: 3, }), }); const result = await reader("member-1"); expect(result.profile?.id).toBe("member-1"); expect(result.xp).toMatchObject({ level: 2, totalXp: "1200", rank: 4 }); expect(result.voice).toEqual({ totalSeconds: "90", rank: 3 }); expect(result.profileUnavailable).toBeFalse(); }); test("keeps healthy sections when one source fails", async () => { const failures: string[] = []; const reader = createGuildProfileReader({ getProfile: async () => null, getXp: async () => { throw new Error("leaderboard unavailable"); }, getCurrentVoiceChannels: async () => [], getVoice: async () => ({ totalSeconds: "0", rank: null }), reportFailure: (source) => failures.push(source), }); const result = await reader("member-1"); expect(result.profile).toBeNull(); expect(result.profileUnavailable).toBeTrue(); expect(result.xp).toBeNull(); expect(result.voice).toEqual({ totalSeconds: "0", rank: null }); expect(failures).toEqual(["xp"]); }); });