package service import ( "fmt" "net/http" "testing" "time" "github.com/stretchr/testify/assert" "apskel-pos-be/internal/processor" "apskel-pos-be/internal/repository" "apskel-pos-be/internal/util" ) func TestPinErrorResponse(t *testing.T) { until := time.Date(2026, 9, 30, 12, 30, 0, 0, time.UTC) for name, c := range map[string]struct { err error code string status int data map[string]interface{} }{ "not set": {&processor.PinError{Code: processor.PinErrNotSet}, "PIN_NOT_SET", http.StatusForbidden, map[string]interface{}{"code": "PIN_NOT_SET"}}, "invalid": {fmt.Errorf("pay: %w", &processor.PinError{Code: processor.PinErrInvalid, RemainingAttempts: 2}), "PIN_INVALID", http.StatusBadRequest, map[string]interface{}{"code": "PIN_INVALID", "remaining_attempts": 2}}, "locked": {&processor.PinError{Code: processor.PinErrLocked, Until: &until}, "PIN_LOCKED", http.StatusLocked, map[string]interface{}{"code": "PIN_LOCKED", "locked_until": &until}}, "transfer": {&processor.PinError{Code: processor.PinErrTransferBlocked, Until: &until}, "TRANSFER_BLOCKED", http.StatusForbidden, map[string]interface{}{"code": "TRANSFER_BLOCKED", "transfer_blocked_until": &until}}, } { resp := PinErrorResponse(c.err) assert.False(t, resp.Success, name) assert.Equal(t, c.code, resp.Errors[0].Code, name) assert.Equal(t, c.status, util.MapErrorCodeToHttpStatus(resp.Errors[0].Code), name) assert.Equal(t, c.data, resp.Data, name) } for name, c := range map[string]struct { err error status int }{ "weak PIN": {fmt.Errorf("%w: too easy", processor.ErrInvalidPinInput), http.StatusBadRequest}, "bad OTP": {processor.ErrPinOtpInvalid, http.StatusBadRequest}, "already set": {processor.ErrPinAlreadySet, http.StatusBadRequest}, "too soon": {processor.ErrPinOtpTooSoon, http.StatusTooManyRequests}, "no customer": {repository.ErrPinCustomerNotFound, http.StatusNotFound}, "anything else": {fmt.Errorf("db down"), http.StatusInternalServerError}, } { resp := PinErrorResponse(c.err) assert.Equal(t, c.status, util.MapErrorCodeToHttpStatus(resp.Errors[0].Code), name) } }