| package admin |
|
|
| import ( |
| "bytes" |
| "encoding/json" |
| "net/http" |
| "net/http/httptest" |
| "testing" |
|
|
| "github.com/Wei-Shaw/sub2api/internal/service" |
| "github.com/gin-gonic/gin" |
| "github.com/stretchr/testify/assert" |
| "github.com/stretchr/testify/require" |
| ) |
|
|
| |
| |
| |
| func newCreateAndRedeemHandler() *RedeemHandler { |
| return &RedeemHandler{ |
| adminService: newStubAdminService(), |
| redeemService: &service.RedeemService{}, |
| } |
| } |
|
|
| |
| |
| |
| |
| func postCreateAndRedeemValidation(t *testing.T, handler *RedeemHandler, body any) (code int) { |
| t.Helper() |
| gin.SetMode(gin.TestMode) |
| w := httptest.NewRecorder() |
| c, _ := gin.CreateTestContext(w) |
|
|
| jsonBytes, err := json.Marshal(body) |
| require.NoError(t, err) |
| c.Request, _ = http.NewRequest(http.MethodPost, "/api/v1/admin/redeem-codes/create-and-redeem", bytes.NewReader(jsonBytes)) |
| c.Request.Header.Set("Content-Type", "application/json") |
|
|
| defer func() { |
| if r := recover(); r != nil { |
| |
| code = 0 |
| } |
| }() |
| handler.CreateAndRedeem(c) |
| return w.Code |
| } |
|
|
| func TestCreateAndRedeem_TypeDefaultsToBalance(t *testing.T) { |
| |
| |
| h := newCreateAndRedeemHandler() |
| code := postCreateAndRedeemValidation(t, h, map[string]any{ |
| "code": "test-balance-default", |
| "value": 10.0, |
| "user_id": 1, |
| }) |
|
|
| assert.NotEqual(t, http.StatusBadRequest, code, |
| "omitting type should default to balance and pass validation") |
| } |
|
|
| func TestCreateAndRedeem_SubscriptionRequiresGroupID(t *testing.T) { |
| h := newCreateAndRedeemHandler() |
| code := postCreateAndRedeemValidation(t, h, map[string]any{ |
| "code": "test-sub-no-group", |
| "type": "subscription", |
| "value": 29.9, |
| "user_id": 1, |
| "validity_days": 30, |
| |
| }) |
|
|
| assert.Equal(t, http.StatusBadRequest, code) |
| } |
|
|
| func TestCreateAndRedeem_SubscriptionRequiresPositiveValidityDays(t *testing.T) { |
| groupID := int64(5) |
| h := newCreateAndRedeemHandler() |
|
|
| cases := []struct { |
| name string |
| validityDays int |
| }{ |
| {"zero", 0}, |
| {"negative", -1}, |
| } |
|
|
| for _, tc := range cases { |
| t.Run(tc.name, func(t *testing.T) { |
| code := postCreateAndRedeemValidation(t, h, map[string]any{ |
| "code": "test-sub-bad-days-" + tc.name, |
| "type": "subscription", |
| "value": 29.9, |
| "user_id": 1, |
| "group_id": groupID, |
| "validity_days": tc.validityDays, |
| }) |
|
|
| assert.Equal(t, http.StatusBadRequest, code) |
| }) |
| } |
| } |
|
|
| func TestCreateAndRedeem_SubscriptionValidParamsPassValidation(t *testing.T) { |
| groupID := int64(5) |
| h := newCreateAndRedeemHandler() |
| code := postCreateAndRedeemValidation(t, h, map[string]any{ |
| "code": "test-sub-valid", |
| "type": "subscription", |
| "value": 29.9, |
| "user_id": 1, |
| "group_id": groupID, |
| "validity_days": 31, |
| }) |
|
|
| assert.NotEqual(t, http.StatusBadRequest, code, |
| "valid subscription params should pass validation") |
| } |
|
|
| func TestCreateAndRedeem_BalanceIgnoresSubscriptionFields(t *testing.T) { |
| h := newCreateAndRedeemHandler() |
| |
| code := postCreateAndRedeemValidation(t, h, map[string]any{ |
| "code": "test-balance-no-extras", |
| "type": "balance", |
| "value": 50.0, |
| "user_id": 1, |
| }) |
|
|
| assert.NotEqual(t, http.StatusBadRequest, code, |
| "balance type should not require group_id or validity_days") |
| } |
|
|