Просмотр исходного кода

add test for multipart-uploader

Futa Arai 1 год назад
Родитель
Сommit
5d47d17c34

+ 1 - 8
apps/app/src/server/service/file-uploader/aws/multipart-uploader.ts

@@ -5,18 +5,11 @@ import {
 
 import loggerFactory from '~/utils/logger';
 
-import { MultipartUploader, type IMultipartUploader } from '../multipart-uploader';
+import { MultipartUploader, UploadStatus, type IMultipartUploader } from '../multipart-uploader';
 
 
 const logger = loggerFactory('growi:services:fileUploaderAws:multipartUploader');
 
-enum UploadStatus {
-  BEFORE_INIT,
-  IN_PROGRESS,
-  COMPLETED,
-  ABORTED
-}
-
 export type IAwsMultipartUploader = IMultipartUploader
 
 /**

+ 1 - 8
apps/app/src/server/service/file-uploader/gcs/multipart-uploader.ts

@@ -2,19 +2,12 @@ import type { Bucket, File } from '@google-cloud/storage';
 
 import loggerFactory from '~/utils/logger';
 
-import { MultipartUploader, type IMultipartUploader } from '../multipart-uploader';
+import { MultipartUploader, UploadStatus, type IMultipartUploader } from '../multipart-uploader';
 
 import axios from 'src/utils/axios';
 
 const logger = loggerFactory('growi:services:fileUploaderGcs:multipartUploader');
 
-enum UploadStatus {
-  BEFORE_INIT,
-  IN_PROGRESS,
-  COMPLETED,
-  ABORTED
-}
-
 export type IGcsMultipartUploader = IMultipartUploader
 
 /**

+ 69 - 0
apps/app/src/server/service/file-uploader/multipart-uploader.integ.ts

@@ -0,0 +1,69 @@
+import { UploadStatus, MultipartUploader } from './multipart-uploader';
+
+class MockMultipartUploader extends MultipartUploader {
+
+  async initUpload(): Promise<void> { return }
+
+  async uploadPart(part: Buffer, partNumber: number): Promise<void> { return }
+
+  async completeUpload(): Promise<void> { return }
+
+  async abortUpload(): Promise<void> { return }
+
+  async getUploadedFileSize(): Promise<number> { return 0 }
+
+  // Expose the protected method for testing
+  testValidateUploadStatus(desired: UploadStatus): void {
+    this.validateUploadStatus(desired);
+  }
+
+  setCurrentStatus(status: UploadStatus): void {
+    this.currentStatus = status;
+  }
+
+}
+
+describe('MultipartUploader', () => {
+  let uploader: MockMultipartUploader;
+
+  beforeEach(() => {
+    uploader = new MockMultipartUploader('test-upload-key', 10485760);
+  });
+
+  describe('validateUploadStatus', () => {
+    describe('When current status is equal to desired status', () => {
+      it('should not throw error', () => {
+        uploader.setCurrentStatus(UploadStatus.ABORTED);
+        expect(() => uploader.testValidateUploadStatus(UploadStatus.ABORTED)).not.toThrow();
+      });
+    });
+
+    describe('When current status is not equal to desired status', () => {
+      it('should throw expected error', () => {
+        const expectedErrorsByStatus = [
+          { current: UploadStatus.BEFORE_INIT, desired: UploadStatus.IN_PROGRESS, errorMessage: 'Multipart upload has not been initiated' },
+          { current: UploadStatus.BEFORE_INIT, desired: UploadStatus.COMPLETED, errorMessage: 'Multipart upload has not been initiated' },
+          { current: UploadStatus.BEFORE_INIT, desired: UploadStatus.ABORTED, errorMessage: 'Multipart upload has not been initiated' },
+          { current: UploadStatus.IN_PROGRESS, desired: UploadStatus.BEFORE_INIT, errorMessage: 'Multipart upload is already in progress' },
+          { current: UploadStatus.IN_PROGRESS, desired: UploadStatus.COMPLETED, errorMessage: 'Multipart upload is still in progress' },
+          { current: UploadStatus.IN_PROGRESS, desired: UploadStatus.ABORTED, errorMessage: 'Multipart upload is still in progress' },
+          { current: UploadStatus.COMPLETED, desired: UploadStatus.BEFORE_INIT, errorMessage: 'Multipart upload has already been completed' },
+          { current: UploadStatus.COMPLETED, desired: UploadStatus.IN_PROGRESS, errorMessage: 'Multipart upload has already been completed' },
+          { current: UploadStatus.COMPLETED, desired: UploadStatus.ABORTED, errorMessage: 'Multipart upload has already been completed' },
+          { current: UploadStatus.ABORTED, desired: UploadStatus.BEFORE_INIT, errorMessage: 'Multipart upload has been aborted' },
+          { current: UploadStatus.ABORTED, desired: UploadStatus.IN_PROGRESS, errorMessage: 'Multipart upload has been aborted' },
+          { current: UploadStatus.ABORTED, desired: UploadStatus.COMPLETED, errorMessage: 'Multipart upload has been aborted' },
+        ];
+
+        expectedErrorsByStatus.forEach(({
+          current, desired, errorMessage,
+        }) => {
+          it(`should throw error when current status is ${current} but desired status is ${desired}`, () => {
+            uploader.setCurrentStatus(current);
+            expect(() => uploader.testValidateUploadStatus(desired)).toThrow(errorMessage);
+          });
+        });
+      });
+    });
+  });
+});

+ 10 - 7
apps/app/src/server/service/file-uploader/multipart-uploader.ts

@@ -2,7 +2,7 @@ import loggerFactory from '~/utils/logger';
 
 const logger = loggerFactory('growi:services:fileUploader:multipartUploader');
 
-enum UploadStatus {
+export enum UploadStatus {
   BEFORE_INIT,
   IN_PROGRESS,
   COMPLETED,
@@ -67,14 +67,17 @@ export abstract class MultipartUploader implements IMultipartUploader {
       errMsg = 'Multipart upload has been aborted';
     }
 
-    // currentStatus is IN_PROGRESS or BEFORE_INIT
-
-    if (this.currentStatus === UploadStatus.IN_PROGRESS && desiredStatus === UploadStatus.BEFORE_INIT) {
-      errMsg = 'Multipart upload has already been initiated';
+    if (this.currentStatus === UploadStatus.IN_PROGRESS) {
+      if (desiredStatus === UploadStatus.BEFORE_INIT) {
+        errMsg = 'Multipart upload is already in progress';
+      }
+      else {
+        errMsg = 'Multipart upload is still in progress';
+      }
     }
 
-    if (this.currentStatus === UploadStatus.BEFORE_INIT && desiredStatus === UploadStatus.IN_PROGRESS) {
-      errMsg = 'Multipart upload not initiated';
+    if (this.currentStatus === UploadStatus.BEFORE_INIT) {
+      errMsg = 'Multipart upload has not been initiated';
     }
 
     if (errMsg != null) {