Skip to content

Conversation

@AndyTWF
Copy link
Contributor

@AndyTWF AndyTWF commented Dec 15, 2025

Summary

This PR improves unit test isolation and maintainability by introducing a MockConfigManager that replaces filesystem-based config setup in tests.

FTF-132

Problem

Unit tests were creating temporary directories and writing TOML config files for each test. This caused:

  • Race conditions when tests ran in parallel (tests shared filesystem state)
  • Slow tests due to filesystem I/O overhead
  • Boilerplate code - each test file had ~30 lines of setup/teardown for temp directories
  • Flaky tests - timing-dependent failures in CI

Solution

1. Replace toml package with smol-toml

  • The toml package was unmaintained (4 years old, parse-only)
  • smol-toml provides both parse and stringify, removing ~85 lines of custom TOML formatting code

2. Extract ConfigManager interface

  • Convert ConfigManager from concrete class to interface
  • Rename implementation to TomlConfigManager
  • Enables dependency injection of mock in tests

3. Add MockConfigManager

  • In-memory implementation of ConfigManager interface
  • Provides DEFAULT_TEST_CONFIG with standard test values
  • Helper functions: getMockConfigManager(), resetMockConfig(), clearAccounts()
  • Auto-initialized by unit test setup file

4. Migrate all unit tests

  • Remove temp directory setup from 62 test files
  • Net reduction of ~2,000 lines of boilerplate
  • Tests that need real file I/O (e.g., config/show.test.ts) can opt-out

5. Re-enable parallel test execution

  • Tests no longer share filesystem state, so they can run in parallel again

Follow-up

As follow up, I plan to make all the mocks (e.g. realtime, spaces, chat) global in a similar way to the config, so we don't have lots of repetitive setup there.

Summary by CodeRabbit

Release Notes

  • Refactor
    • Improved configuration management architecture with factory pattern initialization
    • Switched TOML parsing library for better performance and compatibility
    • Added automatic migration support for existing configuration files to new format

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel
Copy link

vercel bot commented Dec 15, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
cli-web-cli Ready Ready Preview, Comment Dec 16, 2025 3:19pm

@coderabbitai
Copy link

coderabbitai bot commented Dec 15, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This pull request refactors the configuration management system from a concrete class to an interface-based design with a factory pattern. The toml package dependency is replaced with smol-toml. Extensive test infrastructure is introduced, including a comprehensive MockConfigManager and centralized DEFAULT_TEST_CONFIG. Test files across the codebase are migrated from filesystem-based setup/teardown to in-memory mock configuration, eliminating per-test environment manipulation and global mock overwriting.

Changes

Cohort / File(s) Summary
Dependency Updates
package.json
Replaced toml (^3.0.0) with smol-toml (^1.3.1)
Core Config Manager Refactoring
src/services/config-manager.ts
Replaced ConfigManager class with interface; introduced createConfigManager() factory function; added TomlConfigManager concrete implementation; integrated smol-toml for parsing/serialization; added config migration logic
Config Manager Usage Updates
src/base-command.ts, src/help.ts
Updated to use createConfigManager() factory instead of new ConfigManager(); imports adjusted to include factory function
TOML Parser Migration
src/commands/config/show.ts
Replaced toml.parse() with smol-toml parse() function
Factory Pattern Adoption
src/commands/mcp/start-server.ts
Updated to use createConfigManager() factory instead of direct class instantiation
Test Mock Infrastructure
test/helpers/mock-config-manager.ts
New file; introduced MockConfigManager class, DEFAULT_TEST_CONFIG constant, and helper functions (getMockConfigManager, initializeMockConfigManager, resetMockConfig, hasMockConfigManager)
Global Test Setup
test/setup.ts
Extended global __TEST_MOCKS__ interface with optional configManager property
Unit Test Setup
test/unit/setup.ts
New file; wires initializeMockConfigManager() via beforeAll and resetMockConfig() via beforeEach for unit tests
E2E Auth Tests
test/e2e/auth/basic-auth.test.ts
Updated to import and instantiate TomlConfigManager instead of ConfigManager
Unit Test: Base Command
test/unit/base/base-command.test.ts
Added TomlConfigManager to test imports; updated spy/stub references to use TomlConfigManager.prototype
Unit Tests: Config/Accounts
test/unit/commands/accounts/login.test.ts, logout.test.ts
Replaced filesystem-based config setup with mock config manager; removed temp directory creation; assertions now validate state via getMockConfigManager().getConfig()
Unit Tests: Apps (Channel Rules)
test/unit/commands/apps/channel-rules/create.test.ts, delete.test.ts, list.test.ts, update.test.ts
Removed beforeEach setup; replaced hard-coded IDs with DEFAULT_TEST_CONFIG.appId; eliminated temp config directories and environment variables
Unit Tests: Apps (Core)
test/unit/commands/apps/create.test.ts, current.test.ts, delete.test.ts, update.test.ts
Replaced in-test configuration and filesystem setup with mock config manager; dynamic ID retrieval from mock config; removed env var and directory manipulation
Unit Tests: Apps (Logs)
test/unit/commands/apps/logs/history.test.ts, subscribe.test.ts
Replaced environment setup with global __TEST_MOCKS__ cleanup; adjusted mock initialization to preserve existing mocks via spread operator
Unit Tests: Apps (Set APNS)
test/unit/commands/apps/set-apns-p12.test.ts
Introduced DEFAULT_TEST_CONFIG for appId; adjusted temp directory usage for test artifacts
Unit Tests: Auth (Token Issuance)
test/unit/commands/auth/issue-ably-token.test.ts, issue-jwt-token.test.ts
Replaced file-system config manipulation with mock config manager; used DEFAULT_TEST_CONFIG for token values
Unit Tests: Auth (Keys)
test/unit/commands/auth/keys/create.test.ts, current.test.ts, get.test.ts, list.test.ts, revoke.test.ts, update.test.ts
Standardized on DEFAULT_TEST_CONFIG.appId and DEFAULT_TEST_CONFIG.keyId; removed per-test environment/config setup; simplified nock mocks
Unit Tests: Auth (Token Management)
test/unit/commands/auth/revoke-token.test.ts
Updated to use DEFAULT_TEST_CONFIG values; removed environment setup
Unit Tests: Bench
test/unit/commands/bench/benchmarking.test.ts
Adjusted mock initialization to merge with existing __TEST_MOCKS__ instead of overwriting
Unit Tests: Channel Rules
test/unit/commands/channel-rule/create.test.ts, delete.test.ts, list.test.ts, update.test.ts
Removed per-test config directory setup; uses DEFAULT_TEST_CONFIG.appId
Unit Tests: Channels (Publish/History)
test/unit/commands/channels/batch-publish.test.ts, history.test.ts, list.test.ts
Adjusted mock merging logic to preserve existing mocks; selective cleanup in afterEach
Unit Tests: Channels (Occupancy/Presence)
test/unit/commands/channels/occupancy/subscribe.test.ts, presence/enter.test.ts, presence/subscribe.test.ts, subscribe.test.ts
Removed environment/filesystem setup; implemented mock merging strategy to preserve configManager
Unit Tests: Config
test/unit/commands/config/path.test.ts, show.test.ts
Removed filesystem scaffolding; show.test.ts added logic to temporarily disable mock during test for real file I/O
Unit Tests: Integrations
test/unit/commands/integrations/create.test.ts, delete.test.ts, get.test.ts, update.test.ts
Replaced hard-coded tokens/IDs with DEFAULT_TEST_CONFIG; removed per-test config setup
Unit Tests: Logs
test/unit/commands/logs/app/subscribe.test.ts, channel-lifecycle.test.ts, channel-lifecycle/subscribe.test.ts, connection-lifecycle/history.test.ts, push/history.test.ts
Shifted from filesystem/env-based setup to in-memory mock management; implemented mock preservation via spread operator
Unit Tests: Queues
test/unit/commands/queues/create.test.ts, delete.test.ts, list.test.ts
Replaced hard-coded constants with DEFAULT_TEST_CONFIG and getMockConfigManager(); removed config directory setup
Unit Tests: Rooms
test/unit/commands/rooms/messages/reactions/remove.test.ts, send.test.ts, subscribe.test.ts, presence/subscribe.test.ts, reactions/subscribe.test.ts, typing/subscribe.test.ts
Removed environment/filesystem setup; implemented mock merging to preserve existing mocks
Unit Tests: Spaces
test/unit/commands/spaces/cursors/get-all.test.ts, cursors/subscribe.test.ts, locations/get-all.test.ts, locations/subscribe.test.ts, locks/get-all.test.ts, locks/get.test.ts, locks/subscribe.test.ts, spaces.test.ts
Removed per-test environment setup; implemented global mock merging strategy; simplified teardown
Service Tests
test/unit/services/config-manager.test.ts
Updated to import and instantiate TomlConfigManager
Vitest Configuration
vitest.config.ts
Added setupFiles for both ./test/setup.ts and ./test/unit/setup.ts; removed previous fileParallelism workaround

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • ConfigManager refactoring: Interface design, factory pattern implementation, and TomlConfigManager concrete class require careful review to ensure type safety and correct delegation
  • TOML parser migration: Verify smol-toml API compatibility (parse/stringify) and behavior parity with toml package
  • Mock infrastructure: MockConfigManager implementation must correctly satisfy the ConfigManager interface and maintain consistent state
  • Test mock preservation: ~70 test files updated with similar merging/cleanup patterns; spot-check multiple files to ensure global mock preservation logic is correct across different test structures
  • Factory pattern adoption: Verify all usages of createConfigManager() and that test mode properly returns MockConfigManager via __TEST_MOCKS__

