From c7b6f4b44e0e1a5ddf8338137746cb5302d4015e Mon Sep 17 00:00:00 2001 From: Kat <00-kat@proton.me> Date: Fri, 20 Mar 2026 03:50:10 +1100 Subject: [PATCH] cmd/pkgserver: relocate JS tests --- .gitignore | 4 + cmd/pkgserver/main.go | 1 + cmd/pkgserver/test_ui.go | 97 +++++++++++++++++++ cmd/pkgserver/test_ui_stub.go | 7 ++ cmd/pkgserver/ui.go | 24 ----- cmd/pkgserver/ui_full.go | 2 +- .../{ui/static => ui_test}/all_tests.ts | 0 .../run_tests.ts => ui_test/lib/cli.ts} | 2 +- .../static => ui_test/lib}/failure-closed.svg | 0 .../static => ui_test/lib}/failure-open.svg | 0 .../lib}/go_test_entrypoint.ts | 2 +- .../static => ui_test/lib}/skip-closed.svg | 0 .../{ui/static => ui_test/lib}/skip-open.svg | 0 .../static => ui_test/lib}/success-closed.svg | 0 .../static => ui_test/lib}/success-open.svg | 0 .../{ui/static => ui_test/lib}/test.ts | 0 .../{ui/test.html => ui_test/lib/ui.html} | 6 +- .../static/test.scss => ui_test/lib/ui.scss} | 12 +-- .../{ui/static => ui_test}/test_tests.ts | 2 +- cmd/pkgserver/ui_test/tsconfig.json | 6 ++ 20 files changed, 128 insertions(+), 37 deletions(-) create mode 100644 cmd/pkgserver/test_ui.go create mode 100644 cmd/pkgserver/test_ui_stub.go rename cmd/pkgserver/{ui/static => ui_test}/all_tests.ts (100%) rename cmd/pkgserver/{ui/static/run_tests.ts => ui_test/lib/cli.ts} (98%) rename cmd/pkgserver/{ui/static => ui_test/lib}/failure-closed.svg (100%) rename cmd/pkgserver/{ui/static => ui_test/lib}/failure-open.svg (100%) rename cmd/pkgserver/{ui/static => ui_test/lib}/go_test_entrypoint.ts (76%) rename cmd/pkgserver/{ui/static => ui_test/lib}/skip-closed.svg (100%) rename cmd/pkgserver/{ui/static => ui_test/lib}/skip-open.svg (100%) rename cmd/pkgserver/{ui/static => ui_test/lib}/success-closed.svg (100%) rename cmd/pkgserver/{ui/static => ui_test/lib}/success-open.svg (100%) rename cmd/pkgserver/{ui/static => ui_test/lib}/test.ts (100%) rename cmd/pkgserver/{ui/test.html => ui_test/lib/ui.html} (83%) rename cmd/pkgserver/{ui/static/test.scss => ui_test/lib/ui.scss} (83%) rename cmd/pkgserver/{ui/static => ui_test}/test_tests.ts (99%) create mode 100644 cmd/pkgserver/ui_test/tsconfig.json diff --git a/.gitignore b/.gitignore index 5469a0f2..b541d009 100644 --- a/.gitignore +++ b/.gitignore @@ -31,6 +31,10 @@ go.work.sum /cmd/pkgserver/ui/static/*.js /cmd/pkgserver/ui/static/*.css* /cmd/pkgserver/ui/static/*.css.map +/cmd/pkgserver/ui_test/*.js +/cmd/pkgserver/ui_test/lib/*.js +/cmd/pkgserver/ui_test/lib/*.css* +/cmd/pkgserver/ui_test/lib/*.css.map /internal/pkg/testdata/testtool /internal/rosa/hakurei_current.tar.gz diff --git a/cmd/pkgserver/main.go b/cmd/pkgserver/main.go index af59ff2e..e5151eee 100644 --- a/cmd/pkgserver/main.go +++ b/cmd/pkgserver/main.go @@ -82,6 +82,7 @@ func main() { }() var mux http.ServeMux uiRoutes(&mux) + testUiRoutes(&mux) index.registerAPI(&mux) server := http.Server{ Addr: flagAddr, diff --git a/cmd/pkgserver/test_ui.go b/cmd/pkgserver/test_ui.go new file mode 100644 index 00000000..12881add --- /dev/null +++ b/cmd/pkgserver/test_ui.go @@ -0,0 +1,97 @@ +//go:build frontend && frontend_test + +package main + +import ( + "embed" + "net/http" + "path" + "strings" +) + +//go:generate tsc -p ui_test +//go:generate sass ui_test/lib/ui.scss ui_test/lib/ui.css +//go:embed ui_test/* +var test_content embed.FS + +func serveTestWebUI(w http.ResponseWriter, r *http.Request) { + w.Header().Set("X-Content-Type-Options", "nosniff") + w.Header().Set("X-XSS-Protection", "1") + w.Header().Set("X-Frame-Options", "DENY") + + http.ServeFileFS(w, r, test_content, "ui_test/lib/ui.html") +} + +func serveTestWebUIStaticContent(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case "/testui/style.css": + http.ServeFileFS(w, r, test_content, "ui_test/lib/ui.css") + case "/testui/skip-closed.svg": + http.ServeFileFS(w, r, test_content, "ui_test/lib/skip-closed.svg") + case "/testui/skip-open.svg": + http.ServeFileFS(w, r, test_content, "ui_test/lib/skip-open.svg") + case "/testui/success-closed.svg": + http.ServeFileFS(w, r, test_content, "ui_test/lib/success-closed.svg") + case "/testui/success-open.svg": + http.ServeFileFS(w, r, test_content, "ui_test/lib/success-open.svg") + case "/testui/failure-closed.svg": + http.ServeFileFS(w, r, test_content, "ui_test/lib/failure-closed.svg") + case "/testui/failure-open.svg": + http.ServeFileFS(w, r, test_content, "ui_test/lib/failure-open.svg") + default: + http.NotFound(w, r) + } +} + +func serveTestLibrary(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case "/test/lib/test.js": + http.ServeFileFS(w, r, test_content, "ui_test/lib/test.js") + default: + http.NotFound(w, r) + } +} + +func serveTests(w http.ResponseWriter, r *http.Request) { + if r.URL.Path == "/test/" { + http.Redirect(w, r, "/test.html", http.StatusMovedPermanently) + return + } + testPath := strings.TrimPrefix(r.URL.Path, "/test/") + + if path.Ext(testPath) != ".js" { + http.Error(w, "403 forbidden", http.StatusForbidden) + } + + w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") + w.Header().Set("Pragma", "no-cache") + w.Header().Set("Expires", "0") + + http.ServeFileFS(w, r, test_content, "ui_test/"+testPath) +} + +func redirectUI(w http.ResponseWriter, r *http.Request) { + // The base path should not redirect to the root. + if r.URL.Path == "/ui/" { + http.NotFound(w, r) + return + } + if path.Ext(r.URL.Path) != ".js" { + http.Error(w, "403 forbidden", http.StatusForbidden) + return + } + + w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") + w.Header().Set("Pragma", "no-cache") + w.Header().Set("Expires", "0") + + http.Redirect(w, r, strings.TrimPrefix(r.URL.Path, "/ui"), http.StatusFound) +} + +func testUiRoutes(mux *http.ServeMux) { + mux.HandleFunc("GET /test.html", serveTestWebUI) + mux.HandleFunc("GET /testui/", serveTestWebUIStaticContent) + mux.HandleFunc("GET /test/lib", serveTestLibrary) + mux.HandleFunc("GET /test/", serveTests) + mux.HandleFunc("GET /ui/", redirectUI) +} diff --git a/cmd/pkgserver/test_ui_stub.go b/cmd/pkgserver/test_ui_stub.go new file mode 100644 index 00000000..65d86baa --- /dev/null +++ b/cmd/pkgserver/test_ui_stub.go @@ -0,0 +1,7 @@ +//go:build !(frontend && frontend_test) + +package main + +import "net/http" + +func testUiRoutes(mux *http.ServeMux) {} diff --git a/cmd/pkgserver/ui.go b/cmd/pkgserver/ui.go index 4a09edf0..e4c42832 100644 --- a/cmd/pkgserver/ui.go +++ b/cmd/pkgserver/ui.go @@ -25,38 +25,14 @@ func serveStaticContent(w http.ResponseWriter, r *http.Request) { http.ServeFileFS(w, r, content, "ui/static/favicon.ico") case "/static/index.js": http.ServeFileFS(w, r, content, "ui/static/index.js") - case "/static/test.js": - http.ServeFileFS(w, r, content, "ui/static/test.js") - case "/static/test.css": - http.ServeFileFS(w, r, content, "ui/static/test.css") - case "/static/all_tests.js": - http.ServeFileFS(w, r, content, "ui/static/all_tests.js") - case "/static/test_tests.js": - http.ServeFileFS(w, r, content, "ui/static/test_tests.js") - case "/static/success-closed.svg": - http.ServeFileFS(w, r, content, "ui/static/success-closed.svg") - case "/static/success-open.svg": - http.ServeFileFS(w, r, content, "ui/static/success-open.svg") - case "/static/failure-closed.svg": - http.ServeFileFS(w, r, content, "ui/static/failure-closed.svg") - case "/static/failure-open.svg": - http.ServeFileFS(w, r, content, "ui/static/failure-open.svg") - case "/static/skip-closed.svg": - http.ServeFileFS(w, r, content, "ui/static/skip-closed.svg") - case "/static/skip-open.svg": - http.ServeFileFS(w, r, content, "ui/static/skip-open.svg") default: http.NotFound(w, r) } } -func serveTester(w http.ResponseWriter, r *http.Request) { - http.ServeFileFS(w, r, content, "ui/test.html") -} func uiRoutes(mux *http.ServeMux) { mux.HandleFunc("GET /{$}", serveWebUI) mux.HandleFunc("GET /favicon.ico", serveStaticContent) mux.HandleFunc("GET /static/", serveStaticContent) - mux.HandleFunc("GET /test.html", serveTester) } diff --git a/cmd/pkgserver/ui_full.go b/cmd/pkgserver/ui_full.go index 837d64d8..f9ca8816 100644 --- a/cmd/pkgserver/ui_full.go +++ b/cmd/pkgserver/ui_full.go @@ -4,6 +4,6 @@ package main import "embed" -//go:generate sh -c "sass ui/static/dark.scss ui/static/dark.css && sass ui/static/light.scss ui/static/light.css && sass ui/static/test.scss ui/static/test.css && tsc -p ui/static" +//go:generate sh -c "sass ui/static/dark.scss ui/static/dark.css && sass ui/static/light.scss ui/static/light.css && tsc -p ui/static" //go:embed ui/* var content embed.FS diff --git a/cmd/pkgserver/ui/static/all_tests.ts b/cmd/pkgserver/ui_test/all_tests.ts similarity index 100% rename from cmd/pkgserver/ui/static/all_tests.ts rename to cmd/pkgserver/ui_test/all_tests.ts diff --git a/cmd/pkgserver/ui/static/run_tests.ts b/cmd/pkgserver/ui_test/lib/cli.ts similarity index 98% rename from cmd/pkgserver/ui/static/run_tests.ts rename to cmd/pkgserver/ui_test/lib/cli.ts index 88353ecd..7d149d7f 100644 --- a/cmd/pkgserver/ui/static/run_tests.ts +++ b/cmd/pkgserver/ui_test/lib/cli.ts @@ -4,7 +4,7 @@ // provides faster iteration, especially for those acclimated to test-driven // development. -import "./all_tests.js"; +import "../all_tests.js"; import { StreamReporter, TESTS } from "./test.js"; // TypeScript doesn't like process and Deno as their type definitions aren't diff --git a/cmd/pkgserver/ui/static/failure-closed.svg b/cmd/pkgserver/ui_test/lib/failure-closed.svg similarity index 100% rename from cmd/pkgserver/ui/static/failure-closed.svg rename to cmd/pkgserver/ui_test/lib/failure-closed.svg diff --git a/cmd/pkgserver/ui/static/failure-open.svg b/cmd/pkgserver/ui_test/lib/failure-open.svg similarity index 100% rename from cmd/pkgserver/ui/static/failure-open.svg rename to cmd/pkgserver/ui_test/lib/failure-open.svg diff --git a/cmd/pkgserver/ui/static/go_test_entrypoint.ts b/cmd/pkgserver/ui_test/lib/go_test_entrypoint.ts similarity index 76% rename from cmd/pkgserver/ui/static/go_test_entrypoint.ts rename to cmd/pkgserver/ui_test/lib/go_test_entrypoint.ts index 7a4ef171..e8962055 100644 --- a/cmd/pkgserver/ui/static/go_test_entrypoint.ts +++ b/cmd/pkgserver/ui_test/lib/go_test_entrypoint.ts @@ -1,3 +1,3 @@ -import "./all_tests.js"; +import "../all_tests.js"; import { GoTestReporter, TESTS } from "./test.js"; TESTS.run(new GoTestReporter()); diff --git a/cmd/pkgserver/ui/static/skip-closed.svg b/cmd/pkgserver/ui_test/lib/skip-closed.svg similarity index 100% rename from cmd/pkgserver/ui/static/skip-closed.svg rename to cmd/pkgserver/ui_test/lib/skip-closed.svg diff --git a/cmd/pkgserver/ui/static/skip-open.svg b/cmd/pkgserver/ui_test/lib/skip-open.svg similarity index 100% rename from cmd/pkgserver/ui/static/skip-open.svg rename to cmd/pkgserver/ui_test/lib/skip-open.svg diff --git a/cmd/pkgserver/ui/static/success-closed.svg b/cmd/pkgserver/ui_test/lib/success-closed.svg similarity index 100% rename from cmd/pkgserver/ui/static/success-closed.svg rename to cmd/pkgserver/ui_test/lib/success-closed.svg diff --git a/cmd/pkgserver/ui/static/success-open.svg b/cmd/pkgserver/ui_test/lib/success-open.svg similarity index 100% rename from cmd/pkgserver/ui/static/success-open.svg rename to cmd/pkgserver/ui_test/lib/success-open.svg diff --git a/cmd/pkgserver/ui/static/test.ts b/cmd/pkgserver/ui_test/lib/test.ts similarity index 100% rename from cmd/pkgserver/ui/static/test.ts rename to cmd/pkgserver/ui_test/lib/test.ts diff --git a/cmd/pkgserver/ui/test.html b/cmd/pkgserver/ui_test/lib/ui.html similarity index 83% rename from cmd/pkgserver/ui/test.html rename to cmd/pkgserver/ui_test/lib/ui.html index 4e0f5399..f4c4b7f9 100644 --- a/cmd/pkgserver/ui/test.html +++ b/cmd/pkgserver/ui_test/lib/ui.html @@ -3,7 +3,7 @@ - + PkgServer Tests @@ -23,8 +23,8 @@ diff --git a/cmd/pkgserver/ui/static/test.scss b/cmd/pkgserver/ui_test/lib/ui.scss similarity index 83% rename from cmd/pkgserver/ui/static/test.scss rename to cmd/pkgserver/ui_test/lib/ui.scss index 2fc8395a..ae75c721 100644 --- a/cmd/pkgserver/ui/static/test.scss +++ b/cmd/pkgserver/ui_test/lib/ui.scss @@ -45,24 +45,24 @@ details.test-node { * [3]: https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/summary#changing_the_summarys_icon */ color: var(--fg); - content: url("/static/success-closed.svg") / "success"; + content: url("/testui/success-closed.svg") / "success"; } &.success[open] > summary::marker { - content: url("/static/success-open.svg") / "success"; + content: url("/testui/success-open.svg") / "success"; } &.failure > summary::marker { color: red; - content: url("/static/failure-closed.svg") / "failure"; + content: url("/testui/failure-closed.svg") / "failure"; } &.failure[open] > summary::marker { - content: url("/static/failure-open.svg") / "failure"; + content: url("/testui/failure-open.svg") / "failure"; } &.skip > summary::marker { color: blue; - content: url("/static/skip-closed.svg") / "skip"; + content: url("/testui/skip-closed.svg") / "skip"; } &.skip[open] > summary::marker { - content: url("/static/skip-open.svg") / "skip"; + content: url("/testui/skip-open.svg") / "skip"; } } diff --git a/cmd/pkgserver/ui/static/test_tests.ts b/cmd/pkgserver/ui_test/test_tests.ts similarity index 99% rename from cmd/pkgserver/ui/static/test_tests.ts rename to cmd/pkgserver/ui_test/test_tests.ts index 1ccec6a1..8d1b5526 100644 --- a/cmd/pkgserver/ui/static/test_tests.ts +++ b/cmd/pkgserver/ui_test/test_tests.ts @@ -1,4 +1,4 @@ -import { NoOpReporter, TestRegistrar, context, group, suite, test } from "./test.js"; +import { NoOpReporter, TestRegistrar, context, group, suite, test } from "./lib/test.js"; suite("dog", [ group("tail", [ diff --git a/cmd/pkgserver/ui_test/tsconfig.json b/cmd/pkgserver/ui_test/tsconfig.json new file mode 100644 index 00000000..02161c32 --- /dev/null +++ b/cmd/pkgserver/ui_test/tsconfig.json @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "strict": true, + "target": "ES2024" + } +}