|
7 | 7 | * 内容被写入 swagger.json(与 swagger 插件冲突、互相覆盖)。 |
8 | 8 | */ |
9 | 9 | import { describe, expect, test } from "vitest"; |
| 10 | +import { z } from "zod"; |
10 | 11 | import generateAxios from "../lib/plugin/generate_axios"; |
11 | 12 | import generatePostman from "../lib/plugin/generate_postman"; |
12 | | -import generateSwagger from "../lib/plugin/generate_swagger"; |
| 13 | +import generateSwagger, { buildSwagger } from "../lib/plugin/generate_swagger"; |
| 14 | + |
| 15 | +/** 从写入回调里解析 postman 输出 JSON */ |
| 16 | +function capturePostman(api: Record<string, unknown>) { |
| 17 | + let captured = ""; |
| 18 | + const writer = (_p: string, data: string) => (captured = data); |
| 19 | + generatePostman( |
| 20 | + { |
| 21 | + info: { title: "t", description: "d", host: "http://x", basePath: "" }, |
| 22 | + group: { G: "G" }, |
| 23 | + types: {}, |
| 24 | + apis: { "get_/test": { method: "get", path: "/test", realPath: "/test", group: "G", title: "t", ...api } }, |
| 25 | + } as any, |
| 26 | + "/out", |
| 27 | + { postman: "postman.json" } as any, |
| 28 | + writer |
| 29 | + ); |
| 30 | + return JSON.parse(captured); |
| 31 | +} |
13 | 32 |
|
14 | 33 | describe("文档插件文件名解析", () => { |
15 | 34 | // 构造最小可用 docData(插件实际只读少量字段) |
@@ -57,3 +76,71 @@ describe("文档插件文件名解析", () => { |
57 | 76 | expect(written[0]).toContain("postman.json"); |
58 | 77 | }); |
59 | 78 | }); |
| 79 | + |
| 80 | +describe("swagger response schema(issue #6)", () => { |
| 81 | + const baseInfo = { title: "t", description: "d", host: "http://x", basePath: "" }; |
| 82 | + const realPath = "/test"; |
| 83 | + |
| 84 | + function buildWithApi(api: Record<string, unknown>) { |
| 85 | + const data = { |
| 86 | + info: baseInfo, |
| 87 | + group: { G: "G" }, |
| 88 | + types: {}, |
| 89 | + apis: { "get_/test": { method: "get", path: "/test", realPath, group: "G", title: "t", ...api } }, |
| 90 | + } as any; |
| 91 | + return buildSwagger(data); |
| 92 | + } |
| 93 | + |
| 94 | + test("有 responseSchema 时,responses.200 应包含 schema(含字段与 required)", () => { |
| 95 | + const result = buildWithApi({ |
| 96 | + responseSchema: z.object({ id: z.number(), name: z.string(), age: z.number().optional() }), |
| 97 | + }); |
| 98 | + const op = (result.paths as any)[realPath].get; |
| 99 | + expect(op.responses[200].description).toBe("请求成功"); |
| 100 | + const schema = op.responses[200].schema; |
| 101 | + expect(schema.type).toBe("object"); |
| 102 | + // required 字段应包含非 optional 的字段 |
| 103 | + expect(schema.required).toEqual(expect.arrayContaining(["id", "name"])); |
| 104 | + expect(schema.required).not.toContain("age"); |
| 105 | + // 属性存在 |
| 106 | + expect(Object.keys(schema.properties).toSorted()).toEqual(["age", "id", "name"]); |
| 107 | + expect(schema.properties.id.type).toBe("number"); |
| 108 | + expect(schema.properties.name.type).toBe("string"); |
| 109 | + }); |
| 110 | + |
| 111 | + test("无 responseSchema 时,responses.200 保持原有占位(仅 description)", () => { |
| 112 | + const result = buildWithApi({}); |
| 113 | + const op = (result.paths as any)[realPath].get; |
| 114 | + expect(op.responses[200].description).toBe("请求成功"); |
| 115 | + // 未定义 response 时不应输出 schema 字段 |
| 116 | + expect(op.responses[200].schema).toBeUndefined(); |
| 117 | + }); |
| 118 | + |
| 119 | + test("responseSchema 为 enum 时应输出 enum 取值", () => { |
| 120 | + const result = buildWithApi({ |
| 121 | + responseSchema: z.object({ status: z.enum(["ok", "fail"]) }), |
| 122 | + }); |
| 123 | + const op = (result.paths as any)[realPath].get; |
| 124 | + expect(op.responses[200].schema.properties.status.enum).toEqual(["ok", "fail"]); |
| 125 | + }); |
| 126 | +}); |
| 127 | + |
| 128 | +describe("postman response 示例(issue #6)", () => { |
| 129 | + test("有 responseSchema 时,item 应带 response 示例(含字段名 key)", () => { |
| 130 | + const postman = capturePostman({ |
| 131 | + responseSchema: z.object({ id: z.number(), name: z.string() }), |
| 132 | + }); |
| 133 | + const item = postman.item[0].item[0]; |
| 134 | + expect(item.response).toBeDefined(); |
| 135 | + expect(item.response).toHaveLength(1); |
| 136 | + // response body 应是 JSON,包含 schema 的字段名 |
| 137 | + const body = JSON.parse(item.response[0].body); |
| 138 | + expect(Object.keys(body).toSorted()).toEqual(["id", "name"]); |
| 139 | + }); |
| 140 | + |
| 141 | + test("无 responseSchema 时,item 不带 response 字段", () => { |
| 142 | + const postman = capturePostman({}); |
| 143 | + const item = postman.item[0].item[0]; |
| 144 | + expect(item.response).toBeUndefined(); |
| 145 | + }); |
| 146 | +}); |
0 commit comments