import { describe, expect, it } from 'bun:test';
describe('S3 XML Builders', () => {
it('builds ListBuckets XML', async () => {
const xml = await import('../src/interfaces/s3/xml');
const result = xml.listBucketsXml(
[{ name: 'test-bucket', createdAt: new Date('2026-01-01T00:00:00Z') }],
'req-1',
);
expect(result).toContain('test-bucket');
expect(result).toContain('2026-01-01T00:00:00Z');
});
it('builds escaped ListBucketResult XML', async () => {
const xml = await import('../src/interfaces/s3/xml');
const result = xml.listBucketResultXml(
'my-bucket',
[
{
key: 'folder/a&b.txt',
sizeBytes: 100,
etag: 'abc',
lastModified: new Date('2026-01-01T00:00:00Z'),
mimeType: 'text/plain',
},
],
['photos/'],
false,
null,
1000,
'',
'/',
null,
'req-1',
);
expect(result).toContain('folder/a&b.txt');
expect(result).toContain('100');
expect(result).toContain('photos/');
});
it('builds ListBucketV2 XML', async () => {
const xml = await import('../src/interfaces/s3/xml');
const result = xml.listBucketV2ResultXml(
'my-bucket',
[
{
key: 'a.txt',
sizeBytes: 50,
etag: 'def',
lastModified: new Date('2026-01-01T00:00:00Z'),
mimeType: 'text/plain',
},
],
[],
false,
1000,
'',
null,
null,
null,
1,
'req-2',
);
expect(result).toContain('1');
expect(result).toContain('a.txt');
});
it('builds multipart and copy XML responses', async () => {
const xml = await import('../src/interfaces/s3/xml');
expect(xml.initiateMultipartUploadXml('bucket', 'key', 'upload-123')).toContain(
'upload-123',
);
expect(
xml.completeMultipartUploadXml('bucket', 'key', 'etag-abc', 'http://localhost/bucket/key'),
).toContain(' {
const xml = await import('../src/interfaces/s3/xml');
const result = xml.s3ErrorXml(
'NoSuchBucket',
'The specified bucket does not exist',
'/bucket',
'req-1',
);
expect(result).toContain('NoSuchBucket');
expect(result).toContain('req-1');
const res = xml.s3ErrorResponse('NoSuchBucket', 'Missing', '/bucket', 404, 'req-2');
expect(res.status).toBe(404);
expect(res.headers.get('x-amz-request-id')).toBe('req-2');
});
it('parses DeleteObjects body', async () => {
const xml = await import('../src/interfaces/s3/xml');
const body =
'true';
const { keys, quiet } = xml.parseDeleteObjectsBody(body);
expect(keys).toEqual(['file1.txt', 'file2.txt']);
expect(quiet).toBe(true);
});
it('parses CompleteMultipartUpload body', async () => {
const xml = await import('../src/interfaces/s3/xml');
const body =
'1"abc"2"def"';
const parts = xml.parseCompleteMultipartBody(body);
expect(parts).toEqual([
{ partNumber: 1, etag: 'abc' },
{ partNumber: 2, etag: 'def' },
]);
});
});