11import { afterAll , beforeAll , beforeEach , describe , expect , it , jest } from '@jest/globals' ;
2+ import { Buffer } from 'node:buffer' ;
3+ import type * as Party from 'partykit/server' ;
24import * as Y from 'yjs' ;
35
4- const verifyTokenMock = jest . fn ( ) ;
5- const checkUserVerifiedMock = jest . fn ( ) ;
6- const getDocumentMock = jest . fn ( ) ;
7- const upsertDocumentMock = jest . fn ( ) ;
8- const partyOnConnectMock = jest . fn ( ) ;
6+ const verifyTokenMock = jest . fn < ( ) => Promise < { valid : boolean ; payload ?: any ; error ?: any } > > ( ) ;
7+ const checkUserVerifiedMock = jest . fn < ( ) => Promise < boolean > > ( ) ;
8+ const getDocumentMock = jest . fn < ( ) => Promise < { data : any ; error : any } > > ( ) ;
9+ const upsertDocumentMock = jest . fn < ( roomId : string , content : Uint8Array ) => Promise < { data : any ; error : any } > > ( ) ;
10+ const partyOnConnectMock = jest . fn <
11+ (
12+ connection : Party . Connection ,
13+ room : Party . Room ,
14+ options : {
15+ load : ( ) => Promise < Y . Doc > ;
16+ callback ?: { handler : ( doc : Y . Doc ) => Promise < void > } ;
17+ }
18+ ) => Promise < void >
19+ > ( ) ;
920
1021jest . unstable_mockModule ( '../utils/jwt.js' , ( ) => ( {
1122 verifyToken : verifyTokenMock ,
@@ -16,17 +27,19 @@ jest.unstable_mockModule('../storage/db.js', () => ({
1627 getDocument : getDocumentMock ,
1728 upsertDocument : upsertDocumentMock ,
1829 checkRoomExists : jest . fn ( ) ,
30+ deleteRoom : jest . fn ( ) ,
1931} ) ) ;
2032
2133jest . unstable_mockModule ( 'y-partykit' , ( ) => ( {
2234 onConnect : partyOnConnectMock ,
2335} ) ) ;
2436
25- let YjsServer : typeof import ( '../party/codeServer .js' ) . default ;
37+ let YjsServer : typeof import ( '../party/websocketServer .js' ) . default ;
2638
2739const createConnection = ( ) =>
2840 ( {
2941 close : jest . fn ( ) ,
42+ addEventListener : jest . fn ( ) ,
3043 } ) as unknown as Party . Connection ;
3144
3245const buildContext = ( token ?: string ) =>
@@ -41,7 +54,7 @@ const buildContext = (token?: string) =>
4154const room = { id : 'room-1' } as unknown as Party . Room ;
4255
4356beforeAll ( async ( ) => {
44- ( { default : YjsServer } = await import ( '../party/codeServer .js' ) ) ;
57+ ( { default : YjsServer } = await import ( '../party/websocketServer .js' ) ) ;
4558} ) ;
4659
4760describe ( 'YjsServer.onConnect' , ( ) => {
@@ -76,7 +89,7 @@ describe('YjsServer.onConnect', () => {
7689 const server = new YjsServer ( room ) ;
7790 const connection = createConnection ( ) ;
7891
79- verifyTokenMock . mockResolvedValue ( { valid : false , error : new Error ( 'invalid token' ) } as any ) ;
92+ verifyTokenMock . mockResolvedValue ( { valid : false , error : new Error ( 'invalid token' ) } ) ;
8093
8194 await server . onConnect ( connection , buildContext ( 'token-1' ) ) ;
8295
@@ -91,7 +104,7 @@ describe('YjsServer.onConnect', () => {
91104 verifyTokenMock . mockResolvedValue ( {
92105 valid : true ,
93106 payload : { userId : 'user-1' } ,
94- } as any ) ;
107+ } ) ;
95108 checkUserVerifiedMock . mockResolvedValue ( false ) ;
96109
97110 await server . onConnect ( connection , buildContext ( 'token-1' ) ) ;
@@ -110,10 +123,10 @@ describe('YjsServer.onConnect', () => {
110123 verifyTokenMock . mockResolvedValue ( {
111124 valid : true ,
112125 payload : { userId : 'user-1' } ,
113- } as any ) ;
126+ } ) ;
114127 checkUserVerifiedMock . mockResolvedValue ( true ) ;
115- getDocumentMock . mockResolvedValue ( { data : null , error : null } as any ) ;
116- upsertDocumentMock . mockResolvedValue ( { data : null , error : null } as any ) ;
128+ getDocumentMock . mockResolvedValue ( { data : null , error : null } ) ;
129+ upsertDocumentMock . mockResolvedValue ( { data : null , error : null } ) ;
117130
118131 partyOnConnectMock . mockImplementation ( async ( _connection , _ , options ) => {
119132 const doc = await options . load ( ) ;
@@ -138,13 +151,13 @@ describe('YjsServer.onConnect', () => {
138151 verifyTokenMock . mockResolvedValue ( {
139152 valid : true ,
140153 payload : { userId : 'user-1' } ,
141- } as any ) ;
154+ } ) ;
142155 checkUserVerifiedMock . mockResolvedValue ( true ) ;
143156 getDocumentMock . mockResolvedValue ( {
144157 data : { document : Buffer . from ( encoded ) . toString ( 'base64' ) } ,
145158 error : null ,
146- } as any ) ;
147- upsertDocumentMock . mockResolvedValue ( { data : null , error : null } as any ) ;
159+ } ) ;
160+ upsertDocumentMock . mockResolvedValue ( { data : null , error : null } ) ;
148161
149162 let loadedDoc : Y . Doc | null = null ;
150163 partyOnConnectMock . mockImplementation ( async ( _connection , _ , options ) => {
@@ -153,7 +166,8 @@ describe('YjsServer.onConnect', () => {
153166
154167 await server . onConnect ( connection , buildContext ( 'token-1' ) ) ;
155168
156- expect ( loadedDoc ?. getText ( 'codemirror' ) . toString ( ) ) . toBe ( 'hello' ) ;
169+ expect ( loadedDoc ) . not . toBeNull ( ) ;
170+ expect ( loadedDoc ! . getText ( 'codemirror' ) . toString ( ) ) . toBe ( 'hello' ) ;
157171 } ) ;
158172
159173 it ( 'closes the connection when loading the document fails' , async ( ) => {
@@ -163,20 +177,22 @@ describe('YjsServer.onConnect', () => {
163177 verifyTokenMock . mockResolvedValue ( {
164178 valid : true ,
165179 payload : { userId : 'user-1' } ,
166- } as any ) ;
180+ } ) ;
167181 checkUserVerifiedMock . mockResolvedValue ( true ) ;
168182 getDocumentMock . mockResolvedValue ( {
169183 data : null ,
170184 error : { message : 'database offline' } ,
171- } as any ) ;
185+ } ) ;
172186
173187 partyOnConnectMock . mockImplementation ( async ( _connection , _ , options ) => {
188+ // This will throw an error which should be caught by the outer try-catch
174189 await options . load ( ) ;
175190 } ) ;
176191
177192 await server . onConnect ( connection , buildContext ( 'token-1' ) ) ;
178193
179194 expect ( connection . close ) . toHaveBeenCalledWith ( 4000 , 'Internal server error' ) ;
195+ expect ( partyOnConnectMock ) . toHaveBeenCalledTimes ( 1 ) ;
180196 } ) ;
181197} ) ;
182198
0 commit comments