| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- //go:build unit
- package errors
- import (
- stderrors "errors"
- "fmt"
- "io"
- "net/http"
- "testing"
- "github.com/stretchr/testify/require"
- )
- func TestApplicationError_Basics(t *testing.T) {
- tests := []struct {
- name string
- err *ApplicationError
- want Status
- wantIs bool
- target error
- wrapped error
- }{
- {
- name: "new",
- err: New(400, "BAD_REQUEST", "invalid input"),
- want: Status{
- Code: 400,
- Reason: "BAD_REQUEST",
- Message: "invalid input",
- },
- },
- {
- name: "is_matches_code_and_reason",
- err: New(401, "UNAUTHORIZED", "nope"),
- want: Status{Code: 401, Reason: "UNAUTHORIZED", Message: "nope"},
- target: New(401, "UNAUTHORIZED", "ignored message"),
- wantIs: true,
- },
- {
- name: "is_does_not_match_reason",
- err: New(401, "UNAUTHORIZED", "nope"),
- want: Status{Code: 401, Reason: "UNAUTHORIZED", Message: "nope"},
- target: New(401, "DIFFERENT", "ignored message"),
- wantIs: false,
- },
- {
- name: "from_error_unwraps_wrapped_application_error",
- err: New(404, "NOT_FOUND", "missing"),
- wrapped: fmt.Errorf("wrap: %w", New(404, "NOT_FOUND", "missing")),
- want: Status{
- Code: 404,
- Reason: "NOT_FOUND",
- Message: "missing",
- },
- },
- }
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- if tt.err != nil {
- require.Equal(t, tt.want, tt.err.Status)
- }
- if tt.target != nil {
- require.Equal(t, tt.wantIs, stderrors.Is(tt.err, tt.target))
- }
- if tt.wrapped != nil {
- got := FromError(tt.wrapped)
- require.Equal(t, tt.want, got.Status)
- }
- })
- }
- }
- func TestApplicationError_WithMetadataDeepCopy(t *testing.T) {
- tests := []struct {
- name string
- md map[string]string
- }{
- {name: "non_nil", md: map[string]string{"a": "1"}},
- {name: "nil", md: nil},
- }
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- appErr := BadRequest("BAD_REQUEST", "invalid input").WithMetadata(tt.md)
- if tt.md == nil {
- require.Nil(t, appErr.Metadata)
- return
- }
- tt.md["a"] = "changed"
- require.Equal(t, "1", appErr.Metadata["a"])
- })
- }
- }
- func TestFromError_Generic(t *testing.T) {
- tests := []struct {
- name string
- err error
- wantCode int32
- wantReason string
- wantMsg string
- }{
- {
- name: "plain_error",
- err: stderrors.New("boom"),
- wantCode: UnknownCode,
- wantReason: UnknownReason,
- wantMsg: UnknownMessage,
- },
- {
- name: "wrapped_plain_error",
- err: fmt.Errorf("wrap: %w", io.EOF),
- wantCode: UnknownCode,
- wantReason: UnknownReason,
- wantMsg: UnknownMessage,
- },
- }
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- got := FromError(tt.err)
- require.Equal(t, tt.wantCode, got.Code)
- require.Equal(t, tt.wantReason, got.Reason)
- require.Equal(t, tt.wantMsg, got.Message)
- require.Equal(t, tt.err, got.Unwrap())
- })
- }
- }
- func TestToHTTP(t *testing.T) {
- tests := []struct {
- name string
- err error
- wantStatusCode int
- wantBody Status
- }{
- {
- name: "nil_error",
- err: nil,
- wantStatusCode: http.StatusOK,
- wantBody: Status{Code: int32(http.StatusOK)},
- },
- {
- name: "application_error",
- err: Forbidden("FORBIDDEN", "no access"),
- wantStatusCode: http.StatusForbidden,
- wantBody: Status{
- Code: int32(http.StatusForbidden),
- Reason: "FORBIDDEN",
- Message: "no access",
- },
- },
- }
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- code, body := ToHTTP(tt.err)
- require.Equal(t, tt.wantStatusCode, code)
- require.Equal(t, tt.wantBody, body)
- })
- }
- }
- func TestToHTTP_MetadataDeepCopy(t *testing.T) {
- md := map[string]string{"k": "v"}
- appErr := BadRequest("BAD_REQUEST", "invalid").WithMetadata(md)
- code, body := ToHTTP(appErr)
- require.Equal(t, http.StatusBadRequest, code)
- require.Equal(t, "v", body.Metadata["k"])
- md["k"] = "changed"
- require.Equal(t, "v", body.Metadata["k"])
- appErr.Metadata["k"] = "changed-again"
- require.Equal(t, "v", body.Metadata["k"])
- }
|