feat: complete TASK-WP4-03 text templates
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
import { randomUUID } from "node:crypto";
|
||||
import { mkdtempSync, rmSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
|
||||
import { createApp } from "../../apps/api/src/app.js";
|
||||
import { RecentAssetService } from "../../apps/api/src/recent-assets.js";
|
||||
import { RegistrationService } from "../../apps/api/src/registration.js";
|
||||
import { MockResendAdapter } from "../../apps/api/src/resend-adapter.js";
|
||||
|
||||
const now = Date.parse("2026-08-03T03:00:00.000Z");
|
||||
const headers = { host: "127.0.0.1:43121", origin: "http://127.0.0.1:43121" };
|
||||
const roots: string[] = [];
|
||||
const registrations: RegistrationService[] = [];
|
||||
|
||||
function harness() {
|
||||
const root = mkdtempSync(join(tmpdir(), "dada-wp4-03-api-"));
|
||||
roots.push(root);
|
||||
const registration = new RegistrationService({
|
||||
challengePepper: Buffer.alloc(32, 0x31), clock: () => now,
|
||||
currentPrivacyNoticeVersion: "p0a-registration-notice-v1", databasePath: join(root, "dada.sqlite3"),
|
||||
invitePepper: Buffer.alloc(32, 0x32), resend: new MockResendAdapter(), sessionPepper: Buffer.alloc(32, 0x33),
|
||||
});
|
||||
registrations.push(registration);
|
||||
const userId = randomUUID();
|
||||
registration.database.prepare(`
|
||||
INSERT INTO users (user_id, normalized_email, role, status, counts_toward_stage_limit, registration_id, created_at)
|
||||
VALUES (?, 'recent@example.invalid', 'user', 'active', 1, ?, ?)
|
||||
`).run(userId, randomUUID(), now);
|
||||
registration.database.prepare("INSERT INTO user_profiles (user_id, creator_name, social_id) VALUES (?, 'Recent User', '@recent_user')").run(userId);
|
||||
registration.database.prepare("INSERT INTO credit_accounts (user_id, available_balance, reserved_balance, updated_at) VALUES (?, 10, 0, ?)").run(userId, now);
|
||||
const session = registration.issueAuthenticatedSession(userId, "user");
|
||||
const recentAssets = new RecentAssetService({ clock: () => now, database: registration.database });
|
||||
return { recentAssets, registration, session, userId };
|
||||
}
|
||||
|
||||
afterEach(() => {
|
||||
for (const registration of registrations.splice(0)) registration.close();
|
||||
for (const root of roots.splice(0)) rmSync(root, { force: true, recursive: true });
|
||||
});
|
||||
|
||||
describe("TASK-WP4-03 recent asset API", () => {
|
||||
it("records and returns only the current account's successfully used text template", async () => {
|
||||
const fixture = harness();
|
||||
const app = await createApp({
|
||||
browserGate: false, networkBoundary: { allowTestPort: true }, recentAssets: fixture.recentAssets, registration: fixture.registration,
|
||||
});
|
||||
const cookie = `dada_session=${fixture.session.sessionToken}`;
|
||||
const session = await app.inject({ headers: { ...headers, cookie }, method: "GET", url: "/api/v1/auth/session" });
|
||||
const csrf = session.json().csrf_token;
|
||||
const before = await app.inject({ headers: { ...headers, cookie }, method: "GET", url: "/api/v1/assets/recent?asset_kind=text_template" });
|
||||
expect(before.statusCode).toBe(200);
|
||||
expect(before.json()).toEqual({ items: [] });
|
||||
|
||||
const record = await app.inject({
|
||||
headers: { ...headers, cookie, "x-csrf-token": csrf }, method: "POST",
|
||||
payload: { asset_id: "FLOWER001", asset_kind: "text_template", resource_version: "wp4-fixture-v1" },
|
||||
url: "/api/v1/assets/recent",
|
||||
});
|
||||
expect(record.statusCode).toBe(200);
|
||||
expect(record.json()).toEqual({ status: "recorded" });
|
||||
const after = await app.inject({ headers: { ...headers, cookie }, method: "GET", url: "/api/v1/assets/recent?asset_kind=text_template" });
|
||||
expect(after.json()).toEqual({ items: [{ asset_id: "FLOWER001", asset_kind: "text_template", resource_version: "wp4-fixture-v1" }] });
|
||||
expect(fixture.recentAssets.list(randomUUID(), "text_template")).toEqual([]);
|
||||
await app.close();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user