package handlers import ( "encoding/json" "net/http" "net/http/httptest" "testing" "time" "git.threesix.ai/jordan/sp4-verify-1770325799/pkg/auth" "git.threesix.ai/jordan/sp4-verify-1770325799/pkg/logging" ) func TestValidate_Check(t *testing.T) { secret := []byte("test-secret") logger := logging.New(logging.Config{Level: logging.LevelDebug}) validator := auth.NewJWTValidator(auth.JWTConfig{ Secret: secret, Issuer: "sp4-verify-1770325799", }) handler := NewValidate(validator, logger) // Generate a valid token user := &auth.User{ ID: "user-123", Email: "test@example.com", Roles: []string{"admin"}, Scopes: []string{"read", "write"}, } validToken, err := auth.GenerateTokenWithIssuer(secret, user, time.Hour, "sp4-verify-1770325799", "") if err != nil { t.Fatalf("failed to generate token: %v", err) } tests := []struct { name string authHeader string queryToken string wantValid bool wantUserID string wantStatusCode int }{ { name: "valid token in Authorization header", authHeader: "Bearer " + validToken, wantValid: true, wantUserID: "user-123", wantStatusCode: http.StatusOK, }, { name: "valid token without Bearer prefix", authHeader: validToken, wantValid: true, wantUserID: "user-123", wantStatusCode: http.StatusOK, }, { name: "valid token in query parameter", queryToken: validToken, wantValid: true, wantUserID: "user-123", wantStatusCode: http.StatusOK, }, { name: "invalid token", authHeader: "Bearer invalid-token", wantValid: false, wantStatusCode: http.StatusOK, }, { name: "missing token", wantValid: false, wantStatusCode: http.StatusBadRequest, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { url := "/api/auth-svc/validate" if tt.queryToken != "" { url += "?token=" + tt.queryToken } req := httptest.NewRequest(http.MethodGet, url, nil) if tt.authHeader != "" { req.Header.Set("Authorization", tt.authHeader) } rr := httptest.NewRecorder() err := handler.Check(rr, req) // Check if error was returned (for bad request cases) if tt.wantStatusCode == http.StatusBadRequest { if err == nil { t.Error("expected error for missing token") } return } if err != nil { t.Fatalf("handler returned error: %v", err) } if rr.Code != tt.wantStatusCode { t.Errorf("status code = %d, want %d", rr.Code, tt.wantStatusCode) } var resp struct { Data ValidateResponse `json:"data"` } if err := json.NewDecoder(rr.Body).Decode(&resp); err != nil { t.Fatalf("failed to decode response: %v", err) } if resp.Data.Valid != tt.wantValid { t.Errorf("valid = %v, want %v", resp.Data.Valid, tt.wantValid) } if tt.wantValid && resp.Data.User != nil { if resp.Data.User.ID != tt.wantUserID { t.Errorf("user ID = %s, want %s", resp.Data.User.ID, tt.wantUserID) } } }) } }