Browse Source

test: add afterEach cleanup and socket.destroy non-call assertions

- yjs.integ.ts: Add afterEach to clean up Revision data between tests,
  preventing state contamination across test cases. Fix error.code type safety.
- upgrade-handler.spec.ts: Add socket.destroy non-call assertions to all
  error test cases, verifying the contract that upgrade-handler writes error
  responses without closing the socket.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Yuki Takei 1 week ago
parent
commit
01a1ef45d5

+ 3 - 0
apps/app/src/server/service/yjs/upgrade-handler.spec.ts

@@ -94,6 +94,7 @@ describe('UpgradeHandler', () => {
       expect(result.statusCode).toBe(400);
       expect(result.statusCode).toBe(400);
     }
     }
     expect(socket.write).toHaveBeenCalledWith(expect.stringContaining('400'));
     expect(socket.write).toHaveBeenCalledWith(expect.stringContaining('400'));
+    expect(socket.destroy).not.toHaveBeenCalled();
   });
   });
 
 
   it('should reject with 403 when user has no page access', async () => {
   it('should reject with 403 when user has no page access', async () => {
@@ -113,6 +114,7 @@ describe('UpgradeHandler', () => {
       expect(result.statusCode).toBe(403);
       expect(result.statusCode).toBe(403);
     }
     }
     expect(socket.write).toHaveBeenCalledWith(expect.stringContaining('403'));
     expect(socket.write).toHaveBeenCalledWith(expect.stringContaining('403'));
+    expect(socket.destroy).not.toHaveBeenCalled();
   });
   });
 
 
   it('should reject with 401 when unauthenticated user has no page access', async () => {
   it('should reject with 401 when unauthenticated user has no page access', async () => {
@@ -128,6 +130,7 @@ describe('UpgradeHandler', () => {
     if (!result.authorized) {
     if (!result.authorized) {
       expect(result.statusCode).toBe(401);
       expect(result.statusCode).toBe(401);
     }
     }
+    expect(socket.destroy).not.toHaveBeenCalled();
   });
   });
 
 
   it('should allow guest user when page allows guest access', async () => {
   it('should allow guest user when page allows guest access', async () => {

+ 5 - 4
apps/app/src/server/service/yjs/yjs.integ.ts

@@ -49,11 +49,11 @@ describe('YjsService', () => {
       initializeYjsService(httpServer, ioMock, sessionConfig);
       initializeYjsService(httpServer, ioMock, sessionConfig);
     });
     });
 
 
-    afterAll(async () => {
-      // flush revisions
+    afterEach(async () => {
       await Revision.deleteMany({});
       await Revision.deleteMany({});
+    });
 
 
-      // flush yjs-writings
+    afterAll(async () => {
       const yjsService = getYjsService();
       const yjsService = getYjsService();
       const privateMdb = getPrivateMdbInstance(yjsService);
       const privateMdb = getPrivateMdbInstance(yjsService);
       try {
       try {
@@ -62,7 +62,8 @@ describe('YjsService', () => {
         // Ignore errors that can occur due to async index creation:
         // Ignore errors that can occur due to async index creation:
         // - 26: NamespaceNotFound (collection not yet created)
         // - 26: NamespaceNotFound (collection not yet created)
         // - 276: IndexBuildAborted (cleanup during index creation)
         // - 276: IndexBuildAborted (cleanup during index creation)
-        if (error.code !== 26 && error.code !== 276) {
+        const code = (error as { code?: number }).code;
+        if (code !== 26 && code !== 276) {
           throw error;
           throw error;
         }
         }
       }
       }