返回 DeepSeek-Reasonix
index.test.ts
根目录 / workers / forum / src / index.test.ts
1 import { describe, expect, it } from "vitest";
2 import app from "./index";
3 import type { Bindings } from "./env";
4
5 function bindings(db: D1Database): Bindings {
6 return {
7 DB: db,
8 APP_ORIGIN: "https://reasonix.io",
9 ALLOWED_ORIGINS: "https://reasonix.io",
10 ID_ORIGIN: "https://id.reasonix.io",
11 };
12 }
13
14 describe("forum public API", () => {
15 it("maps invalid query input to a client error", async () => {
16 const db = { prepare: () => { throw new Error("database should not be reached"); } } as unknown as D1Database;
17 const response = await app.request("https://forum.reasonix.io/topics?sort=invalid", {}, bindings(db));
18 expect(response.status).toBe(422);
19 await expect(response.json()).resolves.toMatchObject({ error: { code: "invalid_input" } });
20 });
21
22 it("selects public handles instead of stored author emails", async () => {
23 const queries: string[] = [];
24 const rows = [{
25 id: 1,
26 title: "Safe public topic",
27 slug: "safe-public-topic",
28 status: "open",
29 pinned: 0,
30 replyCount: 0,
31 viewCount: 0,
32 author: "alice",
33 createdAt: "2026-08-05T00:00:00.000Z",
34 lastPostAt: "2026-08-05T00:00:00.000Z",
35 category: "help",
36 categoryName: "Help & Support",
37 }];
38 const statement = {
39 bind() { return this; },
40 async all() { return { results: rows }; },
41 };
42 const db = {
43 prepare(query: string) {
44 queries.push(query);
45 return statement;
46 },
47 } as unknown as D1Database;
48
49 const response = await app.request("https://forum.reasonix.io/topics", {}, bindings(db));
50 expect(response.status).toBe(200);
51 const payload = await response.json();
52 expect(payload).toEqual({ topics: rows });
53 expect(queries[0]).toContain("m.handle, 'deleted') AS author");
54 expect(queries[0]).not.toMatch(/\bt\.author\s*,/);
55 expect(JSON.stringify(payload)).not.toContain("example.test");
56 });
57 });
58
58 lines TYPESCRIPT