Files
gongxue-base/scripts/openapi-documentation-contract-test.js

40 lines
1.8 KiB
JavaScript

import assert from 'node:assert/strict';
import fs from 'node:fs';
const document = JSON.parse(fs.readFileSync(process.argv[2] || '/tmp/tiku-openapi.json', 'utf8'));
const schemas = document.components?.schemas || {};
const operations = [];
for (const [path, pathItem] of Object.entries(document.paths || {})) {
for (const [method, operation] of Object.entries(pathItem)) {
if (!['get', 'post', 'put', 'patch', 'delete'].includes(method)) continue;
if (operation['x-migration-status'] === 'legacy') continue;
operations.push({ path, method, operation });
}
}
assert.equal(operations.length, 50, '首批原生 Nest 接口数量应为 50');
for (const { path, method, operation } of operations) {
assert.match(operation.summary || '', /[\u4e00-\u9fff]/, `${method.toUpperCase()} ${path} 缺少中文摘要`);
assert.ok(operation.responses?.['200']?.content?.['application/json']?.schema, `${method.toUpperCase()} ${path} 缺少 200 响应 schema`);
}
const bodyless = new Set([
'POST /api/auth/logout',
'POST /api/profile/check-in',
]);
for (const { path, method, operation } of operations.filter(item => ['post', 'put', 'patch'].includes(item.method))) {
const key = `${method.toUpperCase()} ${path}`;
if (bodyless.has(key)) continue;
const bodySchema = operation.requestBody?.content?.['application/json']?.schema;
assert.ok(bodySchema, `${key} 缺少 requestBody schema`);
const ref = bodySchema.$ref?.split('/').pop();
const resolved = ref ? schemas[ref] : bodySchema;
assert.ok(resolved?.properties && Object.keys(resolved.properties).length > 0, `${key} 的 DTO 没有可见字段`);
for (const [field, property] of Object.entries(resolved.properties)) {
assert.ok(property.description, `${key} 的字段 ${field} 缺少中文说明`);
}
}
console.log('[PASS] 50 个 Nest 接口均有中文摘要、请求 DTO 字段和响应 schema');