Files
Sauci/apps/api/test/media.routes.test.ts
T
jjbrunton 006761d3b0 feat(backend): add standalone data plane
Replace the Supabase application data plane with the Node/PostgreSQL API, migrate mobile, admin, web, and MCP callers, add controlled cutover tooling, and define hardened Dokploy infrastructure.
2026-08-28 14:42:11 +01:00

30 lines
1.8 KiB
TypeScript

import { Hono } from 'hono';
import { describe, expect, it, vi } from 'vitest';
import type { AuthIdentity } from '../src/auth.js';
import { MediaError, type MediaRepository } from '../src/domains/media/repository.js';
import { registerMediaRoutes } from '../src/domains/media/routes.js';
import type { FilesystemMediaStorage } from '../src/domains/media/storage.js';
const identity: AuthIdentity={id:'11111111-1111-4111-8111-111111111111',email:'u@example.com',name:null,avatarUrl:null};
function app(repository: Partial<MediaRepository>, storage: Partial<FilesystemMediaStorage>) {
const api=new Hono<{Variables:{identity:AuthIdentity}}>(); api.use('*',async(c,next)=>{c.set('identity',identity);await next();});
registerMediaRoutes(api,repository as MediaRepository,storage as FilesystemMediaStorage); return api;
}
describe('media routes',()=>{
it('requires a supported content type before reading the body',async()=>{
const api=app({}, {validate:vi.fn(()=>{throw new Error('unsupported_media_type');})});
const response=await api.request('/v1/media/avatar',{method:'POST',headers:{'content-type':'text/html'},body:'bad'});
expect(response.status).toBe(415);
});
it('does not issue a URL when repository authorization fails',async()=>{
const signedUrl=vi.fn(); const api=app({accessible:vi.fn(async()=>{throw new MediaError('media_not_found','Media not found',404);})},{signedUrl});
const response=await api.request('/v1/media/22222222-2222-4222-8222-222222222222/url');
expect(response.status).toBe(404); expect(signedUrl).not.toHaveBeenCalled();
});
it('rejects unsigned content reads',async()=>{
const api=app({}, {verify:vi.fn(()=>false)});
const response=await api.request('/media/22222222-2222-4222-8222-222222222222/content?expires=1&signature=no');
expect(response.status).toBe(403);
});
});