fix(openapi): guard suffix matching and add ambient context test
This commit is contained in:
@@ -98,9 +98,12 @@ export async function getOpenApiSpec(
|
|||||||
// 2. Specific path lookup
|
// 2. Specific path lookup
|
||||||
if (options?.path) {
|
if (options?.path) {
|
||||||
const target = normalizePath(options.path);
|
const target = normalizePath(options.path);
|
||||||
|
const suffix = target.replace(/^\/api\/v3/, "");
|
||||||
const matchedKey =
|
const matchedKey =
|
||||||
allPaths.find((p) => p.toLowerCase() === target) ||
|
allPaths.find((p) => p.toLowerCase() === target) ||
|
||||||
allPaths.find((p) => p.toLowerCase().endsWith(target.replace(/^\/api\/v3/, "")));
|
(suffix.length > 0 && suffix !== "/"
|
||||||
|
? allPaths.find((p) => p.toLowerCase().endsWith(suffix))
|
||||||
|
: undefined);
|
||||||
|
|
||||||
if (!matchedKey || !doc.paths[matchedKey]) {
|
if (!matchedKey || !doc.paths[matchedKey]) {
|
||||||
const sample = allPaths.slice(0, 10).join(", ");
|
const sample = allPaths.slice(0, 10).join(", ");
|
||||||
|
|||||||
+13
-5
@@ -6,6 +6,7 @@ import {
|
|||||||
} from "../src/services/openapi.ts";
|
} from "../src/services/openapi.ts";
|
||||||
import { OpenProjectClient } from "../src/client/api-client.ts";
|
import { OpenProjectClient } from "../src/client/api-client.ts";
|
||||||
import { OpenProjectNotFoundError } from "../src/client/errors.ts";
|
import { OpenProjectNotFoundError } from "../src/client/errors.ts";
|
||||||
|
import { runWithContext } from "../src/context.ts";
|
||||||
|
|
||||||
describe("OpenApi Service", () => {
|
describe("OpenApi Service", () => {
|
||||||
const mockSpec = {
|
const mockSpec = {
|
||||||
@@ -144,10 +145,17 @@ describe("OpenApi Service", () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("full mode returns the complete raw specification", async () => {
|
test("resolves ambient client from RequestContext when client is omitted", async () => {
|
||||||
const result = (await getOpenApiSpec({ full: true }, mockClient)) as typeof mockSpec;
|
const res = await runWithContext({ client: mockClient, isReadOnly: true }, async () => {
|
||||||
expect(result.openapi).toBe("3.0.3");
|
return getOpenApiSpec({});
|
||||||
expect(result.paths).toBeDefined();
|
});
|
||||||
expect(result.components).toBeDefined();
|
expect((res as OpenApiSummary).title).toBe("OpenProject API V3 (Test)");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("path mode does not falsely match root /api/v3 via empty suffix", async () => {
|
||||||
|
// If /api/v3 itself is not a path key, requesting it must throw OpenProjectNotFoundError
|
||||||
|
expect(getOpenApiSpec({ path: "/api/v3" }, mockClient)).rejects.toThrow(
|
||||||
|
OpenProjectNotFoundError
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user