import { describe, expect, it } from 'bun:test'; describe('S3 XML Builders', () => { it('builds ListBuckets XML', async () => { const xml = await import('../src/utils/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/utils/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/utils/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/utils/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/utils/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/utils/s3/xml'); const body = 'file1.txtfile2.txttrue'; 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/utils/s3/xml'); const body = '1"abc"2"def"'; const parts = xml.parseCompleteMultipartBody(body); expect(parts).toEqual([ { partNumber: 1, etag: 'abc' }, { partNumber: 2, etag: 'def' }, ]); }); });