Areas requiring extra attention:

  • src/services/config-manager.ts — complex refactoring with migration logic and new interface surface
  • test/helpers/mock-config-manager.ts — comprehensive mock implementation must cover all interface methods
  • Global mock merging patterns in test files — ensure ...globalThis.__TEST_MOCKS__ spread is applied consistently
  • Config migration logic in loadConfig method — verify old config shapes are correctly transformed and persisted

Suggested reviewers

  • jamiehenson
  • denissellu

Poem

🐰 The config now hops with a factory's grace,
No more class constructor cluttering the place!
With mocks in memory and tests so clean,
The finest refactoring I've ever seen!
From toml to smol-toml, we leap so high,
Configuration dreams reaching the sky! 🌟

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'test: introduce mock config manager, use in tests' clearly and specifically summarizes the main change: introducing a MockConfigManager and adopting it across the test suite.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@AndyTWF AndyTWF force-pushed the config-manager-updates branch from 3c433d8 to 55c0272 Compare December 15, 2025 19:51
@AndyTWF AndyTWF marked this pull request as ready for review December 15, 2025 22:04
@AndyTWF AndyTWF changed the title [wip] test: introduce mock config manager, use in tests test: introduce mock config manager, use in tests Dec 15, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
test/unit/commands/channels/history.test.ts (1)

4-9: Add configManager to the type definition.

The comment at line 41 indicates that configManager is expected to exist in globalThis.__TEST_MOCKS__, but the type definition only declares ablyRestMock. This creates a type safety gap.

Apply this diff to include configManager in the type definition:

 declare global {
   var __TEST_MOCKS__: {
     ablyRestMock?: unknown;
+    configManager?: unknown;
   };
 }
test/unit/commands/auth/issue-jwt-token.test.ts (1)

184-196: Restore mock configuration state after the test.

The test at line 187 clears the app configuration (setCurrentAppIdForAccount(undefined)) but doesn't restore it afterward. This could affect subsequent tests that rely on the default app configuration from DEFAULT_TEST_CONFIG.

Consider adding an afterEach hook or wrapping this test to restore the configuration:

it("should not produce token output when app configuration is missing", async () => {
  // Use mock config manager to clear app configuration
  const mock = getMockConfigManager();
  const originalAppId = mock.getCurrentAppId();
  mock.setCurrentAppIdForAccount(undefined);

  const { stdout } = await runCommand(
    ["auth:issue-jwt-token"],
    import.meta.url,
  );

  // Restore the original state
  mock.setCurrentAppIdForAccount(originalAppId);

  // When no app is configured, command should not produce token output
  expect(stdout).not.toContain("Generated Ably JWT Token");
});
🧹 Nitpick comments (15)
test/unit/commands/spaces/locations/get-all.test.ts (2)

5-10: beforeEach cleanup might be redundant.

The beforeEach deletes the same mocks that afterEach already cleans up. While this defensive approach ensures a clean state even if a previous test fails, it may be unnecessary given that afterEach runs after each test. Consider removing this redundant cleanup if afterEach consistently runs.


12-17: Add explicit mock restoration and resource cleanup.

As per coding guidelines, tests must ensure resources are properly closed and mocks are restored in afterEach. Consider adding:

  • vi.restoreAllMocks() to clear all mock/spy state between tests
  • Although the mock clients are created per-test, establishing the pattern of calling close() would align with the guideline requirement

Based on coding guidelines: "Always ensure resources are properly closed/cleaned up in tests (e.g., call await client.close() and sinon.restore() in afterEach)."

Apply this diff to add explicit cleanup:

 afterEach(() => {
   if (globalThis.__TEST_MOCKS__) {
     delete globalThis.__TEST_MOCKS__.ablyRealtimeMock;
     delete globalThis.__TEST_MOCKS__.ablySpacesMock;
   }
+  vi.restoreAllMocks();
 });
test/unit/commands/rooms/reactions/subscribe.test.ts (1)

6-18: Consider consolidating cleanup logic.

The mock cleanup is duplicated in both beforeEach and afterEach. Since each test sets up mocks inline and afterEach already performs cleanup, the beforeEach cleanup appears redundant. Consider removing the beforeEach block to simplify the test structure.

