Repository navigation
Expand file tree
/
Copy patherrors_test.go
More file actions
107 lines (90 loc) · 3.01 KB
/
Copy patherrors_test.go
File metadata and controls
107 lines (90 loc) · 3.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package itglue
import (
"errors"
"testing"
"time"
)
func TestError_Interface(t *testing.T) {
err := Error{Code: 404, Message: "Not found", Type: "not_found"}
if err.Error() != "itglue: Not found (code: 404)" {
t.Errorf("Unexpected error string: %s", err.Error())
}
// Test that it implements error interface
var _ error = err
}
func TestRateLimitError_RetryAfter(t *testing.T) {
err := RateLimitError{
BaseError: Error{Code: 429, Message: "Rate limit exceeded", Type: "rate_limit"},
RetryAfter: 30 * time.Second,
}
expected := "itglue: rate limit exceeded, retry after 30s"
if err.Error() != expected {
t.Errorf("Expected %q, got %q", expected, err.Error())
}
}
func TestValidationError_Message(t *testing.T) {
err := ValidationError{
BaseError: Error{Code: 422, Message: "Validation failed", Type: "validation"},
Field: "email",
Reason: "invalid format",
}
expected := "itglue: validation error on field 'email': invalid format"
if err.Error() != expected {
t.Errorf("Expected %q, got %q", expected, err.Error())
}
}
func TestAuthError_Message(t *testing.T) {
err := AuthError{
BaseError: Error{Code: 401, Message: "Unauthorized", Type: "auth"},
}
expected := "itglue: authentication failed - invalid or expired API key"
if err.Error() != expected {
t.Errorf("Expected %q, got %q", expected, err.Error())
}
}
func TestNotFoundError_Message(t *testing.T) {
err := NotFoundError{
BaseError: Error{Code: 404, Message: "Not found", Type: "not_found"},
ResourceType: "organization",
ResourceID: "123",
}
expected := "itglue: organization with id '123' not found"
if err.Error() != expected {
t.Errorf("Expected %q, got %q", expected, err.Error())
}
}
func TestErrors_Is_MatchesSentinels(t *testing.T) {
// handleErrorResponse always returns pointers, so exercise the same
// shape here: errors.Is must unwrap through the pointer to the sentinel.
tests := []struct {
name string
err error
sentinel error
}{
{"AuthError -> ErrUnauthorized", &AuthError{BaseError: Error{Code: 401}}, ErrUnauthorized},
{"ForbiddenError -> ErrForbidden", &ForbiddenError{BaseError: Error{Code: 403}}, ErrForbidden},
{"NotFoundError -> ErrNotFound", &NotFoundError{BaseError: Error{Code: 404}}, ErrNotFound},
{"RateLimitError -> ErrRateLimited", &RateLimitError{BaseError: Error{Code: 429}}, ErrRateLimited},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if !errors.Is(tt.err, tt.sentinel) {
t.Errorf("errors.Is(%T, %v) = false, want true", tt.err, tt.sentinel)
}
})
}
// Sanity check: unrelated sentinels must not match.
if errors.Is(&AuthError{}, ErrNotFound) {
t.Error("errors.Is(*AuthError, ErrNotFound) = true, want false")
}
}
func TestAPIError_Message(t *testing.T) {
err := APIError{
BaseError: Error{Code: 400, Message: "Bad request", Type: "api"},
Errors: []ErrorDetail{}, // Empty for this test
}
expected := "itglue: Bad request (code: 400)"
if err.Error() != expected {
t.Errorf("Expected %q, got %q", expected, err.Error())
}
}