-
Notifications
You must be signed in to change notification settings - Fork 0
feat: add centralized mock helpers for Ably SDKs #121
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Add centralized mock helpers for unit tests that provide consistent mocking of Ably Realtime, REST, Chat, and Spaces SDKs. Each mock: - Uses vi.fn() for all methods to allow assertions and customization - Provides _emit helpers with proper SDK types for simulating events - Uses Ably's internal EventEmitter for consistent event handling - Auto-initializes and resets via test/unit/setup.ts New files: - test/helpers/ably-event-emitter.ts - Shared EventEmitter - test/helpers/mock-ably-realtime.ts - Realtime client mock - test/helpers/mock-ably-rest.ts - REST client mock - test/helpers/mock-ably-chat.ts - Chat SDK mock - test/helpers/mock-ably-spaces.ts - Spaces SDK mock 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughIntroduces centralized mock helpers for Ably SDK services (Realtime, REST, Chat, Spaces) to reduce test boilerplate. Updates 30+ test files to use these helpers instead of ad-hoc mocking, removing manual mock construction and improving consistency. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25–35 minutes Areas requiring extra attention:
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (5 passed)
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. Comment |
Update channel command tests to use the centralized mock helpers: - channels/subscribe.test.ts - channels/occupancy/subscribe.test.ts - channels/presence/subscribe.test.ts - channels/presence/enter.test.ts - channels/batch-publish.test.ts - channels/list.test.ts - channels/history.test.ts (remove unused vi import) Tests now use getMockAblyRealtime() and getMockAblyRest() instead of manually creating mocks, reducing code duplication and ensuring consistent mock behavior. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Migrate logs history tests (connection-lifecycle, push) to use getMockAblyRest() - Migrate logs subscribe tests (app, channel-lifecycle) to use getMockAblyRealtime() - Migrate all spaces tests (locks, locations, cursors) to use getMockAblySpaces() - Add cursor channel mock to mock-ably-spaces for subscribe test support - Fix assertion handling for undefined error messages Reduces test code by ~1,750 lines through centralized mock pattern. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…pers - Replace globalThis.__TEST_MOCKS__ pattern with getMockAblyRest() - Use mock.channels._getChannel() for channel-specific mock setup - Simplify beforeEach/afterEach with automatic mock reset 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Migrate all remaining unit tests to use the centralized mock helpers: - auth/issue-ably-token, revoke-token tests - bench/benchmarking tests - logs/channel-lifecycle tests - rooms/messages/reactions/send, remove, subscribe tests - rooms/presence/subscribe tests - rooms/reactions/subscribe tests Also fix mock helpers to restore globalThis mocks on reset, ensuring tests that delete mocks don't break subsequent tests. Fix mock-ably-chat to use correct Chat SDK method names (send/delete instead of add/remove for message reactions). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Migrate bench, channels/publish, channels/occupancy/get, connections/stats, connections/test, logs/connection/subscribe, logs/connection-lifecycle/subscribe, rooms/features, and rooms/messages tests to use centralized mock helpers - Add presence.get mock to satisfy checkAndWaitForSubscribers in bench tests - Simplify connections/test to flag validation tests (command bypasses mock injection) - Remove live mode tests from connections/stats (command runs indefinitely) - Add mock helper improvements for chat and realtime 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 10
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
test/unit/commands/logs/channel-lifecycle/subscribe.test.ts (1)
98-111: Inconsistent mock pattern: Direct globalThis manipulation across multiple tests.This test directly manipulates
globalThis.__TEST_MOCKS__.ablyRealtimeMock, which bypasses the centralized mock reset mechanism. The same pattern appears in at least 6 other test files (channel-lifecycle, app/subscribe, connection/subscribe, connection-lifecycle/subscribe, config/show, channels/occupancy/subscribe).The centralized infrastructure in
test/unit/setup.tsprovidesresetMockAblyRealtime()which handles mock restoration toglobalThis, andmock-ably-realtime.tsexplicitly supports this use case. However, tests should not directly manipulateglobalThisto achieve this.Either:
- Add a centralized helper method (e.g.,
clearMockAblyRealtime()following the pattern inmock-config-manager.tswithclearAccounts()) to properly disable the mock- Or remove this test entirely if the scenario is no longer relevant, since
setup.tsensures mocks are always initialized before each test
🧹 Nitpick comments (15)
test/unit/commands/auth/revoke-token.test.ts (1)
13-14: Remove unused mock initialization from test setup.The
getMockAblyRealtime()call is initialized but never used. The command creates a Realtime client that is stored but not used for HTTP operations; instead, it makes direct HTTPS requests torest.ably.iovia Node'shttpsmodule, whichnockmocks at the HTTP level. Removing this initialization will improve test clarity without affecting test functionality.test/unit/commands/bench/benchmarking.test.ts (1)
7-36: Consider preserving existing auth mock properties when adding clientId.Line 23 overwrites the entire
authobject with just{ clientId: "test-client-id" }, which may remove other mocked auth methods (likecreateTokenRequest,requestToken) that the centralized mock provides. If the benchmarking command uses other auth methods, this could cause issues.Consider using object spread to preserve existing properties:
- realtimeMock.auth = { clientId: "test-client-id" }; + realtimeMock.auth = { ...realtimeMock.auth, clientId: "test-client-id" };Alternatively, if only
clientIdis needed, verify the centralized mock already provides it or set it directly:- realtimeMock.auth = { clientId: "test-client-id" }; + realtimeMock.auth.clientId = "test-client-id";test/unit/commands/apps/logs/subscribe.test.ts (1)
42-56: Optional: Redundant mock retrieval.Line 43 calls
getMockAblyRealtime()again after it was already initialized inbeforeEach. While this works (returns the same singleton), it's redundant. Consider storing the mock reference in a test-scoped variable if you need to access it in multiple tests, or retrieve it once per test only when needed.Apply this pattern if you want to avoid redundant calls:
describe("alias behavior", () => { it("should delegate to logs:app:subscribe with --rewind flag", async () => { - const mock = getMockAblyRealtime(); - const { stdout } = await runCommand( ["apps:logs:subscribe", "--rewind", "5"], import.meta.url, ); + const mock = getMockAblyRealtime(); // Should delegate to logs:app:subscribe and show subscription message expect(stdout).toContain("Subscribing to app logs");test/unit/commands/channels/presence/subscribe.test.ts (1)
72-91: Optional: Reduce redundant mock retrievals.Lines 73-74 and 130-131 retrieve the mock again after it was initialized in
beforeEach. While functional, this pattern is redundant. Consider retrieving the mock only when needed for assertions, or storing it in a test-scoped variable if used across multiple tests.Also applies to: 129-148
test/unit/commands/logs/channel-lifecycle/subscribe.test.ts (1)
72-94: Optional: Redundant mock retrieval.Lines 72 and 81 retrieve the mock again after
beforeEachinitialization. This is redundant but functional.test/unit/commands/channels/list.test.ts (1)
102-151: Optional: Reduce redundant mock retrievals.Multiple tests retrieve the mock via
getMockAblyRest()after it's already initialized inbeforeEach(lines 102, 114, 127, 139, 198). While functional, this is redundant.Also applies to: 198-211
test/unit/commands/channels/subscribe.test.ts (1)
87-102: Optional: Redundant mock retrievals.Lines 88, 193, and 216 retrieve the mock after
beforeEachinitialization. This pattern is redundant but functional.Also applies to: 193-235
test/unit/commands/logs/app/subscribe.test.ts (1)
78-80: Consider removing redundant mock retrieval.The mocks are already initialized in
beforeEach(lines 7-8). Re-fetching them in individual tests is redundant, though harmless since they return the same singleton instance.Apply this pattern if you prefer cleaner tests:
it("should subscribe to specific log types", async () => { - const mock = getMockAblyRealtime(); - const channel = mock.channels._getChannel("[meta]log"); + // Mock already initialized in beforeEach + const channel = getMockAblyRealtime().channels._getChannel("[meta]log");Also applies to: 94-95
test/unit/commands/bench/bench.test.ts (1)
1-1: Remove unusedviimport.Static analysis correctly identifies that
viis imported but never used in this file.-import { describe, it, expect, beforeEach, vi } from "vitest"; +import { describe, it, expect, beforeEach } from "vitest";test/unit/commands/rooms/messages.test.ts (2)
281-281: SIGINT emission may leak across tests.Using
process.emit("SIGINT", "SIGINT")to terminate subscription commands could inadvertently affect other parts of the test process or subsequent tests if handlers aren't properly cleaned up. This is a global side effect.Consider using a more isolated approach, such as mocking the signal handler or using a timeout-based test termination strategy that doesn't emit process-level signals.
129-133: Timing assertions may be flaky in CI environments.Tests that assert on elapsed time (e.g.,
expect(totalTime).toBeGreaterThanOrEqual(100)) can be flaky in CI due to system load, CPU scheduling, or slow runners. Consider adding a tolerance margin or using a different approach to verify delay behavior (e.g., verifying mock timers were called with correct delay values).test/helpers/mock-ably-realtime.ts (1)
417-427:vi.clearAllMocks()affects all mocks globally.Using
vi.clearAllMocks()in_reset()clears call history for all mocks in the test suite, not just this Realtime mock instance. This could inadvertently reset mocks from other helpers (Chat, REST, Spaces) or test-specific mocks.Consider clearing only the mocks owned by this instance:
_reset: () => { // Clear all channels channels._channels.clear(); // Reset connection state connection.state = "connected"; connection.errorReason = null; // Reset auth auth.clientId = "mock-client-id"; - // Clear all mock call history - vi.clearAllMocks(); + // Clear only this instance's mock call history + channels.get.mockClear(); + channels.release.mockClear(); + connection.on.mockClear(); + connection.off.mockClear(); + connection.once.mockClear(); + connection.connect.mockClear(); + connection.close.mockClear(); + connection.ping.mockClear(); + mock.close.mockClear(); + mock.connect.mockClear(); + mock.time.mockClear(); + mock.stats.mockClear(); + // ... and auth mocks },test/helpers/mock-ably-chat.ts (1)
382-411: Minor redundancy:attach/detachare defined twice.
attachanddetachare first assigned as barevi.fn()on lines 382-383, then immediately overwritten with implementations on lines 406-411. This is harmless but slightly confusing—consider defining them once with the implementation inline.- attach: vi.fn(), - detach: vi.fn(), + attach: vi.fn().mockImplementation(async () => { + room.status = RoomStatus.Attached; + }), + detach: vi.fn().mockImplementation(async () => { + room.status = RoomStatus.Detached; + }), onStatusChange: vi.fn((callback) => { // ... }), // ... }; - - // Bind attach/detach to room so they use the auto-emitting setter - room.attach = vi.fn().mockImplementation(async () => { - room.status = RoomStatus.Attached; - }); - room.detach = vi.fn().mockImplementation(async () => { - room.status = RoomStatus.Detached; - }); return room;test/helpers/mock-ably-spaces.ts (1)
139-154: Consider extracting duplicated subscribe/unsubscribe logic.The same subscribe/unsubscribe pattern handling multiple overloads (
eventOrCallback,callback?) is repeated increateMockSpaceMembers,createMockSpaceLocations,createMockSpaceLocks, andcreateMockSpaceCursors. Consider extracting a helper:function createSubscribeMock(emitter: AblyEventEmitter): Mock { return vi.fn((eventOrCallback, callback?) => { const cb = callback ?? eventOrCallback; const event = callback ? eventOrCallback : null; emitter.on(event, cb); }); } function createUnsubscribeMock(emitter: AblyEventEmitter): Mock { return vi.fn((eventOrCallback?, callback?) => { if (!eventOrCallback) { emitter.off(); } else if (typeof eventOrCallback === "function") { emitter.off(null, eventOrCallback); } else if (callback) { emitter.off(eventOrCallback, callback); } }); }This reduces duplication and ensures consistent behavior. However, if explicitness is preferred for test helpers, the current approach is acceptable.
test/helpers/mock-ably-rest.ts (1)
62-67:MockRequestinterface appears unused.The
MockRequestinterface is defined but not used anywhere—MockAblyRest.requestis typed directly asMock(line 95), notMockRequest. Consider removing this unused interface or using it for consistency.Either remove the unused interface:
-/** - * Mock request type for REST API calls. - */ -export interface MockRequest { - request: Mock; -}Or use it in
MockAblyRest:export interface MockAblyRest { channels: MockRestChannels; auth: MockRestAuth; - request: Mock; + request: MockRequest["request"];
📜 Review details
Configuration used: Repository 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.
📒 Files selected for processing (47)
test/helpers/ably-event-emitter.ts(1 hunks)test/helpers/mock-ably-chat.ts(1 hunks)test/helpers/mock-ably-realtime.ts(1 hunks)test/helpers/mock-ably-rest.ts(1 hunks)test/helpers/mock-ably-spaces.ts(1 hunks)test/helpers/mock-config-manager.ts(2 hunks)test/unit/commands/apps/logs/history.test.ts(7 hunks)test/unit/commands/apps/logs/subscribe.test.ts(3 hunks)test/unit/commands/auth/issue-ably-token.test.ts(16 hunks)test/unit/commands/auth/revoke-token.test.ts(1 hunks)test/unit/commands/bench/bench.test.ts(1 hunks)test/unit/commands/bench/benchmarking.test.ts(8 hunks)test/unit/commands/channels/batch-publish.test.ts(14 hunks)test/unit/commands/channels/history.test.ts(11 hunks)test/unit/commands/channels/list.test.ts(8 hunks)test/unit/commands/channels/occupancy/get.test.ts(3 hunks)test/unit/commands/channels/occupancy/subscribe.test.ts(4 hunks)test/unit/commands/channels/presence/enter.test.ts(8 hunks)test/unit/commands/channels/presence/subscribe.test.ts(5 hunks)test/unit/commands/channels/publish.test.ts(2 hunks)test/unit/commands/channels/subscribe.test.ts(4 hunks)test/unit/commands/connections/stats.test.ts(2 hunks)test/unit/commands/connections/test.test.ts(1 hunks)test/unit/commands/logs/app/subscribe.test.ts(4 hunks)test/unit/commands/logs/channel-lifecycle.test.ts(4 hunks)test/unit/commands/logs/channel-lifecycle/subscribe.test.ts(4 hunks)test/unit/commands/logs/connection-lifecycle/history.test.ts(5 hunks)test/unit/commands/logs/connection-lifecycle/subscribe.test.ts(1 hunks)test/unit/commands/logs/connection/subscribe.test.ts(1 hunks)test/unit/commands/logs/push/history.test.ts(5 hunks)test/unit/commands/rooms/features.test.ts(1 hunks)test/unit/commands/rooms/messages.test.ts(1 hunks)test/unit/commands/rooms/messages/reactions/remove.test.ts(5 hunks)test/unit/commands/rooms/messages/reactions/send.test.ts(4 hunks)test/unit/commands/rooms/messages/reactions/subscribe.test.ts(5 hunks)test/unit/commands/rooms/presence/subscribe.test.ts(5 hunks)test/unit/commands/rooms/reactions/subscribe.test.ts(5 hunks)test/unit/commands/rooms/typing/subscribe.test.ts(6 hunks)test/unit/commands/spaces/cursors/get-all.test.ts(6 hunks)test/unit/commands/spaces/cursors/subscribe.test.ts(7 hunks)test/unit/commands/spaces/locations/get-all.test.ts(3 hunks)test/unit/commands/spaces/locations/subscribe.test.ts(8 hunks)test/unit/commands/spaces/locks/get-all.test.ts(3 hunks)test/unit/commands/spaces/locks/get.test.ts(3 hunks)test/unit/commands/spaces/locks/subscribe.test.ts(9 hunks)test/unit/commands/spaces/spaces.test.ts(10 hunks)test/unit/setup.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.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/spaces/cursors/subscribe.test.tstest/unit/commands/channels/list.test.tstest/unit/commands/auth/issue-ably-token.test.tstest/unit/commands/logs/app/subscribe.test.tstest/unit/commands/spaces/locations/get-all.test.tstest/unit/commands/logs/channel-lifecycle.test.tstest/unit/commands/rooms/messages/reactions/remove.test.tstest/unit/commands/apps/logs/history.test.tstest/unit/commands/rooms/typing/subscribe.test.tstest/unit/commands/logs/push/history.test.tstest/unit/commands/spaces/locks/subscribe.test.tstest/unit/commands/spaces/cursors/get-all.test.tstest/unit/commands/channels/occupancy/get.test.tstest/unit/commands/rooms/reactions/subscribe.test.tstest/unit/commands/rooms/messages.test.tstest/unit/commands/logs/connection-lifecycle/subscribe.test.tstest/unit/commands/rooms/features.test.tstest/unit/commands/spaces/spaces.test.tstest/unit/commands/logs/connection-lifecycle/history.test.tstest/unit/commands/channels/presence/enter.test.tstest/unit/commands/spaces/locks/get.test.tstest/unit/commands/connections/test.test.tstest/unit/commands/channels/occupancy/subscribe.test.tstest/unit/commands/connections/stats.test.tstest/unit/commands/rooms/messages/reactions/send.test.tstest/unit/commands/spaces/locks/get-all.test.tstest/unit/commands/auth/revoke-token.test.tstest/unit/commands/logs/connection/subscribe.test.tstest/unit/commands/channels/presence/subscribe.test.tstest/unit/commands/spaces/locations/subscribe.test.tstest/unit/commands/apps/logs/subscribe.test.tstest/unit/commands/channels/batch-publish.test.tstest/unit/commands/rooms/presence/subscribe.test.tstest/unit/commands/logs/channel-lifecycle/subscribe.test.tstest/unit/commands/channels/history.test.tstest/unit/commands/channels/subscribe.test.tstest/unit/commands/bench/benchmarking.test.tstest/unit/commands/bench/bench.test.tstest/unit/commands/rooms/messages/reactions/subscribe.test.tstest/unit/commands/channels/publish.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/spaces/cursors/subscribe.test.tstest/helpers/ably-event-emitter.tstest/unit/commands/channels/list.test.tstest/helpers/mock-config-manager.tstest/unit/commands/auth/issue-ably-token.test.tstest/unit/commands/logs/app/subscribe.test.tstest/unit/commands/spaces/locations/get-all.test.tstest/unit/commands/logs/channel-lifecycle.test.tstest/unit/setup.tstest/unit/commands/rooms/messages/reactions/remove.test.tstest/unit/commands/apps/logs/history.test.tstest/unit/commands/rooms/typing/subscribe.test.tstest/unit/commands/logs/push/history.test.tstest/unit/commands/spaces/locks/subscribe.test.tstest/unit/commands/spaces/cursors/get-all.test.tstest/unit/commands/channels/occupancy/get.test.tstest/unit/commands/rooms/reactions/subscribe.test.tstest/unit/commands/rooms/messages.test.tstest/unit/commands/logs/connection-lifecycle/subscribe.test.tstest/helpers/mock-ably-realtime.tstest/unit/commands/rooms/features.test.tstest/unit/commands/spaces/spaces.test.tstest/unit/commands/logs/connection-lifecycle/history.test.tstest/unit/commands/channels/presence/enter.test.tstest/unit/commands/spaces/locks/get.test.tstest/unit/commands/connections/test.test.tstest/unit/commands/channels/occupancy/subscribe.test.tstest/unit/commands/connections/stats.test.tstest/unit/commands/rooms/messages/reactions/send.test.tstest/unit/commands/spaces/locks/get-all.test.tstest/unit/commands/auth/revoke-token.test.tstest/unit/commands/logs/connection/subscribe.test.tstest/unit/commands/channels/presence/subscribe.test.tstest/unit/commands/spaces/locations/subscribe.test.tstest/unit/commands/apps/logs/subscribe.test.tstest/helpers/mock-ably-chat.tstest/helpers/mock-ably-spaces.tstest/unit/commands/channels/batch-publish.test.tstest/unit/commands/rooms/presence/subscribe.test.tstest/unit/commands/logs/channel-lifecycle/subscribe.test.tstest/unit/commands/channels/history.test.tstest/unit/commands/channels/subscribe.test.tstest/unit/commands/bench/benchmarking.test.tstest/unit/commands/bench/bench.test.tstest/unit/commands/rooms/messages/reactions/subscribe.test.tstest/helpers/mock-ably-rest.tstest/unit/commands/channels/publish.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/spaces/cursors/subscribe.test.tstest/helpers/ably-event-emitter.tstest/unit/commands/channels/list.test.tstest/helpers/mock-config-manager.tstest/unit/commands/auth/issue-ably-token.test.tstest/unit/commands/logs/app/subscribe.test.tstest/unit/commands/spaces/locations/get-all.test.tstest/unit/commands/logs/channel-lifecycle.test.tstest/unit/setup.tstest/unit/commands/rooms/messages/reactions/remove.test.tstest/unit/commands/apps/logs/history.test.tstest/unit/commands/rooms/typing/subscribe.test.tstest/unit/commands/logs/push/history.test.tstest/unit/commands/spaces/locks/subscribe.test.tstest/unit/commands/spaces/cursors/get-all.test.tstest/unit/commands/channels/occupancy/get.test.tstest/unit/commands/rooms/reactions/subscribe.test.tstest/unit/commands/rooms/messages.test.tstest/unit/commands/logs/connection-lifecycle/subscribe.test.tstest/helpers/mock-ably-realtime.tstest/unit/commands/rooms/features.test.tstest/unit/commands/spaces/spaces.test.tstest/unit/commands/logs/connection-lifecycle/history.test.tstest/unit/commands/channels/presence/enter.test.tstest/unit/commands/spaces/locks/get.test.tstest/unit/commands/connections/test.test.tstest/unit/commands/channels/occupancy/subscribe.test.tstest/unit/commands/connections/stats.test.tstest/unit/commands/rooms/messages/reactions/send.test.tstest/unit/commands/spaces/locks/get-all.test.tstest/unit/commands/auth/revoke-token.test.tstest/unit/commands/logs/connection/subscribe.test.tstest/unit/commands/channels/presence/subscribe.test.tstest/unit/commands/spaces/locations/subscribe.test.tstest/unit/commands/apps/logs/subscribe.test.tstest/helpers/mock-ably-chat.tstest/helpers/mock-ably-spaces.tstest/unit/commands/channels/batch-publish.test.tstest/unit/commands/rooms/presence/subscribe.test.tstest/unit/commands/logs/channel-lifecycle/subscribe.test.tstest/unit/commands/channels/history.test.tstest/unit/commands/channels/subscribe.test.tstest/unit/commands/bench/benchmarking.test.tstest/unit/commands/bench/bench.test.tstest/unit/commands/rooms/messages/reactions/subscribe.test.tstest/helpers/mock-ably-rest.tstest/unit/commands/channels/publish.test.ts
🧬 Code graph analysis (37)
test/unit/commands/channels/list.test.ts (2)
src/base-command.ts (1)
getMockAblyRest(225-231)test/helpers/command-helpers.ts (1)
runCommand(67-83)
test/unit/commands/auth/issue-ably-token.test.ts (3)
test/helpers/mock-ably-rest.ts (1)
getMockAblyRest(241-246)test/helpers/command-helpers.ts (1)
runCommand(67-83)test/helpers/cli-runner.ts (1)
stdout(125-127)
test/unit/commands/logs/app/subscribe.test.ts (2)
test/root-hooks.ts (1)
beforeEach(8-11)test/helpers/command-helpers.ts (1)
runCommand(67-83)
test/unit/commands/spaces/locations/get-all.test.ts (4)
test/root-hooks.ts (1)
beforeEach(8-11)test/helpers/mock-ably-spaces.ts (1)
getMockAblySpaces(316-321)test/helpers/command-helpers.ts (1)
runCommand(67-83)test/helpers/cli-runner.ts (1)
stdout(125-127)
test/unit/commands/rooms/messages/reactions/remove.test.ts (3)
test/root-hooks.ts (1)
beforeEach(8-11)test/helpers/mock-ably-chat.ts (1)
getMockAblyChat(496-501)test/helpers/cli-runner.ts (1)
stdout(125-127)
test/unit/commands/apps/logs/history.test.ts (2)
test/root-hooks.ts (1)
beforeEach(8-11)test/helpers/command-helpers.ts (1)
runCommand(67-83)
test/unit/commands/rooms/typing/subscribe.test.ts (2)
test/helpers/mock-ably-chat.ts (1)
getMockAblyChat(496-501)test/helpers/command-helpers.ts (1)
runCommand(67-83)
test/unit/commands/logs/push/history.test.ts (2)
test/root-hooks.ts (1)
beforeEach(8-11)test/helpers/command-helpers.ts (1)
runCommand(67-83)
test/unit/commands/spaces/locks/subscribe.test.ts (3)
test/root-hooks.ts (1)
beforeEach(8-11)test/helpers/mock-ably-spaces.ts (1)
getMockAblySpaces(316-321)test/helpers/cli-runner.ts (1)
stdout(125-127)
test/unit/commands/spaces/cursors/get-all.test.ts (4)
test/root-hooks.ts (1)
beforeEach(8-11)test/helpers/mock-ably-spaces.ts (1)
getMockAblySpaces(316-321)test/helpers/command-helpers.ts (1)
runCommand(67-83)test/helpers/cli-runner.ts (1)
stdout(125-127)
test/unit/commands/channels/occupancy/get.test.ts (4)
test/root-hooks.ts (1)
beforeEach(8-11)src/base-command.ts (1)
getMockAblyRest(225-231)test/helpers/command-helpers.ts (1)
runCommand(67-83)test/helpers/cli-runner.ts (1)
stdout(125-127)
test/unit/commands/rooms/reactions/subscribe.test.ts (1)
test/helpers/mock-ably-chat.ts (1)
getMockAblyChat(496-501)
test/helpers/mock-ably-realtime.ts (1)
test/helpers/ably-event-emitter.ts (2)
AblyEventEmitter(14-19)EventEmitter(25-27)
test/unit/commands/rooms/features.test.ts (5)
test/root-hooks.ts (1)
beforeEach(8-11)test/helpers/mock-ably-chat.ts (1)
getMockAblyChat(496-501)src/base-command.ts (1)
getMockAblyChat(262-268)test/helpers/command-helpers.ts (1)
runCommand(67-83)test/helpers/cli-runner.ts (1)
stdout(125-127)
test/unit/commands/spaces/spaces.test.ts (4)
test/helpers/mock-ably-realtime.ts (1)
getMockAblyRealtime(440-445)src/base-command.ts (2)
getMockAblyRealtime(237-244)getMockAblySpaces(250-256)test/helpers/mock-ably-spaces.ts (1)
getMockAblySpaces(316-321)test/helpers/cli-runner.ts (1)
stdout(125-127)
test/unit/commands/logs/connection-lifecycle/history.test.ts (2)
test/root-hooks.ts (1)
beforeEach(8-11)test/helpers/command-helpers.ts (1)
runCommand(67-83)
test/unit/commands/channels/presence/enter.test.ts (2)
test/root-hooks.ts (1)
beforeEach(8-11)src/base-command.ts (1)
getMockAblyRealtime(237-244)
test/unit/commands/connections/test.test.ts (5)
test/root-hooks.ts (1)
beforeEach(8-11)test/helpers/mock-ably-realtime.ts (1)
getMockAblyRealtime(440-445)src/base-command.ts (1)
getMockAblyRealtime(237-244)test/helpers/command-helpers.ts (1)
runCommand(67-83)test/helpers/cli-runner.ts (1)
stdout(125-127)
test/unit/commands/channels/occupancy/subscribe.test.ts (3)
test/root-hooks.ts (1)
beforeEach(8-11)test/helpers/command-helpers.ts (1)
runCommand(67-83)test/helpers/cli-runner.ts (1)
stdout(125-127)
test/unit/commands/rooms/messages/reactions/send.test.ts (4)
test/root-hooks.ts (1)
beforeEach(8-11)test/helpers/mock-ably-chat.ts (1)
getMockAblyChat(496-501)test/helpers/command-helpers.ts (1)
runCommand(67-83)test/helpers/cli-runner.ts (1)
stdout(125-127)
test/unit/commands/spaces/locks/get-all.test.ts (3)
test/root-hooks.ts (1)
beforeEach(8-11)test/helpers/mock-ably-spaces.ts (1)
getMockAblySpaces(316-321)test/helpers/command-helpers.ts (1)
runCommand(67-83)
test/unit/commands/auth/revoke-token.test.ts (1)
test/helpers/mock-ably-realtime.ts (1)
getMockAblyRealtime(440-445)
test/unit/commands/logs/connection/subscribe.test.ts (5)
test/root-hooks.ts (1)
beforeEach(8-11)test/helpers/mock-ably-realtime.ts (1)
getMockAblyRealtime(440-445)src/base-command.ts (1)
getMockAblyRealtime(237-244)test/helpers/command-helpers.ts (1)
runCommand(67-83)test/helpers/cli-runner.ts (1)
stdout(125-127)
test/unit/commands/channels/presence/subscribe.test.ts (2)
test/root-hooks.ts (1)
beforeEach(8-11)src/base-command.ts (1)
getMockAblyRealtime(237-244)
test/unit/commands/spaces/locations/subscribe.test.ts (3)
test/root-hooks.ts (1)
beforeEach(8-11)test/helpers/mock-ably-spaces.ts (1)
getMockAblySpaces(316-321)test/helpers/cli-runner.ts (1)
stdout(125-127)
test/unit/commands/apps/logs/subscribe.test.ts (1)
test/root-hooks.ts (1)
beforeEach(8-11)
test/helpers/mock-ably-chat.ts (2)
test/helpers/ably-event-emitter.ts (2)
AblyEventEmitter(14-19)EventEmitter(25-27)test/helpers/mock-ably-realtime.ts (2)
MockAblyRealtime(116-126)getMockAblyRealtime(440-445)
test/helpers/mock-ably-spaces.ts (1)
test/helpers/ably-event-emitter.ts (2)
AblyEventEmitter(14-19)EventEmitter(25-27)
test/unit/commands/channels/batch-publish.test.ts (2)
test/root-hooks.ts (1)
beforeEach(8-11)src/base-command.ts (1)
getMockAblyRest(225-231)
test/unit/commands/rooms/presence/subscribe.test.ts (2)
test/helpers/mock-ably-chat.ts (1)
getMockAblyChat(496-501)test/helpers/command-helpers.ts (1)
runCommand(67-83)
test/unit/commands/logs/channel-lifecycle/subscribe.test.ts (2)
test/root-hooks.ts (1)
beforeEach(8-11)test/helpers/command-helpers.ts (1)
runCommand(67-83)
test/unit/commands/channels/history.test.ts (2)
test/helpers/mock-ably-rest.ts (1)
getMockAblyRest(241-246)src/base-command.ts (1)
getMockAblyRest(225-231)
test/unit/commands/channels/subscribe.test.ts (2)
test/root-hooks.ts (1)
beforeEach(8-11)src/base-command.ts (1)
getMockAblyRealtime(237-244)
test/unit/commands/bench/benchmarking.test.ts (4)
test/root-hooks.ts (1)
beforeEach(8-11)test/helpers/mock-ably-realtime.ts (1)
getMockAblyRealtime(440-445)src/base-command.ts (2)
getMockAblyRealtime(237-244)getMockAblyRest(225-231)test/helpers/mock-ably-rest.ts (1)
getMockAblyRest(241-246)
test/unit/commands/bench/bench.test.ts (4)
test/root-hooks.ts (1)
beforeEach(8-11)test/helpers/mock-ably-realtime.ts (1)
getMockAblyRealtime(440-445)src/base-command.ts (1)
getMockAblyRealtime(237-244)test/helpers/command-helpers.ts (1)
runCommand(67-83)
test/unit/commands/rooms/messages/reactions/subscribe.test.ts (3)
test/root-hooks.ts (1)
beforeEach(8-11)test/helpers/mock-ably-chat.ts (1)
getMockAblyChat(496-501)test/helpers/command-helpers.ts (1)
runCommand(67-83)
test/unit/commands/channels/publish.test.ts (5)
test/root-hooks.ts (1)
beforeEach(8-11)test/helpers/mock-ably-realtime.ts (1)
getMockAblyRealtime(440-445)src/base-command.ts (2)
getMockAblyRealtime(237-244)getMockAblyRest(225-231)test/helpers/command-helpers.ts (1)
runCommand(67-83)test/helpers/cli-runner.ts (2)
stdout(125-127)stderr(129-131)
🪛 GitHub Check: e2e-cli
test/unit/commands/bench/bench.test.ts
[warning] 1-1:
'vi' is defined but never used. Allowed unused vars must match /^_/u
🪛 GitHub Check: setup
test/unit/commands/bench/bench.test.ts
[warning] 1-1:
'vi' is defined but never used. Allowed unused vars must match /^_/u
🪛 GitHub Check: test
test/unit/commands/bench/bench.test.ts
[warning] 1-1:
'vi' is defined but never used. Allowed unused vars must match /^_/u
- Fix MockMessageReactions.subscribe return type to return { unsubscribe }
- Centralize vi.clearAllMocks() in test/unit/setup.ts
- Remove vi.clearAllMocks() from individual mock helpers
- Remove process.emit("SIGINT") from unit tests
- Add waitUntilInterruptedOrTimeout to subscribe commands
- Remove redundant unsubscribe/cleanup code from commands
- Remove unused vi import from bench.test.ts
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
jamiehenson
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cheers clive
The general mocking substitutions widely make sense, mocking a snapshot of various apis seems like an ongoing burden but at least it's more centralised now - I'm sure improving this further is all a part of the plan
| * Access it from the Ably.Realtime class where it's exposed internally. | ||
| */ | ||
| export const EventEmitter = ( | ||
| Ably.Realtime as unknown as { EventEmitter: new () => AblyEventEmitter } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This "cast X as Y via unknown" pattern is sometimes a smell for getting around tsc without actually setting correct types - given my lack of familiarity with this, what's the story here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ably-js doesn't formally export its EventEmitter type in ably.d.ts, but we do actually export it at the JS level so it's available to wrapper libraries (e.g. Chat) that use it. This is just the necessary typescript-fu to get access to it 😅
Similar thing in Chat: https://github.com/ably/ably-chat-js/blob/main/src/core/utils/event-emitter.ts
Add centralized mock helpers for unit tests that provide consistent mocking of Ably Realtime, REST, Chat, and Spaces SDKs. Each mock:
New files:
Bonuses:
FTF-132
Summary by CodeRabbit
Release Notes
No user-facing changes. This release contains internal testing infrastructure improvements, including centralized mock utilities and test suite refactoring to enhance maintainability and consistency across the test codebase.
✏️ Tip: You can customize this high-level summary in your review settings.