zuka
zuka/src/api/openapi.rs

worklyn / zukapublic

Agent-first git hosting. One Rust binary: git over HTTP and SSH, a REST API, MCP, CI, and multi-tenant isolation.

Get a copy: git clone https://zuka.worklyn.com/worklyn/zuka.git
zuka/src/api/openapi.rs
RSopenapi.rs3.7 KBDownload
1// The OpenAPI document, served at `/openapi.json` and committed as `openapi.json`.
2//
3// Embedded with `include_str!` so the served document and the committed file cannot
4// drift: there is one artifact.
5//
6// The coverage test below checks a hand-maintained list, so it catches a route that
7// is documented and removed, not one that is added and never documented. Deriving
8// the list from the router would need a route table the router does not have.
9
10/// The committed OpenAPI 3.1 document.
11pub const DOCUMENT: &str = include_str!("../../openapi.json");
12
13#[cfg(test)]
14mod tests {
15 use super::*;
16
17 fn document() -> serde_json::Value {
18 serde_json::from_str(DOCUMENT).expect("openapi.json must be valid JSON")
19 }
20
21 #[test]
22 fn is_a_valid_openapi_3_1_document() {
23 let doc = document();
24 assert_eq!(doc["openapi"], "3.1.0");
25 assert!(doc["info"]["title"].is_string());
26 assert!(doc["info"]["version"].is_string());
27 assert!(doc["paths"].is_object());
28 }
29
30 #[test]
31 fn documents_every_route_the_router_serves() {
32 let doc = document();
33 let paths = doc["paths"].as_object().expect("paths is an object");
34
35 for route in [
36 "/healthz",
37 "/openapi.json",
38 "/v1/account",
39 "/v1/keys",
40 "/v1/keys/{id}",
41 "/v1/repos",
42 "/v1/repos/{account}/{repo}",
43 "/v1/repos/{account}/{repo}/refs",
44 "/v1/repos/{account}/{repo}/tree/{path}",
45 "/v1/repos/{account}/{repo}/raw/{path}",
46 "/v1/repos/{account}/{repo}/commits",
47 "/v1/repos/{account}/{repo}/commits/{sha}",
48 "/v1/repos/{account}/{repo}/compare",
49 "/v1/repos/{account}/{repo}/search",
50 "/v1/repos/{account}/{repo}/blame/{path}",
51 "/mcp",
52 "/v1/repos/{account}/{repo}/runs",
53 "/v1/repos/{account}/{repo}/runs/{id}",
54 "/v1/repos/{account}/{repo}/runs/{id}/logs",
55 "/{account}/{repo}.git/info/refs",
56 ] {
57 assert!(
58 paths.contains_key(route),
59 "{route} is served but undocumented"
60 );
61 }
62 }
63
64 #[test]
65 fn the_document_identifies_the_running_crate() {
66 let doc = document();
67 assert_eq!(doc["info"]["version"], crate::brand::VERSION);
68 assert_eq!(
69 doc["info"]["title"],
70 crate::brand::NAME,
71 "the served document must name the service that serves it"
72 );
73 }
74
75 #[test]
76 fn quota_and_rate_limit_problems_are_documented() {
77 let doc = document();
78 let examples = doc["components"]["schemas"]["Problem"]["properties"]["type"]["examples"]
79 .as_array()
80 .expect("problem types are enumerated")
81 .iter()
82 .filter_map(|v| v.as_str())
83 .collect::<Vec<_>>()
84 .join(" ");
85 assert!(examples.contains("quota-exceeded"));
86 assert!(examples.contains("rate-limited"));
87 }
88
89 #[test]
90 fn every_operation_declares_its_security_except_the_public_ones() {
91 let doc = document();
92 let public = ["/healthz", "/openapi.json"];
93
94 for (path, item) in doc["paths"].as_object().unwrap() {
95 for (method, operation) in item.as_object().unwrap() {
96 if method == "parameters" {
97 continue;
98 }
99 let declared = operation.get("security").is_some();
100 if public.contains(&path.as_str()) {
101 assert!(!declared, "{path} {method} is public but declares security");
102 } else {
103 assert!(declared, "{path} {method} does not declare security");
104 }
105 }
106 }
107 }
108}