1+ import { DatastreamClient , Logger , MessageHandlerFunc , ConnectionReadyHandlerFunc , DataStreamResp , EntityType , Action } from '../datastream' ;
2+
3+ // Mock logger implementation
4+ class MockLogger implements Logger {
5+ debug ( ctx : any , message : string , ...args : any [ ] ) : void {
6+ console . log ( `[DEBUG] ${ message } ` , ...args ) ;
7+ }
8+
9+ info ( ctx : any , message : string , ...args : any [ ] ) : void {
10+ console . log ( `[INFO] ${ message } ` , ...args ) ;
11+ }
12+
13+ warn ( ctx : any , message : string , ...args : any [ ] ) : void {
14+ console . log ( `[WARN] ${ message } ` , ...args ) ;
15+ }
16+
17+ error ( ctx : any , message : string , ...args : any [ ] ) : void {
18+ console . error ( `[ERROR] ${ message } ` , ...args ) ;
19+ }
20+ }
21+
22+ describe ( 'DatastreamClient' , ( ) => {
23+ let client : DatastreamClient ;
24+ const mockLogger = new MockLogger ( ) ;
25+
26+ const mockMessageHandler : MessageHandlerFunc = async ( ctx : any , message : DataStreamResp ) => {
27+ console . log ( 'Received message:' , message ) ;
28+ } ;
29+
30+ const mockConnectionReadyHandler : ConnectionReadyHandlerFunc = async ( ctx : any ) => {
31+ console . log ( 'Connection ready' ) ;
32+ } ;
33+
34+ afterEach ( ( ) => {
35+ if ( client ) {
36+ client . close ( ) ;
37+ }
38+ } ) ;
39+
40+ test ( 'should create client with required options' , ( ) => {
41+ expect ( ( ) => {
42+ client = new DatastreamClient ( {
43+ url : 'wss://datastream.example.com/datastream' ,
44+ apiKey : 'test-key' ,
45+ messageHandler : mockMessageHandler ,
46+ logger : mockLogger ,
47+ } ) ;
48+ } ) . not . toThrow ( ) ;
49+
50+ expect ( client . isConnected ( ) ) . toBe ( false ) ;
51+ expect ( client . isReady ( ) ) . toBe ( false ) ;
52+ } ) ;
53+
54+ test ( 'should throw error when URL is missing' , ( ) => {
55+ expect ( ( ) => {
56+ new DatastreamClient ( {
57+ url : '' ,
58+ apiKey : 'test-key' ,
59+ messageHandler : mockMessageHandler ,
60+ } ) ;
61+ } ) . toThrow ( 'URL is required' ) ;
62+ } ) ;
63+
64+ test ( 'should throw error when API key is missing' , ( ) => {
65+ expect ( ( ) => {
66+ new DatastreamClient ( {
67+ url : 'wss://example.com' ,
68+ apiKey : '' ,
69+ messageHandler : mockMessageHandler ,
70+ } ) ;
71+ } ) . toThrow ( 'ApiKey is required' ) ;
72+ } ) ;
73+
74+ test ( 'should throw error when message handler is missing' , ( ) => {
75+ expect ( ( ) => {
76+ new DatastreamClient ( {
77+ url : 'wss://example.com' ,
78+ apiKey : 'test-key' ,
79+ messageHandler : undefined as any ,
80+ } ) ;
81+ } ) . toThrow ( 'MessageHandler is required' ) ;
82+ } ) ;
83+
84+ test ( 'should convert HTTP URL to WebSocket URL' , ( ) => {
85+ client = new DatastreamClient ( {
86+ url : 'https://api.schematichq.com' ,
87+ apiKey : 'test-key' ,
88+ messageHandler : mockMessageHandler ,
89+ logger : mockLogger ,
90+ } ) ;
91+
92+ // The URL conversion is tested internally - we can't directly access the private url property
93+ // But we can verify the client was created successfully
94+ expect ( client ) . toBeDefined ( ) ;
95+ expect ( client . isConnected ( ) ) . toBe ( false ) ;
96+ } ) ;
97+
98+ test ( 'should convert HTTP localhost URL to WebSocket URL' , ( ) => {
99+ client = new DatastreamClient ( {
100+ url : 'http://localhost:8080' ,
101+ apiKey : 'test-key' ,
102+ messageHandler : mockMessageHandler ,
103+ logger : mockLogger ,
104+ } ) ;
105+
106+ expect ( client ) . toBeDefined ( ) ;
107+ expect ( client . isConnected ( ) ) . toBe ( false ) ;
108+ } ) ;
109+
110+ test ( 'should handle WebSocket URL directly' , ( ) => {
111+ client = new DatastreamClient ( {
112+ url : 'wss://datastream.example.com/datastream' ,
113+ apiKey : 'test-key' ,
114+ messageHandler : mockMessageHandler ,
115+ logger : mockLogger ,
116+ } ) ;
117+
118+ expect ( client ) . toBeDefined ( ) ;
119+ expect ( client . isConnected ( ) ) . toBe ( false ) ;
120+ } ) ;
121+
122+ test ( 'should set default options when not provided' , ( ) => {
123+ client = new DatastreamClient ( {
124+ url : 'wss://example.com' ,
125+ apiKey : 'test-key' ,
126+ messageHandler : mockMessageHandler ,
127+ } ) ;
128+
129+ // Defaults are applied internally - we verify by successful construction
130+ expect ( client ) . toBeDefined ( ) ;
131+ } ) ;
132+
133+ test ( 'should use custom options when provided' , ( ) => {
134+ client = new DatastreamClient ( {
135+ url : 'wss://example.com' ,
136+ apiKey : 'test-key' ,
137+ messageHandler : mockMessageHandler ,
138+ connectionReadyHandler : mockConnectionReadyHandler ,
139+ logger : mockLogger ,
140+ maxReconnectAttempts : 5 ,
141+ minReconnectDelay : 2000 ,
142+ maxReconnectDelay : 60000 ,
143+ } ) ;
144+
145+ expect ( client ) . toBeDefined ( ) ;
146+ } ) ;
147+
148+ test ( 'should emit events' , ( done ) => {
149+ client = new DatastreamClient ( {
150+ url : 'wss://example.com' ,
151+ apiKey : 'test-key' ,
152+ messageHandler : mockMessageHandler ,
153+ logger : mockLogger ,
154+ } ) ;
155+
156+ // Test that the client can emit events
157+ client . on ( 'error' , ( error ) => {
158+ expect ( error ) . toBeDefined ( ) ;
159+ done ( ) ;
160+ } ) ;
161+
162+ // Trigger an error to test event emission
163+ client . emit ( 'error' , new Error ( 'Test error' ) ) ;
164+ } ) ;
165+
166+ test ( 'should reject sendMessage when not connected' , async ( ) => {
167+ client = new DatastreamClient ( {
168+ url : 'wss://example.com' ,
169+ apiKey : 'test-key' ,
170+ messageHandler : mockMessageHandler ,
171+ logger : mockLogger ,
172+ } ) ;
173+
174+ await expect ( client . sendMessage ( { test : 'message' } ) ) . rejects . toThrow ( 'WebSocket connection is not available!' ) ;
175+ } ) ;
176+ } ) ;
0 commit comments