package extension import ( "context" "errors" "fmt" "net/http" "strings" "testing" ) type codedTestError int func (e codedTestError) Error() string { return "provider detail about other-owner" } func (e codedTestError) StatusCode() int { return int(e) } func TestWorkFailureStatusAndTextCarryNoIdentifiers(t *testing.T) { for reason, code := range map[string]int{ WorkFailureDuplicateName: http.StatusConflict, WorkFailurePolicyRejected: http.StatusForbidden, WorkFailureMappingNotReady: http.StatusServiceUnavailable, WorkFailureServiceUnavailable: http.StatusServiceUnavailable, "invented": 0, } { failure := WorkFailure{Operation: WorkOperationMemberAdd, Reason: reason} if failure.StatusCode() != code || failure.Error() != WorkOperationMemberAdd+": "+reason { t.Fatalf("%s: status=%d text=%q", reason, failure.StatusCode(), failure.Error()) } } } func TestCategorizeWorkFailure(t *testing.T) { cases := []struct { op string err error reason string ok bool }{ {WorkOperationProjectCreate, fmt.Errorf("wrap: %w", WorkFailure{Reason: WorkFailureMappingNotReady}), WorkFailureMappingNotReady, true}, {WorkOperationProjectCreate, codedTestError(409), WorkFailureDuplicateName, true}, {WorkOperationMemberAdd, codedTestError(403), WorkFailurePolicyRejected, true}, {WorkOperationConversation, codedTestError(503), WorkFailureServiceUnavailable, true}, {WorkOperationConversation, codedTestError(409), "", false}, {WorkOperationConversation, context.DeadlineExceeded, WorkFailureServiceUnavailable, true}, {WorkOperationMemberAdd, codedTestError(404), "", false}, {WorkOperationMemberAdd, WorkFailure{Reason: "invented"}, "", false}, {WorkOperationMemberAdd, errors.New("plain"), "", false}, {WorkOperationMemberAdd, nil, "", false}, } for _, tc := range cases { failure, ok := CategorizeWorkFailure(tc.op, tc.err) if ok != tc.ok || failure.Reason != tc.reason || (ok && failure.Operation != tc.op) || strings.Contains(failure.Error(), "other-owner") { t.Fatalf("%s %v: failure=%+v ok=%v", tc.op, tc.err, failure, ok) } } }