milestone 8: web server, rest api, sse, auth, metrics and static assets
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
//! `GET /api/openapi.yaml` — the API contract, served verbatim (ruling 23).
|
||||
//!
|
||||
//! The document is hand-written and embedded; nothing renders or validates it
|
||||
//! at runtime (rendering is Phase 10, external validators are dependencies we
|
||||
//! refused). What keeps it honest is W10's contract suite plus the tests
|
||||
//! below: every route the router serves must appear textually in the
|
||||
//! document, so a route added without documentation fails the build's tests
|
||||
//! rather than drifting silently.
|
||||
|
||||
const std = @import("std");
|
||||
|
||||
const http_util = @import("http_util.zig");
|
||||
const router = @import("router.zig");
|
||||
const server = @import("server.zig");
|
||||
|
||||
pub const yaml: []const u8 = @embedFile("openapi.yaml");
|
||||
|
||||
pub const content_type = "application/yaml";
|
||||
|
||||
pub fn handle(
|
||||
state: *server.WebState,
|
||||
io: std.Io,
|
||||
request: *http_util.Request,
|
||||
) http_util.HandlerError!void {
|
||||
_ = state;
|
||||
_ = io;
|
||||
return http_util.respondBytes(request, .ok, yaml, content_type, &.{});
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// tests
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const testing = std.testing;
|
||||
|
||||
test "every served route appears textually in the document" {
|
||||
for (router.routes) |route| {
|
||||
var key_buf: [128]u8 = undefined;
|
||||
// Path keys are two-space indented under `paths:`; requiring the
|
||||
// colon keeps `/api/groups` from being satisfied by its `{id}` twin.
|
||||
const key = try std.fmt.bufPrint(&key_buf, "\n {s}:\n", .{route.pattern});
|
||||
try testing.expect(std.mem.containsAtLeast(u8, yaml, 1, key));
|
||||
|
||||
var method_buf: [16]u8 = undefined;
|
||||
const method = try std.fmt.bufPrint(&method_buf, " {s}:\n", .{@tagName(route.method)});
|
||||
_ = std.ascii.lowerString(&method_buf, method);
|
||||
try testing.expect(std.mem.containsAtLeast(u8, yaml, 1, method_buf[0..method.len]));
|
||||
}
|
||||
}
|
||||
|
||||
test "the document does not promise what phase 9 owns" {
|
||||
// Ruling 2: certs/reload lands with the DoH/DoT server, whole.
|
||||
try testing.expect(!std.mem.containsAtLeast(u8, yaml, 1, "certs/reload"));
|
||||
}
|
||||
|
||||
test "the document names the contract's fixed points" {
|
||||
for ([_][]const u8{
|
||||
"openapi: 3.0.3",
|
||||
"nxdns_session",
|
||||
"text/event-stream",
|
||||
"snake_case",
|
||||
"Retry-After",
|
||||
}) |needle| {
|
||||
try testing.expect(std.mem.containsAtLeast(u8, yaml, 1, needle));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user