packages/connector-directline has zero unit tests today. After the read-tick semantics fix (commit 7a305d0) we rely on manual sandbox verification, which means a future regression won't be caught by CI.
Why this is needed
The fix in 7a305d0 is non-trivial:
sendMessage emits "sent" synchronously before postActivity resolves.
- The activity stream's echo branch silently consumes nothing — does not touch
pendingIds.
flushPendingToRead() only fires on actual bot message activities (not typing, not events, not the user's own echo).
A naive refactor would easily reintroduce the original "echo → instant double-tick" bug.
Approach
The blocker is mocking botframework-directlinejs. The connector imports DirectLine, ConnectionStatus, and an Activity type from there. The real SDK opens a WebSocket on connect() so it can't run in jsdom directly.
Sketch:
// __tests__/_directLineMock.ts
import { Subject } from "rxjs"; // or hand-rolled minimal Observable
export class FakeDirectLine {
connectionStatus$ = new Subject<number>();
activity$ = new Subject<Activity>();
postActivity = vi.fn(() => of({}));
end = vi.fn();
}
vi.mock("botframework-directlinejs", () => ({
DirectLine: vi.fn().mockImplementation(() => new FakeDirectLine()),
ConnectionStatus: { Online: 2, ExpiredToken: 4, FailedToConnect: 5, Ended: 5 },
}));
Then write tests that:
- Drive
activity$.next(...) to simulate echo / typing / message arrivals.
- Assert
messageStatusHandler calls in order via vi.invocationCallOrder.
Tests to add
Acceptance criteria
Spun out of todos.md.
packages/connector-directlinehas zero unit tests today. After the read-tick semantics fix (commit7a305d0) we rely on manual sandbox verification, which means a future regression won't be caught by CI.Why this is needed
The fix in
7a305d0is non-trivial:sendMessageemits"sent"synchronously beforepostActivityresolves.pendingIds.flushPendingToRead()only fires on actual bot message activities (not typing, not events, not the user's own echo).A naive refactor would easily reintroduce the original "echo → instant double-tick" bug.
Approach
The blocker is mocking
botframework-directlinejs. The connector importsDirectLine,ConnectionStatus, and anActivitytype from there. The real SDK opens a WebSocket onconnect()so it can't run in jsdom directly.Sketch:
Then write tests that:
activity$.next(...)to simulate echo / typing / message arrivals.messageStatusHandlercalls in order viavi.invocationCallOrder.Tests to add
sendMessageemits"sent"synchronously (beforepostActivityresolves).messageStatusHandler."read"."sent".name) does not flush."read"order; never downgrades.Acceptance criteria
packages/connector-directline/src/__tests__/and run withpnpm -F @chativa/connector-directline test.Spun out of
todos.md.