Expand OpenAPI parity guard to all pulls routes

swadhinbiswas committed 8 months ago
8c3e006
1 parent e655053
commit 8c3e006
2 files changed
+18 -10
▼doc/feature_audit.md
+1-1
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
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