this repo has no description
at main 3.9 kB view raw
1import { afterEach, describe, expect, mock, test } from "bun:test"; 2import { cleanupUserCache, getUserInfo } from "./user-cache"; 3 4describe("user-cache", () => { 5 const mockSlackClient = { 6 users: { 7 info: mock(async () => ({ 8 user: { 9 name: "testuser", 10 real_name: "Test User", 11 }, 12 })), 13 }, 14 }; 15 16 afterEach(() => { 17 cleanupUserCache(); 18 mockSlackClient.users.info.mockClear(); 19 mockSlackClient.users.info.mockReset(); 20 }); 21 22 describe("getUserInfo", () => { 23 test("uses display name from event if provided", async () => { 24 const client = { 25 users: { 26 info: mock(async () => ({ 27 user: { 28 name: "testuser", 29 real_name: "Test User", 30 }, 31 })), 32 }, 33 }; 34 35 const result = await getUserInfo("U123", client, "Event Display Name"); 36 37 expect(result).toEqual({ 38 name: "Event Display Name", 39 realName: "Event Display Name", 40 }); 41 // Should not call API when display name provided 42 expect(client.users.info).toHaveBeenCalledTimes(0); 43 }); 44 45 test("fetches user info from Slack on cache miss", async () => { 46 const client = { 47 users: { 48 info: mock(async () => ({ 49 user: { 50 name: "testuser", 51 real_name: "Test User", 52 }, 53 })), 54 }, 55 }; 56 57 const result = await getUserInfo("U125", client); 58 59 expect(result).toEqual({ 60 name: "testuser", 61 realName: "Test User", 62 }); 63 expect(client.users.info).toHaveBeenCalledTimes(1); 64 }); 65 66 test("returns cached data on cache hit", async () => { 67 const client = { 68 users: { 69 info: mock(async () => ({ 70 user: { 71 name: "testuser", 72 real_name: "Test User", 73 }, 74 })), 75 }, 76 }; 77 78 // First call - cache miss 79 await getUserInfo("U124", client); 80 expect(client.users.info).toHaveBeenCalledTimes(1); 81 82 // Second call - cache hit 83 const result = await getUserInfo("U124", client); 84 expect(result).toEqual({ 85 name: "testuser", 86 realName: "Test User", 87 }); 88 expect(client.users.info).toHaveBeenCalledTimes(1); // Still 1 89 }); 90 91 test("uses name as fallback for real_name", async () => { 92 const client = { 93 users: { 94 info: mock(async () => ({ 95 user: { 96 name: "testuser", 97 }, 98 })), 99 }, 100 }; 101 102 const result = await getUserInfo("U456", client); 103 expect(result).toEqual({ 104 name: "testuser", 105 realName: "testuser", 106 }); 107 }); 108 109 test("handles missing user data gracefully", async () => { 110 const client = { 111 users: { 112 info: mock(async () => ({})), 113 }, 114 }; 115 116 const result = await getUserInfo("U789", client); 117 expect(result).toEqual({ 118 name: "Unknown", 119 realName: "Unknown", 120 }); 121 }); 122 123 test("handles Slack API errors", async () => { 124 const client = { 125 users: { 126 info: mock(async () => { 127 throw new Error("API Error"); 128 }), 129 }, 130 }; 131 132 const result = await getUserInfo("U999", client); 133 expect(result).toBeNull(); 134 }); 135 136 test("caches different users separately", async () => { 137 const client = { 138 users: { 139 info: mock(async ({ user }: { user: string }) => { 140 if (user === "U111") { 141 return { user: { name: "alice", real_name: "Alice" } }; 142 } 143 return { user: { name: "bob", real_name: "Bob" } }; 144 }), 145 }, 146 }; 147 148 const result1 = await getUserInfo("U111", client); 149 const result2 = await getUserInfo("U222", client); 150 151 expect(result1?.name).toBe("alice"); 152 expect(result2?.name).toBe("bob"); 153 expect(client.users.info).toHaveBeenCalledTimes(2); 154 155 // Both should be cached now 156 await getUserInfo("U111", client); 157 await getUserInfo("U222", client); 158 expect(client.users.info).toHaveBeenCalledTimes(2); // Still 2 159 }); 160 }); 161 162 describe("cleanupUserCache", () => { 163 test("cleanup runs without errors", () => { 164 // Just test that cleanup doesn't throw 165 expect(() => cleanupUserCache()).not.toThrow(); 166 }); 167 }); 168});