fix(twitch): export clearRegistryForTest for cross-test isolation (#8… · openclaw/openclaw@ff5354e
clawsweeper
·
2026-05-20
·
via Recent Commits to openclaw:main
| Original file line number | Diff line number | Diff line change |
|---|
@@ -14,6 +14,7 @@ Docs: https://docs.openclaw.ai
|
14 | 14 | - CLI/message: include a stable top-level `messageId` in `openclaw message --json` output when channel sends return one. (#84191) Thanks @100menotu001. |
15 | 15 | - Plugins/hooks: apply a default 30-second timeout to `before_compaction` and `after_compaction` hooks so a hung plugin handler no longer blocks compaction completion. (#84153) |
16 | 16 | - Discord: preserve disabled presentation buttons when adapting and rendering Discord message controls. (#84188) Thanks @100menotu001. |
| 17 | +- Twitch: add a test-only client-manager registry reset helper so non-isolated Twitch tests can clear cached managers between cases. Fixes #83887. (#84244) Thanks @hclsys. |
17 | 18 | - Plugins/perf: thread explicit plugin discovery results through `loadBundledCapabilityRuntimeRegistry`, `resolveBundledPluginSources`, and `listChannelCatalogEntries` so callers that already hold a discovery result skip redundant filesystem walks. Thanks @SebTardif. |
18 | 19 | - harden update restart script creation [AI]. (#84088) Thanks @pgondhi987. |
19 | 20 | - Docker: keep the bundled Codex plugin in official release image keep lists so the default OpenAI agent harness remains available after Docker pruning. Fixes #83613. (#83626) Thanks @YuanHanzhong. |
|
| Original file line number | Diff line number | Diff line change |
|---|
|
| 1 | +import { afterEach, describe, expect, it, vi } from "vitest"; |
| 2 | +import { |
| 3 | +clearRegistryForTest, |
| 4 | +getClientManager, |
| 5 | +getOrCreateClientManager, |
| 6 | +} from "./client-manager-registry.js"; |
| 7 | +import type { ChannelLogSink } from "./types.js"; |
| 8 | + |
| 9 | +function makeLogger(): ChannelLogSink { |
| 10 | +return { |
| 11 | +info: vi.fn(), |
| 12 | +warn: vi.fn(), |
| 13 | +error: vi.fn(), |
| 14 | +debug: vi.fn(), |
| 15 | +}; |
| 16 | +} |
| 17 | + |
| 18 | +describe("client manager registry", () => { |
| 19 | +afterEach(async () => { |
| 20 | +await clearRegistryForTest(); |
| 21 | +}); |
| 22 | + |
| 23 | +it("clears cached managers for hot module test isolation", async () => { |
| 24 | +const firstManager = getOrCreateClientManager("default", makeLogger()); |
| 25 | +const disconnectAll = vi.spyOn(firstManager, "disconnectAll"); |
| 26 | + |
| 27 | +expect(getClientManager("default")).toBe(firstManager); |
| 28 | +expect(getOrCreateClientManager("default", makeLogger())).toBe(firstManager); |
| 29 | + |
| 30 | +await clearRegistryForTest(); |
| 31 | + |
| 32 | +expect(disconnectAll).toHaveBeenCalledOnce(); |
| 33 | +expect(getClientManager("default")).toBeUndefined(); |
| 34 | +expect(getOrCreateClientManager("default", makeLogger())).not.toBe(firstManager); |
| 35 | +}); |
| 36 | +}); |
| Original file line number | Diff line number | Diff line change |
|---|
@@ -85,3 +85,25 @@ export async function removeClientManager(accountId: string): Promise<void> {
|
85 | 85 | registry.delete(accountId); |
86 | 86 | entry.logger.info(`Unregistered client manager for account: ${accountId}`); |
87 | 87 | } |
| 88 | + |
| 89 | +/** |
| 90 | + * Test-only: clear the module-level registry of all client manager entries. |
| 91 | + * |
| 92 | + * Mirrors the `clearForTest` escape hatch on `TwitchClientManager`. Without |
| 93 | + * this, the module-level `registry` Map survives across tests when vitest |
| 94 | + * is run with `--isolate=false` (or any harness that does not tear the |
| 95 | + * module graph down between cases), and a stale entry from one test will |
| 96 | + * shadow `getOrCreateClientManager` calls in subsequent tests, silently |
| 97 | + * handing back another test's mocked logger/manager. See #83887. |
| 98 | + * |
| 99 | + * Production code MUST NOT call this. It disconnects cached managers before |
| 100 | + * clearing the registry so tests do not leave handlers or clients behind. |
| 101 | + */ |
| 102 | +export async function clearRegistryForTest(): Promise<void> { |
| 103 | +const entries = [...registry.values()]; |
| 104 | +try { |
| 105 | +await Promise.all(entries.map((entry) => entry.manager.disconnectAll())); |
| 106 | +} finally { |
| 107 | +registry.clear(); |
| 108 | +} |
| 109 | +} |
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。