T-HUB/apps/api/src/storage/storage.integration.test.ts
glass beadian aa5e262f3a Tactical Media Broadcast Hub — initial release
Self-hosted multi-platform broadcast newsroom for activist collectives:
publishing pipeline with group approval and DST-proof scheduling, TweetDeck-style
column wall with hostile-content-safe rendering, live control room with Auto
Director, bridged chat governance with polls and quorum, distributed sandboxed
transcode workers, encrypted content-addressed archive, monthly analytics.

MIT licensed. See README.md and docs/.
2026-10-10 11:56:42 +00:00

60 lines
2.4 KiB
TypeScript

import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { S3Storage } from "./storage.js";
/**
* Live roundtrip against any S3-compatible endpoint (S3_ENDPOINT env;
* dev = MinIO from infra compose). Skipped without env — the pure key-scheme
* suite in storage.test.ts always runs.
*/
const cfg = process.env.S3_ENDPOINT;
describe.skipIf(cfg === undefined)("S3 storage (live endpoint)", () => {
let storage: S3Storage;
beforeAll(() => {
storage = new S3Storage({
endpoint: cfg,
region: process.env.S3_REGION ?? "us-east-1",
accessKeyId: process.env.S3_ACCESS_KEY ?? "tactical-media-broadcast-hub",
secretAccessKey: process.env.S3_SECRET_KEY ?? "tactical-media-broadcast-hub_dev",
bucket: process.env.S3_BUCKET ?? "tactical-media-broadcast-hub-media-test",
});
});
afterAll(async () => {
// bucket intentionally retained for inspection; content is content-addressed test bytes
void storage;
});
it("put → get roundtrips bytes", async () => {
const payload = Buffer.from(`qa-roundtrip-${Date.now()}`);
const stored = await storage.putContent(payload, "image/png");
expect(stored.deduplicated).toBe(false);
const back = await storage.getObject(stored.key);
expect(back.equals(payload)).toBe(true);
});
it("identical bytes deduplicate (second put is a no-op)", async () => {
const payload = Buffer.from("dedupe-me-identical");
const first = await storage.putContent(payload, "video/mp4");
const second = await storage.putContent(Buffer.from("dedupe-me-identical"), "video/mp4");
expect(first.deduplicated).toBe(false);
expect(second.deduplicated).toBe(true);
expect(second.key).toBe(first.key);
expect(await storage.hasContent(second.hash, "video/mp4")).toBe(true);
});
it("same bytes, different content-type land on different keys", async () => {
const payload = Buffer.from("multi-format");
const asPng = await storage.putContent(payload, "image/png");
const asMp4 = await storage.putContent(payload, "video/mp4");
expect(asPng.key).not.toBe(asMp4.key);
});
it("presigns a GET url", async () => {
const stored = await storage.putContent(Buffer.from("presign-me"), "image/png");
const url = await storage.presign(stored.key, 60);
expect(url).toContain(encodeURIComponent(stored.key).split("%2F")[1] ?? stored.key.slice(7));
expect(url.startsWith("http")).toBe(true);
});
});