package service import ( "testing" "time" "github.com/golang-jwt/jwt/v5" ) func TestAuthService_GenerateAndValidateToken(t *testing.T) { s := &AuthService{jwtSecret: "test-secret"} t.Run("valid access token", func(t *testing.T) { tokenStr, err := s.generateToken(1, "access", 15*time.Minute) if err != nil { t.Fatalf("generateToken error: %v", err) } claims, err := s.validateToken(tokenStr, "access") if err != nil { t.Fatalf("validateToken error: %v", err) } userID, ok := claims["user_id"].(float64) if !ok || int64(userID) != 1 { t.Errorf("expected user_id 1, got %v", claims["user_id"]) } }) t.Run("wrong token type rejected", func(t *testing.T) { tokenStr, _ := s.generateToken(1, "refresh", time.Hour) _, err := s.validateToken(tokenStr, "access") if err != ErrInvalidToken { t.Errorf("expected ErrInvalidToken, got %v", err) } }) t.Run("expired token rejected", func(t *testing.T) { tokenStr, _ := s.generateToken(1, "access", -time.Hour) _, err := s.validateToken(tokenStr, "access") if err != ErrInvalidToken { t.Errorf("expected ErrInvalidToken, got %v", err) } }) t.Run("wrong secret rejected", func(t *testing.T) { otherService := &AuthService{jwtSecret: "other-secret"} tokenStr, _ := otherService.generateToken(1, "access", time.Hour) _, err := s.validateToken(tokenStr, "access") if err != ErrInvalidToken { t.Errorf("expected ErrInvalidToken, got %v", err) } }) t.Run("tampered token rejected", func(t *testing.T) { tokenStr, _ := s.generateToken(1, "access", time.Hour) _, err := s.validateToken(tokenStr+"x", "access") if err != ErrInvalidToken { t.Errorf("expected ErrInvalidToken, got %v", err) } }) t.Run("HMAC signing method accepted", func(t *testing.T) { token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ "user_id": float64(1), "type": "access", "exp": time.Now().Add(time.Hour).Unix(), }) tokenStr, _ := token.SignedString([]byte("test-secret")) claims, err := s.validateToken(tokenStr, "access") if err != nil { t.Fatalf("should accept HS256: %v", err) } if claims["type"] != "access" { t.Error("claims type mismatch") } }) } func TestErrWeakPassword(t *testing.T) { if ErrWeakPassword.Error() != "password must be at least 8 characters" { t.Errorf("unexpected error message: %s", ErrWeakPassword.Error()) } } func TestErrInvalidCredentials(t *testing.T) { if ErrInvalidCredentials.Error() != "invalid credentials" { t.Errorf("unexpected error message: %s", ErrInvalidCredentials.Error()) } } func TestErrEmailNotVerified(t *testing.T) { if ErrEmailNotVerified.Error() != "email not verified" { t.Errorf("unexpected error message: %s", ErrEmailNotVerified.Error()) } }