You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

210 lines
5.4 KiB

package errors
import (
"errors"
"testing"
)
func TestValidationError(t *testing.T) {
err := ErrInvalidEventID
if err.Code() != "INVALID_ID" {
t.Errorf("expected code INVALID_ID, got %s", err.Code())
}
if err.Category() != "validation" {
t.Errorf("expected category validation, got %s", err.Category())
}
if err.Field != "id" {
t.Errorf("expected field id, got %s", err.Field)
}
if err.IsRetryable() {
t.Error("validation errors should not be retryable")
}
}
func TestAuthorizationError(t *testing.T) {
err := ErrAuthRequired
if err.Code() != "AUTH_REQUIRED" {
t.Errorf("expected code AUTH_REQUIRED, got %s", err.Code())
}
if !err.NeedsAuth() {
t.Error("ErrAuthRequired should indicate auth is needed")
}
err2 := ErrBanned
if err2.NeedsAuth() {
t.Error("ErrBanned should not indicate auth is needed")
}
}
func TestProcessingError(t *testing.T) {
err := ErrRateLimited
if err.Code() != "RATE_LIMITED" {
t.Errorf("expected code RATE_LIMITED, got %s", err.Code())
}
if !err.IsRetryable() {
t.Error("rate limit errors should be retryable")
}
err2 := ErrDuplicate
if err2.IsRetryable() {
t.Error("duplicate errors should not be retryable")
}
}
func TestStorageError(t *testing.T) {
err := ErrDatabaseUnavailable
if err.Code() != "DB_UNAVAILABLE" {
t.Errorf("expected code DB_UNAVAILABLE, got %s", err.Code())
}
if err.Category() != "storage" {
t.Errorf("expected category storage, got %s", err.Category())
}
if !err.IsRetryable() {
t.Error("database unavailable should be retryable")
}
}
func TestPolicyError(t *testing.T) {
err := NewPolicyBlocked("kind_whitelist", "kind 30023 not allowed")
if err.Code() != "POLICY_BLOCKED" {
t.Errorf("expected code POLICY_BLOCKED, got %s", err.Code())
}
if err.RuleName != "kind_whitelist" {
t.Errorf("expected rule name kind_whitelist, got %s", err.RuleName)
}
if err.Action != "block" {
t.Errorf("expected action block, got %s", err.Action)
}
}
func TestIsHelper(t *testing.T) {
if !Is(ErrInvalidEventID, ErrInvalidEventID) {
t.Error("Is should return true for same error")
}
if Is(ErrInvalidEventID, ErrInvalidSignature) {
t.Error("Is should return false for different errors")
}
// Test with non-domain error
stdErr := errors.New("standard error")
if Is(stdErr, ErrInvalidEventID) {
t.Error("Is should return false for non-domain errors")
}
}
func TestCodeHelper(t *testing.T) {
if Code(ErrInvalidEventID) != "INVALID_ID" {
t.Errorf("expected INVALID_ID, got %s", Code(ErrInvalidEventID))
}
stdErr := errors.New("standard error")
if Code(stdErr) != "" {
t.Errorf("expected empty string for non-domain error, got %s", Code(stdErr))
}
}
func TestCategoryHelper(t *testing.T) {
if Category(ErrInvalidEventID) != "validation" {
t.Errorf("expected validation, got %s", Category(ErrInvalidEventID))
}
if Category(ErrBanned) != "authorization" {
t.Errorf("expected authorization, got %s", Category(ErrBanned))
}
if Category(ErrDuplicate) != "processing" {
t.Errorf("expected processing, got %s", Category(ErrDuplicate))
}
stdErr := errors.New("standard error")
if Category(stdErr) != "unknown" {
t.Errorf("expected unknown for non-domain error, got %s", Category(stdErr))
}
}
func TestIsRetryableHelper(t *testing.T) {
if !IsRetryable(ErrRateLimited) {
t.Error("ErrRateLimited should be retryable")
}
if !IsRetryable(ErrDatabaseUnavailable) {
t.Error("ErrDatabaseUnavailable should be retryable")
}
if IsRetryable(ErrDuplicate) {
t.Error("ErrDuplicate should not be retryable")
}
if IsRetryable(ErrInvalidEventID) {
t.Error("ErrInvalidEventID should not be retryable")
}
}
func TestTypeCheckers(t *testing.T) {
if !IsValidation(ErrInvalidEventID) {
t.Error("ErrInvalidEventID should be a validation error")
}
if !IsAuthorization(ErrBanned) {
t.Error("ErrBanned should be an authorization error")
}
if !IsProcessing(ErrDuplicate) {
t.Error("ErrDuplicate should be a processing error")
}
if !IsPolicy(ErrKindBlocked) {
t.Error("ErrKindBlocked should be a policy error")
}
if !IsStorage(ErrDatabaseUnavailable) {
t.Error("ErrDatabaseUnavailable should be a storage error")
}
}
func TestNeedsAuthHelper(t *testing.T) {
if !NeedsAuth(ErrAuthRequired) {
t.Error("ErrAuthRequired should need auth")
}
if NeedsAuth(ErrBanned) {
t.Error("ErrBanned should not need auth")
}
if NeedsAuth(ErrInvalidEventID) {
t.Error("validation errors should not need auth")
}
}
func TestWithCause(t *testing.T) {
cause := errors.New("underlying error")
err := ErrDatabaseUnavailable.Base.WithCause(cause)
if err.Unwrap() != cause {
t.Error("WithCause should set the cause")
}
if err.Error() != "database not available: underlying error" {
t.Errorf("unexpected error message: %s", err.Error())
}
}
func TestWithMessage(t *testing.T) {
err := ErrInvalidEventID.Base.WithMessage("custom message")
if err.Error() != "custom message" {
t.Errorf("expected custom message, got %s", err.Error())
}
if err.Code() != "INVALID_ID" {
t.Error("code should be preserved")
}
}
func TestWithPubkey(t *testing.T) {
pubkey := []byte{1, 2, 3, 4}
err := ErrBanned.WithPubkey(pubkey)
if len(err.Pubkey) != 4 {
t.Error("pubkey should be set")
}
}
func TestWithEventID(t *testing.T) {
eventID := []byte{1, 2, 3, 4}
err := ErrDuplicate.WithEventID(eventID)
if len(err.EventID) != 4 {
t.Error("event ID should be set")
}
}
func TestWithKind(t *testing.T) {
err := ErrDuplicate.WithKind(30023)
if err.Kind != 30023 {
t.Errorf("expected kind 30023, got %d", err.Kind)
}
}