|
@@ -370,4 +370,239 @@ describe('AwsS3Multipart', () => {
|
|
|
expect(client[Symbol.for('uppy test: getCompanionHeaders')]().authorization).toEqual(newToken)
|
|
|
})
|
|
|
})
|
|
|
+
|
|
|
+ describe('file metadata across custom main functions', () => {
|
|
|
+ let core
|
|
|
+ const createMultipartUpload = jest.fn(file => {
|
|
|
+ core.setFileMeta(file.id, {
|
|
|
+ ...file.meta,
|
|
|
+ createMultipartUpload: true,
|
|
|
+ })
|
|
|
+
|
|
|
+ return {
|
|
|
+ uploadId: 'upload1234',
|
|
|
+ key: file.name,
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ const signPart = jest.fn((file, partData) => {
|
|
|
+ expect(file.meta.createMultipartUpload).toBe(true)
|
|
|
+
|
|
|
+ core.setFileMeta(file.id, {
|
|
|
+ ...file.meta,
|
|
|
+ signPart: true,
|
|
|
+ [`part${partData.partNumber}`]: partData.partNumber,
|
|
|
+ })
|
|
|
+
|
|
|
+ return {
|
|
|
+ url: `https://bucket.s3.us-east-2.amazonaws.com/test/upload/multitest.dat?partNumber=${partData.partNumber}&uploadId=6aeb1980f3fc7ce0b5454d25b71992&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIATEST%2F20210729%2Fus-east-2%2Fs3%2Faws4_request&X-Amz-Date=20210729T014044Z&X-Amz-Expires=600&X-Amz-SignedHeaders=host&X-Amz-Signature=test`,
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ const listParts = jest.fn((file) => {
|
|
|
+ expect(file.meta.createMultipartUpload).toBe(true)
|
|
|
+ core.setFileMeta(file.id, {
|
|
|
+ ...file.meta,
|
|
|
+ listParts: true,
|
|
|
+ })
|
|
|
+
|
|
|
+ const partKeys = Object.keys(file.meta).filter(metaKey => metaKey.startsWith('part'))
|
|
|
+ return partKeys.map(metaKey => ({
|
|
|
+ PartNumber: file.meta[metaKey],
|
|
|
+ ETag: metaKey,
|
|
|
+ Size: 5 * MB,
|
|
|
+ }))
|
|
|
+ })
|
|
|
+
|
|
|
+ const completeMultipartUpload = jest.fn((file) => {
|
|
|
+ expect(file.meta.createMultipartUpload).toBe(true)
|
|
|
+ expect(file.meta.signPart).toBe(true)
|
|
|
+ for (let i = 1; i <= 10; i++) {
|
|
|
+ expect(file.meta[`part${i}`]).toBe(i)
|
|
|
+ }
|
|
|
+ return {}
|
|
|
+ })
|
|
|
+
|
|
|
+ const abortMultipartUpload = jest.fn((file) => {
|
|
|
+ expect(file.meta.createMultipartUpload).toBe(true)
|
|
|
+ expect(file.meta.signPart).toBe(true)
|
|
|
+ expect(file.meta.abortingPart).toBe(5)
|
|
|
+ return {}
|
|
|
+ })
|
|
|
+
|
|
|
+ beforeEach(() => {
|
|
|
+ createMultipartUpload.mockClear()
|
|
|
+ signPart.mockClear()
|
|
|
+ listParts.mockClear()
|
|
|
+ abortMultipartUpload.mockClear()
|
|
|
+ completeMultipartUpload.mockClear()
|
|
|
+ })
|
|
|
+
|
|
|
+ it('preserves file metadata if upload is completed', async () => {
|
|
|
+ core = new Core()
|
|
|
+ .use(AwsS3Multipart, {
|
|
|
+ createMultipartUpload,
|
|
|
+ signPart,
|
|
|
+ listParts,
|
|
|
+ completeMultipartUpload,
|
|
|
+ abortMultipartUpload,
|
|
|
+ })
|
|
|
+
|
|
|
+ nock('https://bucket.s3.us-east-2.amazonaws.com')
|
|
|
+ .defaultReplyHeaders({
|
|
|
+ 'access-control-allow-headers': '*',
|
|
|
+ 'access-control-allow-method': 'PUT',
|
|
|
+ 'access-control-allow-origin': '*',
|
|
|
+ 'access-control-expose-headers': 'ETag',
|
|
|
+ })
|
|
|
+ .put((uri) => uri.includes('test/upload/multitest.dat'))
|
|
|
+ .reply(200, '', { ETag: 'test' })
|
|
|
+ .persist()
|
|
|
+
|
|
|
+ const fileSize = 50 * MB
|
|
|
+ core.addFile({
|
|
|
+ source: 'jest',
|
|
|
+ name: 'multitest.dat',
|
|
|
+ type: 'application/octet-stream',
|
|
|
+ data: new File([new Uint8Array(fileSize)], {
|
|
|
+ type: 'application/octet-stream',
|
|
|
+ }),
|
|
|
+ })
|
|
|
+
|
|
|
+ await core.upload()
|
|
|
+ expect(createMultipartUpload).toHaveBeenCalled()
|
|
|
+ expect(signPart).toHaveBeenCalledTimes(10)
|
|
|
+ expect(completeMultipartUpload).toHaveBeenCalled()
|
|
|
+ })
|
|
|
+
|
|
|
+ it('preserves file metadata if upload is aborted', async () => {
|
|
|
+ const signPartWithAbort = jest.fn((file, partData) => {
|
|
|
+ expect(file.meta.createMultipartUpload).toBe(true)
|
|
|
+ if (partData.partNumber === 5) {
|
|
|
+ core.setFileMeta(file.id, {
|
|
|
+ ...file.meta,
|
|
|
+ abortingPart: partData.partNumber,
|
|
|
+ })
|
|
|
+ core.removeFile(file.id)
|
|
|
+ return {}
|
|
|
+ }
|
|
|
+
|
|
|
+ core.setFileMeta(file.id, {
|
|
|
+ ...file.meta,
|
|
|
+ signPart: true,
|
|
|
+ [`part${partData.partNumber}`]: partData.partNumber,
|
|
|
+ })
|
|
|
+
|
|
|
+ return {
|
|
|
+ url: `https://bucket.s3.us-east-2.amazonaws.com/test/upload/multitest.dat?partNumber=${partData.partNumber}&uploadId=6aeb1980f3fc7ce0b5454d25b71992&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIATEST%2F20210729%2Fus-east-2%2Fs3%2Faws4_request&X-Amz-Date=20210729T014044Z&X-Amz-Expires=600&X-Amz-SignedHeaders=host&X-Amz-Signature=test`,
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ core = new Core()
|
|
|
+ .use(AwsS3Multipart, {
|
|
|
+ createMultipartUpload,
|
|
|
+ signPart: signPartWithAbort,
|
|
|
+ listParts,
|
|
|
+ completeMultipartUpload,
|
|
|
+ abortMultipartUpload,
|
|
|
+ })
|
|
|
+
|
|
|
+ nock('https://bucket.s3.us-east-2.amazonaws.com')
|
|
|
+ .defaultReplyHeaders({
|
|
|
+ 'access-control-allow-headers': '*',
|
|
|
+ 'access-control-allow-method': 'PUT',
|
|
|
+ 'access-control-allow-origin': '*',
|
|
|
+ 'access-control-expose-headers': 'ETag',
|
|
|
+ })
|
|
|
+ .put((uri) => uri.includes('test/upload/multitest.dat'))
|
|
|
+ .reply(200, '', { ETag: 'test' })
|
|
|
+ .persist()
|
|
|
+
|
|
|
+ const fileSize = 50 * MB
|
|
|
+ core.addFile({
|
|
|
+ source: 'jest',
|
|
|
+ name: 'multitest.dat',
|
|
|
+ type: 'application/octet-stream',
|
|
|
+ data: new File([new Uint8Array(fileSize)], {
|
|
|
+ type: 'application/octet-stream',
|
|
|
+ }),
|
|
|
+ })
|
|
|
+
|
|
|
+ await core.upload()
|
|
|
+ expect(createMultipartUpload).toHaveBeenCalled()
|
|
|
+ expect(signPartWithAbort).toHaveBeenCalled()
|
|
|
+ expect(abortMultipartUpload).toHaveBeenCalled()
|
|
|
+ })
|
|
|
+
|
|
|
+ it('preserves file metadata if upload is paused and resumed', async () => {
|
|
|
+ const completeMultipartUploadAfterPause = jest.fn((file) => {
|
|
|
+ expect(file.meta.createMultipartUpload).toBe(true)
|
|
|
+ expect(file.meta.signPart).toBe(true)
|
|
|
+ for (let i = 1; i <= 10; i++) {
|
|
|
+ expect(file.meta[`part${i}`]).toBe(i)
|
|
|
+ }
|
|
|
+
|
|
|
+ expect(file.meta.listParts).toBe(true)
|
|
|
+ return {}
|
|
|
+ })
|
|
|
+
|
|
|
+ const signPartWithPause = jest.fn((file, partData) => {
|
|
|
+ expect(file.meta.createMultipartUpload).toBe(true)
|
|
|
+ if (partData.partNumber === 3) {
|
|
|
+ core.setFileMeta(file.id, {
|
|
|
+ ...file.meta,
|
|
|
+ abortingPart: partData.partNumber,
|
|
|
+ })
|
|
|
+ core.pauseResume(file.id)
|
|
|
+ setTimeout(() => core.pauseResume(file.id), 500)
|
|
|
+ }
|
|
|
+
|
|
|
+ core.setFileMeta(file.id, {
|
|
|
+ ...file.meta,
|
|
|
+ signPart: true,
|
|
|
+ [`part${partData.partNumber}`]: partData.partNumber,
|
|
|
+ })
|
|
|
+
|
|
|
+ return {
|
|
|
+ url: `https://bucket.s3.us-east-2.amazonaws.com/test/upload/multitest.dat?partNumber=${partData.partNumber}&uploadId=6aeb1980f3fc7ce0b5454d25b71992&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIATEST%2F20210729%2Fus-east-2%2Fs3%2Faws4_request&X-Amz-Date=20210729T014044Z&X-Amz-Expires=600&X-Amz-SignedHeaders=host&X-Amz-Signature=test`,
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ core = new Core()
|
|
|
+ .use(AwsS3Multipart, {
|
|
|
+ createMultipartUpload,
|
|
|
+ signPart: signPartWithPause,
|
|
|
+ listParts,
|
|
|
+ completeMultipartUpload: completeMultipartUploadAfterPause,
|
|
|
+ abortMultipartUpload,
|
|
|
+ })
|
|
|
+
|
|
|
+ nock('https://bucket.s3.us-east-2.amazonaws.com')
|
|
|
+ .defaultReplyHeaders({
|
|
|
+ 'access-control-allow-headers': '*',
|
|
|
+ 'access-control-allow-method': 'PUT',
|
|
|
+ 'access-control-allow-origin': '*',
|
|
|
+ 'access-control-expose-headers': 'ETag',
|
|
|
+ })
|
|
|
+ .put((uri) => uri.includes('test/upload/multitest.dat'))
|
|
|
+ .reply(200, '', { ETag: 'test' })
|
|
|
+ .persist()
|
|
|
+
|
|
|
+ const fileSize = 50 * MB
|
|
|
+ core.addFile({
|
|
|
+ source: 'jest',
|
|
|
+ name: 'multitest.dat',
|
|
|
+ type: 'application/octet-stream',
|
|
|
+ data: new File([new Uint8Array(fileSize)], {
|
|
|
+ type: 'application/octet-stream',
|
|
|
+ }),
|
|
|
+ })
|
|
|
+
|
|
|
+ await core.upload()
|
|
|
+ expect(createMultipartUpload).toHaveBeenCalled()
|
|
|
+ expect(signPartWithPause).toHaveBeenCalled()
|
|
|
+ expect(listParts).toHaveBeenCalled()
|
|
|
+ expect(completeMultipartUploadAfterPause).toHaveBeenCalled()
|
|
|
+ })
|
|
|
+ })
|
|
|
})
|