openreader/tests/unit/audiobooks-blobstore.vitest.spec.ts
Richard R aa7700e844 refactor(core): improve streaming, validation, and rate limit logic
- Stream request body in blob upload fallback route to enforce size limits
  without buffering entire payload
- Enhance admin provider panel error handling for multi-status responses
- Adjust positive integer validation to require value >= 1
- Use full rate limit config for job event recording and prune by largest window
- Fix PDF layout job event userId usage in docx-to-pdf upload route
- Add missing windows array fallback in documents register route
- Minor CI workflow and env example corrections
- Update audiobooks blobstore test to use beforeAll directly

These changes improve efficiency, correctness, and maintainability across API, admin, rate limiting, and test modules.
2026-05-30 16:41:17 -06:00

52 lines
2.1 KiB
TypeScript

import { beforeAll, describe, expect, test } from 'vitest';
import {
audiobookKey,
audiobookPrefix,
isMissingBlobError,
isPreconditionFailed,
} from '../../src/lib/server/audiobooks/blobstore';
function configureS3Env() {
process.env.S3_BUCKET = process.env.S3_BUCKET || 'test-bucket';
process.env.S3_REGION = process.env.S3_REGION || 'us-east-1';
process.env.S3_ACCESS_KEY_ID = process.env.S3_ACCESS_KEY_ID || 'test-access';
process.env.S3_SECRET_ACCESS_KEY = process.env.S3_SECRET_ACCESS_KEY || 'test-secret';
process.env.S3_PREFIX = 'openreader-test';
}
describe('audiobooks-blobstore', () => {
beforeAll(() => {
configureS3Env();
});
test('builds audiobook prefix with namespace', () => {
const prefix = audiobookPrefix('book-123', 'user-abc', 'worker1');
expect(prefix).toBe('openreader-test/audiobooks_v1/ns/worker1/users/user-abc/book-123-audiobook/');
});
test('builds audiobook prefix without namespace', () => {
const prefix = audiobookPrefix('book-123', 'unclaimed', null);
expect(prefix).toBe('openreader-test/audiobooks_v1/users/unclaimed/book-123-audiobook/');
});
test('builds key for chapter file', () => {
const key = audiobookKey('book-123', 'user-abc', '0001__Chapter%201.mp3', null);
expect(key).toBe('openreader-test/audiobooks_v1/users/user-abc/book-123-audiobook/0001__Chapter%201.mp3');
});
test('rejects invalid file names in keys', () => {
expect(() => audiobookKey('book-123', 'user-abc', '../bad.mp3', null)).toThrow(/Invalid audiobook file name/);
});
test('detects missing blob errors', () => {
expect(isMissingBlobError({ name: 'NoSuchKey' })).toBeTruthy();
expect(isMissingBlobError({ $metadata: { httpStatusCode: 404 } })).toBeTruthy();
expect(isMissingBlobError({ name: 'AccessDenied' })).toBeFalsy();
});
test('detects precondition failed errors', () => {
expect(isPreconditionFailed({ name: 'PreconditionFailed' })).toBeTruthy();
expect(isPreconditionFailed({ $metadata: { httpStatusCode: 412 } })).toBeTruthy();
expect(isPreconditionFailed({ $metadata: { httpStatusCode: 409 } })).toBeFalsy();
});
});