Files
MeshTender/internal/core/endpoints_shared_test.go
T

112 lines
3.6 KiB
Go

package core
import (
"io"
"net/http"
"net/url"
"strings"
"testing"
)
// These black-box tests cover the non-visual "plumbing" endpoints from the
// endpoint inventory (docs/endpoint-inventory.md): health, static assets, and the
// pure host/redirect behaviors. They use the splitServer harness (real three-host
// server + real Postgres) and assert status/redirect Location rather than any
// rendered UI.
// #1 /healthz — returns "ok" on every surface.
func TestHealthzEndpoint(t *testing.T) {
t.Parallel()
_, _, ts, h := splitServer(t)
for _, host := range []string{h.app, h.auth, h.root} {
resp := do(t, ts, host, "/healthz")
body, _ := io.ReadAll(resp.Body)
resp.Body.Close()
if resp.StatusCode != http.StatusOK || strings.TrimSpace(string(body)) != "ok" {
t.Fatalf("%s/healthz = %d %q, want 200 \"ok\"", host, resp.StatusCode, body)
}
}
}
// #2 /static/* — serves an embedded asset.
func TestStaticAssetEndpoint(t *testing.T) {
t.Parallel()
_, _, ts, h := splitServer(t)
resp := do(t, ts, h.app, "/static/ui.js")
body, _ := io.ReadAll(resp.Body)
resp.Body.Close()
if resp.StatusCode != http.StatusOK {
t.Fatalf("/static/ui.js = %d, want 200", resp.StatusCode)
}
if ct := resp.Header.Get("Content-Type"); !strings.Contains(ct, "javascript") {
t.Fatalf("/static/ui.js Content-Type = %q, want a javascript type", ct)
}
if len(body) == 0 {
t.Fatal("/static/ui.js served an empty body")
}
}
// #15 auth host `/` — bare visits 303 to the sign-in page.
func TestAuthRootRedirectsToLogin(t *testing.T) {
t.Parallel()
_, _, ts, h := splitServer(t)
resp := do(t, ts, h.auth, "/")
resp.Body.Close()
if resp.StatusCode != http.StatusSeeOther {
t.Fatalf("auth / = %d, want 303", resp.StatusCode)
}
if loc, _ := url.Parse(resp.Header.Get("Location")); loc.Path != "/login" {
t.Fatalf("auth / → %q, want /login", resp.Header.Get("Location"))
}
}
// #35 app host `/signup` — starts the signup handoff, bouncing to the auth host.
func TestAppSignupRedirectsToAuth(t *testing.T) {
t.Parallel()
_, _, ts, h := splitServer(t)
resp := do(t, ts, h.app, "/signup")
resp.Body.Close()
if resp.StatusCode != http.StatusSeeOther {
t.Fatalf("app /signup = %d, want 303", resp.StatusCode)
}
if loc, _ := url.Parse(resp.Header.Get("Location")); loc.Host != h.auth || loc.Path != "/signup" {
t.Fatalf("app /signup → %q, want auth host /signup", resp.Header.Get("Location"))
}
}
// #97 custom org domain — a verified domain serves the org's public page at `/`
// and 302-redirects every other path to the app host.
func TestCustomDomainRedirect(t *testing.T) {
t.Parallel()
st, ctx, ts, _ := splitServer(t)
owner, err := st.CreateUser(ctx, "domainowner", "")
if err != nil {
t.Fatal(err)
}
org, err := st.CreateOrg(ctx, "Domain Org", owner.ID)
if err != nil {
t.Fatal(err)
}
const customHost = "mesh.example.org"
dom, err := st.CreateOrgDomain(ctx, org.ID, customHost)
if err != nil {
t.Fatal(err)
}
if err := st.MarkOrgDomainVerified(ctx, org.ID, dom.ID); err != nil {
t.Fatal(err)
}
// Non-root path on the custom host → 302 to the same path on the app host.
resp := do(t, ts, customHost, "/repeaters/abc")
resp.Body.Close()
if resp.StatusCode != http.StatusFound {
t.Fatalf("custom-domain /repeaters/abc = %d, want 302", resp.StatusCode)
}
if loc, _ := url.Parse(resp.Header.Get("Location")); loc.Hostname() != testAppHost || loc.Path != "/repeaters/abc" {
t.Fatalf("custom-domain redirect = %q, want app host /repeaters/abc", resp.Header.Get("Location"))
}
// (The custom-domain `/` org page — inventory #96 — is a rendered page left to
// manual/browser verification.)
}