package reverseproxy import ( "context" "errors" "net/http" "net/http/httptest" "testing" "time" ) type staticToken string func (s staticToken) Token(context.Context) (string, error) { return string(s), nil } func TestNPMClientReadsOnlyProxyHostsAndUsesExternalToken(t *testing.T) { var method, authorization, path string server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { method, authorization, path = r.Method, r.Header.Get("Authorization"), r.URL.Path w.Header().Set("Content-Type", "application/json") _, _ = w.Write([]byte("[{\"id\":7,\"domain_names\":[\"pulse.example.test\"],\"forward_scheme\":\"http\",\"forward_host\":\"10.0.0.7\",\"forward_port\":8080,\"enabled\":true,\"meta\":{\"pulse_service_id\":\"svc-api\"}}]")) })) defer server.Close() now := time.Date(2026, 8, 2, 12, 0, 0, 0, time.UTC) routes, err := (NPMClient{BaseURL: server.URL, Token: staticToken("external-token"), Now: func() time.Time { return now }}).ListRoutes(context.Background()) if err != nil { t.Fatal(err) } if method != http.MethodGet || path != "/api/nginx/proxy-hosts" || authorization != "Bearer external-token" { t.Fatalf("unexpected request method=%s path=%s authorization=%s", method, path, authorization) } if len(routes) != 1 || routes[0].ID != "7:pulse.example.test" || routes[0].TargetServiceID != "svc-api" || routes[0].SourceID != "npm" { t.Fatalf("unexpected routes: %+v", routes) } } func TestNPMClientRejectsMutationAndOversizedResponses(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet { t.Fatalf("unexpected method %s", r.Method) } _, _ = w.Write([]byte("[]")) })) defer server.Close() client := NPMClient{BaseURL: server.URL, MaxBody: 1024} if _, err := client.ListRoutes(context.Background()); err != nil { t.Fatalf("small valid response should pass: %v", err) } if _, err := (NPMClient{BaseURL: server.URL, MaxBody: 9 << 20}).ListRoutes(context.Background()); err == nil { t.Fatal("expected unsafe body bound") } ctx, cancel := context.WithCancel(context.Background()) cancel() if _, err := client.ListRoutes(ctx); !errors.Is(err, context.Canceled) { t.Fatalf("expected cancellation, got %v", err) } }