test(danmaku): assert openCommentXml withRelated contract
This commit is contained in:
parent
5b095d677f
commit
07c7108789
|
|
@ -17,8 +17,8 @@
|
|||
| `@app/models` | Drizzle 表定义(唯一 schema 源) | drizzle-orm |
|
||||
| `@app/db` | libSQL/Turso 客户端单例 + drizzle-kit | models |
|
||||
| `@app/dao` | 数据访问层(`userDao` / `mountDao` / `mediaItemDao` 等) | db, models |
|
||||
| `@app/trpc` | tRPC 路由 + service 业务逻辑(调用 DAO) | types, dao |
|
||||
| `@app/web` | Astro 前端 + React islands + 本地 tRPC HTTP 适配 | trpc, types, design-tokens, seo-geo, i18n, ui |
|
||||
| `@app/trpc` | tRPC 路由 + service 业务逻辑(调用 DAO) | types, dao, danmaku |
|
||||
| `@app/web` | Astro 前端 + React islands + 本地 tRPC HTTP 适配 | trpc, types, danmaku(`./browser`), design-tokens, seo-geo, i18n, ui |
|
||||
| `@app/ui` | shadcn 风格基础 UI 组件(源码直出 + Storybook) | design-tokens, react (peer) |
|
||||
| `@app/design-tokens` | 共享 CSS 设计令牌(`tokens.css`) | — |
|
||||
| `@app/seo-geo` | SEO/GEO 纯函数(meta、sitemap、JSON-D、llms.txt) | zod, schema-dts, escape-html, fast-xml-builder, serialize-javascript, mdast-util-to-markdown |
|
||||
|
|
|
|||
|
|
@ -1,5 +1,12 @@
|
|||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { hasOpenCredentials, openApiBase, openHeaders, readOpenCredentials } from "./client.js";
|
||||
import {
|
||||
hasOpenCredentials,
|
||||
openApiBase,
|
||||
openCommentXml,
|
||||
openHeaders,
|
||||
openMatch,
|
||||
readOpenCredentials,
|
||||
} from "./client.js";
|
||||
|
||||
afterEach(() => {
|
||||
vi.unstubAllEnvs();
|
||||
|
|
@ -50,3 +57,59 @@ describe("openHeaders", () => {
|
|||
expect(openHeaders("/api/v2/match", null)).toEqual({ "Content-Type": "application/json" });
|
||||
});
|
||||
});
|
||||
|
||||
function stubFetchJson(json: unknown) {
|
||||
const fetchMock = vi.fn().mockResolvedValue({
|
||||
ok: true,
|
||||
status: 200,
|
||||
json: async () => json,
|
||||
});
|
||||
vi.stubGlobal("fetch", fetchMock);
|
||||
return fetchMock;
|
||||
}
|
||||
|
||||
describe("openCommentXml 请求契约", () => {
|
||||
it("请求路径含 ?withRelated=true(关联弹幕计入)", async () => {
|
||||
const fetchMock = stubFetchJson({ success: true, comments: [] });
|
||||
await openCommentXml(555);
|
||||
expect(fetchMock).toHaveBeenCalledTimes(1);
|
||||
const url = String(fetchMock.mock.calls[0]?.[0]);
|
||||
expect(url).toBe("https://api.dandanplay.net/api/v2/comment/555?withRelated=true");
|
||||
});
|
||||
|
||||
it("comments 序列化为 xml,HTTP 失败返回 null", async () => {
|
||||
const fetchMock = stubFetchJson({
|
||||
success: true,
|
||||
comments: [{ p: "12.5,1,0,0,0,0,,", m: "hi" }],
|
||||
});
|
||||
await expect(openCommentXml(555)).resolves.toContain("<d ");
|
||||
expect(fetchMock).toHaveBeenCalledTimes(1);
|
||||
|
||||
fetchMock.mockResolvedValue({ ok: false, status: 500, json: async () => ({}) });
|
||||
await expect(openCommentXml(555)).resolves.toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe("openMatch 请求契约", () => {
|
||||
it("POST /api/v2/match,matchMode 随 hash 切换", async () => {
|
||||
const fetchMock = stubFetchJson({ success: true, isMatched: true, matches: [] });
|
||||
|
||||
await openMatch("Show - 02", 100, "abc");
|
||||
const [url1, init1] = fetchMock.mock.calls[0] ?? [];
|
||||
expect(String(url1)).toBe("https://api.dandanplay.net/api/v2/match");
|
||||
expect(init1?.method).toBe("POST");
|
||||
expect(JSON.parse(String(init1?.body))).toEqual({
|
||||
fileName: "Show - 02",
|
||||
fileHash: "abc",
|
||||
fileSize: 100,
|
||||
matchMode: "hashAndFileName",
|
||||
});
|
||||
|
||||
await openMatch("Show - 02", 100, null);
|
||||
const init2 = fetchMock.mock.calls[1]?.[1];
|
||||
expect(JSON.parse(String(init2?.body))).toMatchObject({
|
||||
fileHash: "",
|
||||
matchMode: "fileNameOnly",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue