payment_config_plans_validation_test.go 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. //go:build unit
  2. package service
  3. import (
  4. "testing"
  5. "github.com/stretchr/testify/require"
  6. )
  7. func TestValidatePlanRequired_AllValid(t *testing.T) {
  8. err := validatePlanRequired("Pro", 1, 9.99, 30, "days", nil)
  9. require.NoError(t, err)
  10. }
  11. func TestValidatePlanRequired_EmptyName(t *testing.T) {
  12. err := validatePlanRequired("", 1, 9.99, 30, "days", nil)
  13. require.Error(t, err)
  14. require.Contains(t, err.Error(), "plan name")
  15. }
  16. func TestValidatePlanRequired_WhitespaceName(t *testing.T) {
  17. err := validatePlanRequired(" ", 1, 9.99, 30, "days", nil)
  18. require.Error(t, err)
  19. require.Contains(t, err.Error(), "plan name")
  20. }
  21. func TestValidatePlanRequired_ZeroGroupID(t *testing.T) {
  22. err := validatePlanRequired("Pro", 0, 9.99, 30, "days", nil)
  23. require.Error(t, err)
  24. require.Contains(t, err.Error(), "group")
  25. }
  26. func TestValidatePlanRequired_NegativeGroupID(t *testing.T) {
  27. err := validatePlanRequired("Pro", -1, 9.99, 30, "days", nil)
  28. require.Error(t, err)
  29. require.Contains(t, err.Error(), "group")
  30. }
  31. func TestValidatePlanRequired_ZeroPrice(t *testing.T) {
  32. err := validatePlanRequired("Pro", 1, 0, 30, "days", nil)
  33. require.Error(t, err)
  34. require.Contains(t, err.Error(), "price")
  35. }
  36. func TestValidatePlanRequired_NegativePrice(t *testing.T) {
  37. err := validatePlanRequired("Pro", 1, -5, 30, "days", nil)
  38. require.Error(t, err)
  39. require.Contains(t, err.Error(), "price")
  40. }
  41. func TestValidatePlanRequired_ZeroValidityDays(t *testing.T) {
  42. err := validatePlanRequired("Pro", 1, 9.99, 0, "days", nil)
  43. require.Error(t, err)
  44. require.Contains(t, err.Error(), "validity days")
  45. }
  46. func TestValidatePlanRequired_NegativeValidityDays(t *testing.T) {
  47. err := validatePlanRequired("Pro", 1, 9.99, -7, "days", nil)
  48. require.Error(t, err)
  49. require.Contains(t, err.Error(), "validity days")
  50. }
  51. func TestValidatePlanRequired_EmptyValidityUnit(t *testing.T) {
  52. err := validatePlanRequired("Pro", 1, 9.99, 30, "", nil)
  53. require.Error(t, err)
  54. require.Contains(t, err.Error(), "validity unit")
  55. }
  56. func TestValidatePlanRequired_WhitespaceValidityUnit(t *testing.T) {
  57. err := validatePlanRequired("Pro", 1, 9.99, 30, " ", nil)
  58. require.Error(t, err)
  59. require.Contains(t, err.Error(), "validity unit")
  60. }
  61. func TestValidatePlanRequired_NameValidatedFirst(t *testing.T) {
  62. err := validatePlanRequired("", 0, 0, 0, "", nil)
  63. require.Error(t, err)
  64. require.Contains(t, err.Error(), "plan name")
  65. }
  66. func TestValidatePlanRequired_TrimmedValidName(t *testing.T) {
  67. err := validatePlanRequired(" Pro ", 1, 9.99, 30, "days", nil)
  68. require.NoError(t, err)
  69. }
  70. func TestValidatePlanRequired_NegativeOriginalPrice(t *testing.T) {
  71. neg := -10.0
  72. err := validatePlanRequired("Pro", 1, 9.99, 30, "days", &neg)
  73. require.Error(t, err)
  74. require.Contains(t, err.Error(), "original price")
  75. }
  76. func TestValidatePlanRequired_ZeroOriginalPrice(t *testing.T) {
  77. zero := 0.0
  78. err := validatePlanRequired("Pro", 1, 9.99, 30, "days", &zero)
  79. require.NoError(t, err)
  80. }
  81. func TestValidatePlanRequired_ValidOriginalPrice(t *testing.T) {
  82. op := 19.99
  83. err := validatePlanRequired("Pro", 1, 9.99, 30, "days", &op)
  84. require.NoError(t, err)
  85. }
  86. // --- validatePlanPatch tests ---
  87. func TestValidatePlanPatch_NegativeOriginalPrice(t *testing.T) {
  88. neg := -5.0
  89. err := validatePlanPatch(UpdatePlanRequest{OriginalPrice: &neg})
  90. require.Error(t, err)
  91. require.Contains(t, err.Error(), "original price")
  92. }
  93. func TestValidatePlanPatch_ZeroOriginalPrice(t *testing.T) {
  94. zero := 0.0
  95. err := validatePlanPatch(UpdatePlanRequest{OriginalPrice: &zero})
  96. require.NoError(t, err)
  97. }
  98. func TestValidatePlanPatch_ValidOriginalPrice(t *testing.T) {
  99. op := 29.99
  100. err := validatePlanPatch(UpdatePlanRequest{OriginalPrice: &op})
  101. require.NoError(t, err)
  102. }
  103. func TestValidatePlanPatch_NilOriginalPrice(t *testing.T) {
  104. err := validatePlanPatch(UpdatePlanRequest{OriginalPrice: nil})
  105. require.NoError(t, err)
  106. }
  107. // --- validatePlanPatch: other fields ---
  108. func ptrStr(s string) *string { return &s }
  109. func ptrInt(i int) *int { return &i }
  110. func ptrInt64(i int64) *int64 { return &i }
  111. func ptrFloat(f float64) *float64 { return &f }
  112. func TestValidatePlanPatch_EmptyName(t *testing.T) {
  113. err := validatePlanPatch(UpdatePlanRequest{Name: ptrStr("")})
  114. require.Error(t, err)
  115. require.Contains(t, err.Error(), "plan name")
  116. }
  117. func TestValidatePlanPatch_ValidName(t *testing.T) {
  118. err := validatePlanPatch(UpdatePlanRequest{Name: ptrStr("Basic")})
  119. require.NoError(t, err)
  120. }
  121. func TestValidatePlanPatch_ZeroGroupID(t *testing.T) {
  122. err := validatePlanPatch(UpdatePlanRequest{GroupID: ptrInt64(0)})
  123. require.Error(t, err)
  124. require.Contains(t, err.Error(), "group")
  125. }
  126. func TestValidatePlanPatch_NegativePrice(t *testing.T) {
  127. err := validatePlanPatch(UpdatePlanRequest{Price: ptrFloat(-1)})
  128. require.Error(t, err)
  129. require.Contains(t, err.Error(), "price")
  130. }
  131. func TestValidatePlanPatch_ZeroPrice(t *testing.T) {
  132. err := validatePlanPatch(UpdatePlanRequest{Price: ptrFloat(0)})
  133. require.Error(t, err)
  134. require.Contains(t, err.Error(), "price")
  135. }
  136. func TestValidatePlanPatch_ValidPrice(t *testing.T) {
  137. err := validatePlanPatch(UpdatePlanRequest{Price: ptrFloat(9.99)})
  138. require.NoError(t, err)
  139. }
  140. func TestValidatePlanPatch_ZeroValidityDays(t *testing.T) {
  141. err := validatePlanPatch(UpdatePlanRequest{ValidityDays: ptrInt(0)})
  142. require.Error(t, err)
  143. require.Contains(t, err.Error(), "validity days")
  144. }
  145. func TestValidatePlanPatch_EmptyValidityUnit(t *testing.T) {
  146. err := validatePlanPatch(UpdatePlanRequest{ValidityUnit: ptrStr("")})
  147. require.Error(t, err)
  148. require.Contains(t, err.Error(), "validity unit")
  149. }
  150. func TestValidatePlanPatch_ValidValidityUnit(t *testing.T) {
  151. err := validatePlanPatch(UpdatePlanRequest{ValidityUnit: ptrStr("days")})
  152. require.NoError(t, err)
  153. }
  154. func TestValidatePlanPatch_AllNil(t *testing.T) {
  155. err := validatePlanPatch(UpdatePlanRequest{})
  156. require.NoError(t, err)
  157. }
  158. // --- normalizePlanCurrency tests ---
  159. // Empty must stay empty (not coerced to the default payment currency),
  160. // so existing plans keep rendering without any currency label.
  161. func TestNormalizePlanCurrency_EmptyKeepsEmpty(t *testing.T) {
  162. currency, err := normalizePlanCurrency("")
  163. require.NoError(t, err)
  164. require.Equal(t, "", currency)
  165. }
  166. func TestNormalizePlanCurrency_WhitespaceKeepsEmpty(t *testing.T) {
  167. currency, err := normalizePlanCurrency(" ")
  168. require.NoError(t, err)
  169. require.Equal(t, "", currency)
  170. }
  171. func TestNormalizePlanCurrency_LowercaseNormalized(t *testing.T) {
  172. currency, err := normalizePlanCurrency("nzd")
  173. require.NoError(t, err)
  174. require.Equal(t, "NZD", currency)
  175. }
  176. func TestNormalizePlanCurrency_ValidUppercase(t *testing.T) {
  177. currency, err := normalizePlanCurrency("USD")
  178. require.NoError(t, err)
  179. require.Equal(t, "USD", currency)
  180. }
  181. func TestNormalizePlanCurrency_TooShort(t *testing.T) {
  182. _, err := normalizePlanCurrency("NZ")
  183. require.Error(t, err)
  184. require.Contains(t, err.Error(), "currency")
  185. }
  186. func TestNormalizePlanCurrency_TooLong(t *testing.T) {
  187. _, err := normalizePlanCurrency("NZDD")
  188. require.Error(t, err)
  189. require.Contains(t, err.Error(), "currency")
  190. }
  191. func TestNormalizePlanCurrency_NonLetter(t *testing.T) {
  192. _, err := normalizePlanCurrency("N2D")
  193. require.Error(t, err)
  194. require.Contains(t, err.Error(), "currency")
  195. }