94 lines
2.7 KiB
Go
94 lines
2.7 KiB
Go
package woodpecker
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestAPIErrorToContextStatusMapping(t *testing.T) {
|
|
cases := []struct {
|
|
status int
|
|
wantCode string
|
|
wantInDesc string
|
|
}{
|
|
{401, "AUTH_ERROR", "Authentication failed"},
|
|
{403, "PERMISSION_ERROR", "Access denied"},
|
|
{404, "NOT_FOUND", "Resource not found"},
|
|
{429, "RATE_LIMIT", "Rate limit exceeded"},
|
|
{500, "SERVER_ERROR", "server error"},
|
|
{502, "SERVER_ERROR", "server error"},
|
|
{503, "SERVER_ERROR", "server error"},
|
|
{504, "SERVER_ERROR", "server error"},
|
|
{418, "UNKNOWN_ERROR", "Request failed"},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
t.Run(strings.ToLower(tc.wantCode), func(t *testing.T) {
|
|
e := &APIError{Status: tc.status, Message: "boom"}
|
|
got := e.ToContext("sample operation")
|
|
|
|
var ctx errorContext
|
|
if err := json.Unmarshal([]byte(got), &ctx); err != nil {
|
|
t.Fatalf("ToContext returned invalid JSON: %v\n%s", err, got)
|
|
}
|
|
if ctx.Error != tc.wantCode {
|
|
t.Errorf("error code = %q, want %q", ctx.Error, tc.wantCode)
|
|
}
|
|
if !strings.Contains(ctx.Description, tc.wantInDesc) {
|
|
t.Errorf("description %q does not contain %q", ctx.Description, tc.wantInDesc)
|
|
}
|
|
if !strings.Contains(ctx.Description, "sample operation") {
|
|
t.Errorf("description %q does not mention the context", ctx.Description)
|
|
}
|
|
if len(ctx.Suggestions) == 0 {
|
|
t.Error("suggestions must not be empty")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestAPIErrorToContextUnknownIncludesMessage(t *testing.T) {
|
|
e := &APIError{Status: 418, Message: "some detail"}
|
|
var ctx errorContext
|
|
if err := json.Unmarshal([]byte(e.ToContext("op")), &ctx); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !strings.Contains(ctx.Description, "some detail") {
|
|
t.Errorf("description %q should include the underlying message", ctx.Description)
|
|
}
|
|
}
|
|
|
|
func TestAPIErrorSuggestionsMatchReference(t *testing.T) {
|
|
cases := []struct {
|
|
status int
|
|
want []string
|
|
}{
|
|
{401, []string{
|
|
"Check that your WOODPECKER_TOKEN environment variable is set correctly",
|
|
"Verify the token has not expired",
|
|
"Ensure the token has sufficient permissions",
|
|
}},
|
|
{404, []string{
|
|
"Double-check the repository name, pipeline number, or step ID",
|
|
"Verify the resource exists and hasn't been deleted",
|
|
}},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
e := &APIError{Status: tc.status}
|
|
var ctx errorContext
|
|
if err := json.Unmarshal([]byte(e.ToContext("op")), &ctx); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(ctx.Suggestions) != len(tc.want) {
|
|
t.Fatalf("status %d: got %d suggestions, want %d", tc.status, len(ctx.Suggestions), len(tc.want))
|
|
}
|
|
for i := range tc.want {
|
|
if ctx.Suggestions[i] != tc.want[i] {
|
|
t.Errorf("status %d suggestion %d = %q, want %q", tc.status, i, ctx.Suggestions[i], tc.want[i])
|
|
}
|
|
}
|
|
}
|
|
}
|