From 0da04e5865f4d76b304184b6a727f28dd11bca5d Mon Sep 17 00:00:00 2001 From: crisnicandrei <62384997+crisnicandrei@users.noreply.github.com> Date: Fri, 16 May 2025 19:20:31 +0300 Subject: [PATCH] PER-10200 Web app display error on multi part uploads Fix response from multi part upload --- src/app/core/services/upload/uploader.spec.ts | 62 +++++++++++++++++++ src/app/core/services/upload/uploader.ts | 7 +-- src/app/shared/services/api/record.repo.ts | 34 +++++----- 3 files changed, 83 insertions(+), 20 deletions(-) diff --git a/src/app/core/services/upload/uploader.spec.ts b/src/app/core/services/upload/uploader.spec.ts index 1a49a2bcf..dfd92c255 100644 --- a/src/app/core/services/upload/uploader.spec.ts +++ b/src/app/core/services/upload/uploader.spec.ts @@ -10,10 +10,17 @@ class MockApiService { public static gotPresigned: boolean = false; public static registeredRecord: RecordVO = null; public static registeredDestination: string = null; + public static multipartRegistered: { + record: RecordVO; + uploadId: string; + key: string; + eTags: string[]; + } = null; public static reset() { MockApiService.gotPresigned = false; MockApiService.registeredRecord = null; MockApiService.registeredDestination = null; + MockApiService.multipartRegistered = null; } public record = { async registerRecord(record: RecordVO, url: string) { @@ -53,6 +60,30 @@ class MockApiService { ], }); }, + + async getMultipartUploadURLs(size: number) { + const partSize = 10 * 1024 * 1024; + const partCount = Math.ceil(size / partSize); + return { + urls: Array(partCount) + .fill(null) + .map((_, i) => `multipart-url-${i}`), + uploadId: 'test-upload-id', + key: 'test-file-key', + }; + }, + async registerMultipartRecord( + record: RecordVO, + uploadId: string, + key: string, + eTags: string[], + ) { + MockApiService.multipartRegistered = { record, uploadId, key, eTags }; + return new RecordVO({ + displayName: 'multipart.txt', + parentFolderId: record.parentFolderId, + }); + }, }; } @@ -97,4 +128,35 @@ describe('Uploader', () => { expect(MockApiService.registeredRecord.parentFolderId).toBe(1); expect(MockApiService.registeredDestination).toBe('testurl'); }); + + it('can do a multipart upload using MockApiService', async () => { + const file = new File([new Uint8Array(200 * 1024 * 1024)], 'multipart.txt'); + const uploadItem = new UploadItem( + file, + new FolderVO({ folderId: 2, folder_linkId: 2 }), + ); + + const progressSpy = jasmine.createSpy(); + + spyOn(uploader, 'uploadToMultipartUrl').and.callFake( + async ( + _url: string, + _item: UploadItem, + _pointer: number, + eTags: string[], + ) => { + eTags.push('etag-mock'); + }, + ); + + const result = await (uploader as any).uploadMultipart( + uploadItem, + progressSpy, + ); + + expect(MockApiService.multipartRegistered.record.parentFolderId).toBe(2); + expect(MockApiService.multipartRegistered.eTags.length).toBe(20); + expect(progressSpy).toHaveBeenCalled(); + expect(result.displayName).toBe('multipart.txt'); + }); }); diff --git a/src/app/core/services/upload/uploader.ts b/src/app/core/services/upload/uploader.ts index 04fada53e..ac855ce7e 100644 --- a/src/app/core/services/upload/uploader.ts +++ b/src/app/core/services/upload/uploader.ts @@ -3,6 +3,7 @@ import { HttpClient, HttpEvent, HttpEventType } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { ApiService } from '@shared/services/api/api.service'; import { EventService } from '@shared/services/event/event.service'; +import { RecordVO } from '@models/index'; import { UploadItem } from './uploadItem'; const buildForm = (fields: object, file: File) => { @@ -125,22 +126,20 @@ export class Uploader { emitProgress(progress); } - const response = await this.api.record.registerMultipartRecord( + const record = await this.api.record.registerMultipartRecord( item.RecordVO, uploadId, key, eTags, ); - const record = response.getRecordVO(); - this.event.dispatch({ action: 'submit', entity: 'record', record, }); - return response; + return record; }; async uploadFile( diff --git a/src/app/shared/services/api/record.repo.ts b/src/app/shared/services/api/record.repo.ts index 4b114df74..9ff253c2a 100644 --- a/src/app/shared/services/api/record.repo.ts +++ b/src/app/shared/services/api/record.repo.ts @@ -138,23 +138,25 @@ export class RecordRepo extends BaseRepo { uploadId: string, key: string, eTags: string[], - ): Promise { + ): Promise { + const body = { + displayName: record.displayName, + parentFolderId: record.parentFolderId, + uploadFileName: record.uploadFileName, + size: record.size, + multipartUploadData: { + uploadId, + key, + parts: eTags.map((ETag, index) => ({ + PartNumber: index + 1, + ETag, + })), + }, + }; + return getFirst( - this.httpV2.post('/record/registerRecord', { - displayName: record.displayName, - parentFolderId: record.parentFolderId, - uploadFileName: record.uploadFileName, - size: record.size, - multipartUploadData: { - uploadId, - key, - parts: eTags.map((ETag, index) => ({ - PartNumber: index + 1, - ETag, - })), - }, - }), - ).toPromise() as unknown as RecordResponse; + this.httpV2.post('/record/registerRecord', body), + ).toPromise(); } public async update(recordVOs: RecordVO[], archiveId: number) {