Files
flynn/src/gateway/protocol.test.ts
T
William Valentin e052778b0a feat: add gateway protocol attachment support
Extends the gateway wire protocol with GatewayAttachment type and
attachment event. agent.send handler now accepts optional attachments
parameter and converts them for the agent pipeline. Includes 5 new
tests for protocol and handler layers.
2026-02-07 09:09:06 -08:00

109 lines
3.1 KiB
TypeScript

import { describe, it, expect } from 'vitest';
import {
isValidRequest,
parseMessage,
makeResponse,
makeError,
makeEvent,
ErrorCode,
} from './protocol.js';
describe('protocol', () => {
describe('isValidRequest', () => {
it('accepts valid request with params', () => {
expect(isValidRequest({ id: 1, method: 'agent.send', params: { message: 'hello' } })).toBe(true);
});
it('accepts valid request without params', () => {
expect(isValidRequest({ id: 1, method: 'system.health' })).toBe(true);
});
it('rejects missing id', () => {
expect(isValidRequest({ method: 'test' })).toBe(false);
});
it('rejects missing method', () => {
expect(isValidRequest({ id: 1 })).toBe(false);
});
it('rejects non-object', () => {
expect(isValidRequest('not an object')).toBe(false);
expect(isValidRequest(null)).toBe(false);
expect(isValidRequest(42)).toBe(false);
});
it('rejects non-numeric id', () => {
expect(isValidRequest({ id: 'abc', method: 'test' })).toBe(false);
});
it('rejects non-string method', () => {
expect(isValidRequest({ id: 1, method: 42 })).toBe(false);
});
it('rejects non-object params', () => {
expect(isValidRequest({ id: 1, method: 'test', params: 'bad' })).toBe(false);
});
});
describe('parseMessage', () => {
it('parses valid JSON into GatewayRequest', () => {
const msg = parseMessage('{"id":1,"method":"agent.send","params":{"message":"hi"}}');
expect(msg).toEqual({ id: 1, method: 'agent.send', params: { message: 'hi' } });
});
it('returns null for invalid JSON', () => {
expect(parseMessage('not json')).toBeNull();
});
it('returns null for valid JSON that is not a valid request', () => {
expect(parseMessage('{"method":"test"}')).toBeNull();
});
});
describe('makeResponse', () => {
it('creates a response message', () => {
expect(makeResponse(1, { status: 'ok' })).toEqual({
id: 1,
result: { status: 'ok' },
});
});
});
describe('makeError', () => {
it('creates an error message', () => {
expect(makeError(1, ErrorCode.MethodNotFound, 'Not found')).toEqual({
id: 1,
error: { code: -3, message: 'Not found' },
});
});
});
describe('makeEvent', () => {
it('creates an event message', () => {
expect(makeEvent(1, 'content', { text: 'hello' })).toEqual({
id: 1,
event: 'content',
data: { text: 'hello' },
});
});
it('creates an attachment event message', () => {
const data = { mimeType: 'image/png', data: 'iVBOR...', filename: 'screenshot.png' };
expect(makeEvent(1, 'attachment', data)).toEqual({
id: 1,
event: 'attachment',
data,
});
});
it('creates an attachment event with url', () => {
const data = { mimeType: 'application/pdf', url: 'https://example.com/doc.pdf', filename: 'doc.pdf' };
expect(makeEvent(2, 'attachment', data)).toEqual({
id: 2,
event: 'attachment',
data,
});
});
});
});