Make the edge protocol contract test pass on its own
tests/edge_protocol.test.ts validates schemas carrying format: "uuid" and format: "uri" but registered neither. TypeBox treats an unregistered format as a failure, not a pass, so every start_print in that file was rejected - and the file still went green, because some other test in the same run imported Elysia first and registered the formats globally. Run alone it failed. A contract test that depends on which files ran before it is the worst way for one to behave. It now imports src/validation/formats, which exists for exactly this and gains a "uri" validator: anything the platform parses as an absolute URL. Lenient on purpose - the only user is a presigned object-store GET that this backend mints itself, so a stricter pattern would have to anticipate whatever query parameters a signer adds, and rejecting a URL R2 would have honoured costs a print for no security.
This commit is contained in:
@@ -3,6 +3,12 @@ import { FormatRegistry } from "@sinclair/typebox";
|
|||||||
/**
|
/**
|
||||||
* Registers the string formats this codebase uses with TypeBox.
|
* Registers the string formats this codebase uses with TypeBox.
|
||||||
*
|
*
|
||||||
|
* Import this from any test that validates a schema carrying a `format`
|
||||||
|
* without standing up Elysia. `tests/edge_protocol.test.ts` did not, and so
|
||||||
|
* passed only because some *other* test file in the same run happened to
|
||||||
|
* import Elysia first and register the formats globally - run on its own it
|
||||||
|
* failed, which is the worst way for a contract test to behave.
|
||||||
|
*
|
||||||
* TypeBox ships no format validators: `format` is a registry lookup, and an
|
* TypeBox ships no format validators: `format` is a registry lookup, and an
|
||||||
* *unregistered* format does not pass - it fails. So a schema written with
|
* *unregistered* format does not pass - it fails. So a schema written with
|
||||||
* `format: "uuid"` and checked outside Elysia rejects every value, including
|
* `format: "uuid"` and checked outside Elysia rejects every value, including
|
||||||
@@ -28,6 +34,24 @@ if (!FormatRegistry.Has("uuid")) {
|
|||||||
FormatRegistry.Set("uuid", (value) => UUID.test(value));
|
FormatRegistry.Set("uuid", (value) => UUID.test(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!FormatRegistry.Has("uri")) {
|
||||||
|
// `PrinterCommand.start_print.url` is the only user, and it carries a
|
||||||
|
// presigned object-store GET. Lenient on purpose: anything the platform
|
||||||
|
// parses as an absolute URL passes. A stricter pattern would have to
|
||||||
|
// anticipate whatever query parameters a signer adds, and rejecting a URL
|
||||||
|
// R2 would have honoured costs a print for no security - the command is
|
||||||
|
// minted by this backend, not submitted by a client.
|
||||||
|
FormatRegistry.Set("uri", (value) => {
|
||||||
|
try {
|
||||||
|
// Rejects a relative reference, which `format: "uri"` is supposed to:
|
||||||
|
// the two-argument form would happily resolve "../x" against a base.
|
||||||
|
return new URL(value).protocol.length > 0;
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (!FormatRegistry.Has("date-time")) {
|
if (!FormatRegistry.Has("date-time")) {
|
||||||
// Deliberately lenient: anything `Date.parse` understands. The producers
|
// Deliberately lenient: anything `Date.parse` understands. The producers
|
||||||
// are `new Date().toISOString()` in TypeScript and chrono's RFC 3339 in
|
// are `new Date().toISOString()` in TypeScript and chrono's RFC 3339 in
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
import { describe, expect, it } from "bun:test";
|
import { describe, expect, it } from "bun:test";
|
||||||
import { Value } from "@sinclair/typebox/value";
|
import { Value } from "@sinclair/typebox/value";
|
||||||
import { EdgeClientMessageSchema, EdgeServerMessageSchema } from "@continuum/ts-types";
|
import { EdgeClientMessageSchema, EdgeServerMessageSchema } from "@continuum/ts-types";
|
||||||
|
// Registers `uuid` and `uri`. Not optional: TypeBox treats an unregistered
|
||||||
|
// format as a failure, so without this every `start_print` in this file is
|
||||||
|
// rejected for its job_id and url. This file used to rely on another test
|
||||||
|
// file importing Elysia first, which made it pass in a full run and fail on
|
||||||
|
// its own.
|
||||||
|
import "../src/validation/formats";
|
||||||
|
|
||||||
import currentCapture from "./fixtures/gateway_frames.json";
|
import currentCapture from "./fixtures/gateway_frames.json";
|
||||||
import legacyCapture from "./fixtures/gateway_frames_legacy_nulls.json";
|
import legacyCapture from "./fixtures/gateway_frames_legacy_nulls.json";
|
||||||
|
|||||||
Reference in New Issue
Block a user