97 lines
3.5 KiB
TypeScript
97 lines
3.5 KiB
TypeScript
import { it, expect, beforeEach, describe } from "vitest";
|
|
import { defineContractSuite } from "@repo/core-testing/contract";
|
|
import type { IMediaRepository } from "../application/repositories/media.repository.interface.js";
|
|
import { mediaFactory } from "../__factories__/media.factory.js";
|
|
|
|
export const mediaRepositoryContract =
|
|
defineContractSuite<IMediaRepository>(
|
|
"IMediaRepository",
|
|
({ buildSubject, getTracer }) => {
|
|
let repo: IMediaRepository;
|
|
|
|
beforeEach(async () => {
|
|
mediaFactory.reset();
|
|
repo = await buildSubject();
|
|
});
|
|
|
|
// --- getMedia ---
|
|
|
|
it("getMedia returns undefined for a missing id", async () => {
|
|
const result = await repo.getMedia("does-not-exist");
|
|
expect(result).toBeUndefined();
|
|
});
|
|
|
|
// --- listMedia ---
|
|
|
|
it("listMedia returns empty array when no media exists", async () => {
|
|
const result = await repo.listMedia();
|
|
expect(result).toHaveLength(0);
|
|
});
|
|
|
|
// --- deleteMedia ---
|
|
|
|
it("deleteMedia removes the item so getMedia returns undefined", async () => {
|
|
const seed = mediaFactory.build({ id: "contract-1" });
|
|
// @ts-expect-error _store is a test helper on MockMediaRepository
|
|
if (typeof repo._store === "function") {
|
|
// @ts-expect-error _store is a test helper
|
|
await repo._store(seed);
|
|
}
|
|
await repo.deleteMedia("contract-1");
|
|
const result = await repo.getMedia("contract-1");
|
|
expect(result).toBeUndefined();
|
|
});
|
|
|
|
it("listMedia with limit returns at most limit items", async () => {
|
|
// Only verifiable on mock; for real impl this checks the interface
|
|
const result = await repo.listMedia({ limit: 0 });
|
|
expect(Array.isArray(result)).toBe(true);
|
|
});
|
|
|
|
it("listMedia with offset skips items", async () => {
|
|
const result = await repo.listMedia({ offset: 100 });
|
|
expect(Array.isArray(result)).toBe(true);
|
|
});
|
|
|
|
it("getMedia returns undefined for empty string id", async () => {
|
|
const result = await repo.getMedia("");
|
|
expect(result).toBeUndefined();
|
|
});
|
|
|
|
describe("span emission (R50)", () => {
|
|
it("getMedia emits media.getMedia span with id attribute", async () => {
|
|
if (!getTracer) return;
|
|
const tracer = getTracer();
|
|
tracer.reset();
|
|
await repo.getMedia("nonexistent");
|
|
const span = tracer.findSpan("media.getMedia");
|
|
expect(span).toBeDefined();
|
|
expect(span!.op).toBe("repository");
|
|
expect(span!.attributes.id).toBe("nonexistent");
|
|
});
|
|
|
|
it("listMedia emits media.listMedia span with op=repository", async () => {
|
|
if (!getTracer) return;
|
|
const tracer = getTracer();
|
|
tracer.reset();
|
|
await repo.listMedia({ limit: 10 });
|
|
const span = tracer.findSpan("media.listMedia");
|
|
expect(span).toBeDefined();
|
|
expect(span!.op).toBe("repository");
|
|
expect(span!.attributes.limit).toBe(10);
|
|
});
|
|
|
|
it("deleteMedia emits media.deleteMedia span with id attribute", async () => {
|
|
if (!getTracer) return;
|
|
const tracer = getTracer();
|
|
tracer.reset();
|
|
await repo.deleteMedia("nonexistent");
|
|
const span = tracer.findSpan("media.deleteMedia");
|
|
expect(span).toBeDefined();
|
|
expect(span!.op).toBe("repository");
|
|
expect(span!.attributes.id).toBe("nonexistent");
|
|
});
|
|
});
|
|
},
|
|
);
|