48 lines
2.0 KiB
TypeScript
48 lines
2.0 KiB
TypeScript
|
|
// packages/contracts/src/__tests__/ads.test.ts
|
|||
|
|
// 广告位契约守护:openapi.yaml 中三处硬编码的广告图字节上限(maximum: 2097152)
|
|||
|
|
// 必须与 constants.ts 的 AD_UPLOAD_MAX_BYTES 恒等(1:1 守护,对照 events.test.ts
|
|||
|
|
// 的枚举同步守护)。契约文件无 js-yaml 依赖(pnpm 严格 node_modules),按文件
|
|||
|
|
// 既有的固定缩进块风格做文本切片解析:schema 名 4 空格、属性名 8 空格、
|
|||
|
|
// 属性约束 10 空格——缩进漂移会令定位失败而报错,本身就是守护的一部分。
|
|||
|
|
import { readFileSync } from 'node:fs';
|
|||
|
|
import { resolve } from 'node:path';
|
|||
|
|
import { AD_UPLOAD_MAX_BYTES } from '../constants.js';
|
|||
|
|
|
|||
|
|
const openapiYaml = readFileSync(
|
|||
|
|
resolve(__dirname, '../../openapi.yaml'),
|
|||
|
|
'utf8',
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
/** 取 components/schemas 下指定 schema 的文本块(至下一个 4 空格缩进的键)。 */
|
|||
|
|
function schemaBlock(name: string): string {
|
|||
|
|
const start = openapiYaml.indexOf(`\n ${name}:`);
|
|||
|
|
if (start === -1) {
|
|||
|
|
throw new Error(`openapi.yaml 缺少 schema:${name}`);
|
|||
|
|
}
|
|||
|
|
const body = openapiYaml.slice(start + 1);
|
|||
|
|
const next = body.search(/\n [A-Za-z]/);
|
|||
|
|
return next === -1 ? body : body.slice(0, next);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/** 取 schema 块内指定属性的 maximum 约束值(属性块内首个 maximum)。 */
|
|||
|
|
function maximumOf(name: string, prop: string): number {
|
|||
|
|
const block = schemaBlock(name);
|
|||
|
|
const match = block.match(
|
|||
|
|
new RegExp(`^ {8}${prop}:\\n(?: {10}[^\\n]+\\n)*? {10}maximum: (\\d+)`, 'm'),
|
|||
|
|
);
|
|||
|
|
if (match === null) {
|
|||
|
|
throw new Error(`${name}.${prop} 缺少 maximum 约束`);
|
|||
|
|
}
|
|||
|
|
return Number(match[1]);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
describe('openapi 广告图上限 ↔ AD_UPLOAD_MAX_BYTES 同步', () => {
|
|||
|
|
it.each([
|
|||
|
|
['AdCreateRequest', 'imageBytes'],
|
|||
|
|
['AdUpdateRequest', 'imageBytes'],
|
|||
|
|
['AdUploadInitRequest', 'bytes'],
|
|||
|
|
] as const)('%s.%s 的 maximum 恒等于 AD_UPLOAD_MAX_BYTES', (schema, prop) => {
|
|||
|
|
expect(maximumOf(schema, prop)).toBe(AD_UPLOAD_MAX_BYTES);
|
|||
|
|
});
|
|||
|
|
});
|