Apply this diff to consolidate cleanup:

-  beforeEach(() => {
-    if (globalThis.__TEST_MOCKS__) {
-      delete globalThis.__TEST_MOCKS__.ablyRealtimeMock;
-      delete globalThis.__TEST_MOCKS__.ablyChatMock;
-    }
-  });
-
   afterEach(() => {
     if (globalThis.__TEST_MOCKS__) {
       delete globalThis.__TEST_MOCKS__.ablyRealtimeMock;
       delete globalThis.__TEST_MOCKS__.ablyChatMock;
     }
   });
test/unit/commands/rooms/messages/reactions/subscribe.test.ts (1)

87-94: Guard against undefined __TEST_MOCKS__ when spreading.

The spread operator assumes globalThis.__TEST_MOCKS__ is already initialized. If the test setup fails to initialize it, this will throw a runtime error.

Consider adding a defensive check:

-      globalThis.__TEST_MOCKS__ = {
-        ...globalThis.__TEST_MOCKS__,
+      globalThis.__TEST_MOCKS__ = {
+        ...(globalThis.__TEST_MOCKS__ || {}),
         ablyChatMock: {
           rooms: mockRooms,
           realtime: mockRealtimeClient,
         } as any,
         ablyRealtimeMock: mockRealtimeClient as any,
       };

This is optional since the test setup files should initialize __TEST_MOCKS__, but it adds resilience against setup issues.

Also applies to: 183-190

test/unit/commands/spaces/cursors/get-all.test.ts (1)

75-79: Consider defensive spreading for undefined __TEST_MOCKS__.

All five mock injection points use the spread operator without checking if globalThis.__TEST_MOCKS__ exists. While test setup should initialize it, adding ...(globalThis.__TEST_MOCKS__ || {}) would make the tests more resilient.

Also applies to: 151-155, 208-212, 259-263, 314-318

test/unit/commands/apps/logs/subscribe.test.ts (1)

51-58: Optional: Add defensive check when spreading __TEST_MOCKS__.

Same pattern as other files—consider ...(globalThis.__TEST_MOCKS__ || {}) for resilience, though test setup should initialize the global.

Also applies to: 95-102

test/unit/commands/rooms/messages/reactions/remove.test.ts (1)

111-115: Optional: Defensive spreading for robustness.

Consider using ...(globalThis.__TEST_MOCKS__ || {}) to handle cases where test setup might not have initialized __TEST_MOCKS__.

test/e2e/auth/basic-auth.test.ts (1)

71-74: Consider moving the dynamic import to the top level.

The dynamic import pattern is repeated across multiple test cases. Consider importing TomlConfigManager at the module level for cleaner code.

Apply this diff to simplify:

+import { TomlConfigManager } from "../../../src/services/config-manager.js";
 import {
   describe,
   it,
...
-      const { TomlConfigManager } = await import(
-        "../../../src/services/config-manager.js"
-      );
-      const configManager = new TomlConfigManager();
+      const configManager = new TomlConfigManager();
test/unit/commands/auth/issue-ably-token.test.ts (1)

43-48: Optional: Extract mock setup to a helper function.

The conditional mock assignment pattern is repeated 9 times. Consider extracting to a helper:

function setAblyRestMock(mockAuth: object) {
  if (globalThis.__TEST_MOCKS__) {
    globalThis.__TEST_MOCKS__.ablyRestMock = {
      auth: mockAuth,
      close: vi.fn(),
    };
  }
}

This is a minor suggestion for reducing duplication.

test/unit/commands/queues/list.test.ts (1)

1-20: Missing beforeEach could cause test isolation issues.

This file lacks a beforeEach hook to reset mock state before each test. Most tests assume DEFAULT_TEST_CONFIG accounts exist, but the test at line 372-380 calls getMockConfigManager().clearAccounts() which modifies global state. If tests run in different orders, this could cause failures.

Add a beforeEach to ensure consistent state:

+import { describe, it, expect, beforeEach, afterEach } from "vitest";
-import { describe, it, expect, afterEach } from "vitest";
 import nock from "nock";
 import { runCommand } from "@oclif/test";
 import {
   DEFAULT_TEST_CONFIG,
   getMockConfigManager,
+  resetMockConfig,
 } from "../../../helpers/mock-config-manager.js";

 describe("queues:list command", () => {
   const mockAppId = DEFAULT_TEST_CONFIG.appId;
   const mockAccountId = DEFAULT_TEST_CONFIG.accountId;

+  beforeEach(() => {
+    nock.cleanAll();
+    resetMockConfig(); // Ensure consistent state
+  });
+
   afterEach(() => {
     nock.cleanAll();
   });
test/unit/commands/apps/create.test.ts (1)

10-16: Consider resetting mock config in beforeEach for test isolation.

The beforeEach only cleans nock, but tests modify the mock config (e.g., the "auto-switch" test updates current app). Without resetting the mock between tests, modifications could leak across tests if execution order changes.

 beforeEach(() => {
   nock.cleanAll();
+  getMockConfigManager().reset();
 });
test/unit/commands/apps/delete.test.ts (1)

9-15: Consider resetting mock config in beforeEach for test isolation.

Similar to create.test.ts, the test at line 262 calls mock.setCurrentAppIdForAccount(undefined) which modifies shared mock state. Without a reset, this could affect other tests.

 beforeEach(() => {
   nock.cleanAll();
+  getMockConfigManager().reset();
 });
src/services/config-manager.ts (1)

468-498: LGTM - Migration logic handles legacy config format.

The migration from current.app to accounts[alias].currentAppId is correct. Using any for accessing legacy properties is appropriate given the eslint-disable comment.

Consider adding a debug log when migration occurs to help users understand config format changes:

          this.config.accounts[currentAccountAlias].currentAppId =
              oldConfig.current.app;
            delete oldConfig.current.app; // Remove from current section
+           console.debug('Migrated config from legacy format');
            this.saveConfig(); // Save the migrated config
test/helpers/mock-config-manager.ts (2)

255-267: Minor inconsistency: removeAccount doesn't call saveConfig().

TomlConfigManager.removeAccount() calls saveConfig() after deletion, but MockConfigManager doesn't. While functionally equivalent (mock's saveConfig is a no-op), matching the pattern would ensure consistent behavior if tests ever verify save operations.

   public removeAccount(alias: string): boolean {
     if (!this.config.accounts[alias]) {
       return false;
     }

     delete this.config.accounts[alias];

     if (this.config.current?.account === alias) {
       delete this.config.current.account;
     }

+    // Match TomlConfigManager behavior (no-op for mock but consistent)
+    this.saveConfig();
     return true;
   }

429-436: Apply the suggested defensive initialization pattern to preserve existing mocks.

The test suite consistently uses spread operator merging when updating __TEST_MOCKS__ (see comments in benchmarking.test.ts, spaces.test.ts, etc. stating "don't overwrite configManager"). To follow this established pattern and guard against accidental re-initialization, conditionally set configManager only if it doesn't already exist:

 export function initializeMockConfigManager(): void {
   if (!globalThis.__TEST_MOCKS__) {
     globalThis.__TEST_MOCKS__ = {
       ablyRestMock: {},
     };
   }
-  globalThis.__TEST_MOCKS__.configManager = new MockConfigManager();
+  if (!globalThis.__TEST_MOCKS__.configManager) {
+    globalThis.__TEST_MOCKS__.configManager = new MockConfigManager();
+  }
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between f3e813a and e5d4831.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (75)
  • package.json (1 hunks)
  • src/base-command.ts (2 hunks)
  • src/commands/config/show.ts (2 hunks)
  • src/commands/mcp/start-server.ts (2 hunks)
  • src/help.ts (2 hunks)
  • src/services/config-manager.ts (4 hunks)
  • test/e2e/auth/basic-auth.test.ts (6 hunks)
  • test/helpers/mock-config-manager.ts (1 hunks)
  • test/setup.ts (2 hunks)
  • test/unit/base/base-command.test.ts (2 hunks)
  • test/unit/commands/accounts/login.test.ts (6 hunks)
  • test/unit/commands/accounts/logout.test.ts (7 hunks)
  • test/unit/commands/apps/channel-rules/create.test.ts (1 hunks)
  • test/unit/commands/apps/channel-rules/delete.test.ts (1 hunks)
  • test/unit/commands/apps/channel-rules/list.test.ts (1 hunks)
  • test/unit/commands/apps/channel-rules/update.test.ts (1 hunks)
  • test/unit/commands/apps/create.test.ts (13 hunks)
  • test/unit/commands/apps/current.test.ts (2 hunks)
  • test/unit/commands/apps/delete.test.ts (19 hunks)
  • test/unit/commands/apps/logs/history.test.ts (3 hunks)
  • test/unit/commands/apps/logs/subscribe.test.ts (3 hunks)
  • test/unit/commands/apps/set-apns-p12.test.ts (1 hunks)
  • test/unit/commands/apps/update.test.ts (17 hunks)
  • test/unit/commands/auth/issue-ably-token.test.ts (12 hunks)
  • test/unit/commands/auth/issue-jwt-token.test.ts (6 hunks)
  • test/unit/commands/auth/keys/create.test.ts (25 hunks)
  • test/unit/commands/auth/keys/current.test.ts (2 hunks)
  • test/unit/commands/auth/keys/get.test.ts (3 hunks)
  • test/unit/commands/auth/keys/list.test.ts (6 hunks)
  • test/unit/commands/auth/keys/revoke.test.ts (3 hunks)
  • test/unit/commands/auth/keys/update.test.ts (6 hunks)
  • test/unit/commands/auth/revoke-token.test.ts (16 hunks)
  • test/unit/commands/bench/benchmarking.test.ts (2 hunks)
  • test/unit/commands/channel-rule/create.test.ts (1 hunks)
  • test/unit/commands/channel-rule/delete.test.ts (1 hunks)
  • test/unit/commands/channel-rule/list.test.ts (1 hunks)
  • test/unit/commands/channel-rule/update.test.ts (1 hunks)
  • test/unit/commands/channels/batch-publish.test.ts (2 hunks)
  • test/unit/commands/channels/history.test.ts (2 hunks)
  • test/unit/commands/channels/list.test.ts (2 hunks)
  • test/unit/commands/channels/occupancy/subscribe.test.ts (7 hunks)
  • test/unit/commands/channels/presence/enter.test.ts (2 hunks)
  • test/unit/commands/channels/presence/subscribe.test.ts (2 hunks)
  • test/unit/commands/channels/subscribe.test.ts (2 hunks)
  • test/unit/commands/config/path.test.ts (3 hunks)
  • test/unit/commands/config/show.test.ts (2 hunks)
  • test/unit/commands/integrations/create.test.ts (5 hunks)
  • test/unit/commands/integrations/delete.test.ts (6 hunks)
  • test/unit/commands/integrations/get.test.ts (3 hunks)
  • test/unit/commands/integrations/update.test.ts (1 hunks)
  • test/unit/commands/logs/app/subscribe.test.ts (5 hunks)
  • test/unit/commands/logs/channel-lifecycle.test.ts (9 hunks)
  • test/unit/commands/logs/channel-lifecycle/subscribe.test.ts (5 hunks)
  • test/unit/commands/logs/connection-lifecycle/history.test.ts (3 hunks)
  • test/unit/commands/logs/push/history.test.ts (3 hunks)
  • test/unit/commands/queues/create.test.ts (2 hunks)
  • test/unit/commands/queues/delete.test.ts (4 hunks)
  • test/unit/commands/queues/list.test.ts (2 hunks)
  • test/unit/commands/rooms/messages/reactions/remove.test.ts (2 hunks)
  • test/unit/commands/rooms/messages/reactions/send.test.ts (2 hunks)
  • test/unit/commands/rooms/messages/reactions/subscribe.test.ts (3 hunks)
  • test/unit/commands/rooms/presence/subscribe.test.ts (3 hunks)
  • test/unit/commands/rooms/reactions/subscribe.test.ts (3 hunks)
  • test/unit/commands/rooms/typing/subscribe.test.ts (3 hunks)
  • test/unit/commands/spaces/cursors/get-all.test.ts (6 hunks)
  • test/unit/commands/spaces/cursors/subscribe.test.ts (6 hunks)
  • test/unit/commands/spaces/locations/get-all.test.ts (4 hunks)
  • test/unit/commands/spaces/locations/subscribe.test.ts (7 hunks)
  • test/unit/commands/spaces/locks/get-all.test.ts (4 hunks)
  • test/unit/commands/spaces/locks/get.test.ts (4 hunks)
  • test/unit/commands/spaces/locks/subscribe.test.ts (8 hunks)
  • test/unit/commands/spaces/spaces.test.ts (2 hunks)
  • test/unit/services/config-manager.test.ts (7 hunks)
  • test/unit/setup.ts (1 hunks)
  • vitest.config.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.test.ts

📄 CodeRabbit inference engine (.cursor/rules/AI-Assistance.mdc)

**/*.test.ts: When testing, mock the Ably SDK properly by stubbing the constructor (e.g., sinon.stub(Ably, 'Rest').returns(mockClient)).
Always ensure resources are properly closed/cleaned up in tests (e.g., call await client.close() and sinon.restore() in afterEach).

Files:

  • test/unit/commands/rooms/messages/reactions/send.test.ts
  • test/unit/commands/channels/list.test.ts
  • test/unit/commands/bench/benchmarking.test.ts
  • test/unit/commands/auth/keys/update.test.ts
  • test/unit/commands/apps/channel-rules/list.test.ts
  • test/unit/commands/logs/channel-lifecycle.test.ts
  • test/unit/commands/channels/subscribe.test.ts
  • test/unit/commands/rooms/reactions/subscribe.test.ts
  • test/unit/commands/rooms/messages/reactions/subscribe.test.ts
  • test/unit/commands/auth/keys/get.test.ts
  • test/unit/commands/channels/presence/enter.test.ts
  • test/unit/commands/apps/current.test.ts
  • test/e2e/auth/basic-auth.test.ts
  • test/unit/commands/channels/presence/subscribe.test.ts
  • test/unit/commands/integrations/get.test.ts
  • test/unit/commands/queues/delete.test.ts
  • test/unit/commands/auth/keys/revoke.test.ts
  • test/unit/commands/auth/issue-ably-token.test.ts
  • test/unit/commands/rooms/typing/subscribe.test.ts
  • test/unit/commands/spaces/locations/subscribe.test.ts
  • test/unit/commands/apps/channel-rules/update.test.ts
  • test/unit/commands/channels/history.test.ts
  • test/unit/commands/logs/push/history.test.ts
  • test/unit/commands/rooms/presence/subscribe.test.ts
  • test/unit/commands/auth/issue-jwt-token.test.ts
  • test/unit/commands/channels/occupancy/subscribe.test.ts
  • test/unit/base/base-command.test.ts
  • test/unit/commands/spaces/cursors/get-all.test.ts
  • test/unit/commands/logs/channel-lifecycle/subscribe.test.ts
  • test/unit/commands/config/path.test.ts
  • test/unit/commands/auth/revoke-token.test.ts
  • test/unit/commands/apps/create.test.ts
  • test/unit/commands/integrations/delete.test.ts
  • test/unit/commands/apps/logs/history.test.ts
  • test/unit/commands/auth/keys/current.test.ts
  • test/unit/commands/apps/channel-rules/delete.test.ts
  • test/unit/commands/channel-rule/delete.test.ts
  • test/unit/commands/logs/connection-lifecycle/history.test.ts
  • test/unit/commands/spaces/locks/subscribe.test.ts
  • test/unit/commands/apps/update.test.ts
  • test/unit/commands/config/show.test.ts
  • test/unit/commands/auth/keys/create.test.ts
  • test/unit/services/config-manager.test.ts
  • test/unit/commands/accounts/login.test.ts
  • test/unit/commands/auth/keys/list.test.ts
  • test/unit/commands/apps/logs/subscribe.test.ts
  • test/unit/commands/apps/set-apns-p12.test.ts
  • test/unit/commands/channels/batch-publish.test.ts
  • test/unit/commands/queues/create.test.ts
  • test/unit/commands/integrations/update.test.ts
  • test/unit/commands/integrations/create.test.ts
  • test/unit/commands/spaces/cursors/subscribe.test.ts
  • test/unit/commands/spaces/locks/get-all.test.ts
  • test/unit/commands/spaces/spaces.test.ts
  • test/unit/commands/apps/delete.test.ts
  • test/unit/commands/spaces/locks/get.test.ts
  • test/unit/commands/rooms/messages/reactions/remove.test.ts
  • test/unit/commands/channel-rule/create.test.ts
  • test/unit/commands/channel-rule/update.test.ts
  • test/unit/commands/queues/list.test.ts
  • test/unit/commands/spaces/locations/get-all.test.ts
  • test/unit/commands/apps/channel-rules/create.test.ts
  • test/unit/commands/accounts/logout.test.ts
  • test/unit/commands/logs/app/subscribe.test.ts
  • test/unit/commands/channel-rule/list.test.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/Development.mdc)

**/*.{ts,tsx}: Use TypeScript and follow best practice naming conventions
ESLint is used to ensure all code adheres best practices; ensure you check that all code passes the linter before concluding your work.

Files:

  • test/unit/commands/rooms/messages/reactions/send.test.ts
  • test/setup.ts
  • test/unit/commands/channels/list.test.ts
  • test/unit/commands/bench/benchmarking.test.ts
  • src/commands/config/show.ts
  • test/unit/commands/auth/keys/update.test.ts
  • test/unit/commands/apps/channel-rules/list.test.ts
  • test/unit/commands/logs/channel-lifecycle.test.ts
  • test/unit/commands/channels/subscribe.test.ts
  • test/unit/commands/rooms/reactions/subscribe.test.ts
  • test/unit/commands/rooms/messages/reactions/subscribe.test.ts
  • test/unit/commands/auth/keys/get.test.ts
  • test/unit/commands/channels/presence/enter.test.ts
  • test/unit/commands/apps/current.test.ts
  • test/e2e/auth/basic-auth.test.ts
  • test/unit/commands/channels/presence/subscribe.test.ts
  • test/unit/commands/integrations/get.test.ts
  • test/unit/commands/queues/delete.test.ts
  • test/unit/commands/auth/keys/revoke.test.ts
  • test/unit/commands/auth/issue-ably-token.test.ts
  • src/help.ts
  • test/unit/commands/rooms/typing/subscribe.test.ts
  • test/unit/commands/spaces/locations/subscribe.test.ts
  • test/unit/commands/apps/channel-rules/update.test.ts
  • test/unit/commands/channels/history.test.ts
  • test/unit/commands/logs/push/history.test.ts
  • test/unit/commands/rooms/presence/subscribe.test.ts
  • src/commands/mcp/start-server.ts
  • test/unit/commands/auth/issue-jwt-token.test.ts
  • test/unit/commands/channels/occupancy/subscribe.test.ts
  • test/unit/base/base-command.test.ts
  • test/unit/commands/spaces/cursors/get-all.test.ts
  • test/unit/commands/logs/channel-lifecycle/subscribe.test.ts
  • test/unit/commands/config/path.test.ts
  • test/unit/commands/auth/revoke-token.test.ts
  • vitest.config.ts
  • test/unit/commands/apps/create.test.ts
  • test/unit/commands/integrations/delete.test.ts
  • test/unit/commands/apps/logs/history.test.ts
  • test/unit/commands/auth/keys/current.test.ts
  • test/unit/commands/apps/channel-rules/delete.test.ts
  • test/unit/commands/channel-rule/delete.test.ts
  • test/unit/commands/logs/connection-lifecycle/history.test.ts
  • test/unit/commands/spaces/locks/subscribe.test.ts
  • test/unit/commands/apps/update.test.ts
  • test/unit/commands/config/show.test.ts
  • src/base-command.ts
  • test/unit/commands/auth/keys/create.test.ts
  • test/unit/services/config-manager.test.ts
  • test/unit/commands/accounts/login.test.ts
  • test/unit/commands/auth/keys/list.test.ts
  • test/unit/commands/apps/logs/subscribe.test.ts
  • test/unit/commands/apps/set-apns-p12.test.ts
  • test/unit/commands/channels/batch-publish.test.ts
  • test/unit/commands/queues/create.test.ts
  • test/unit/commands/integrations/update.test.ts
  • test/unit/commands/integrations/create.test.ts
  • test/unit/commands/spaces/cursors/subscribe.test.ts
  • test/unit/commands/spaces/locks/get-all.test.ts
  • test/unit/commands/spaces/spaces.test.ts
  • test/unit/commands/apps/delete.test.ts
  • test/unit/commands/spaces/locks/get.test.ts
  • test/unit/commands/rooms/messages/reactions/remove.test.ts
  • test/unit/commands/channel-rule/create.test.ts
  • test/unit/commands/channel-rule/update.test.ts
  • test/unit/commands/queues/list.test.ts
  • test/unit/commands/spaces/locations/get-all.test.ts
  • test/unit/commands/apps/channel-rules/create.test.ts
  • test/unit/setup.ts
  • src/services/config-manager.ts
  • test/unit/commands/accounts/logout.test.ts
  • test/unit/commands/logs/app/subscribe.test.ts
  • test/helpers/mock-config-manager.ts
  • test/unit/commands/channel-rule/list.test.ts
{test/**/*.{ts,js},**/*.{test,spec}.{ts,js}}

📄 CodeRabbit inference engine (.cursor/rules/Development.mdc)

When new features are added or changes made, tests must be updated or added, and it is your responsibility to ensure the tests pass before deeming your work complete.

Files:

  • test/unit/commands/rooms/messages/reactions/send.test.ts
  • test/setup.ts
  • test/unit/commands/channels/list.test.ts
  • test/unit/commands/bench/benchmarking.test.ts
  • test/unit/commands/auth/keys/update.test.ts
  • test/unit/commands/apps/channel-rules/list.test.ts
  • test/unit/commands/logs/channel-lifecycle.test.ts
  • test/unit/commands/channels/subscribe.test.ts
  • test/unit/commands/rooms/reactions/subscribe.test.ts
  • test/unit/commands/rooms/messages/reactions/subscribe.test.ts
  • test/unit/commands/auth/keys/get.test.ts
  • test/unit/commands/channels/presence/enter.test.ts
  • test/unit/commands/apps/current.test.ts
  • test/e2e/auth/basic-auth.test.ts
  • test/unit/commands/channels/presence/subscribe.test.ts
  • test/unit/commands/integrations/get.test.ts
  • test/unit/commands/queues/delete.test.ts
  • test/unit/commands/auth/keys/revoke.test.ts
  • test/unit/commands/auth/issue-ably-token.test.ts
  • test/unit/commands/rooms/typing/subscribe.test.ts
  • test/unit/commands/spaces/locations/subscribe.test.ts
  • test/unit/commands/apps/channel-rules/update.test.ts
  • test/unit/commands/channels/history.test.ts
  • test/unit/commands/logs/push/history.test.ts
  • test/unit/commands/rooms/presence/subscribe.test.ts
  • test/unit/commands/auth/issue-jwt-token.test.ts
  • test/unit/commands/channels/occupancy/subscribe.test.ts
  • test/unit/base/base-command.test.ts
  • test/unit/commands/spaces/cursors/get-all.test.ts
  • test/unit/commands/logs/channel-lifecycle/subscribe.test.ts
  • test/unit/commands/config/path.test.ts
  • test/unit/commands/auth/revoke-token.test.ts
  • test/unit/commands/apps/create.test.ts
  • test/unit/commands/integrations/delete.test.ts
  • test/unit/commands/apps/logs/history.test.ts
  • test/unit/commands/auth/keys/current.test.ts
  • test/unit/commands/apps/channel-rules/delete.test.ts
  • test/unit/commands/channel-rule/delete.test.ts
  • test/unit/commands/logs/connection-lifecycle/history.test.ts
  • test/unit/commands/spaces/locks/subscribe.test.ts
  • test/unit/commands/apps/update.test.ts
  • test/unit/commands/config/show.test.ts
  • test/unit/commands/auth/keys/create.test.ts
  • test/unit/services/config-manager.test.ts
  • test/unit/commands/accounts/login.test.ts
  • test/unit/commands/auth/keys/list.test.ts
  • test/unit/commands/apps/logs/subscribe.test.ts
  • test/unit/commands/apps/set-apns-p12.test.ts
  • test/unit/commands/channels/batch-publish.test.ts
  • test/unit/commands/queues/create.test.ts
  • test/unit/commands/integrations/update.test.ts
  • test/unit/commands/integrations/create.test.ts
  • test/unit/commands/spaces/cursors/subscribe.test.ts
  • test/unit/commands/spaces/locks/get-all.test.ts
  • test/unit/commands/spaces/spaces.test.ts
  • test/unit/commands/apps/delete.test.ts
  • test/unit/commands/spaces/locks/get.test.ts
  • test/unit/commands/rooms/messages/reactions/remove.test.ts
  • test/unit/commands/channel-rule/create.test.ts
  • test/unit/commands/channel-rule/update.test.ts
  • test/unit/commands/queues/list.test.ts
  • test/unit/commands/spaces/locations/get-all.test.ts
  • test/unit/commands/apps/channel-rules/create.test.ts
  • test/unit/setup.ts
  • test/unit/commands/accounts/logout.test.ts
  • test/unit/commands/logs/app/subscribe.test.ts
  • test/helpers/mock-config-manager.ts
  • test/unit/commands/channel-rule/list.test.ts
src/commands/**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/AI-Assistance.mdc)

src/commands/**/*.ts: Commands should follow the oclif structure: export default class MyCommand extends Command { ... }
Command should support auth via the standard auth helper (import { getAuth } from '../../helpers/auth') and use it in the run method.
Use try/catch for error handling in commands, and provide user-friendly error messages (e.g., handle error.code === 40100 for authentication failures).
Do not use direct HTTP requests (e.g., fetch) for data plane APIs; use the Ably SDK instead.
Do not use hardcoded endpoint URLs; use configuration values (e.g., flags.controlHost, config.controlHost) when constructing URLs.
Do not use non-standard command structures (e.g., export default class { async execute(args) { ... } }); always use the oclif Command class.

Files:

  • src/commands/config/show.ts
  • src/commands/mcp/start-server.ts
src/commands/**/*.{ts,js}

📄 CodeRabbit inference engine (.cursor/rules/Development.mdc)

Follow oclif framework best practices as described in the oclif documentation.

Files:

  • src/commands/config/show.ts
  • src/commands/mcp/start-server.ts
🧬 Code graph analysis (52)
test/setup.ts (1)
test/helpers/mock-config-manager.ts (1)
  • MockConfigManager (41-401)
test/unit/commands/auth/keys/update.test.ts (3)
test/root-hooks.ts (2)
  • beforeEach (8-11)
  • afterEach (13-61)
test/helpers/mock-config-manager.ts (1)
  • DEFAULT_TEST_CONFIG (24-35)
test/helpers/cli-runner.ts (1)
  • stdout (125-127)
test/unit/commands/apps/channel-rules/list.test.ts (1)
test/helpers/mock-config-manager.ts (1)
  • DEFAULT_TEST_CONFIG (24-35)
test/unit/commands/logs/channel-lifecycle.test.ts (1)
test/root-hooks.ts (1)
  • afterEach (13-61)
test/unit/commands/rooms/reactions/subscribe.test.ts (1)
test/root-hooks.ts (1)
  • afterEach (13-61)
test/unit/commands/apps/current.test.ts (2)
test/helpers/cli-runner.ts (1)
  • stdout (125-127)
test/helpers/mock-config-manager.ts (2)
  • DEFAULT_TEST_CONFIG (24-35)
  • getMockConfigManager (407-414)
test/e2e/auth/basic-auth.test.ts (1)
src/services/config-manager.ts (1)
  • TomlConfigManager (124-499)
test/unit/commands/queues/delete.test.ts (2)
test/helpers/mock-config-manager.ts (2)
  • DEFAULT_TEST_CONFIG (24-35)
  • getMockConfigManager (407-414)
test/helpers/command-helpers.ts (1)
  • runCommand (67-83)
test/unit/commands/auth/keys/revoke.test.ts (2)
test/helpers/mock-config-manager.ts (1)
  • DEFAULT_TEST_CONFIG (24-35)
test/helpers/cli-runner.ts (1)
  • stdout (125-127)
test/unit/commands/auth/issue-ably-token.test.ts (3)
test/root-hooks.ts (2)
  • beforeEach (8-11)
  • afterEach (13-61)
test/helpers/mock-config-manager.ts (2)
  • DEFAULT_TEST_CONFIG (24-35)
  • getMockConfigManager (407-414)
test/helpers/command-helpers.ts (1)
  • runCommand (67-83)
src/help.ts (1)
src/services/config-manager.ts (1)
  • createConfigManager (114-122)
test/unit/commands/rooms/typing/subscribe.test.ts (1)
test/root-hooks.ts (1)
  • afterEach (13-61)
test/unit/commands/spaces/locations/subscribe.test.ts (1)
test/root-hooks.ts (1)
  • afterEach (13-61)
test/unit/commands/apps/channel-rules/update.test.ts (1)
test/helpers/mock-config-manager.ts (1)
  • DEFAULT_TEST_CONFIG (24-35)
test/unit/commands/rooms/presence/subscribe.test.ts (1)
test/root-hooks.ts (1)
  • afterEach (13-61)
src/commands/mcp/start-server.ts (1)
src/services/config-manager.ts (1)
  • createConfigManager (114-122)
test/unit/commands/auth/issue-jwt-token.test.ts (2)
test/helpers/mock-config-manager.ts (2)
  • DEFAULT_TEST_CONFIG (24-35)
  • getMockConfigManager (407-414)
test/helpers/cli-runner.ts (1)
  • stdout (125-127)
test/unit/commands/channels/occupancy/subscribe.test.ts (1)
test/root-hooks.ts (1)
  • afterEach (13-61)
test/unit/base/base-command.test.ts (1)
src/services/config-manager.ts (1)
  • TomlConfigManager (124-499)
test/unit/commands/logs/channel-lifecycle/subscribe.test.ts (1)
test/root-hooks.ts (1)
  • afterEach (13-61)
test/unit/commands/config/path.test.ts (2)
test/helpers/command-helpers.ts (1)
  • runCommand (67-83)
test/helpers/cli-runner.ts (1)
  • stdout (125-127)
test/unit/commands/apps/create.test.ts (3)
test/root-hooks.ts (2)
  • beforeEach (8-11)
  • afterEach (13-61)
test/helpers/mock-config-manager.ts (1)
  • getMockConfigManager (407-414)
test/helpers/cli-runner.ts (1)
  • stdout (125-127)
test/unit/commands/integrations/delete.test.ts (3)
test/helpers/mock-config-manager.ts (1)
  • DEFAULT_TEST_CONFIG (24-35)
test/helpers/cli-runner.ts (1)
  • stdout (125-127)
test/helpers/command-helpers.ts (1)
  • runCommand (67-83)
test/unit/commands/auth/keys/current.test.ts (3)
test/helpers/command-helpers.ts (1)
  • runCommand (67-83)
test/helpers/cli-runner.ts (1)
  • stdout (125-127)
test/helpers/mock-config-manager.ts (1)
  • DEFAULT_TEST_CONFIG (24-35)
test/unit/commands/apps/channel-rules/delete.test.ts (1)
test/helpers/mock-config-manager.ts (1)
  • DEFAULT_TEST_CONFIG (24-35)
test/unit/commands/channel-rule/delete.test.ts (1)
test/helpers/mock-config-manager.ts (1)
  • DEFAULT_TEST_CONFIG (24-35)
test/unit/commands/spaces/locks/subscribe.test.ts (1)
test/root-hooks.ts (1)
  • afterEach (13-61)
test/unit/commands/apps/update.test.ts (4)
test/root-hooks.ts (2)
  • beforeEach (8-11)
  • afterEach (13-61)
test/helpers/mock-config-manager.ts (1)
  • getMockConfigManager (407-414)
test/helpers/cli-runner.ts (1)
  • stdout (125-127)
test/helpers/command-helpers.ts (1)
  • runCommand (67-83)
test/unit/commands/config/show.test.ts (1)
test/root-hooks.ts (1)
  • beforeEach (8-11)
src/base-command.ts (1)
src/services/config-manager.ts (1)
  • createConfigManager (114-122)
test/unit/commands/auth/keys/create.test.ts (1)
test/helpers/mock-config-manager.ts (2)
  • getMockConfigManager (407-414)
  • DEFAULT_TEST_CONFIG (24-35)
test/unit/services/config-manager.test.ts (1)
src/services/config-manager.ts (1)
  • TomlConfigManager (124-499)
test/unit/commands/accounts/login.test.ts (2)
test/root-hooks.ts (1)
  • beforeEach (8-11)
test/helpers/mock-config-manager.ts (1)
  • getMockConfigManager (407-414)
test/unit/commands/auth/keys/list.test.ts (4)
test/root-hooks.ts (2)
  • beforeEach (8-11)
  • afterEach (13-61)
test/helpers/mock-config-manager.ts (2)
  • DEFAULT_TEST_CONFIG (24-35)
  • getMockConfigManager (407-414)
test/helpers/cli-runner.ts (1)
  • stdout (125-127)
test/helpers/command-helpers.ts (1)
  • runCommand (67-83)
test/unit/commands/apps/logs/subscribe.test.ts (1)
test/root-hooks.ts (1)
  • afterEach (13-61)
test/unit/commands/apps/set-apns-p12.test.ts (1)
test/helpers/mock-config-manager.ts (1)
  • DEFAULT_TEST_CONFIG (24-35)
test/unit/commands/queues/create.test.ts (1)
test/helpers/mock-config-manager.ts (2)
  • DEFAULT_TEST_CONFIG (24-35)
  • getMockConfigManager (407-414)
test/unit/commands/integrations/update.test.ts (1)
test/helpers/mock-config-manager.ts (1)
  • DEFAULT_TEST_CONFIG (24-35)
test/unit/commands/integrations/create.test.ts (4)
test/helpers/mock-config-manager.ts (1)
  • DEFAULT_TEST_CONFIG (24-35)
test/root-hooks.ts (1)
  • afterEach (13-61)
test/helpers/cli-runner.ts (1)
  • stdout (125-127)
test/helpers/command-helpers.ts (1)
  • runCommand (67-83)
test/unit/commands/spaces/cursors/subscribe.test.ts (1)
test/root-hooks.ts (1)
  • afterEach (13-61)
test/unit/commands/spaces/locks/get-all.test.ts (1)
test/root-hooks.ts (1)
  • afterEach (13-61)
test/unit/commands/apps/delete.test.ts (3)
test/root-hooks.ts (2)
  • beforeEach (8-11)
  • afterEach (13-61)
test/helpers/mock-config-manager.ts (1)
  • getMockConfigManager (407-414)
test/helpers/cli-runner.ts (1)
  • stdout (125-127)
test/unit/commands/channel-rule/create.test.ts (1)
test/helpers/mock-config-manager.ts (1)
  • DEFAULT_TEST_CONFIG (24-35)
test/unit/commands/channel-rule/update.test.ts (1)
test/helpers/mock-config-manager.ts (1)
  • DEFAULT_TEST_CONFIG (24-35)
test/unit/commands/queues/list.test.ts (2)
test/helpers/mock-config-manager.ts (2)
  • DEFAULT_TEST_CONFIG (24-35)
  • getMockConfigManager (407-414)
test/helpers/command-helpers.ts (1)
  • runCommand (67-83)
test/unit/commands/spaces/locations/get-all.test.ts (1)
test/root-hooks.ts (1)
  • afterEach (13-61)
test/unit/commands/apps/channel-rules/create.test.ts (1)
test/helpers/mock-config-manager.ts (1)
  • DEFAULT_TEST_CONFIG (24-35)
test/unit/setup.ts (2)
test/helpers/mock-config-manager.ts (2)
  • initializeMockConfigManager (429-436)
  • resetMockConfig (420-423)
test/root-hooks.ts (1)
  • beforeEach (8-11)
src/services/config-manager.ts (6)
test/unit/commands/rooms/messages.test.ts (3)
  • parse (19-21)
  • parse (55-57)
  • parse (96-98)
test/unit/commands/bench/bench.test.ts (1)
  • parse (17-19)
test/unit/commands/connections/test.test.ts (1)
  • parse (18-20)
test/unit/commands/connections/stats.test.ts (1)
  • parse (19-21)
test/unit/commands/mcp/mcp.test.ts (1)
  • parse (19-21)
test/unit/commands/rooms/features.test.ts (6)
  • parse (22-24)
  • parse (55-57)
  • parse (89-91)
  • parse (126-128)
  • parse (163-165)
  • parse (200-202)
test/unit/commands/logs/app/subscribe.test.ts (1)
test/root-hooks.ts (1)
  • afterEach (13-61)
test/helpers/mock-config-manager.ts (1)
src/services/config-manager.ts (4)
  • ConfigManager (42-99)
  • AblyConfig (27-40)
  • AppConfig (8-13)
  • AccountConfig (15-25)
test/unit/commands/channel-rule/list.test.ts (1)
test/helpers/mock-config-manager.ts (1)
  • DEFAULT_TEST_CONFIG (24-35)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: rate-limit-test

Copy link
Member

@jamiehenson jamiehenson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LG. Looks gnarly at first but actually boiled down to a handful of update patterns. Only have small non-blocking nits and questions.

"react": "^18.3.1",
"react-dom": "^18.3.1",
"toml": "^3.0.0",
"smol-toml": "^1.5.2",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// Mock get key details
nock("https://control.ably.net")
.get(`/v1/apps/${mockAppId}/keys/${mockKeyId}`)
.get(`/v1/apps/${DEFAULT_TEST_CONFIG.appId}/keys/${mockKeyId}`)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

World's smallest nit: could destructure appId off of DEFAULT_TEST_CONFIG first to save all the object access repetition. Same applies to other related files with this pattern

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Went a step further - changed tests to use the methods on the config manager, also made the values randomised each test to avoid leakage / accidental passing.

AndyTWF and others added 6 commits December 16, 2025 13:42
Replace the unmaintained "toml" package (last published 4 years ago,
parse-only) with "smol-toml" which is actively maintained and provides
both parse and stringify functions.

This change removes ~85 lines of custom TOML formatting code in the
formatToToml() method, replacing it with smol-toml's built-in stringify
function. The result is simpler, more maintainable code that relies on
a well-tested library implementation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Convert ConfigManager from a concrete class to an interface, with
TomlConfigManager as the implementation. This enables easier mocking
in tests since consumers can now depend on the interface rather than
the concrete implementation.

- Add ConfigManager interface with all public method signatures
- Rename ConfigManager class to TomlConfigManager implements ConfigManager
- Update all instantiation sites to use new TomlConfigManager()
- Update test mocks to spy on TomlConfigManager.prototype

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Introduce an in-memory MockConfigManager that implements the ConfigManager
interface, allowing unit tests to run without filesystem operations and
with fine-grained control over configuration state.

- Add MockConfigManager class with DEFAULT_TEST_CONFIG values
- Add test helper functions (getMockConfigManager, resetMockConfig, etc.)
- Add createConfigManager() factory that returns mock in test mode
- Add unit test setup file that initializes mock for all unit tests
- Update apps/current.test.ts to use the mock as a reference example

This enables faster, more isolated unit tests by removing the dependency
on temp directories and file I/O for configuration.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove temp directory config setup from 16 test files
- Use DEFAULT_TEST_CONFIG for module-level constants
- Use getMockConfigManager().clearAccounts() for "no config" scenarios
- Add opt-out mechanism for config/show.test.ts (needs real file I/O)
- Fix integrations tests to use correct flag names (--rule-type)
- Remove redundant mockConfig.reset() calls (handled by setup file)
- Clean up empty afterEach blocks

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Now that we don't have tests sharing temporary config files, they don't race anymore.
MockConfigManager is only used for tests, so it belongs in the test
folder rather than src. This keeps production code separate from test
infrastructure.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Made getTestValues() private in MockConfigManager
- Added getRegisteredAppId() method for tests that need an appId
  even when currentAppId is undefined
- Updated all test files to use ConfigManager interface methods:
  - getCurrentAppId() for current app ID
  - getRegisteredAppId() for tests that modify config state
  - getApiKey() for API key
  - getKeyId() for key ID
  - getKeyName() for key name
  - getCurrentAccount()!.accountId for account ID
  - getCurrentAccount()!.accountName for account name
  - getAppName(appId) for app name

This ensures test isolation through randomized values while using
the proper ConfigManager interface rather than directly accessing
test fixture values.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link
Member

@denissellu denissellu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚡ this one wasn't a slug to get through, dare i say i almost smiled :D

@AndyTWF AndyTWF merged commit 83559e5 into main Dec 16, 2025
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants