b3a7f98e5a
CI / E2E Cloudflare (4/8) (push) Failing after 0s
CI / E2E Cloudflare (8/8) (push) Failing after 1s
CI / Lint (push) Failing after 1s
Auto Extract / Extract (push) Failing after 4s
CI / Version Check (push) Failing after 9s
CI / Integration Tests (push) Failing after 1s
CI / E2E tests (1/8) (push) Failing after 1s
CI / E2E tests (2/8) (push) Failing after 2s
CI / E2E tests (3/8) (push) Failing after 2s
CI / Browser Tests (push) Failing after 1s
CI / E2E tests (5/8) (push) Failing after 1s
CI / E2E Cloudflare (2/8) (push) Failing after 2s
CI / Typecheck (push) Failing after 1s
CI / Changeset Validation (push) Failing after 2s
CI / E2E Cloudflare (5/8) (push) Failing after 1s
CI / E2E Cloudflare (6/8) (push) Failing after 1s
CI / E2E Cloudflare (7/8) (push) Failing after 1s
CodeQL / Analyze (javascript-typescript) (push) Failing after 1s
Format / Format (push) Failing after 0s
CodeQL / Analyze (actions) (push) Failing after 4s
CI / E2E tests (4/8) (push) Failing after 1s
CI / E2E tests (6/8) (push) Failing after 1s
CI / E2E tests (7/8) (push) Failing after 2s
CI / E2E tests (8/8) (push) Failing after 1s
CI / E2E Cloudflare (1/8) (push) Failing after 1s
CI / E2E Cloudflare (3/8) (push) Failing after 2s
Preview Releases / Publish Preview (push) Failing after 0s
zizmor / Run zizmor (push) Failing after 1s
Release / Release (push) Failing after 2s
CI / Smoke Tests (push) Failing after 5m36s
CI / Tests (push) Failing after 6m36s
Release / Sync Templates (push) Has been skipped
CI / E2E Tests (push) Has been cancelled
86 lines
2.5 KiB
TypeScript
86 lines
2.5 KiB
TypeScript
import type { Kysely } from "kysely";
|
|
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
|
|
import { MediaRepository } from "../../../src/database/repositories/media.js";
|
|
import type { Database } from "../../../src/database/types.js";
|
|
import { createMediaAccessWithWrite } from "../../../src/plugins/context.js";
|
|
import type { Storage } from "../../../src/storage/types.js";
|
|
import { JPEG_4x4 } from "../../utils/image-fixtures.js";
|
|
import { setupTestDatabase, teardownTestDatabase } from "../../utils/test-db.js";
|
|
|
|
function fakeStorage(): Storage {
|
|
const store = new Map<string, Uint8Array>();
|
|
return {
|
|
async upload(o) {
|
|
const b = o.body instanceof Uint8Array ? o.body : new Uint8Array(o.body as ArrayBuffer);
|
|
store.set(o.key, b);
|
|
return { key: o.key, url: `/m/${o.key}`, size: b.byteLength };
|
|
},
|
|
async download(key) {
|
|
const b = store.get(key) ?? new Uint8Array();
|
|
return {
|
|
body: new Response(b).body as ReadableStream<Uint8Array>,
|
|
contentType: "application/octet-stream",
|
|
size: b.byteLength,
|
|
};
|
|
},
|
|
async delete(key) {
|
|
store.delete(key);
|
|
},
|
|
async exists(key) {
|
|
return store.has(key);
|
|
},
|
|
async list() {
|
|
return { files: [] };
|
|
},
|
|
async getSignedUploadUrl(o) {
|
|
return {
|
|
url: `/s/${o.key}`,
|
|
method: "PUT",
|
|
headers: {},
|
|
expiresAt: new Date().toISOString(),
|
|
};
|
|
},
|
|
getPublicUrl(key) {
|
|
return `/m/${key}`;
|
|
},
|
|
};
|
|
}
|
|
|
|
describe("plugin ctx.media.upload — metadata enrichment", () => {
|
|
let db: Kysely<Database>;
|
|
|
|
beforeEach(async () => {
|
|
db = await setupTestDatabase();
|
|
});
|
|
|
|
afterEach(async () => {
|
|
await teardownTestDatabase(db);
|
|
});
|
|
|
|
it("populates width, height, blurhash and dominantColor for an image upload", async () => {
|
|
const media = createMediaAccessWithWrite(db, undefined, fakeStorage());
|
|
const ab = JPEG_4x4.slice().buffer; // clean ArrayBuffer copy
|
|
const result = await media.upload("derived.jpg", "image/jpeg", ab);
|
|
|
|
const row = await new MediaRepository(db).findById(result.mediaId);
|
|
expect(row?.width).toBe(4);
|
|
expect(row?.height).toBe(4);
|
|
expect(row?.blurhash).toBeTruthy();
|
|
expect(row?.dominantColor).toMatch(/^rgb\(/);
|
|
});
|
|
|
|
it("leaves metadata null for a non-image upload without throwing", async () => {
|
|
const media = createMediaAccessWithWrite(db, undefined, fakeStorage());
|
|
const result = await media.upload(
|
|
"data.bin",
|
|
"application/octet-stream",
|
|
new Uint8Array([1, 2, 3, 4]).buffer,
|
|
);
|
|
|
|
const row = await new MediaRepository(db).findById(result.mediaId);
|
|
expect(row?.width).toBeNull();
|
|
expect(row?.blurhash).toBeNull();
|
|
});
|
|
});
|