Files
flynn/src/models/openai.oauth.test.ts
T

69 lines
2.2 KiB
TypeScript

import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { OpenAIClient } from './openai.js';
vi.mock('../auth/openai.js', () => ({
ensureValidOpenAIAuth: vi.fn(async () => ({
access_token: 'at',
refresh_token: 'rt',
expires_at: Date.now() + 60_000,
created_at: new Date().toISOString(),
account_id: 'acct',
})),
}));
function makeSse(events: Array<{ event: string; data: any }>): string {
return events
.map((e) => `event: ${e.event}\ndata: ${JSON.stringify(e.data)}\n\n`)
.join('');
}
describe('OpenAIClient OAuth (Codex)', () => {
const originalFetch = globalThis.fetch;
beforeEach(() => {
vi.useFakeTimers();
});
afterEach(() => {
globalThis.fetch = originalFetch;
vi.useRealTimers();
vi.restoreAllMocks();
});
it('streams SSE and accumulates output_text.delta', async () => {
const sse = makeSse([
{ event: 'response.created', data: { type: 'response.created', response: { id: 'r1' } } },
{ event: 'response.output_text.delta', data: { type: 'response.output_text.delta', delta: 'hel' } },
{ event: 'response.output_text.delta', data: { type: 'response.output_text.delta', delta: 'lo' } },
{ event: 'response.completed', data: { type: 'response.completed', response: { usage: { input_tokens: 2, output_tokens: 2 } } } },
]);
globalThis.fetch = vi.fn(async (_url: any, init?: any) => {
const parsed = JSON.parse(init.body);
expect(parsed.store).toBe(false);
expect(parsed.stream).toBe(true);
expect(typeof parsed.instructions).toBe('string');
expect(Array.isArray(parsed.input)).toBe(true);
const stream = new ReadableStream({
start(controller) {
controller.enqueue(new TextEncoder().encode(sse));
controller.close();
},
});
return new Response(stream, { status: 200 });
}) as any;
const client = new OpenAIClient({ model: 'gpt-5.3-codex', useOAuth: true });
const resp = await client.chat({
system: 'You are helpful.',
messages: [{ role: 'user', content: 'hi' }],
});
expect(resp.content).toBe('hello');
expect(resp.usage).toEqual({ inputTokens: 2, outputTokens: 2 });
});
});