diff --git a/extensions/feishu/src/client.test.ts b/extensions/feishu/src/client.test.ts index 8a4ba4f2ebf0..2f3202d531f1 100644 --- a/extensions/feishu/src/client.test.ts +++ b/extensions/feishu/src/client.test.ts @@ -386,6 +386,31 @@ describe("createFeishuClient HTTP timeout", () => { timeout: 45_000, }); }); + + it("evicts client cache when SDK is replaced via setFeishuClientRuntimeForTest (#83911)", () => { + const ctorCountA = clientCtorMock.mock.calls.length; + + // First client gets cached + createFeishuClient({ appId: "app_7", appSecret: "secret_7", accountId: "cache-clear-test" }); // pragma: allowlist secret + expect(clientCtorMock.mock.calls.length).toBe(ctorCountA + 1); + + // SDK swap via setFeishuClientRuntimeForTest should clear the cache + setFeishuClientRuntimeForTest({ + sdk: { + AppType: { SelfBuild: "self" } as never, + Client: clientCtorMock as never, + Domain: { Feishu: "https://open.feishu.cn", Lark: "https://open.larksuite.com" } as never, + LoggerLevel: { info: "info" } as never, + WSClient: vi.fn() as never, + EventDispatcher: vi.fn() as never, + defaultHttpInstance: mockBaseHttpInstance as never, + }, + }); + + // Same credentials — would hit cache before the fix; now evicted + createFeishuClient({ appId: "app_7", appSecret: "secret_7", accountId: "cache-clear-test" }); // pragma: allowlist secret + expect(clientCtorMock.mock.calls.length).toBe(ctorCountA + 2); + }); }); describe("createFeishuWSClient proxy handling", () => { diff --git a/extensions/feishu/src/client.ts b/extensions/feishu/src/client.ts index 22b091920c2c..194d68e075d7 100644 --- a/extensions/feishu/src/client.ts +++ b/extensions/feishu/src/client.ts @@ -260,4 +260,5 @@ export function setFeishuClientRuntimeForTest(overrides?: { feishuClientSdk = overrides?.sdk ? { ...defaultFeishuClientSdk, ...overrides.sdk } : defaultFeishuClientSdk; + clearClientCache(); }