package bouncer import ( "net/http" "net/http/httptest" "strings" "testing" ) // Gap (a): Registry.Register of a type implementing neither Guard nor // CredentialGuard is already asserted by TestRegisterNeitherInterfaceNamesPluginAndName. // This file covers the remaining Register fail-loud branches and the // authenticate() default that Register itself makes unreachable through // the public API. func TestRegisterNilRegistryAndEmptyGuard(t *testing.T) { var nilReg *Registry if err := nilReg.Register("golem15.demo", "jwt", writerGuard{}); err == nil || !strings.Contains(err.Error(), "nil") { t.Fatalf("nil registry: %v", err) } reg := NewRegistry() if err := reg.Register("golem15.demo", "", writerGuard{}); err == nil || !strings.Contains(err.Error(), "golem15.demo") { t.Fatalf("empty name: %v", err) } if err := reg.Register("golem15.demo", "jwt", nil); err == nil || !strings.Contains(err.Error(), "jwt") { t.Fatalf("nil guard: %v", err) } } func TestAuthenticateDefaultNeitherInterface(t *testing.T) { // Register rejects this type; authenticate's default is only reachable // by calling it directly (same-package coverage of the fail-closed branch). p, cred, err := authenticate(notAGuard{}, httptest.NewRequest(http.MethodGet, "/", nil)) if p != nil || cred != nil { t.Fatalf("principal=%v cred=%v", p, cred) } if err == nil || !strings.Contains(err.Error(), "neither Guard nor CredentialGuard") { t.Fatalf("want neither-interface error, got %v", err) } } func TestNilRegistryMiddleware(t *testing.T) { var nilReg *Registry if _, err := nilReg.Middleware("jwt"); err == nil || !strings.Contains(err.Error(), "nil") { t.Fatalf("nil registry Middleware: %v", err) } } func TestGuardAuthenticateSuccessAttachesUser(t *testing.T) { reg := NewRegistry() principal := &Principal{ID: 7} if err := reg.Register("golem15.user", "jwt", writerGuard{principal: principal}); err != nil { t.Fatal(err) } mw, err := reg.Middleware("jwt") if err != nil { t.Fatal(err) } h := mw(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { got, ok := User(r.Context()) if !ok || got != principal { t.Fatalf("user = %+v ok=%t", got, ok) } if _, ok := Credential(r.Context()); ok { t.Fatal("plain Guard must not attach a credential") } w.WriteHeader(http.StatusNoContent) })) rec := httptest.NewRecorder() h.ServeHTTP(rec, httptest.NewRequest(http.MethodGet, "/", nil)) if rec.Code != http.StatusNoContent { t.Fatalf("status = %d", rec.Code) } } func TestWithUserNilContext(t *testing.T) { p := &Principal{ID: 1} got, ok := User(WithUser(nil, p)) if !ok || got != p { t.Fatalf("got %+v ok=%t", got, ok) } if _, ok := User(nil); ok { t.Fatal("nil context must have no user") } }