fix(tests): resolve 4 post-phase test failures

- platformClients.integration: iOS/Android push tests lacked
  setStatus() call before listNodes(), so platform filter excluded
  nodes. Added publishHeartbeat() to set platform on connection state.
- server.test: agent.send now emits run_state events before done (Phase
  1). Added sendAndWaitForDone() helper and updated test to find done
  event rather than assuming index 0.
- handlers.test: updated agent.send/cancel assertions to use find()
  and pass send arg to agent.cancel, consistent with run_state events.
- httpBody: req.destroy() closed socket before 413 response could be
  sent. Removed socket destruction from body reader; 413 responses now
  send Connection: close so Node closes the connection cleanly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
William Valentin
2026-02-25 11:55:14 -08:00
parent 787dd61a6d
commit b39010d602
9 changed files with 62 additions and 28 deletions
+23 -13
View File
@@ -1146,8 +1146,11 @@ describe('agent handlers', () => {
await handlers['agent.send'](req, send);
expect(mockAgent.process).toHaveBeenCalledWith('hello', undefined);
expect(sent).toHaveLength(1);
const doneEvent = sent[0] as GatewayEvent;
const doneEvent = sent.find((msg) => (msg as GatewayEvent).event === 'done') as GatewayEvent | undefined;
expect(doneEvent).toBeTruthy();
if (!doneEvent) {
throw new Error('done event not emitted');
}
expect(doneEvent.event).toBe('done');
expect(getPath(doneEvent.data, 'content')).toBe('response text');
});
@@ -1171,7 +1174,11 @@ describe('agent handlers', () => {
{ mimeType: 'image/png', data: 'iVBOR...', url: undefined, filename: 'screenshot.png' },
{ mimeType: 'application/pdf', data: undefined, url: 'https://example.com/doc.pdf', filename: undefined },
]);
const doneEvent = sent[0] as GatewayEvent;
const doneEvent = sent.find((msg) => (msg as GatewayEvent).event === 'done') as GatewayEvent | undefined;
expect(doneEvent).toBeTruthy();
if (!doneEvent) {
throw new Error('done event not emitted');
}
expect(doneEvent.event).toBe('done');
});
@@ -1187,7 +1194,8 @@ describe('agent handlers', () => {
await handlers['agent.send'](req, send);
expect(mockAgent.process).toHaveBeenCalledWith('hi', []);
expect(sent).toHaveLength(1);
const doneEvent = sent.find((msg) => (msg as GatewayEvent).event === 'done');
expect(doneEvent).toBeTruthy();
});
it('agent.send accepts attachment-only requests', async () => {
@@ -1207,8 +1215,8 @@ describe('agent handlers', () => {
expect(mockAgent.process).toHaveBeenCalledWith('', [
{ mimeType: 'image/png', data: 'iVBOR...', url: undefined, filename: undefined },
]);
expect(sent).toHaveLength(1);
expect((sent[0] as GatewayEvent).event).toBe('done');
const doneEvent = sent.find((msg) => (msg as GatewayEvent).event === 'done');
expect(doneEvent).toBeTruthy();
});
it('agent.send requires message or attachments', async () => {
@@ -1247,10 +1255,8 @@ describe('agent handlers', () => {
await Promise.all([p1, p2]);
// Both should have completed — no AgentBusy error
expect(sent1).toHaveLength(1);
expect((sent1[0] as GatewayEvent).event).toBe('done');
expect(sent2).toHaveLength(1);
expect((sent2[0] as GatewayEvent).event).toBe('done');
expect(sent1.find((msg) => (msg as GatewayEvent).event === 'done')).toBeTruthy();
expect(sent2.find((msg) => (msg as GatewayEvent).event === 'done')).toBeTruthy();
expect(mockAgent.process).toHaveBeenCalledTimes(2);
});
@@ -1262,7 +1268,11 @@ describe('agent handlers', () => {
await handlers['agent.send'](req, send);
const errorEvent = sent[0] as GatewayEvent;
const errorEvent = sent.find((msg) => (msg as GatewayEvent).event === 'error') as GatewayEvent | undefined;
expect(errorEvent).toBeTruthy();
if (!errorEvent) {
throw new Error('error event not emitted');
}
expect(errorEvent.event).toBe('error');
expect(getPath(errorEvent.data, 'message')).toBe('model failed');
});
@@ -1291,7 +1301,7 @@ describe('agent handlers', () => {
it('agent.cancel returns cancelled state', async () => {
mockBridge.cancel.mockReturnValue(true);
const req: GatewayRequest = { id: 7, method: 'agent.cancel', params: { connectionId: 'conn-1' } };
const result = await handlers['agent.cancel'](req) as GatewayResponse;
const result = await handlers['agent.cancel'](req, vi.fn()) as GatewayResponse;
expect(getPath(result.result, 'cancelled')).toBe(true);
expect(getPath(result.result, 'message')).toContain('Cancellation requested');
@@ -1301,7 +1311,7 @@ describe('agent handlers', () => {
it('agent.cancel returns not-cancelled when no active operation exists', async () => {
mockBridge.cancel.mockReturnValue(false);
const req: GatewayRequest = { id: 8, method: 'agent.cancel', params: { connectionId: 'conn-1' } };
const result = await handlers['agent.cancel'](req) as GatewayResponse;
const result = await handlers['agent.cancel'](req, vi.fn()) as GatewayResponse;
expect(getPath(result.result, 'cancelled')).toBe(false);
expect(getPath(result.result, 'message')).toContain('No active operation');