11import { describe , expect , mock , test } from "bun:test" ;
2- import * as http from "node:http" ;
32import { Server as ComputeServer } from "@blink-sdk/compute-protocol/server" ;
4- import { createServerAdapter } from "@whatwg-node/server" ;
53import {
64 readUIMessageStream ,
75 simulateReadableStream ,
@@ -11,10 +9,14 @@ import {
119import { MockLanguageModelV2 } from "ai/test" ;
1210import * as blink from "blink" ;
1311import { Client } from "blink/client" ;
14- import { api as controlApi } from "blink/control" ;
1512import { WebSocketServer } from "ws" ;
1613import type { DaytonaClient , DaytonaSandbox } from "./compute/daytona/index" ;
1714import { type Message , Scout } from "./index" ;
15+ import {
16+ createMockBlinkApiServer ,
17+ noopLogger ,
18+ withBlinkApiUrl ,
19+ } from "./test-helpers" ;
1820
1921// Add async iterator support to ReadableStream for testing
2022declare global {
@@ -341,12 +343,6 @@ describe("config", async () => {
341343 }
342344} ) ;
343345
344- const noopLogger = {
345- info : ( ) => { } ,
346- warn : ( ) => { } ,
347- error : ( ) => { } ,
348- } ;
349-
350346test ( "respond in slack" , async ( ) => {
351347 const { promise : doStreamOptionsPromise , resolve } =
352348 newPromise < DoStreamOptions > ( ) ;
@@ -393,98 +389,6 @@ test("respond in slack", async () => {
393389 ) ;
394390} ) ;
395391
396- // Mock Blink API server for integration tests
397- const createMockBlinkApiServer = ( ) => {
398- const storage : Record < string , string > = { } ;
399-
400- const storeImpl : blink . AgentStore = {
401- async get ( key ) {
402- const decodedKey = decodeURIComponent ( key ) ;
403- return storage [ decodedKey ] ;
404- } ,
405- async set ( key , value ) {
406- const decodedKey = decodeURIComponent ( key ) ;
407- storage [ decodedKey ] = value ;
408- } ,
409- async delete ( key ) {
410- const decodedKey = decodeURIComponent ( key ) ;
411- delete storage [ decodedKey ] ;
412- } ,
413- async list ( prefix , options ) {
414- const decodedPrefix = prefix ? decodeURIComponent ( prefix ) : undefined ;
415- const limit = Math . min ( options ?. limit ?? 100 , 1000 ) ;
416- const allKeys = Object . keys ( storage )
417- . filter ( ( key ) => ! decodedPrefix || key . startsWith ( decodedPrefix ) )
418- . sort ( ) ;
419- let startIndex = 0 ;
420- if ( options ?. cursor ) {
421- const cursorIndex = allKeys . indexOf ( options . cursor ) ;
422- if ( cursorIndex !== - 1 ) startIndex = cursorIndex + 1 ;
423- }
424- const keysToReturn = allKeys . slice ( startIndex , startIndex + limit ) ;
425- return {
426- entries : keysToReturn . map ( ( key ) => ( { key } ) ) ,
427- cursor :
428- startIndex + limit < allKeys . length
429- ? keysToReturn [ keysToReturn . length - 1 ]
430- : undefined ,
431- } ;
432- } ,
433- } ;
434-
435- const chatImpl : blink . AgentChat = {
436- async upsert ( ) {
437- return {
438- id : "00000000-0000-0000-0000-000000000000" as blink . ID ,
439- created : true ,
440- createdAt : new Date ( ) . toISOString ( ) ,
441- } ;
442- } ,
443- async get ( ) {
444- return undefined ;
445- } ,
446- async getMessages ( ) {
447- return [ ] ;
448- } ,
449- async sendMessages ( ) { } ,
450- async deleteMessages ( ) { } ,
451- async start ( ) { } ,
452- async stop ( ) { } ,
453- async delete ( ) { } ,
454- } ;
455-
456- const server = http . createServer (
457- createServerAdapter ( ( req ) => {
458- return controlApi . fetch ( req , {
459- chat : chatImpl ,
460- store : storeImpl ,
461- // biome-ignore lint/suspicious/noExplicitAny: mock
462- otlp : undefined as any ,
463- } ) ;
464- } )
465- ) ;
466-
467- server . listen ( 0 ) ;
468-
469- const getUrl = ( ) => {
470- const addr = server . address ( ) ;
471- if ( addr && typeof addr !== "string" ) {
472- return `http://127.0.0.1:${ addr . port } ` ;
473- }
474- return "http://127.0.0.1:0" ;
475- } ;
476-
477- return {
478- get url ( ) {
479- return getUrl ( ) ;
480- } ,
481- storage,
482- [ Symbol . dispose ] : ( ) => {
483- server . close ( ) ;
484- } ,
485- } ;
486- } ;
487-
488392// Daytona integration test helpers
489393const createMockDaytonaSandbox = (
490394 overrides : Partial < DaytonaSandbox > = { }
@@ -505,20 +409,6 @@ const createMockDaytonaSdk = (
505409 create : mock ( ( ) => Promise . resolve ( sandbox ) ) ,
506410} ) ;
507411
508- const withBlinkApiUrl = ( url : string ) => {
509- const originalApiUrl = process . env . BLINK_API_URL ;
510- process . env . BLINK_API_URL = url ;
511- return {
512- [ Symbol . dispose ] : ( ) => {
513- if ( originalApiUrl ) {
514- process . env . BLINK_API_URL = originalApiUrl ;
515- } else {
516- delete process . env . BLINK_API_URL ;
517- }
518- } ,
519- } ;
520- } ;
521-
522412const createMockComputeServer = ( ) => {
523413 const wss = new WebSocketServer ( { port : 0 } ) ;
524414 const address = wss . address ( ) ;
0 commit comments