package console import ( "errors" "testing" "github.com/aws/smithy-go" ) // TestIsAuthShapedError pins the classifier the review round added: // realCECosts must latch (permanently disable itself for the process) only // on the "billing IAM isn't set up here" shape — AccessDenied and an // unrecognized/invalid credential — and must NOT latch on a throttle, a // service-side limit, a 5xx, or a plain non-API error, all of which are // worth retrying on the next hourly tick. func TestIsAuthShapedError(t *testing.T) { cases := []struct { name string err error want bool }{ {"access denied exception", &smithy.GenericAPIError{Code: "AccessDeniedException"}, true}, {"access denied bare", &smithy.GenericAPIError{Code: "AccessDenied"}, true}, {"unrecognized client", &smithy.GenericAPIError{Code: "UnrecognizedClientException"}, true}, {"invalid client token id", &smithy.GenericAPIError{Code: "InvalidClientTokenId"}, true}, {"invalid access key id", &smithy.GenericAPIError{Code: "InvalidAccessKeyId"}, true}, {"expired token", &smithy.GenericAPIError{Code: "ExpiredTokenException"}, true}, {"auth failure", &smithy.GenericAPIError{Code: "AuthFailure"}, true}, {"throttling", &smithy.GenericAPIError{Code: "ThrottlingException"}, false}, {"limit exceeded", &smithy.GenericAPIError{Code: "LimitExceededException"}, false}, {"internal error", &smithy.GenericAPIError{Code: "InternalError"}, false}, {"service unavailable", &smithy.GenericAPIError{Code: "ServiceUnavailableException"}, false}, {"plain error", errors.New("network is down"), false}, {"nil", nil, false}, } for _, c := range cases { if got := isAuthShapedError(c.err); got != c.want { t.Errorf("%s: isAuthShapedError(%v) = %v, want %v", c.name, c.err, got, c.want) } } }