瀏覽代碼

✅ test(file): implement completeMultipartUpload test cases

- 恢复并完善completeMultipartUpload方法的测试套件
- 添加成功完成分片上传的测试场景
- 添加文件记录不存在的错误处理测试
- 添加分片上传失败的错误处理测试
- 使用getFileUrl和update方法替代直接操作repository
- 优化MinioService的模拟实现方式
yourname 2 月之前
父節點
當前提交
ca96ebda7e
共有 1 個文件被更改,包括 98 次插入75 次删除
  1. 98 75
      src/server/modules/files/__tests__/file.service.test.ts

+ 98 - 75
src/server/modules/files/__tests__/file.service.test.ts

@@ -303,79 +303,102 @@ describe('FileService', () => {
     });
   });
 
-  // describe('completeMultipartUpload', () => {
-  //   it('should complete multipart upload successfully', async () => {
-  //     const uploadData = {
-  //       uploadId: 'upload-123',
-  //       bucket: 'd8dai',
-  //       key: '1/test-file.txt',
-  //       parts: [
-  //         { partNumber: 1, etag: 'etag1' },
-  //         { partNumber: 2, etag: 'etag2' }
-  //       ]
-  //     };
-
-  //     const mockFile = {
-  //       id: 1,
-  //       path: '1/test-file.txt',
-  //       size: 0,
-  //       updatedAt: new Date()
-  //     } as File;
-
-  //     const mockCompleteResult = { size: 2048 };
-  //     const mockFileUrl = 'https://minio.example.com/file.txt';
-
-  //     vi.mocked(mockMinioService.completeMultipartUpload).mockResolvedValue(mockCompleteResult);
-  //     vi.mocked(mockMinioService.getFileUrl).mockReturnValue(mockFileUrl);
-  //     vi.spyOn(fileService.repository, 'findOneBy').mockResolvedValue(mockFile);
-  //     vi.spyOn(fileService.repository, 'save').mockResolvedValue(mockFile);
-
-  //     const result = await fileService.completeMultipartUpload(uploadData);
-
-  //     expect(mockMinioService.completeMultipartUpload).toHaveBeenCalledWith(
-  //       'd8dai',
-  //       '1/test-file.txt',
-  //       'upload-123',
-  //       [{ PartNumber: 1, ETag: 'etag1' }, { PartNumber: 2, ETag: 'etag2' }]
-  //     );
-  //     expect(fileService.repository.findOneBy).toHaveBeenCalledWith({ path: '1/test-file.txt' });
-  //     expect(fileService.repository.save).toHaveBeenCalledWith(expect.objectContaining({
-  //       size: 2048
-  //     }));
-  //     expect(result).toEqual({
-  //       fileId: 1,
-  //       url: mockFileUrl,
-  //       key: '1/test-file.txt',
-  //       size: 2048
-  //     });
-  //   });
-
-  //   it('should throw error when file record not found', async () => {
-  //     const uploadData = {
-  //       uploadId: 'upload-123',
-  //       bucket: 'd8dai',
-  //       key: '1/nonexistent.txt',
-  //       parts: [{ partNumber: 1, etag: 'etag1' }]
-  //     };
-
-  //     vi.mocked(mockMinioService.completeMultipartUpload).mockResolvedValue({ size: 1024 });
-  //     vi.spyOn(fileService.repository, 'findOneBy').mockResolvedValue(null);
-
-  //     await expect(fileService.completeMultipartUpload(uploadData)).rejects.toThrow('文件记录不存在');
-  //   });
-
-  //   it('should handle errors during completion', async () => {
-  //     const uploadData = {
-  //       uploadId: 'upload-123',
-  //       bucket: 'd8dai',
-  //       key: '1/test-file.txt',
-  //       parts: [{ partNumber: 1, etag: 'etag1' }]
-  //     };
-
-  //     vi.mocked(mockMinioService.completeMultipartUpload).mockRejectedValue(new Error('Completion failed'));
-
-  //     await expect(fileService.completeMultipartUpload(uploadData)).rejects.toThrow('完成分片上传失败');
-  //     expect(logger.error).toHaveBeenCalled();
-  //   });
-  // });
+  describe('completeMultipartUpload', () => {
+    it('should complete multipart upload successfully', async () => {
+      const uploadData = {
+        uploadId: 'upload-123',
+        bucket: 'd8dai',
+        key: '1/test-file.txt',
+        parts: [
+          { partNumber: 1, etag: 'etag1' },
+          { partNumber: 2, etag: 'etag2' }
+        ]
+      };
+
+      const mockFile = {
+        id: 1,
+        path: '1/test-file.txt',
+        size: 0,
+        updatedAt: new Date()
+      } as File;
+
+      const mockCompleteResult = { size: 2048 };
+      const mockFileUrl = 'https://minio.example.com/file.txt';
+
+      const mockCompleteMultipartUpload = vi.fn().mockResolvedValue(mockCompleteResult);
+      const mockGetFileUrl = vi.fn().mockReturnValue(mockFileUrl);
+
+      vi.mocked(MinioService).mockImplementation(() => ({
+        completeMultipartUpload: mockCompleteMultipartUpload,
+        getFileUrl: mockGetFileUrl
+      } as unknown as MinioService));
+
+      const fileService = new FileService(mockDataSource);
+
+      // 模拟getById方法返回文件记录
+      vi.spyOn(fileService, 'getById').mockResolvedValue(mockFile);
+
+      // 模拟update方法更新文件大小
+      vi.spyOn(fileService, 'update').mockResolvedValue({ ...mockFile, size: 2048 } as File);
+
+      const result = await fileService.completeMultipartUpload(uploadData);
+
+      expect(mockCompleteMultipartUpload).toHaveBeenCalledWith(
+        'd8dai',
+        '1/test-file.txt',
+        'upload-123',
+        [{ PartNumber: 1, ETag: 'etag1' }, { PartNumber: 2, ETag: 'etag2' }]
+      );
+      expect(fileService.getById).toHaveBeenCalledWith(1);
+      expect(fileService.update).toHaveBeenCalledWith(1, expect.objectContaining({
+        size: 2048
+      }));
+      expect(result).toEqual({
+        fileId: 1,
+        url: mockFileUrl,
+        key: '1/test-file.txt',
+        size: 2048
+      });
+    });
+
+    it('should throw error when file record not found', async () => {
+      const uploadData = {
+        uploadId: 'upload-123',
+        bucket: 'd8dai',
+        key: '1/nonexistent.txt',
+        parts: [{ partNumber: 1, etag: 'etag1' }]
+      };
+
+      const mockCompleteMultipartUpload = vi.fn().mockResolvedValue({ size: 1024 });
+
+      vi.mocked(MinioService).mockImplementation(() => ({
+        completeMultipartUpload: mockCompleteMultipartUpload
+      } as unknown as MinioService));
+
+      const fileService = new FileService(mockDataSource);
+      vi.spyOn(fileService, 'getById').mockResolvedValue(null);
+
+      await expect(fileService.completeMultipartUpload(uploadData)).rejects.toThrow('文件记录不存在');
+    });
+
+    it('should handle errors during completion', async () => {
+      const uploadData = {
+        uploadId: 'upload-123',
+        bucket: 'd8dai',
+        key: '1/test-file.txt',
+        parts: [{ partNumber: 1, etag: 'etag1' }]
+      };
+
+      const mockCompleteMultipartUpload = vi.fn().mockRejectedValue(new Error('Completion failed'));
+
+      vi.mocked(MinioService).mockImplementation(() => ({
+        completeMultipartUpload: mockCompleteMultipartUpload
+      } as unknown as MinioService));
+
+      const fileService = new FileService(mockDataSource);
+
+      await expect(fileService.completeMultipartUpload(uploadData)).rejects.toThrow('完成分片上传失败');
+      expect(logger.error).toHaveBeenCalled();
+    });
+  });
 });