package app import ( "encoding/json" "lingniu/vehicle-data-platform/apps/api/internal/config" "net/http" "net/http/httptest" "strings" "testing" "time" ) func TestWithRequestTimeoutAddsContextDeadline(t *testing.T) { handler := withRequestTimeout(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { deadline, ok := r.Context().Deadline() if !ok { t.Fatal("request context should have deadline") } if time.Until(deadline) > 250*time.Millisecond { t.Fatalf("deadline too far away: %s", time.Until(deadline)) } w.WriteHeader(http.StatusNoContent) }), 200*time.Millisecond) rec := httptest.NewRecorder() req := httptest.NewRequest(http.MethodGet, "/api/ops/health", nil) handler.ServeHTTP(rec, req) if rec.Code != http.StatusNoContent { t.Fatalf("status = %d", rec.Code) } } func TestWithRequestTimeoutReturnsEnvelopeWithTraceID(t *testing.T) { handler := withRequestTimeout(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { <-r.Context().Done() }), time.Millisecond) rec := httptest.NewRecorder() req := httptest.NewRequest(http.MethodGet, "/api/ops/health", nil) req.Header.Set("X-Trace-Id", "trace-from-test") handler.ServeHTTP(rec, req) if rec.Code != http.StatusServiceUnavailable { t.Fatalf("status = %d body=%s", rec.Code, rec.Body.String()) } var body struct { Error struct { Code string `json:"code"` Message string `json:"message"` } `json:"error"` TraceID string `json:"traceId"` } if err := json.Unmarshal(rec.Body.Bytes(), &body); err != nil { t.Fatalf("timeout response should be JSON: %v body=%s", err, rec.Body.String()) } if body.Error.Code != "REQUEST_TIMEOUT" || body.Error.Message != "请求处理超时" || body.TraceID != "trace-from-test" { t.Fatalf("unexpected timeout envelope: %+v body=%s", body, rec.Body.String()) } } func TestAppConfigScriptIsRuntimeRendered(t *testing.T) { handler := withAppConfig(http.NotFoundHandler(), config.Config{ AMapWebJSKey: "web-key", AMapSecurityCode: "security-code", AMapServiceHost: "/_AMapService", }) rec := httptest.NewRecorder() req := httptest.NewRequest(http.MethodGet, "/app-config.js", nil) handler.ServeHTTP(rec, req) if rec.Code != http.StatusOK { t.Fatalf("status = %d body=%s", rec.Code, rec.Body.String()) } if got := rec.Header().Get("Cache-Control"); got != "no-store" { t.Fatalf("Cache-Control = %q, want no-store", got) } body := rec.Body.String() for _, want := range []string{"window.__LINGNIU_APP_CONFIG__=", `"amapWebJsKey":"web-key"`, `"amapSecurityJsCode":"security-code"`, `"amapSecurityServiceHost":"/_AMapService"`} { if !strings.Contains(body, want) { t.Fatalf("app config script missing %q: %s", want, body) } } }