51 lines
2.1 KiB
Go
51 lines
2.1 KiB
Go
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)
|
||
|
|
}
|
||
|
|
}
|