From 8137440698f8972bb17948dd54e6e2bc0019b060 Mon Sep 17 00:00:00 2001 From: gavrielc Date: Sat, 6 Jun 2026 18:44:14 +0300 Subject: [PATCH] test(channels): add behavior registration tests for the remaining channel fleet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit discord, gchat, github, imessage, linear, matrix, resend, teams, telegram, webex, whatsapp-cloud, signal, wechat, whatsapp, emacs. Same behavior shape as the slack/deltachat exemplars: import the real src/channels/index.ts barrel and assert getRegisteredChannelNames() contains the channel. Red if the barrel import line is deleted/drifts, if the barrel fails to evaluate, or (for channels with an npm adapter) if the adapter package is not installed — so each test also implicitly guards the skill's dependency. signal and emacs have no npm adapter (signal-cli binary / http builtin), so their tests guard the single barrel reach-in only. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/channels/discord-registration.test.ts | 34 +++++++++++++++++++ src/channels/emacs-registration.test.ts | 29 ++++++++++++++++ src/channels/gchat-registration.test.ts | 34 +++++++++++++++++++ src/channels/github-registration.test.ts | 34 +++++++++++++++++++ src/channels/imessage-registration.test.ts | 34 +++++++++++++++++++ src/channels/linear-registration.test.ts | 34 +++++++++++++++++++ src/channels/matrix-registration.test.ts | 34 +++++++++++++++++++ src/channels/resend-registration.test.ts | 34 +++++++++++++++++++ src/channels/signal-registration.test.ts | 29 ++++++++++++++++ src/channels/teams-registration.test.ts | 34 +++++++++++++++++++ src/channels/telegram-registration.test.ts | 34 +++++++++++++++++++ src/channels/webex-registration.test.ts | 34 +++++++++++++++++++ src/channels/wechat-registration.test.ts | 29 ++++++++++++++++ .../whatsapp-cloud-registration.test.ts | 34 +++++++++++++++++++ src/channels/whatsapp-registration.test.ts | 29 ++++++++++++++++ 15 files changed, 490 insertions(+) create mode 100644 src/channels/discord-registration.test.ts create mode 100644 src/channels/emacs-registration.test.ts create mode 100644 src/channels/gchat-registration.test.ts create mode 100644 src/channels/github-registration.test.ts create mode 100644 src/channels/imessage-registration.test.ts create mode 100644 src/channels/linear-registration.test.ts create mode 100644 src/channels/matrix-registration.test.ts create mode 100644 src/channels/resend-registration.test.ts create mode 100644 src/channels/signal-registration.test.ts create mode 100644 src/channels/teams-registration.test.ts create mode 100644 src/channels/telegram-registration.test.ts create mode 100644 src/channels/webex-registration.test.ts create mode 100644 src/channels/wechat-registration.test.ts create mode 100644 src/channels/whatsapp-cloud-registration.test.ts create mode 100644 src/channels/whatsapp-registration.test.ts diff --git a/src/channels/discord-registration.test.ts b/src/channels/discord-registration.test.ts new file mode 100644 index 000000000..871c5e1eb --- /dev/null +++ b/src/channels/discord-registration.test.ts @@ -0,0 +1,34 @@ +/** + * Integration test for the discord channel's single reach-in: the self-registration + * import in the `src/channels/index.ts` barrel. Importing the barrel runs discord.ts's + * top-level `registerChannelAdapter('discord', …)`; without the import the channel is + * silently absent. + * + * Behavior, not structural: it imports the real barrel and asserts the registry + * actually contains the channel. This reflects what happens at host boot — if the + * `import './discord.js';` line is deleted, or the barrel fails to evaluate for any + * reason (so the channel genuinely would not register), this goes red. A structural + * check of the import line would falsely pass in that second case. + * + * Importing the barrel is safe: registration is a pure top-level call, and discord.ts + * builds the SDK adapter / bridge only inside its factory (invoked at host startup), + * never at import. It does require the adapter package (`@chat-adapter/discord`) to be installed, + * which holds in a composed install: the skill's `pnpm install` step runs before this + * test — so this test also implicitly guards that dependency (an unmocked import throws + * if the package is missing). + * + * discord is a Chat SDK channel: discord.ts also consumes a load-bearing *core* API — + * `createChatSdkBridge(...)` from ./chat-sdk-bridge.js. That core-consumption is a + * typed call, so the build/typecheck leg (`pnpm run build`) guards it against upstream + * drift, not this test. Every Chat SDK channel follows this same shape. + */ +import { describe, it, expect } from 'vitest'; + +import { getRegisteredChannelNames } from './channel-registry.js'; +import './index.js'; // the real barrel — triggers every channel's self-registration + +describe('discord channel registration', () => { + it('registers discord via the channel barrel', () => { + expect(getRegisteredChannelNames()).toContain('discord'); + }); +}); diff --git a/src/channels/emacs-registration.test.ts b/src/channels/emacs-registration.test.ts new file mode 100644 index 000000000..e485b753e --- /dev/null +++ b/src/channels/emacs-registration.test.ts @@ -0,0 +1,29 @@ +/** + * Integration test for the emacs channel's single reach-in: the self-registration + * import in the `src/channels/index.ts` barrel. Importing the barrel runs emacs.ts's + * top-level `registerChannelAdapter('emacs', …)`; without the import the channel is + * silently absent. + * + * Behavior, not structural: it imports the real barrel and asserts the registry + * actually contains the channel. This reflects what happens at host boot — if the + * `import './emacs.js';` line is deleted, or the barrel fails to evaluate for any + * reason (so the channel genuinely would not register), this goes red. A structural + * check of the import line would falsely pass in that second case. + * + * emacs is a native adapter with no npm dependency (it uses the Node http builtin); it talks to an Emacs HTTP client. + * Importing the barrel is safe: registration is a pure top-level call and emacs.ts + * opens connections / spawns subprocesses only inside setup() (run at host startup), + * never at import. There is no adapter package to guard here — this test guards the + * one barrel reach-in (red if `import './emacs.js';` is deleted or the barrel fails + * to evaluate). + */ +import { describe, it, expect } from 'vitest'; + +import { getRegisteredChannelNames } from './channel-registry.js'; +import './index.js'; // the real barrel — triggers every channel's self-registration + +describe('emacs channel registration', () => { + it('registers emacs via the channel barrel', () => { + expect(getRegisteredChannelNames()).toContain('emacs'); + }); +}); diff --git a/src/channels/gchat-registration.test.ts b/src/channels/gchat-registration.test.ts new file mode 100644 index 000000000..79b7f9e7d --- /dev/null +++ b/src/channels/gchat-registration.test.ts @@ -0,0 +1,34 @@ +/** + * Integration test for the gchat channel's single reach-in: the self-registration + * import in the `src/channels/index.ts` barrel. Importing the barrel runs gchat.ts's + * top-level `registerChannelAdapter('gchat', …)`; without the import the channel is + * silently absent. + * + * Behavior, not structural: it imports the real barrel and asserts the registry + * actually contains the channel. This reflects what happens at host boot — if the + * `import './gchat.js';` line is deleted, or the barrel fails to evaluate for any + * reason (so the channel genuinely would not register), this goes red. A structural + * check of the import line would falsely pass in that second case. + * + * Importing the barrel is safe: registration is a pure top-level call, and gchat.ts + * builds the SDK adapter / bridge only inside its factory (invoked at host startup), + * never at import. It does require the adapter package (`@chat-adapter/gchat`) to be installed, + * which holds in a composed install: the skill's `pnpm install` step runs before this + * test — so this test also implicitly guards that dependency (an unmocked import throws + * if the package is missing). + * + * gchat is a Chat SDK channel: gchat.ts also consumes a load-bearing *core* API — + * `createChatSdkBridge(...)` from ./chat-sdk-bridge.js. That core-consumption is a + * typed call, so the build/typecheck leg (`pnpm run build`) guards it against upstream + * drift, not this test. Every Chat SDK channel follows this same shape. + */ +import { describe, it, expect } from 'vitest'; + +import { getRegisteredChannelNames } from './channel-registry.js'; +import './index.js'; // the real barrel — triggers every channel's self-registration + +describe('gchat channel registration', () => { + it('registers gchat via the channel barrel', () => { + expect(getRegisteredChannelNames()).toContain('gchat'); + }); +}); diff --git a/src/channels/github-registration.test.ts b/src/channels/github-registration.test.ts new file mode 100644 index 000000000..ea82eb3cd --- /dev/null +++ b/src/channels/github-registration.test.ts @@ -0,0 +1,34 @@ +/** + * Integration test for the github channel's single reach-in: the self-registration + * import in the `src/channels/index.ts` barrel. Importing the barrel runs github.ts's + * top-level `registerChannelAdapter('github', …)`; without the import the channel is + * silently absent. + * + * Behavior, not structural: it imports the real barrel and asserts the registry + * actually contains the channel. This reflects what happens at host boot — if the + * `import './github.js';` line is deleted, or the barrel fails to evaluate for any + * reason (so the channel genuinely would not register), this goes red. A structural + * check of the import line would falsely pass in that second case. + * + * Importing the barrel is safe: registration is a pure top-level call, and github.ts + * builds the SDK adapter / bridge only inside its factory (invoked at host startup), + * never at import. It does require the adapter package (`@chat-adapter/github`) to be installed, + * which holds in a composed install: the skill's `pnpm install` step runs before this + * test — so this test also implicitly guards that dependency (an unmocked import throws + * if the package is missing). + * + * github is a Chat SDK channel: github.ts also consumes a load-bearing *core* API — + * `createChatSdkBridge(...)` from ./chat-sdk-bridge.js. That core-consumption is a + * typed call, so the build/typecheck leg (`pnpm run build`) guards it against upstream + * drift, not this test. Every Chat SDK channel follows this same shape. + */ +import { describe, it, expect } from 'vitest'; + +import { getRegisteredChannelNames } from './channel-registry.js'; +import './index.js'; // the real barrel — triggers every channel's self-registration + +describe('github channel registration', () => { + it('registers github via the channel barrel', () => { + expect(getRegisteredChannelNames()).toContain('github'); + }); +}); diff --git a/src/channels/imessage-registration.test.ts b/src/channels/imessage-registration.test.ts new file mode 100644 index 000000000..05472da25 --- /dev/null +++ b/src/channels/imessage-registration.test.ts @@ -0,0 +1,34 @@ +/** + * Integration test for the imessage channel's single reach-in: the self-registration + * import in the `src/channels/index.ts` barrel. Importing the barrel runs imessage.ts's + * top-level `registerChannelAdapter('imessage', …)`; without the import the channel is + * silently absent. + * + * Behavior, not structural: it imports the real barrel and asserts the registry + * actually contains the channel. This reflects what happens at host boot — if the + * `import './imessage.js';` line is deleted, or the barrel fails to evaluate for any + * reason (so the channel genuinely would not register), this goes red. A structural + * check of the import line would falsely pass in that second case. + * + * Importing the barrel is safe: registration is a pure top-level call, and imessage.ts + * builds the SDK adapter / bridge only inside its factory (invoked at host startup), + * never at import. It does require the adapter package (`chat-adapter-imessage`) to be installed, + * which holds in a composed install: the skill's `pnpm install` step runs before this + * test — so this test also implicitly guards that dependency (an unmocked import throws + * if the package is missing). + * + * imessage is a Chat SDK channel: imessage.ts also consumes a load-bearing *core* API — + * `createChatSdkBridge(...)` from ./chat-sdk-bridge.js. That core-consumption is a + * typed call, so the build/typecheck leg (`pnpm run build`) guards it against upstream + * drift, not this test. Every Chat SDK channel follows this same shape. + */ +import { describe, it, expect } from 'vitest'; + +import { getRegisteredChannelNames } from './channel-registry.js'; +import './index.js'; // the real barrel — triggers every channel's self-registration + +describe('imessage channel registration', () => { + it('registers imessage via the channel barrel', () => { + expect(getRegisteredChannelNames()).toContain('imessage'); + }); +}); diff --git a/src/channels/linear-registration.test.ts b/src/channels/linear-registration.test.ts new file mode 100644 index 000000000..86b901dc2 --- /dev/null +++ b/src/channels/linear-registration.test.ts @@ -0,0 +1,34 @@ +/** + * Integration test for the linear channel's single reach-in: the self-registration + * import in the `src/channels/index.ts` barrel. Importing the barrel runs linear.ts's + * top-level `registerChannelAdapter('linear', …)`; without the import the channel is + * silently absent. + * + * Behavior, not structural: it imports the real barrel and asserts the registry + * actually contains the channel. This reflects what happens at host boot — if the + * `import './linear.js';` line is deleted, or the barrel fails to evaluate for any + * reason (so the channel genuinely would not register), this goes red. A structural + * check of the import line would falsely pass in that second case. + * + * Importing the barrel is safe: registration is a pure top-level call, and linear.ts + * builds the SDK adapter / bridge only inside its factory (invoked at host startup), + * never at import. It does require the adapter package (`@chat-adapter/linear`) to be installed, + * which holds in a composed install: the skill's `pnpm install` step runs before this + * test — so this test also implicitly guards that dependency (an unmocked import throws + * if the package is missing). + * + * linear is a Chat SDK channel: linear.ts also consumes a load-bearing *core* API — + * `createChatSdkBridge(...)` from ./chat-sdk-bridge.js. That core-consumption is a + * typed call, so the build/typecheck leg (`pnpm run build`) guards it against upstream + * drift, not this test. Every Chat SDK channel follows this same shape. + */ +import { describe, it, expect } from 'vitest'; + +import { getRegisteredChannelNames } from './channel-registry.js'; +import './index.js'; // the real barrel — triggers every channel's self-registration + +describe('linear channel registration', () => { + it('registers linear via the channel barrel', () => { + expect(getRegisteredChannelNames()).toContain('linear'); + }); +}); diff --git a/src/channels/matrix-registration.test.ts b/src/channels/matrix-registration.test.ts new file mode 100644 index 000000000..50c6bb17d --- /dev/null +++ b/src/channels/matrix-registration.test.ts @@ -0,0 +1,34 @@ +/** + * Integration test for the matrix channel's single reach-in: the self-registration + * import in the `src/channels/index.ts` barrel. Importing the barrel runs matrix.ts's + * top-level `registerChannelAdapter('matrix', …)`; without the import the channel is + * silently absent. + * + * Behavior, not structural: it imports the real barrel and asserts the registry + * actually contains the channel. This reflects what happens at host boot — if the + * `import './matrix.js';` line is deleted, or the barrel fails to evaluate for any + * reason (so the channel genuinely would not register), this goes red. A structural + * check of the import line would falsely pass in that second case. + * + * Importing the barrel is safe: registration is a pure top-level call, and matrix.ts + * builds the SDK adapter / bridge only inside its factory (invoked at host startup), + * never at import. It does require the adapter package (`@beeper/chat-adapter-matrix`) to be installed, + * which holds in a composed install: the skill's `pnpm install` step runs before this + * test — so this test also implicitly guards that dependency (an unmocked import throws + * if the package is missing). + * + * matrix is a Chat SDK channel: matrix.ts also consumes a load-bearing *core* API — + * `createChatSdkBridge(...)` from ./chat-sdk-bridge.js. That core-consumption is a + * typed call, so the build/typecheck leg (`pnpm run build`) guards it against upstream + * drift, not this test. Every Chat SDK channel follows this same shape. + */ +import { describe, it, expect } from 'vitest'; + +import { getRegisteredChannelNames } from './channel-registry.js'; +import './index.js'; // the real barrel — triggers every channel's self-registration + +describe('matrix channel registration', () => { + it('registers matrix via the channel barrel', () => { + expect(getRegisteredChannelNames()).toContain('matrix'); + }); +}); diff --git a/src/channels/resend-registration.test.ts b/src/channels/resend-registration.test.ts new file mode 100644 index 000000000..958cf7287 --- /dev/null +++ b/src/channels/resend-registration.test.ts @@ -0,0 +1,34 @@ +/** + * Integration test for the resend channel's single reach-in: the self-registration + * import in the `src/channels/index.ts` barrel. Importing the barrel runs resend.ts's + * top-level `registerChannelAdapter('resend', …)`; without the import the channel is + * silently absent. + * + * Behavior, not structural: it imports the real barrel and asserts the registry + * actually contains the channel. This reflects what happens at host boot — if the + * `import './resend.js';` line is deleted, or the barrel fails to evaluate for any + * reason (so the channel genuinely would not register), this goes red. A structural + * check of the import line would falsely pass in that second case. + * + * Importing the barrel is safe: registration is a pure top-level call, and resend.ts + * builds the SDK adapter / bridge only inside its factory (invoked at host startup), + * never at import. It does require the adapter package (`@resend/chat-sdk-adapter`) to be installed, + * which holds in a composed install: the skill's `pnpm install` step runs before this + * test — so this test also implicitly guards that dependency (an unmocked import throws + * if the package is missing). + * + * resend is a Chat SDK channel: resend.ts also consumes a load-bearing *core* API — + * `createChatSdkBridge(...)` from ./chat-sdk-bridge.js. That core-consumption is a + * typed call, so the build/typecheck leg (`pnpm run build`) guards it against upstream + * drift, not this test. Every Chat SDK channel follows this same shape. + */ +import { describe, it, expect } from 'vitest'; + +import { getRegisteredChannelNames } from './channel-registry.js'; +import './index.js'; // the real barrel — triggers every channel's self-registration + +describe('resend channel registration', () => { + it('registers resend via the channel barrel', () => { + expect(getRegisteredChannelNames()).toContain('resend'); + }); +}); diff --git a/src/channels/signal-registration.test.ts b/src/channels/signal-registration.test.ts new file mode 100644 index 000000000..b7644a215 --- /dev/null +++ b/src/channels/signal-registration.test.ts @@ -0,0 +1,29 @@ +/** + * Integration test for the signal channel's single reach-in: the self-registration + * import in the `src/channels/index.ts` barrel. Importing the barrel runs signal.ts's + * top-level `registerChannelAdapter('signal', …)`; without the import the channel is + * silently absent. + * + * Behavior, not structural: it imports the real barrel and asserts the registry + * actually contains the channel. This reflects what happens at host boot — if the + * `import './signal.js';` line is deleted, or the barrel fails to evaluate for any + * reason (so the channel genuinely would not register), this goes red. A structural + * check of the import line would falsely pass in that second case. + * + * signal is a native adapter with no npm dependency (it drives the external signal-cli binary over a local TCP socket); it talks to signal-cli. + * Importing the barrel is safe: registration is a pure top-level call and signal.ts + * opens connections / spawns subprocesses only inside setup() (run at host startup), + * never at import. There is no adapter package to guard here — this test guards the + * one barrel reach-in (red if `import './signal.js';` is deleted or the barrel fails + * to evaluate). + */ +import { describe, it, expect } from 'vitest'; + +import { getRegisteredChannelNames } from './channel-registry.js'; +import './index.js'; // the real barrel — triggers every channel's self-registration + +describe('signal channel registration', () => { + it('registers signal via the channel barrel', () => { + expect(getRegisteredChannelNames()).toContain('signal'); + }); +}); diff --git a/src/channels/teams-registration.test.ts b/src/channels/teams-registration.test.ts new file mode 100644 index 000000000..d2eadc0cd --- /dev/null +++ b/src/channels/teams-registration.test.ts @@ -0,0 +1,34 @@ +/** + * Integration test for the teams channel's single reach-in: the self-registration + * import in the `src/channels/index.ts` barrel. Importing the barrel runs teams.ts's + * top-level `registerChannelAdapter('teams', …)`; without the import the channel is + * silently absent. + * + * Behavior, not structural: it imports the real barrel and asserts the registry + * actually contains the channel. This reflects what happens at host boot — if the + * `import './teams.js';` line is deleted, or the barrel fails to evaluate for any + * reason (so the channel genuinely would not register), this goes red. A structural + * check of the import line would falsely pass in that second case. + * + * Importing the barrel is safe: registration is a pure top-level call, and teams.ts + * builds the SDK adapter / bridge only inside its factory (invoked at host startup), + * never at import. It does require the adapter package (`@chat-adapter/teams`) to be installed, + * which holds in a composed install: the skill's `pnpm install` step runs before this + * test — so this test also implicitly guards that dependency (an unmocked import throws + * if the package is missing). + * + * teams is a Chat SDK channel: teams.ts also consumes a load-bearing *core* API — + * `createChatSdkBridge(...)` from ./chat-sdk-bridge.js. That core-consumption is a + * typed call, so the build/typecheck leg (`pnpm run build`) guards it against upstream + * drift, not this test. Every Chat SDK channel follows this same shape. + */ +import { describe, it, expect } from 'vitest'; + +import { getRegisteredChannelNames } from './channel-registry.js'; +import './index.js'; // the real barrel — triggers every channel's self-registration + +describe('teams channel registration', () => { + it('registers teams via the channel barrel', () => { + expect(getRegisteredChannelNames()).toContain('teams'); + }); +}); diff --git a/src/channels/telegram-registration.test.ts b/src/channels/telegram-registration.test.ts new file mode 100644 index 000000000..a007e8643 --- /dev/null +++ b/src/channels/telegram-registration.test.ts @@ -0,0 +1,34 @@ +/** + * Integration test for the telegram channel's single reach-in: the self-registration + * import in the `src/channels/index.ts` barrel. Importing the barrel runs telegram.ts's + * top-level `registerChannelAdapter('telegram', …)`; without the import the channel is + * silently absent. + * + * Behavior, not structural: it imports the real barrel and asserts the registry + * actually contains the channel. This reflects what happens at host boot — if the + * `import './telegram.js';` line is deleted, or the barrel fails to evaluate for any + * reason (so the channel genuinely would not register), this goes red. A structural + * check of the import line would falsely pass in that second case. + * + * Importing the barrel is safe: registration is a pure top-level call, and telegram.ts + * builds the SDK adapter / bridge only inside its factory (invoked at host startup), + * never at import. It does require the adapter package (`@chat-adapter/telegram`) to be installed, + * which holds in a composed install: the skill's `pnpm install` step runs before this + * test — so this test also implicitly guards that dependency (an unmocked import throws + * if the package is missing). + * + * telegram is a Chat SDK channel: telegram.ts also consumes a load-bearing *core* API — + * `createChatSdkBridge(...)` from ./chat-sdk-bridge.js. That core-consumption is a + * typed call, so the build/typecheck leg (`pnpm run build`) guards it against upstream + * drift, not this test. Every Chat SDK channel follows this same shape. + */ +import { describe, it, expect } from 'vitest'; + +import { getRegisteredChannelNames } from './channel-registry.js'; +import './index.js'; // the real barrel — triggers every channel's self-registration + +describe('telegram channel registration', () => { + it('registers telegram via the channel barrel', () => { + expect(getRegisteredChannelNames()).toContain('telegram'); + }); +}); diff --git a/src/channels/webex-registration.test.ts b/src/channels/webex-registration.test.ts new file mode 100644 index 000000000..c1b70bcc2 --- /dev/null +++ b/src/channels/webex-registration.test.ts @@ -0,0 +1,34 @@ +/** + * Integration test for the webex channel's single reach-in: the self-registration + * import in the `src/channels/index.ts` barrel. Importing the barrel runs webex.ts's + * top-level `registerChannelAdapter('webex', …)`; without the import the channel is + * silently absent. + * + * Behavior, not structural: it imports the real barrel and asserts the registry + * actually contains the channel. This reflects what happens at host boot — if the + * `import './webex.js';` line is deleted, or the barrel fails to evaluate for any + * reason (so the channel genuinely would not register), this goes red. A structural + * check of the import line would falsely pass in that second case. + * + * Importing the barrel is safe: registration is a pure top-level call, and webex.ts + * builds the SDK adapter / bridge only inside its factory (invoked at host startup), + * never at import. It does require the adapter package (`@bitbasti/chat-adapter-webex`) to be installed, + * which holds in a composed install: the skill's `pnpm install` step runs before this + * test — so this test also implicitly guards that dependency (an unmocked import throws + * if the package is missing). + * + * webex is a Chat SDK channel: webex.ts also consumes a load-bearing *core* API — + * `createChatSdkBridge(...)` from ./chat-sdk-bridge.js. That core-consumption is a + * typed call, so the build/typecheck leg (`pnpm run build`) guards it against upstream + * drift, not this test. Every Chat SDK channel follows this same shape. + */ +import { describe, it, expect } from 'vitest'; + +import { getRegisteredChannelNames } from './channel-registry.js'; +import './index.js'; // the real barrel — triggers every channel's self-registration + +describe('webex channel registration', () => { + it('registers webex via the channel barrel', () => { + expect(getRegisteredChannelNames()).toContain('webex'); + }); +}); diff --git a/src/channels/wechat-registration.test.ts b/src/channels/wechat-registration.test.ts new file mode 100644 index 000000000..9b3b778a1 --- /dev/null +++ b/src/channels/wechat-registration.test.ts @@ -0,0 +1,29 @@ +/** + * Integration test for the wechat channel's single reach-in: the self-registration + * import in the `src/channels/index.ts` barrel. Importing the barrel runs wechat.ts's + * top-level `registerChannelAdapter('wechat', …)`; without the import the channel is + * silently absent. + * + * Behavior, not structural: it imports the real barrel and asserts the registry + * actually contains the channel. This reflects what happens at host boot — if the + * `import './wechat.js';` line is deleted, or the barrel fails to evaluate for any + * reason (so the channel genuinely would not register), this goes red. A structural + * check of the import line would falsely pass in that second case. + * + * wechat is a native adapter (no Chat SDK bridge). Importing the barrel is safe: + * registration is a pure top-level call and wechat.ts opens connections / spawns + * subprocesses only inside setup() (run at host startup), never at import. It does + * require the adapter package (`wechat-ilink-client`) to be installed, which holds in a composed + * install: the skill's `pnpm install` step runs before this test — so this test also + * implicitly guards that dependency (an unmocked import throws if the package is missing). + */ +import { describe, it, expect } from 'vitest'; + +import { getRegisteredChannelNames } from './channel-registry.js'; +import './index.js'; // the real barrel — triggers every channel's self-registration + +describe('wechat channel registration', () => { + it('registers wechat via the channel barrel', () => { + expect(getRegisteredChannelNames()).toContain('wechat'); + }); +}); diff --git a/src/channels/whatsapp-cloud-registration.test.ts b/src/channels/whatsapp-cloud-registration.test.ts new file mode 100644 index 000000000..6e51b6648 --- /dev/null +++ b/src/channels/whatsapp-cloud-registration.test.ts @@ -0,0 +1,34 @@ +/** + * Integration test for the whatsapp-cloud channel's single reach-in: the self-registration + * import in the `src/channels/index.ts` barrel. Importing the barrel runs whatsapp-cloud.ts's + * top-level `registerChannelAdapter('whatsapp-cloud', …)`; without the import the channel is + * silently absent. + * + * Behavior, not structural: it imports the real barrel and asserts the registry + * actually contains the channel. This reflects what happens at host boot — if the + * `import './whatsapp-cloud.js';` line is deleted, or the barrel fails to evaluate for any + * reason (so the channel genuinely would not register), this goes red. A structural + * check of the import line would falsely pass in that second case. + * + * Importing the barrel is safe: registration is a pure top-level call, and whatsapp-cloud.ts + * builds the SDK adapter / bridge only inside its factory (invoked at host startup), + * never at import. It does require the adapter package (`@chat-adapter/whatsapp`) to be installed, + * which holds in a composed install: the skill's `pnpm install` step runs before this + * test — so this test also implicitly guards that dependency (an unmocked import throws + * if the package is missing). + * + * whatsapp-cloud is a Chat SDK channel: whatsapp-cloud.ts also consumes a load-bearing *core* API — + * `createChatSdkBridge(...)` from ./chat-sdk-bridge.js. That core-consumption is a + * typed call, so the build/typecheck leg (`pnpm run build`) guards it against upstream + * drift, not this test. Every Chat SDK channel follows this same shape. + */ +import { describe, it, expect } from 'vitest'; + +import { getRegisteredChannelNames } from './channel-registry.js'; +import './index.js'; // the real barrel — triggers every channel's self-registration + +describe('whatsapp-cloud channel registration', () => { + it('registers whatsapp-cloud via the channel barrel', () => { + expect(getRegisteredChannelNames()).toContain('whatsapp-cloud'); + }); +}); diff --git a/src/channels/whatsapp-registration.test.ts b/src/channels/whatsapp-registration.test.ts new file mode 100644 index 000000000..a798af183 --- /dev/null +++ b/src/channels/whatsapp-registration.test.ts @@ -0,0 +1,29 @@ +/** + * Integration test for the whatsapp channel's single reach-in: the self-registration + * import in the `src/channels/index.ts` barrel. Importing the barrel runs whatsapp.ts's + * top-level `registerChannelAdapter('whatsapp', …)`; without the import the channel is + * silently absent. + * + * Behavior, not structural: it imports the real barrel and asserts the registry + * actually contains the channel. This reflects what happens at host boot — if the + * `import './whatsapp.js';` line is deleted, or the barrel fails to evaluate for any + * reason (so the channel genuinely would not register), this goes red. A structural + * check of the import line would falsely pass in that second case. + * + * whatsapp is a native adapter (no Chat SDK bridge). Importing the barrel is safe: + * registration is a pure top-level call and whatsapp.ts opens connections / spawns + * subprocesses only inside setup() (run at host startup), never at import. It does + * require the adapter package (`@whiskeysockets/baileys`) to be installed, which holds in a composed + * install: the skill's `pnpm install` step runs before this test — so this test also + * implicitly guards that dependency (an unmocked import throws if the package is missing). + */ +import { describe, it, expect } from 'vitest'; + +import { getRegisteredChannelNames } from './channel-registry.js'; +import './index.js'; // the real barrel — triggers every channel's self-registration + +describe('whatsapp channel registration', () => { + it('registers whatsapp via the channel barrel', () => { + expect(getRegisteredChannelNames()).toContain('whatsapp'); + }); +});