Expand OpenAPI parity guard to all pulls routes
swadhinbiswas committed 8 months ago
8c3e006
1 parent e655053
commit 8c3e006
2 files changed
+18 -10
Showing 2 changed files+18-10
▼doc/feature_audit.md
+1-1
| @@ -200,7 +200,7 @@ | ||
200 | 200 | | CLI | ✅ | `cli/` package - 21+ commands | |
201 | 201 | | Plugin/extension system | ⚠️ | `plugins.ts` infrastructure exists, but basic | |
202 | 202 | | Webhook events | ✅ | Full implementation | |
203 | -| API documentation | ⚠️ | OpenAPI coverage now includes AI callback and AI review trigger/read routes, PR create/detail/update/template routes, review/comment flows (including path-scoped comment visibility metadata), stack approvals/rebase/auto-update/merge routes, PR bulk-merge/auto-merge/checks/merge/impact/rewrite routes, PR issue-links and file-approvals routes, merge-gate reporting metadata, notifications/email test endpoints, and analytics merge-frequency/workload routes, plus parity guard tests for `pulls/{number}` route documentation; broader endpoint parity still incomplete | | |
203 | +| API documentation | ⚠️ | OpenAPI coverage now includes AI callback and AI review trigger/read routes, PR create/detail/update/template routes, review/comment flows (including path-scoped comment visibility metadata), stack approvals/rebase/auto-update/merge routes, PR bulk-merge/auto-merge/checks/merge/impact/rewrite routes, PR issue-links and file-approvals routes, merge-gate reporting metadata, notifications/email test endpoints, and analytics merge-frequency/workload routes, plus parity guard tests for `pulls/*` route documentation; broader endpoint parity still incomplete | | |
204 | 204 | |
205 | 205 | ## 12. Self-Hosted & Deployment |
206 | 206 | | Feature | Status | Implementation Notes | |
207 | 207 | |
▼tests/unit/openapi-pulls-parity.test.ts
+17-9
| @@ -25,20 +25,28 @@ function collectRouteFiles(root: string): string[] { | ||
25 | 25 | |
26 | 26 | function toOpenApiPath(routeFile: string): string { |
27 | 27 | const withoutTs = routeFile.replace(/\.ts$/, ""); |
28 | - if (withoutTs === "index") { | |
29 | - return "/repos/{owner}/{repo}/pulls/{number}"; | |
28 | + let relativePath = withoutTs; | |
29 | + if (relativePath === "index") { | |
30 | + return "/repos/{owner}/{repo}/pulls"; | |
30 | 31 | } |
31 | - const normalized = withoutTs.replace(/\[([^\]]+)\]/g, "{$1}"); | |
32 | - return `/repos/{owner}/{repo}/pulls/{number}/${normalized}`; | |
32 | + if (relativePath.endsWith("/index")) { | |
33 | + relativePath = relativePath.slice(0, -"/index".length); | |
34 | + } | |
35 | + const normalized = relativePath.replace(/\[([^\]]+)\]/g, "{$1}"); | |
36 | + return `/repos/{owner}/{repo}/pulls/${normalized}`; | |
37 | +} | |
38 | + | |
39 | +function canonicalizePath(path: string): string { | |
40 | + return path.replace(/\{[^}]+\}/g, "{}"); | |
33 | 41 | } |
34 | 42 | |
35 | -describe("openapi pulls[number] parity", () => { | |
36 | - it("documents all implemented pull-number routes", () => { | |
37 | - const routeRoot = "src/pages/api/repos/[owner]/[repo]/pulls/[number]"; | |
43 | +describe("openapi pulls parity", () => { | |
44 | + it("documents all implemented pulls routes", () => { | |
45 | + const routeRoot = "src/pages/api/repos/[owner]/[repo]/pulls"; | |
38 | 46 | const routeFiles = collectRouteFiles(routeRoot); |
39 | - const expectedPaths = routeFiles.map(toOpenApiPath); | |
47 | + const expectedPaths = routeFiles.map(toOpenApiPath).map(canonicalizePath); | |
40 | 48 | |
41 | - const openApiPaths = new Set(Object.keys(openApiSpec.paths)); | |
49 | + const openApiPaths = new Set(Object.keys(openApiSpec.paths).map(canonicalizePath)); | |
42 | 50 | const missing = expectedPaths.filter((path) => !openApiPaths.has(path)); |
43 | 51 | |
44 | 52 | expect(missing).toEqual([]); |
45 | 53 | |