package service import ( "baron-sso-backend/internal/domain" "context" "encoding/json" "net/http" "testing" "github.com/stretchr/testify/assert" ) func TestHydraAdminService_ListClients(t *testing.T) { clients := []domain.HydraClient{ {ClientID: "client1", ClientName: "Client 1"}, {ClientID: "client2", ClientName: "Client 2"}, } handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, "/clients", r.URL.Path) assert.Equal(t, "GET", r.Method) assert.Equal(t, "10", r.URL.Query().Get("limit")) assert.Equal(t, "5", r.URL.Query().Get("offset")) w.Header().Set("Content-Type", "application/json") _ = json.NewEncoder(w).Encode(clients) }) s := &HydraAdminService{ AdminURL: "http://hydra-admin.local", HTTPClient: clientForHandler(handler), } result, err := s.ListClients(context.Background(), 10, 5) assert.NoError(t, err) assert.Equal(t, clients, result) } func TestHydraAdminService_GetClient(t *testing.T) { client := domain.HydraClient{ClientID: "test-client", ClientName: "Test Client"} handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, "/clients/test-client", r.URL.Path) assert.Equal(t, "GET", r.Method) w.Header().Set("Content-Type", "application/json") _ = json.NewEncoder(w).Encode(client) }) s := &HydraAdminService{ AdminURL: "http://hydra-admin.local", HTTPClient: clientForHandler(handler), } result, err := s.GetClient(context.Background(), "test-client") assert.NoError(t, err) assert.Equal(t, &client, result) } func TestHydraAdminService_CreateClient(t *testing.T) { client := domain.HydraClient{ClientName: "New Client"} created := domain.HydraClient{ClientID: "new-id", ClientName: "New Client"} handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, "/clients", r.URL.Path) assert.Equal(t, "POST", r.Method) var received domain.HydraClient _ = json.NewDecoder(r.Body).Decode(&received) assert.Equal(t, client.ClientName, received.ClientName) w.WriteHeader(http.StatusCreated) _ = json.NewEncoder(w).Encode(created) }) s := &HydraAdminService{ AdminURL: "http://hydra-admin.local", HTTPClient: clientForHandler(handler), } result, err := s.CreateClient(context.Background(), client) assert.NoError(t, err) assert.Equal(t, &created, result) } func TestHydraAdminService_DeleteClient(t *testing.T) { handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, "/clients/to-delete", r.URL.Path) assert.Equal(t, "DELETE", r.Method) w.WriteHeader(http.StatusNoContent) }) s := &HydraAdminService{ AdminURL: "http://hydra-admin.local", HTTPClient: clientForHandler(handler), } err := s.DeleteClient(context.Background(), "to-delete") assert.NoError(t, err) } func TestHydraAdminService_GetConsentRequest(t *testing.T) { challenge := "challenge123" consentReq := domain.HydraConsentRequest{Challenge: challenge, Subject: "user1"} handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, "/oauth2/auth/requests/consent", r.URL.Path) assert.Equal(t, challenge, r.URL.Query().Get("consent_challenge")) w.Header().Set("Content-Type", "application/json") _ = json.NewEncoder(w).Encode(consentReq) }) s := &HydraAdminService{ AdminURL: "http://hydra-admin.local", HTTPClient: clientForHandler(handler), } result, err := s.GetConsentRequest(context.Background(), challenge) assert.NoError(t, err) assert.Equal(t, &consentReq, result) } func TestHydraAdminService_PatchClientStatus(t *testing.T) { handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, "/clients/test-client", r.URL.Path) assert.Equal(t, "PATCH", r.Method) assert.Equal(t, "application/json-patch+json", r.Header.Get("Content-Type")) var payload []map[string]any _ = json.NewDecoder(r.Body).Decode(&payload) assert.Equal(t, "replace", payload[0]["op"]) assert.Equal(t, "/metadata/status", payload[0]["path"]) assert.Equal(t, "inactive", payload[0]["value"]) w.Header().Set("Content-Type", "application/json") _ = json.NewEncoder(w).Encode(domain.HydraClient{ClientID: "test-client"}) }) s := &HydraAdminService{ AdminURL: "http://hydra-admin.local", HTTPClient: clientForHandler(handler), } _, err := s.PatchClientStatus(context.Background(), "test-client", "inactive") assert.NoError(t, err) } func TestHydraAdminService_UpdateClient(t *testing.T) { client := domain.HydraClient{ClientName: "Updated Name"} handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, "/clients/test-client", r.URL.Path) assert.Equal(t, "PUT", r.Method) w.Header().Set("Content-Type", "application/json") _ = json.NewEncoder(w).Encode(client) }) s := &HydraAdminService{ AdminURL: "http://hydra-admin.local", HTTPClient: clientForHandler(handler), } _, err := s.UpdateClient(context.Background(), "test-client", client) assert.NoError(t, err) } func TestHydraAdminService_ListConsentSessions(t *testing.T) { sessions := []domain.HydraConsentSession{{Subject: "user1"}} handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, "/oauth2/auth/sessions/consent", r.URL.Path) assert.Equal(t, "user1", r.URL.Query().Get("subject")) w.Header().Set("Content-Type", "application/json") _ = json.NewEncoder(w).Encode(sessions) }) s := &HydraAdminService{ AdminURL: "http://hydra-admin.local", HTTPClient: clientForHandler(handler), } result, err := s.ListConsentSessions(context.Background(), "user1", "") assert.NoError(t, err) assert.Equal(t, sessions, result) } func TestHydraAdminService_RevokeConsentSessions(t *testing.T) { handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, "/oauth2/auth/sessions/consent", r.URL.Path) assert.Equal(t, "DELETE", r.Method) w.WriteHeader(http.StatusNoContent) }) s := &HydraAdminService{ AdminURL: "http://hydra-admin.local", HTTPClient: clientForHandler(handler), } err := s.RevokeConsentSessions(context.Background(), "user1", "") assert.NoError(t, err) } func TestHydraAdminService_RejectConsentRequest(t *testing.T) { handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, "/oauth2/auth/requests/consent/reject", r.URL.Path) assert.Equal(t, "PUT", r.Method) w.Header().Set("Content-Type", "application/json") _ = json.NewEncoder(w).Encode(map[string]string{"redirect_to": "http://reject"}) }) s := &HydraAdminService{ AdminURL: "http://hydra-admin.local", HTTPClient: clientForHandler(handler), } resp, err := s.RejectConsentRequest(context.Background(), "challenge") assert.NoError(t, err) assert.Equal(t, "http://reject", resp.RedirectTo) } func TestHydraAdminService_RejectLoginRequest(t *testing.T) { handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, "/oauth2/auth/requests/login/reject", r.URL.Path) assert.Equal(t, "PUT", r.Method) w.Header().Set("Content-Type", "application/json") _ = json.NewEncoder(w).Encode(map[string]string{"redirect_to": "http://reject-login"}) }) s := &HydraAdminService{ AdminURL: "http://hydra-admin.local", HTTPClient: clientForHandler(handler), } resp, err := s.RejectLoginRequest(context.Background(), "challenge", "error", "desc") assert.NoError(t, err) assert.Equal(t, "http://reject-login", resp.RedirectTo) } func TestHydraAdminService_GetLoginRequest(t *testing.T) { loginReq := domain.HydraLoginRequest{Challenge: "challenge"} handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, "/oauth2/auth/requests/login", r.URL.Path) w.Header().Set("Content-Type", "application/json") _ = json.NewEncoder(w).Encode(loginReq) }) s := &HydraAdminService{ AdminURL: "http://hydra-admin.local", HTTPClient: clientForHandler(handler), } result, err := s.GetLoginRequest(context.Background(), "challenge") assert.NoError(t, err) assert.Equal(t, &loginReq, result) } func TestHydraAdminService_AcceptConsentRequest(t *testing.T) { grant := &domain.HydraConsentRequest{RequestedScope: []string{"openid"}} handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, "/oauth2/auth/requests/consent/accept", r.URL.Path) assert.Equal(t, "PUT", r.Method) w.Header().Set("Content-Type", "application/json") _ = json.NewEncoder(w).Encode(map[string]string{"redirect_to": "http://accept"}) }) s := &HydraAdminService{ AdminURL: "http://hydra-admin.local", HTTPClient: clientForHandler(handler), } resp, err := s.AcceptConsentRequest(context.Background(), "challenge", grant, nil) assert.NoError(t, err) assert.Equal(t, "http://accept", resp.RedirectTo) } func TestHydraAdminService_AcceptLoginRequest(t *testing.T) { challenge := "login_challenge" subject := "user@example.com" redirectTo := "http://hydra/auth/confirm" handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, "/oauth2/auth/requests/login/accept", r.URL.Path) assert.Equal(t, challenge, r.URL.Query().Get("login_challenge")) var body map[string]any _ = json.NewDecoder(r.Body).Decode(&body) assert.Equal(t, subject, body["subject"]) w.Header().Set("Content-Type", "application/json") _ = json.NewEncoder(w).Encode(map[string]string{"redirect_to": redirectTo}) }) s := &HydraAdminService{ AdminURL: "http://hydra-admin.local", HTTPClient: clientForHandler(handler), } result, err := s.AcceptLoginRequest(context.Background(), challenge, subject) assert.NoError(t, err) assert.Equal(t, redirectTo, result.RedirectTo) } func TestHydraAdminService_ErrorHandling(t *testing.T) { handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusBadRequest) _, _ = w.Write([]byte("bad request")) }) s := &HydraAdminService{ AdminURL: "http://hydra-admin.local", HTTPClient: clientForHandler(handler), } _, err := s.GetClient(context.Background(), "invalid") assert.Error(t, err) assert.Contains(t, err.Error(), "status=400") err = s.DeleteClient(context.Background(), "invalid") assert.Error(t, err) _, err = s.ListClients(context.Background(), 10, 0) assert.Error(t, err) _, err = s.PatchClientStatus(context.Background(), "invalid", "active") assert.Error(t, err) } func TestHydraAdminService_NotFound(t *testing.T) { handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNotFound) }) s := &HydraAdminService{ AdminURL: "http://hydra-admin.local", HTTPClient: clientForHandler(handler), } _, err := s.GetClient(context.Background(), "none") assert.Equal(t, ErrHydraNotFound, err) }