99 lines
2.9 KiB
TypeScript
99 lines
2.9 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
|
|
import { defineRestOperation } from "../../src/contracts/api-operations.ts";
|
|
import {
|
|
createRestProviderProfile,
|
|
resolveRestSecurityProfiles,
|
|
validateRestProfileBindings,
|
|
} from "../../src/contracts/rest-profiles.ts";
|
|
|
|
/**
|
|
* §24.12: the common REST profile contract must stay independently verifiable
|
|
* after the sample feature is removed, so this suite owns its own operation
|
|
* fixture instead of importing an installed feature contract.
|
|
*/
|
|
const SAMPLE_COMMAND = defineRestOperation({
|
|
method: "POST",
|
|
path: "/api/sample-resources",
|
|
operationId: "CREATE_SAMPLE_RESOURCE",
|
|
auth: "external-session",
|
|
timeoutMs: null,
|
|
idempotency: "keyed",
|
|
retry: "runtime",
|
|
requestSource: "body",
|
|
requestSchema: "SampleCommand",
|
|
responseSchema: "SamplePayload",
|
|
owner: "platform-test-fixture",
|
|
contractVersion: 2,
|
|
protocol: "REST",
|
|
semantics: "COMMAND",
|
|
replayPolicy: "KEYED_COMMAND",
|
|
idempotencyKeyPolicy: "REQUIRED",
|
|
mapperId: "SampleMapper",
|
|
successStatuses: [200, 201],
|
|
responseMediaTypes: ["application/json"],
|
|
maxResponseBytes: 32_768,
|
|
providerId: "PRIMARY_API",
|
|
authProfileId: "REFERENCE_EXTERNAL_BEARER",
|
|
csrfProfileId: "NO_CSRF_BEARER",
|
|
pathSchema: "NoRequest",
|
|
pathParameterNames: [],
|
|
maxEncodedSearchBytes: 0,
|
|
});
|
|
|
|
const SAMPLE_OPERATIONS = Object.freeze({
|
|
CREATE_SAMPLE_RESOURCE: SAMPLE_COMMAND,
|
|
});
|
|
|
|
describe("REST provider/auth/CSRF profiles", () => {
|
|
it("preserves the provider prefix and rejects unsafe endpoint forms", () => {
|
|
expect(
|
|
createRestProviderProfile(
|
|
"PRIMARY_API",
|
|
"https://api.test/base/",
|
|
["omit"],
|
|
),
|
|
).toMatchObject({
|
|
providerId: "PRIMARY_API",
|
|
baseUrl: "https://api.test/base/",
|
|
redirect: "error",
|
|
referrerPolicy: "no-referrer",
|
|
});
|
|
expect(() =>
|
|
createRestProviderProfile(
|
|
"PRIMARY_API",
|
|
"https://user:password@api.test/base/",
|
|
),
|
|
).toThrow("Invalid REST provider profile");
|
|
expect(() =>
|
|
createRestProviderProfile("PRIMARY_API", "http://api.test/base/"),
|
|
).toThrow("Invalid REST provider profile");
|
|
});
|
|
|
|
it("resolves bearer auth to omit credentials and no CSRF", () => {
|
|
const resolved = resolveRestSecurityProfiles(
|
|
SAMPLE_COMMAND,
|
|
createRestProviderProfile("PRIMARY_API", "https://api.test", ["omit"]),
|
|
);
|
|
expect(resolved).toMatchObject({
|
|
auth: {
|
|
transport: "BEARER_HEADER",
|
|
credentials: "omit",
|
|
allowedCredentialHeaders: ["authorization"],
|
|
},
|
|
csrf: { mode: "NONE" },
|
|
});
|
|
});
|
|
|
|
it("validates every installed profile binding as a set", () => {
|
|
expect(
|
|
validateRestProfileBindings(SAMPLE_OPERATIONS, {
|
|
PRIMARY_API: ["omit"],
|
|
}),
|
|
).toBe(true);
|
|
expect(() =>
|
|
validateRestProfileBindings(SAMPLE_OPERATIONS, {}),
|
|
).toThrow("Unregistered REST provider binding");
|
|
});
|
|
});
|