code wiki / _hdl_build / nx_docportal_search_serve_gate.nx

nx_docportal_search_serve_gate.nx source

↩ module page · 347 lines · 23489 B

1// nx_docportal_search_serve_gate.nx -- GATE for R2 (dss_serve). Writes a test PUBLIC shard, then feeds crafted 2// GET /search requests to dss_serve and asserts the rendered branded page: 200 + Content-Length, result count, 3// the hit's text present, empty-query prompt, no-match=0, and XSS-escaping of the echoed query (defensive at the 4// boundary). All over the REAL sovereign seg_store path, no tsv. license_tier: ORIGINAL 5import "nx_docportal_search_serve.nx" 6import "nx_g_puts_lib.nx" 7 8func g_strlen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 9func g_num(v: i64) -> i64 { 10 let bb: *u8 = sys_mmap(28); var m: i64 = v 11 if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m } 12 let t: *u8 = sys_mmap(28); var k: i64 = 0 13 if m == 0 { t[0] = 48 as u8; k = 1 } 14 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 15 var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } 16 sys_write(1, bb, k); return 0 17} 18// does hay[0..hn) contain the null-terminated needle? 19func g_contains(hay: *u8, hn: i64, needle: *u8) -> i64 { 20 let nl: i64 = g_strlen(needle) 21 if nl == 0 { return 1 } 22 var i: i64 = 0 23 while i + nl <= hn { 24 var m: i64 = 1 25 var j: i64 = 0 26 while j < nl { if hay[i + j] != needle[j] { m = 0 } j = j + 1 } 27 if m == 1 { return 1 } 28 i = i + 1 29 } 30 return 0 31} 32func g_streq(a: *u8, b: *u8) -> i64 { 33 var i: i64 = 0 34 while a[i] != (0 as u8) { if a[i] != b[i] { return 0 } i = i + 1 } 35 if b[i] != (0 as u8) { return 0 } 36 return 1 37} 38func g_check(name: *u8, cond: i64, pass: *i64, total: *i64) -> i64 { 39 total[0] = total[0] + 1 40 g_puts(name) 41 if cond == 1 { pass[0] = pass[0] + 1; g_puts(" PASS\n") } else { g_puts(" FAIL\n") } 42 return 0 43} 44 45func main(argc: i64, argv: *i64) -> i64 { 46 g_puts("=== nx_docportal_search_serve gate (R2 /search serve, sovereign) ===\n") 47 let d1: *u8 = "Estate Planning wills living trusts probate inheritance executor" as *u8 48 // zzqservetest = an INVENTED shard-marker token: T16 proves scope=web switches shards by querying it 49 // (present here, absent from any real crawled web page BY CONSTRUCTION -- "probate" stopped working 50 // as the isolation probe the moment the real web corpus ingested wikipedia's estate-planning page) 51 let d2: *u8 = "Family Law divorce child custody support alimony parenting zzqservetest" as *u8 52 let d3: *u8 = "Criminal defense practice page felonies misdemeanors expungement" as *u8 53 let w: *i64 = ss_begin() 54 ss_add(w, 1, "doc:201" as *u8, d1, g_strlen(d1)) 55 ss_add(w, 1, "doc:202" as *u8, d2, g_strlen(d2)) 56 // 203 = an ingested SITE PAGE: carries a url:<cid> row -> its result must link to the PAGE, not /doc 57 ss_add(w, 1, "doc:203" as *u8, d3, g_strlen(d3)) 58 ss_add(w, 1, "url:203" as *u8, "/practice/criminal.html" as *u8, 23) 59 // facet fixture (T45): two docs sharing facterm on DIFFERENT hosts -> the SERP offers site: narrowing 60 let df1: *u8 = "facterm alpha article body" as *u8 61 let df2: *u8 = "facterm beta article body text" as *u8 62 ss_add(w, 1, "doc:211" as *u8, df1, g_strlen(df1)) 63 ss_add(w, 1, "url:211" as *u8, "https://en.wikipedia.org/wiki/Alpha" as *u8, 35) 64 ss_add(w, 1, "doc:212" as *u8, df2, g_strlen(df2)) 65 ss_add(w, 1, "url:212" as *u8, "https://docs.example.org/beta" as *u8, 29) 66 // pager fixture: 22 pgterm docs (> the 20/page cap) -> the SERP must render Next/Prev 67 let dpg: *u8 = "pgterm pagination fixture entry for the serve pager" as *u8 68 let pgkey: *u8 = sys_mmap(24) 69 var pgi: i64 = 301 70 while pgi <= 322 { 71 var ko: i64 = 0 72 let kp: *u8 = "doc:" as *u8 73 while kp[ko] != (0 as u8) { pgkey[ko] = kp[ko]; ko = ko + 1 } 74 pgkey[ko] = (48 + (pgi / 100)) as u8 75 pgkey[ko + 1] = (48 + ((pgi / 10) % 10)) as u8 76 pgkey[ko + 2] = (48 + (pgi % 10)) as u8 77 pgkey[ko + 3] = 0 as u8 78 ss_add(w, 1, pgkey, dpg, g_strlen(dpg)) 79 pgi = pgi + 1 80 } 81 ss_commit("knowledge/store/dp-ssservetest-pub-" as *u8, w, 1) 82 83 let pass: *i64 = sys_mmap(16) as *i64; pass[0] = 0 84 let total: *i64 = sys_mmap(16) as *i64; total[0] = 0 85 let out: *u8 = sys_mmap(DSV_OUTCAP) 86 let dom: *u8 = "ssservetest" as *u8 87 88 // T1: q=probate -> 200 + Content-Length + "1 result" + the estate text 89 let r1: *u8 = "GET /search?q=probate HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 90 let n1: i64 = dss_serve(dom, r1, g_strlen(r1), out) 91 g_check("T1 200-header" as *u8, g_contains(out, n1, "HTTP/1.1 200 OK" as *u8), pass, total) 92 g_check("T1 content-length" as *u8, g_contains(out, n1, "Content-Length: " as *u8), pass, total) 93 g_check("T1 1-result" as *u8, g_contains(out, n1, "1 result(s)" as *u8), pass, total) 94 g_check("T1 hit-text(Estate)" as *u8, g_contains(out, n1, "Estate Planning" as *u8), pass, total) 95 96 // T2: q=divorce -> the family-law doc 97 let r2: *u8 = "GET /search?q=divorce HTTP/1.1\r\n\r\n" as *u8 98 let n2: i64 = dss_serve(dom, r2, g_strlen(r2), out) 99 g_check("T2 hit-text(Family)" as *u8, g_contains(out, n2, "Family Law" as *u8), pass, total) 100 101 // T3: empty query -> prompt, no crash 102 let r3: *u8 = "GET /search HTTP/1.1\r\n\r\n" as *u8 103 let n3: i64 = dss_serve(dom, r3, g_strlen(r3), out) 104 g_check("T3 empty-prompt" as *u8, g_contains(out, n3, "Enter a search term" as *u8), pass, total) 105 106 // T4 NEG: no match -> "0 result(s)" 107 let r4: *u8 = "GET /search?q=zzznotpresent HTTP/1.1\r\n\r\n" as *u8 108 let n4: i64 = dss_serve(dom, r4, g_strlen(r4), out) 109 g_check("T4 NEG 0-results" as *u8, g_contains(out, n4, "0 result(s)" as *u8), pass, total) 110 111 // T5 SECURITY: %3Cscript%3E in q -> echoed ESCAPED (&lt;script&gt;), never raw <script> 112 let r5: *u8 = "GET /search?q=%3Cscript%3E HTTP/1.1\r\n\r\n" as *u8 113 let n5: i64 = dss_serve(dom, r5, g_strlen(r5), out) 114 g_check("T5 xss-escaped(&lt;script)" as *u8, g_contains(out, n5, "&lt;script&gt;" as *u8), pass, total) 115 var raw: i64 = 0 116 if g_contains(out, n5, "<script>" as *u8) == 1 { raw = 1 } 117 g_check("T5 xss no-raw-script" as *u8, (1 - raw), pass, total) 118 119 // T6: urldecode '+' -> space (q=child+custody decodes to two terms; both in family-law doc) 120 let r6: *u8 = "GET /search?q=child+custody HTTP/1.1\r\n\r\n" as *u8 121 let n6: i64 = dss_serve(dom, r6, g_strlen(r6), out) 122 g_check("T6 urldecode-plus(Family)" as *u8, g_contains(out, n6, "Family Law" as *u8), pass, total) 123 124 // T10: results are LINKS -> /doc?cid=<cid>&q=<query> (the SERP click-through) 125 let na: i64 = dss_serve(dom, r1, g_strlen(r1), out) 126 g_check("T10 result-link(href /doc?cid=201&q=probate)" as *u8, g_contains(out, na, "href=\"/doc?cid=201&q=probate\"" as *u8), pass, total) 127 128 // T11: the matched query term is <b>-highlighted in the rendered result (index-tokenizer-aligned) 129 g_check("T11 highlight(<b>probate</b>)" as *u8, g_contains(out, na, "<b>probate</b>" as *u8), pass, total) 130 131 // T12: /doc?cid=201&q=probate -> 200 + the FULL doc text + highlight + back-to-results link 132 let rd1: *u8 = "GET /doc?cid=201&q=probate HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 133 let nd1: i64 = dsv_doc_serve(dom, rd1, g_strlen(rd1), out) 134 var d1ok: i64 = 0 135 // "inheritance"/"executor" straddle the title/body split, so assert each side + highlight + back-link 136 if g_contains(out, nd1, "HTTP/1.1 200 OK" as *u8) == 1 { if g_contains(out, nd1, "inheritance" as *u8) == 1 { if g_contains(out, nd1, "executor" as *u8) == 1 { if g_contains(out, nd1, "<b>probate</b>" as *u8) == 1 { if g_contains(out, nd1, "href=\"/search?q=probate\"" as *u8) == 1 { d1ok = 1 } } } } } 137 g_check("T12 /doc 200 + full text + highlight + back-link" as *u8, d1ok, pass, total) 138 139 // T13 NEG: absent cid -> branded 404, never a 500/crash 140 let rd2: *u8 = "GET /doc?cid=99999 HTTP/1.1\r\n\r\n" as *u8 141 let nd2: i64 = dsv_doc_serve(dom, rd2, g_strlen(rd2), out) 142 var d2ok: i64 = 0 143 if g_contains(out, nd2, "HTTP/1.1 404" as *u8) == 1 { if g_contains(out, nd2, "Document not found" as *u8) == 1 { d2ok = 1 } } 144 g_check("T13 NEG /doc absent-cid -> 404" as *u8, d2ok, pass, total) 145 146 // T14 NEG: malformed cid (digit-guard boundary) -> 404, not a crash / not a store probe with garbage 147 let rd3: *u8 = "GET /doc?cid=12abc HTTP/1.1\r\n\r\n" as *u8 148 let nd3: i64 = dsv_doc_serve(dom, rd3, g_strlen(rd3), out) 149 g_check("T14 NEG /doc malformed-cid -> 404" as *u8, g_contains(out, nd3, "HTTP/1.1 404" as *u8), pass, total) 150 151 // T15: a doc WITH a url:<cid> row links to the REAL page (href = the url value, no /doc) 152 let r15: *u8 = "GET /search?q=expungement HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 153 let n15: i64 = dss_serve(dom, r15, g_strlen(r15), out) 154 var t15: i64 = 0 155 if g_contains(out, n15, "href=\"/practice/criminal.html\"" as *u8) == 1 { if g_contains(out, n15, "/doc?cid=203" as *u8) == 0 { t15 = 1 } } 156 g_check("T15 url-row result links to the page" as *u8, t15, pass, total) 157 158 // T16: scope=web SWITCHES the shard away from the Host domain (a ssservetest-only term must yield 0 159 // under web scope -- isolation proves the switch without touching the real web corpus) + Web tab active 160 let r16: *u8 = "GET /search?q=zzqservetest&scope=web HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 161 let n16: i64 = dss_serve(dom, r16, g_strlen(r16), out) 162 var t16: i64 = 0 163 if g_contains(out, n16, "0 result(s)" as *u8) == 1 { if g_contains(out, n16, "class=on href=\"/search?scope=web" as *u8) == 1 { if g_contains(out, n16, "name=scope value=web" as *u8) == 1 { t16 = 1 } } } 164 g_check("T16 scope=web switches shard + tab active + form keeps scope" as *u8, t16, pass, total) 165 166 // T17: default scope renders the tabs with This-site active 167 let n17: i64 = dss_serve(dom, r1, g_strlen(r1), out) 168 var t17: i64 = 0 169 if g_contains(out, n17, ">This site</a>" as *u8) == 1 { if g_contains(out, n17, ">Web</a>" as *u8) == 1 { t17 = 1 } } 170 g_check("T17 scope tabs render (This site / Web)" as *u8, t17, pass, total) 171 172 // ---- API-FIRST surface (versioned JSON; enterprise contract) ---- 173 // T18: /api/search JSON shape -- v1, count, cid AS STRING, escaped title, CORS + content-type headers 174 let ra1: *u8 = "GET /api/search?q=probate HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 175 let na1: i64 = dss_api_search(dom, ra1, g_strlen(ra1), out) 176 var a1: i64 = 0 177 if g_contains(out, na1, "\"v\":1" as *u8) == 1 { if g_contains(out, na1, "\"nresults\":1" as *u8) == 1 { if g_contains(out, na1, "\"cid\":\"201\"" as *u8) == 1 { if g_contains(out, na1, "application/json" as *u8) == 1 { if g_contains(out, na1, "Access-Control-Allow-Origin: *" as *u8) == 1 { a1 = 1 } } } } } 178 g_check("T18 /api/search JSON v1 + cid-as-string + CORS" as *u8, a1, pass, total) 179 180 // T19: self-describing endpoint (no q -> 200 usage document, still structured) 181 let ra2: *u8 = "GET /api/search HTTP/1.1\r\n\r\n" as *u8 182 let na2: i64 = dss_api_search(dom, ra2, g_strlen(ra2), out) 183 var a2: i64 = 0 184 if g_contains(out, na2, "HTTP/1.1 200" as *u8) == 1 { if g_contains(out, na2, "\"endpoint\":\"/api/search\"" as *u8) == 1 { a2 = 1 } } 185 g_check("T19 /api/search self-describes without q" as *u8, a2, pass, total) 186 187 // T20: /api/doc found -> JSON text; T21: absent -> 404 not_found; T22: malformed -> 400 bad_cid 188 let ra3: *u8 = "GET /api/doc?cid=201 HTTP/1.1\r\n\r\n" as *u8 189 let na3: i64 = dss_api_doc(dom, ra3, g_strlen(ra3), out) 190 var a3: i64 = 0 191 if g_contains(out, na3, "\"found\":true" as *u8) == 1 { if g_contains(out, na3, "Estate Planning" as *u8) == 1 { if g_contains(out, na3, "\"truncated\":false" as *u8) == 1 { a3 = 1 } } } 192 g_check("T20 /api/doc found -> JSON text" as *u8, a3, pass, total) 193 let ra4: *u8 = "GET /api/doc?cid=99999 HTTP/1.1\r\n\r\n" as *u8 194 let na4: i64 = dss_api_doc(dom, ra4, g_strlen(ra4), out) 195 var a4: i64 = 0 196 if g_contains(out, na4, "HTTP/1.1 404" as *u8) == 1 { if g_contains(out, na4, "\"code\":\"not_found\"" as *u8) == 1 { a4 = 1 } } 197 g_check("T21 /api/doc absent -> 404 not_found" as *u8, a4, pass, total) 198 let ra5: *u8 = "GET /api/doc?cid=12abc HTTP/1.1\r\n\r\n" as *u8 199 let na5: i64 = dss_api_doc(dom, ra5, g_strlen(ra5), out) 200 var a5: i64 = 0 201 if g_contains(out, na5, "HTTP/1.1 400" as *u8) == 1 { if g_contains(out, na5, "\"code\":\"bad_cid\"" as *u8) == 1 { a5 = 1 } } 202 g_check("T22 /api/doc malformed -> 400 bad_cid" as *u8, a5, pass, total) 203 204 // T23: url row rides the API too (site pages / web results carry their real location) 205 let ra6: *u8 = "GET /api/search?q=expungement HTTP/1.1\r\n\r\n" as *u8 206 let na6: i64 = dss_api_search(dom, ra6, g_strlen(ra6), out) 207 g_check("T23 /api/search carries url for page-backed docs" as *u8, g_contains(out, na6, "\"url\":\"/practice/criminal.html\"" as *u8), pass, total) 208 209 // ---- MOBILE-FIRST markers (measured mechanically, not vibes) ---- 210 let nm: i64 = dss_serve(dom, r1, g_strlen(r1), out) 211 var mm: i64 = 0 212 if g_contains(out, nm, "font-size:16px" as *u8) == 1 { if g_contains(out, nm, "min-height:44px" as *u8) == 1 { if g_contains(out, nm, "prefers-color-scheme" as *u8) == 1 { if g_contains(out, nm, "text-size-adjust" as *u8) == 1 { mm = 1 } } } } 213 g_check("T24 mobile-first markers (16px input, 44px targets, dark scheme, size-adjust lock)" as *u8, mm, pass, total) 214 215 // ---- S-CLASS SERP DISPLAY rows (the beat-Google/Bing result-page bar, measured mechanically) ---- 216 // T30 the tab title carries the query (multi-tab usability) 217 let n30: i64 = dss_serve(dom, r1, g_strlen(r1), out) 218 g_check("T30 <title> = query + Nishi Search" as *u8, g_contains(out, n30, "<title>probate &mdash; Nishi Search</title>" as *u8), pass, total) 219 // T31 ZERO JavaScript on the whole page (Google's SERP won't even render without JS) 220 var t31: i64 = 0 221 if g_contains(out, n30, "<script" as *u8) == 0 { t31 = 1 } 222 g_check("T31 zero-JS page (no <script anywhere)" as *u8, t31, pass, total) 223 // T32 semantic structure + the measured credo footer 224 var t32: i64 = 0 225 if g_contains(out, n30, "<article class=r" as *u8) == 1 { if g_contains(out, n30, "<h3 class=t" as *u8) == 1 { if g_contains(out, n30, "<footer class=credo" as *u8) == 1 { if g_contains(out, n30, "0 JavaScript" as *u8) == 1 { if g_contains(out, n30, "<main>" as *u8) == 1 { t32 = 1 } } } } } 226 g_check("T32 semantic article/h3/main + credo footer" as *u8, t32, pass, total) 227 // T33 measured query latency in the meta line 228 g_check("T33 meta line shows measured ms" as *u8, g_contains(out, n30, " ms</p>" as *u8), pass, total) 229 // T34 FEATURED ANSWER: a full-coverage sentence gets the answer panel, highlighted 230 let r34: *u8 = "GET /search?q=probate+inheritance HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 231 let n34: i64 = dss_serve(dom, r34, g_strlen(r34), out) 232 var t34: i64 = 0 233 if g_contains(out, n34, "class=ans" as *u8) == 1 { if g_contains(out, n34, "<b>probate</b>" as *u8) == 1 { t34 = 1 } } 234 g_check("T34 featured-answer panel (full term coverage, highlighted)" as *u8, t34, pass, total) 235 // T35 pager: 22 matches -> Next on page 0; Prev + page 2 marker on p=1 236 let r35a: *u8 = "GET /search?q=pgterm HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 237 let n35a: i64 = dss_serve(dom, r35a, g_strlen(r35a), out) 238 var t35: i64 = 0 239 if g_contains(out, n35a, "Next &rarr;" as *u8) == 1 { if g_contains(out, n35a, "&p=1" as *u8) == 1 { 240 let r35b: *u8 = "GET /search?q=pgterm&p=1 HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 241 let n35b: i64 = dss_serve(dom, r35b, g_strlen(r35b), out) 242 if g_contains(out, n35b, "&larr; Prev" as *u8) == 1 { if g_contains(out, n35b, "page 2" as *u8) == 1 { if g_contains(out, n35b, "of 22 matched" as *u8) == 1 { t35 = 1 } } } 243 } } 244 g_check("T35 pager Next/Prev + page marker + total matched" as *u8, t35, pass, total) 245 246 // T36 DID-YOU-MEAN: a typo'd query renders the dictionary's correction as a link 247 let r36: *u8 = "GET /search?q=probete HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 248 let n36: i64 = dss_serve(dom, r36, g_strlen(r36), out) 249 var t36: i64 = 0 250 if g_contains(out, n36, "Did you mean" as *u8) == 1 { if g_contains(out, n36, "href=\"/search?q=probate\"" as *u8) == 1 { t36 = 1 } } 251 g_check("T36 did-you-mean line (probete -> probate link)" as *u8, t36, pass, total) 252 253 // T37 /api/suggest: dictionary completions as versioned JSON 254 let r37: *u8 = "GET /api/suggest?q=prob HTTP/1.1\r\n\r\n" as *u8 255 let n37: i64 = dss_api_suggest(dom, r37, g_strlen(r37), out) 256 var t37: i64 = 0 257 if g_contains(out, n37, "\"v\":1" as *u8) == 1 { if g_contains(out, n37, "\"suggestions\":[\"probate\"" as *u8) == 1 { if g_contains(out, n37, "application/json" as *u8) == 1 { t37 = 1 } } } 258 g_check("T37 /api/suggest JSON completions" as *u8, t37, pass, total) 259 260 // T38 /api/search zero-hit carries did_you_mean 261 let r38: *u8 = "GET /api/search?q=probete HTTP/1.1\r\n\r\n" as *u8 262 let n38: i64 = dss_api_search(dom, r38, g_strlen(r38), out) 263 var t38: i64 = 0 264 if g_contains(out, n38, "\"nresults\":0" as *u8) == 1 { if g_contains(out, n38, "\"did_you_mean\":\"probate\"" as *u8) == 1 { t38 = 1 } } 265 g_check("T38 /api/search did_you_mean field" as *u8, t38, pass, total) 266 267 // T39 +term AND through the serve layer: "probate +custody" -- OR would return BOTH docs; the 268 // required term keeps only the custody-bearing one (distinguishing fixture) 269 let r39: *u8 = "GET /search?q=probate+%2Bcustody HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 270 let n39: i64 = dss_serve(dom, r39, g_strlen(r39), out) 271 var t39: i64 = 0 272 if g_contains(out, n39, "1 result(s)" as *u8) == 1 { if g_contains(out, n39, "Family Law" as *u8) == 1 { t39 = 1 } } 273 g_check("T39 +term AND via serve (OR=2 -> AND=1, custody doc only)" as *u8, t39, pass, total) 274 275 // T40/T41 PHRASE through the serve layer: quoted adjacency matches; reversed order does not 276 let r40: *u8 = "GET /search?q=%22living+trusts%22 HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 277 let n40: i64 = dss_serve(dom, r40, g_strlen(r40), out) 278 g_check("T40 phrase [living trusts] via serve -> 1 result" as *u8, g_contains(out, n40, "1 result(s)" as *u8), pass, total) 279 let r41: *u8 = "GET /search?q=%22trusts+living%22 HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 280 let n41: i64 = dss_serve(dom, r41, g_strlen(r41), out) 281 g_check("T41 NEG reversed phrase -> 0 results" as *u8, g_contains(out, n41, "0 result(s)" as *u8), pass, total) 282 // T42 API carries the exactness contract for quoted queries 283 let r42: *u8 = "GET /api/search?q=%22living+trusts%22 HTTP/1.1\r\n\r\n" as *u8 284 let n42: i64 = dss_api_search(dom, r42, g_strlen(r42), out) 285 var t42: i64 = 0 286 if g_contains(out, n42, "\"phrase_exact\":true" as *u8) == 1 { if g_contains(out, n42, "\"nresults\":1" as *u8) == 1 { t42 = 1 } } 287 g_check("T42 /api/search phrase_exact:true for a quoted query" as *u8, t42, pass, total) 288 289 // T43 OpenAPI 3.1 contract: valid structure, all 3 paths, servers names the Host, cid-as-string note 290 let n43: i64 = dss_api_openapi("andelinwest.com" as *u8, out) 291 var t43: i64 = 0 292 if g_contains(out, n43, "\"openapi\":\"3.1.0\"" as *u8) == 1 { if g_contains(out, n43, "\"/api/search\":" as *u8) == 1 { if g_contains(out, n43, "\"/api/doc\":" as *u8) == 1 { if g_contains(out, n43, "\"/api/suggest\":" as *u8) == 1 { if g_contains(out, n43, "https://andelinwest.com" as *u8) == 1 { if g_contains(out, n43, "SearchResponse" as *u8) == 1 { if g_contains(out, n43, "application/json" as *u8) == 1 { t43 = 1 } } } } } } } 293 g_check("T43 /api/openapi.json valid 3.1 spec (paths+schemas+server+CORS)" as *u8, t43, pass, total) 294 // T44 the SERP footer links the API spec (discoverability) 295 let r44: *u8 = "GET /search?q=probate HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 296 let n44: i64 = dss_serve(dom, r44, g_strlen(r44), out) 297 g_check("T44 SERP footer links /api/openapi.json" as *u8, g_contains(out, n44, "href=\"/api/openapi.json\"" as *u8), pass, total) 298 299 // T48-T50 THREE SCOPES (operator's 2026-07-04 model): the SERP shows This site / Trusted / Web tabs, 300 // each scope-preserving; the API scope name resolves web/trusted/site. 301 let r48: *u8 = "GET /search?q=probate HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 302 let n48: i64 = dss_serve(dom, r48, g_strlen(r48), out) 303 var t48: i64 = 0 304 if g_contains(out, n48, ">This site</a>" as *u8) == 1 { if g_contains(out, n48, ">Trusted</a>" as *u8) == 1 { if g_contains(out, n48, ">Web</a>" as *u8) == 1 { t48 = 1 } } } 305 g_check("T48 three scope tabs (This site / Trusted / Web)" as *u8, t48, pass, total) 306 let r49: *u8 = "GET /api/search?q=probate&scope=trusted HTTP/1.1\r\n\r\n" as *u8 307 let n49: i64 = dss_api_search(dom, r49, g_strlen(r49), out) 308 g_check("T49 /api/search scope=trusted -> \"scope\":\"trusted\"" as *u8, g_contains(out, n49, "\"scope\":\"trusted\"" as *u8), pass, total) 309 let r50: *u8 = "GET /api/search?q=probate&scope=web HTTP/1.1\r\n\r\n" as *u8 310 let n50: i64 = dss_api_search(dom, r50, g_strlen(r50), out) 311 g_check("T50 /api/search scope=web -> \"scope\":\"web\"" as *u8, g_contains(out, n50, "\"scope\":\"web\"" as *u8), pass, total) 312 313 // T45 host FACETS: facterm spans 2 hosts -> the SERP offers one-click site: narrowing 314 let r45: *u8 = "GET /search?q=facterm HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 315 let n45: i64 = dss_serve(dom, r45, g_strlen(r45), out) 316 var t45: i64 = 0 317 if g_contains(out, n45, "Sites: " as *u8) == 1 { if g_contains(out, n45, "site%3Aen.wikipedia.org" as *u8) == 1 { if g_contains(out, n45, "site%3Adocs.example.org" as *u8) == 1 { t45 = 1 } } } 318 g_check("T45 SERP host facets (Sites: line + site: links)" as *u8, t45, pass, total) 319 // T46 the site: OPERATOR through the serve layer narrows to one host + facet line suppressed 320 let r46: *u8 = "GET /search?q=facterm+site%3Adocs.example.org HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 321 let n46: i64 = dss_serve(dom, r46, g_strlen(r46), out) 322 var t46: i64 = 0 323 if g_contains(out, n46, "1 result(s)" as *u8) == 1 { if g_contains(out, n46, "Sites: " as *u8) == 0 { t46 = 1 } } 324 g_check("T46 site: operator via serve (1 result, facets suppressed)" as *u8, t46, pass, total) 325 // T47 API carries the host field 326 let r47: *u8 = "GET /api/search?q=facterm HTTP/1.1\r\n\r\n" as *u8 327 let n47: i64 = dss_api_search(dom, r47, g_strlen(r47), out) 328 g_check("T47 /api/search result carries host" as *u8, g_contains(out, n47, "\"host\":\"en.wikipedia.org\"" as *u8), pass, total) 329 330 // T7-T9: dsv_host (Host-header -> domain; the daemon's /search route feeds this to dss_serve) 331 let hbuf: *u8 = sys_mmap(256) 332 let rh1: *u8 = "GET /search?q=x HTTP/1.1\r\nHost: andelinwest.com:443\r\n\r\n" as *u8 333 dsv_host(rh1, g_strlen(rh1), hbuf, 255) 334 g_check("T7 host(andelinwest.com,port-stripped)" as *u8, g_streq(hbuf, "andelinwest.com" as *u8), pass, total) 335 let rh2: *u8 = "GET / HTTP/1.1\r\nhost: bradrwest.com\r\n\r\n" as *u8 336 dsv_host(rh2, g_strlen(rh2), hbuf, 255) 337 g_check("T8 host(lowercase)" as *u8, g_streq(hbuf, "bradrwest.com" as *u8), pass, total) 338 let rh3: *u8 = "GET / HTTP/1.1\r\n\r\n" as *u8 339 dsv_host(rh3, g_strlen(rh3), hbuf, 255) 340 var t9ok: i64 = 0 341 if hbuf[0] == (0 as u8) { t9ok = 1 } 342 g_check("T9 host-absent-empty" as *u8, t9ok, pass, total) 343 344 g_puts("=== dss_serve gate: "); g_num(pass[0]); g_puts("/"); g_num(total[0]); g_puts(" ") 345 if pass[0] == total[0] { g_puts("GREEN\n"); return 0 } 346 g_puts("RED\n"); return 1 347}