105 lines
3.4 KiB
TypeScript
105 lines
3.4 KiB
TypeScript
import { expect, tap } from '@git.zone/tstest/tapbundle';
|
|
import { S3Client, CreateBucketCommand, ListBucketsCommand, PutObjectCommand, GetObjectCommand, DeleteObjectCommand, DeleteBucketCommand } from '@aws-sdk/client-s3';
|
|
import { Readable } from 'stream';
|
|
import * as smarts3 from '../ts/index.js';
|
|
|
|
let testSmarts3Instance: smarts3.Smarts3;
|
|
let s3Client: S3Client;
|
|
|
|
// Helper to convert stream to string
|
|
async function streamToString(stream: Readable): Promise<string> {
|
|
const chunks: Buffer[] = [];
|
|
return new Promise((resolve, reject) => {
|
|
stream.on('data', (chunk) => chunks.push(Buffer.from(chunk)));
|
|
stream.on('error', reject);
|
|
stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));
|
|
});
|
|
}
|
|
|
|
tap.test('should start the S3 server and configure client', async () => {
|
|
testSmarts3Instance = await smarts3.Smarts3.createAndStart({
|
|
port: 3337,
|
|
cleanSlate: true,
|
|
silent: true,
|
|
});
|
|
|
|
const descriptor = await testSmarts3Instance.getS3Descriptor();
|
|
|
|
s3Client = new S3Client({
|
|
endpoint: `http://${descriptor.endpoint}:${descriptor.port}`,
|
|
region: 'us-east-1',
|
|
credentials: {
|
|
accessKeyId: descriptor.accessKey,
|
|
secretAccessKey: descriptor.accessSecret,
|
|
},
|
|
forcePathStyle: true,
|
|
});
|
|
});
|
|
|
|
tap.test('should list buckets (empty)', async () => {
|
|
const response = await s3Client.send(new ListBucketsCommand({}));
|
|
expect(Array.isArray(response.Buckets)).toEqual(true);
|
|
expect(response.Buckets!.length).toEqual(0);
|
|
});
|
|
|
|
tap.test('should create a bucket', async () => {
|
|
const response = await s3Client.send(new CreateBucketCommand({ Bucket: 'test-bucket' }));
|
|
expect(response.$metadata.httpStatusCode).toEqual(200);
|
|
});
|
|
|
|
tap.test('should list buckets (showing created bucket)', async () => {
|
|
const response = await s3Client.send(new ListBucketsCommand({}));
|
|
expect(response.Buckets!.length).toEqual(1);
|
|
expect(response.Buckets![0].Name).toEqual('test-bucket');
|
|
});
|
|
|
|
tap.test('should upload an object', async () => {
|
|
const response = await s3Client.send(new PutObjectCommand({
|
|
Bucket: 'test-bucket',
|
|
Key: 'test-file.txt',
|
|
Body: 'Hello from AWS SDK!',
|
|
ContentType: 'text/plain',
|
|
}));
|
|
expect(response.$metadata.httpStatusCode).toEqual(200);
|
|
expect(response.ETag).toBeTypeofString();
|
|
});
|
|
|
|
tap.test('should download the object', async () => {
|
|
const response = await s3Client.send(new GetObjectCommand({
|
|
Bucket: 'test-bucket',
|
|
Key: 'test-file.txt',
|
|
}));
|
|
|
|
expect(response.$metadata.httpStatusCode).toEqual(200);
|
|
const content = await streamToString(response.Body as Readable);
|
|
expect(content).toEqual('Hello from AWS SDK!');
|
|
});
|
|
|
|
tap.test('should delete the object', async () => {
|
|
const response = await s3Client.send(new DeleteObjectCommand({
|
|
Bucket: 'test-bucket',
|
|
Key: 'test-file.txt',
|
|
}));
|
|
expect(response.$metadata.httpStatusCode).toEqual(204);
|
|
});
|
|
|
|
tap.test('should fail to get deleted object', async () => {
|
|
await expect(
|
|
s3Client.send(new GetObjectCommand({
|
|
Bucket: 'test-bucket',
|
|
Key: 'test-file.txt',
|
|
}))
|
|
).rejects.toThrow();
|
|
});
|
|
|
|
tap.test('should delete the bucket', async () => {
|
|
const response = await s3Client.send(new DeleteBucketCommand({ Bucket: 'test-bucket' }));
|
|
expect(response.$metadata.httpStatusCode).toEqual(204);
|
|
});
|
|
|
|
tap.test('should stop the S3 server', async () => {
|
|
await testSmarts3Instance.stop();
|
|
});
|
|
|
|
export default tap.start();
|