import { assertEquals, assertExists } from 'jsr:@std/assert'; import { afterAll, beforeAll, describe, it } from 'jsr:@std/testing/bdd'; import { TypedRequest } from '@api.global/typedrequest'; import { createTestContainer, getTestPorts, loginAndGetIdentity } from './helpers/server.helper.ts'; import { ObjectStorageContainer } from '../ts/index.ts'; import type * as interfaces from '../ts_interfaces/index.ts'; import type { IReq_ListBuckets, IReq_CreateBucket, IReq_DeleteBucket, IReq_GetBucketPolicy, IReq_PutBucketPolicy, IReq_DeleteBucketPolicy, } from '../ts_interfaces/requests/buckets.ts'; const PORT_INDEX = 2; const ports = getTestPorts(PORT_INDEX); const url = `http://localhost:${ports.uiPort}/typedrequest`; describe('Bucket management', { sanitizeResources: false, sanitizeOps: false }, () => { let container: ObjectStorageContainer; let identity: interfaces.data.IIdentity; beforeAll(async () => { container = createTestContainer(PORT_INDEX); await container.start(); identity = await loginAndGetIdentity(ports.uiPort); }); afterAll(async () => { await container.stop(); }); it('should list buckets (initially empty)', async () => { const req = new TypedRequest(url, 'listBuckets'); const response = await req.fire({ identity }); assertEquals(response.buckets.length, 0); }); it('should create a bucket', async () => { const req = new TypedRequest(url, 'createBucket'); const response = await req.fire({ identity, bucketName: 'test-bucket-1' }); assertEquals(response.ok, true); }); it('should create a second bucket', async () => { const req = new TypedRequest(url, 'createBucket'); const response = await req.fire({ identity, bucketName: 'test-bucket-2' }); assertEquals(response.ok, true); }); it('should list both buckets', async () => { const req = new TypedRequest(url, 'listBuckets'); const response = await req.fire({ identity }); assertEquals(response.buckets.length, 2); const names = response.buckets.map((b) => b.name).sort(); assertEquals(names, ['test-bucket-1', 'test-bucket-2']); }); it('should have valid bucket metadata', async () => { const req = new TypedRequest(url, 'listBuckets'); const response = await req.fire({ identity }); for (const bucket of response.buckets) { assertEquals(bucket.objectCount, 0); assertEquals(bucket.totalSizeBytes, 0); assertEquals(bucket.creationDate > 0, true); } }); it('should delete a bucket', async () => { const req = new TypedRequest(url, 'deleteBucket'); const response = await req.fire({ identity, bucketName: 'test-bucket-2' }); assertEquals(response.ok, true); }); it('should list one remaining bucket', async () => { const req = new TypedRequest(url, 'listBuckets'); const response = await req.fire({ identity }); assertEquals(response.buckets.length, 1); assertEquals(response.buckets[0].name, 'test-bucket-1'); }); it('should get bucket policy (initially null)', async () => { const req = new TypedRequest(url, 'getBucketPolicy'); const response = await req.fire({ identity, bucketName: 'test-bucket-1' }); assertEquals(response.policy, null); }); it('should put a bucket policy', async () => { const policy = JSON.stringify({ Version: '2012-10-17', Statement: [ { Sid: 'PublicRead', Effect: 'Allow', Principal: '*', Action: 's3:GetObject', Resource: 'arn:aws:s3:::test-bucket-1/*', }, ], }); const req = new TypedRequest(url, 'putBucketPolicy'); const response = await req.fire({ identity, bucketName: 'test-bucket-1', policy }); assertEquals(response.ok, true); }); it('should get the bucket policy back', async () => { const req = new TypedRequest(url, 'getBucketPolicy'); const response = await req.fire({ identity, bucketName: 'test-bucket-1' }); assertExists(response.policy); const parsed = JSON.parse(response.policy!); assertExists(parsed.Statement); assertEquals(parsed.Statement[0].Sid, 'PublicRead'); }); it('should delete bucket policy', async () => { const req = new TypedRequest(url, 'deleteBucketPolicy'); const response = await req.fire({ identity, bucketName: 'test-bucket-1' }); assertEquals(response.ok, true); }); it('should confirm policy is deleted', async () => { const req = new TypedRequest(url, 'getBucketPolicy'); const response = await req.fire({ identity, bucketName: 'test-bucket-1' }); assertEquals(response.policy, null); }); it('cleanup: delete remaining bucket', async () => { const req = new TypedRequest(url, 'deleteBucket'); const response = await req.fire({ identity, bucketName: 'test-bucket-1' }); assertEquals(response.ok, true); }); });