package server import ( "encoding/json" "io" "net/http" "net/http/httptest" "strings" "testing" "error-code-system/domains" "error-code-system/errcode" "error-code-system/httpx" ) func testServer(t *testing.T) *httptest.Server { t.Helper() reg := errcode.NewRegistry() domains.RegisterAll(reg) return httptest.NewServer(New(reg).Handler()) } func TestHealthListGetValidate(t *testing.T) { srv := testServer(t) defer srv.Close() res, err := http.Get(srv.URL + "/v1/health") if err != nil { t.Fatal(err) } defer res.Body.Close() if res.StatusCode != http.StatusOK || res.Header.Get(httpx.TraceHeader) == "" { t.Fatalf("health %d trace %q", res.StatusCode, res.Header.Get(httpx.TraceHeader)) } res, err = http.Get(srv.URL + "/v1/codes?domain=agent&q=provider") if err != nil { t.Fatal(err) } defer res.Body.Close() var defs []errcode.Definition if err := json.NewDecoder(res.Body).Decode(&defs); err != nil { t.Fatal(err) } if len(defs) == 0 { t.Fatal("expected agent provider codes") } for _, def := range defs { if def.Code.Domain() != "agent" || !strings.Contains(string(def.Code), "provider") && !strings.Contains(def.Summary, "提供") { t.Fatalf("unexpected hit %+v", def.Code) } } res, err = http.Get(srv.URL + "/v1/codes/provider_unavailable") if err != nil { t.Fatal(err) } defer res.Body.Close() var def errcode.Definition if err := json.NewDecoder(res.Body).Decode(&def); err != nil { t.Fatal(err) } if def.Code != errcode.AgentProviderUnavailable { t.Fatalf("alias get resolved to %s", def.Code) } res, err = http.Get(srv.URL + "/v1/codes/missing.code") if err != nil { t.Fatal(err) } defer res.Body.Close() if res.StatusCode != http.StatusNotFound { body, _ := io.ReadAll(res.Body) t.Fatalf("missing status %d body %s", res.StatusCode, body) } req, err := http.NewRequest(http.MethodPost, srv.URL+"/v1/validate", strings.NewReader(`{"codes":["TIMEOUT","nope"]}`)) if err != nil { t.Fatal(err) } req.Header.Set(httpx.TraceHeader, "trace-server-1") res, err = http.DefaultClient.Do(req) if err != nil { t.Fatal(err) } defer res.Body.Close() var payload struct { Results []struct { Input string `json:"input"` Known bool `json:"known"` Resolved string `json:"resolved"` } `json:"results"` } if err := json.NewDecoder(res.Body).Decode(&payload); err != nil { t.Fatal(err) } if len(payload.Results) != 2 || !payload.Results[0].Known || payload.Results[0].Resolved != string(errcode.AgentTimeout) { t.Fatalf("validate %+v", payload.Results) } if payload.Results[1].Known || payload.Results[1].Resolved != string(errcode.SysUnknownCode) { t.Fatalf("unknown %+v", payload.Results[1]) } if res.Header.Get(httpx.TraceHeader) != "trace-server-1" { t.Fatal("trace not echoed") } }