test: enable strict AWS SDK multipart coverage
This commit is contained in:
+46
-13
@@ -19,8 +19,10 @@
|
||||
import { afterAll, describe, expect, it } from 'bun:test';
|
||||
import {
|
||||
AbortMultipartUploadCommand,
|
||||
CompleteMultipartUploadCommand,
|
||||
CopyObjectCommand,
|
||||
CreateBucketCommand,
|
||||
CreateMultipartUploadCommand,
|
||||
DeleteBucketCommand,
|
||||
DeleteObjectCommand,
|
||||
DeleteObjectsCommand,
|
||||
@@ -35,6 +37,7 @@ import {
|
||||
NotFound,
|
||||
PutObjectCommand,
|
||||
S3Client,
|
||||
UploadPartCommand,
|
||||
} from '@aws-sdk/client-s3';
|
||||
|
||||
// ── Config ───────────────────────────────────────────────────────────────────
|
||||
@@ -276,6 +279,49 @@ describe('S3 SDK compatibility', () => {
|
||||
}
|
||||
});
|
||||
|
||||
// ── Multipart upload ───────────────────────────────────────────────────────
|
||||
|
||||
it('Multipart upload works with AWS SDK under strict SigV4', async () => {
|
||||
let uploadId: string | undefined;
|
||||
try {
|
||||
const created = await s3.send(
|
||||
new CreateMultipartUploadCommand({ Bucket: BUCKET, Key: 'sdk-multipart.txt' }),
|
||||
);
|
||||
uploadId = created.UploadId;
|
||||
expect(uploadId).toBeTruthy();
|
||||
|
||||
const part1 = await s3.send(
|
||||
new UploadPartCommand({ Bucket: BUCKET, Key: 'sdk-multipart.txt', UploadId: uploadId, PartNumber: 1, Body: 'hello ' }),
|
||||
);
|
||||
const part2 = await s3.send(
|
||||
new UploadPartCommand({ Bucket: BUCKET, Key: 'sdk-multipart.txt', UploadId: uploadId, PartNumber: 2, Body: 'sdk multipart' }),
|
||||
);
|
||||
|
||||
await s3.send(
|
||||
new CompleteMultipartUploadCommand({
|
||||
Bucket: BUCKET,
|
||||
Key: 'sdk-multipart.txt',
|
||||
UploadId: uploadId,
|
||||
MultipartUpload: {
|
||||
Parts: [
|
||||
{ ETag: part1.ETag, PartNumber: 1 },
|
||||
{ ETag: part2.ETag, PartNumber: 2 },
|
||||
],
|
||||
},
|
||||
}),
|
||||
);
|
||||
uploadId = undefined;
|
||||
|
||||
const { Body } = await s3.send(new GetObjectCommand({ Bucket: BUCKET, Key: 'sdk-multipart.txt' }));
|
||||
expect(await Body!.transformToString()).toBe('hello sdk multipart');
|
||||
} finally {
|
||||
if (uploadId) {
|
||||
await s3.send(new AbortMultipartUploadCommand({ Bucket: BUCKET, Key: 'sdk-multipart.txt', UploadId: uploadId })).catch(() => {});
|
||||
}
|
||||
await s3.send(new DeleteObjectCommand({ Bucket: BUCKET, Key: 'sdk-multipart.txt' })).catch(() => {});
|
||||
}
|
||||
});
|
||||
|
||||
// ── Cleanup & delete bucket ────────────────────────────────────────────────
|
||||
|
||||
it('DeleteBucket succeeds for empty bucket', async () => {
|
||||
@@ -287,19 +333,6 @@ describe('S3 SDK compatibility', () => {
|
||||
createdBuckets = createdBuckets.filter((b) => b !== BUCKET);
|
||||
});
|
||||
|
||||
// ── Multipart upload (via manual signer — AWS SDK adds extra signed headers
|
||||
// that may differ from what the server receives through Cloudflare,
|
||||
// causing a 403 SignatureDoesNotMatch. Multipart is verified in
|
||||
// test/production-e2e.test.ts using a manual SigV4 signer.) ───────────────
|
||||
|
||||
it('Multipart upload — verified in production-e2e.test.ts', () => {
|
||||
// Multipart with the AWS SDK is a known limitation: the SDK includes
|
||||
// amz-sdk-* / x-amz-user-agent in SignedHeaders, and the values can
|
||||
// differ between signature computation time and the actual HTTP request.
|
||||
// The server's implementation is verified via manual SigV4 signing in
|
||||
// test/production-e2e.test.ts (S3 API > Multipart upload).
|
||||
});
|
||||
|
||||
// ── Error handling ─────────────────────────────────────────────────────────
|
||||
|
||||
it('NoSuchBucket error on non-existent bucket', async () => {
|
||||
|
||||
Reference in New Issue
Block a user