mengw15 opened a new pull request, #7911:
URL: https://github.com/apache/texera/pull/7911
### What changes were proposed in this PR?
Extends `agent.service.spec.ts` over the WebSocket lifecycle the issue lists
—
connection setup, the `handleWebSocketMessage` dispatch arms, and teardown —
with
15 tests. They live in the existing `websocket lifecycle and events` block
and
reuse its `FakeWebSocket` double; no new harness. Measured locally with
`--coverage`:
| `agent.service.ts` | Before | After |
| --- | --- | --- |
| lines | 301/329 (91.49 %) | **306/329 (93.01 %)** |
| branches | 147/186 (79.03 %) | **160/186 (86.02 %)** |
| functions | 90/103 | **91/103** |
**Connection setup (`startStatePolling`)**
- The `wss:`/`ws:` ternary (411): `window.location` is swapped for one test
with
the `withLocation` helper `virtual-environment.service.spec.ts` already
uses
(jsdom's own is not writable), and the URL the double was constructed with
is
asserted in full. The `ws:` side was already covered.
- The parse-failure path (424): a payload that is not JSON is logged and
does not
throw out of the handler; the connection is left intact.
- The `onerror` handler (428-429), previously an uncalled function.
- The close guard (435), both ways: a stale socket that reports an abnormal
close
after being swapped out must not clear the newer connection or flip the
state.
**Message dispatch (`handleWebSocketMessage`)**
- `message.workflowContent` (466) — a snapshot with no workflow content
leaves the
workflow stream and `wsWorkflowActive` alone, so DB polling stays in
charge.
- `message.step` (478) — a step event with no step changes nothing.
- `message.state` (517) — a status event with no state changes nothing.
- The error arm (534) — an event with no `error` falls back to
`"Agent error occurred"`; the explicit-message side was already covered.
- The `default` arm (451/539) — an unrecognised type warns and changes
nothing.
**Teardown**
- `stopStatePolling` (548) both ways, through `deleteAgent`: for a tracked
agent
the socket is closed and `stopPolling$` completes; for an id that was never
tracked it is a no-op.
- `activateAgent` (580) — an already-open socket is kept (no second socket)
and a
socket that is no longer `OPEN` is replaced. `deactivateAgent` always
clears the
socket, so the inactive-but-still-connected shape this guard defends
against is
set up directly on the tracking entry, with a comment saying so.
- `deactivateAgent` (594-606) — both early returns (unknown agent; already
inactive) and the no-socket side of the close branch, reached the ordinary
way
by letting a normal close event drop the socket first.
**One arm is not reachable.** The issue asks for a step "that does not"
carry an
id (498). `convertApiReActStep` returns
``id: apiStep.id || `${apiStep.messageId}-${apiStep.stepId || 0}` `` — the
fallback
is a template literal, which always yields a non-empty string, so
`convertedStep.id` is never falsy and `if (convertedStep.id)` cannot take
its else
branch. The test covers the fallback side instead (a step with no id still
advances HEAD to `m9-0`) and records why the arm stays half-taken. The
remaining
uncovered lines are the state accessors and HTTP failure paths, which #7908
covers; the two PRs touch disjoint regions of the file.
No production code was changed.
### Any related issues, documentation, discussions?
Closes #7888.
### How was this PR tested?
`ng test --watch=false --include
src/app/workspace/service/agent/agent.service.spec.ts`
— 62 passed (47 before, 15 new), repeated 3× for stability. `yarn format:ci`
clean.
Failure path verified by breaking one assertion in each of the 15 new tests:
16
failed (the 15 plus one pre-existing test that shares the mutated assertion),
non-zero exit, then restored to green.
Determinism: every socket event is delivered by invoking the double's
`onmessage`/`onerror`/`onclose` directly — no real socket, no reconnect
timer, and
no new `vi.useFakeTimers()`. `withLocation` restores `window.location` in a
`finally`, and `vi.restoreAllMocks()` was added to the block's `afterEach`
so the
`console` spies cannot leak into a later test even if an assertion throws.
### Was this PR authored or co-authored using generative AI tooling?
Generated-by: Claude Code (Opus 4.8 [1M context])
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]