Files
sub2api/backend/internal/service/payment_config_plans_validation_test.go
erio ca673f9899 test: add 66 unit tests for balance/quota notify + plan validation
balance_notify_service_test.go (27 tests):
- resolveBalanceThreshold: fixed/percentage/zero recharged/empty type
- quotaDim.resolvedThreshold: fixed normal/exceed/equal limit, percentage 0/30/100/>100, zero/negative limit
- sanitizeEmailHeader: CRLF/CR/LF/clean/empty/multiple newlines
- buildQuotaDims / buildQuotaDimsFromState: all dimensions, empty extra, state-vs-account precedence
- collectBalanceNotifyRecipients: empty, filter disabled/unverified, case-insensitive dedup, skip empty, trim

balance_notify_check_test.go (16 tests):
- CheckBalanceAfterDeduction guard clauses: nil user/disabled/global-off/threshold=0/user-override/no-crossing
- CheckAccountQuotaAfterIncrement guards: nil account/zero cost/negative cost/global-disabled
- getBalanceNotifyConfig: all fields, disabled, invalid threshold
- isAccountQuotaNotifyEnabled: missing/false/true
- getSiteName: default fallback + configured

balance_notify_email_body_test.go (10 tests):
- Guards against fmt.Sprintf arg-count mismatches in email templates
- Verifies HTML escaping of recharge URL
- Verifies CSS %% escape produces literal % in output
- Verifies unlimited/percentage/over-quota display branches

payment_config_plans_validation_test.go (13 tests):
- validatePlanRequired: all 5 validation branches + whitespace handling
2026-04-14 09:31:45 +08:00

90 lines
2.6 KiB
Go

//go:build unit
package service
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestValidatePlanRequired_AllValid(t *testing.T) {
err := validatePlanRequired("Pro", 1, 9.99, 30, "days")
require.NoError(t, err)
}
func TestValidatePlanRequired_EmptyName(t *testing.T) {
err := validatePlanRequired("", 1, 9.99, 30, "days")
require.Error(t, err)
require.Contains(t, err.Error(), "plan name")
}
func TestValidatePlanRequired_WhitespaceName(t *testing.T) {
err := validatePlanRequired(" ", 1, 9.99, 30, "days")
require.Error(t, err)
require.Contains(t, err.Error(), "plan name")
}
func TestValidatePlanRequired_ZeroGroupID(t *testing.T) {
err := validatePlanRequired("Pro", 0, 9.99, 30, "days")
require.Error(t, err)
require.Contains(t, err.Error(), "group")
}
func TestValidatePlanRequired_NegativeGroupID(t *testing.T) {
err := validatePlanRequired("Pro", -1, 9.99, 30, "days")
require.Error(t, err)
require.Contains(t, err.Error(), "group")
}
func TestValidatePlanRequired_ZeroPrice(t *testing.T) {
err := validatePlanRequired("Pro", 1, 0, 30, "days")
require.Error(t, err)
require.Contains(t, err.Error(), "price")
}
func TestValidatePlanRequired_NegativePrice(t *testing.T) {
err := validatePlanRequired("Pro", 1, -5, 30, "days")
require.Error(t, err)
require.Contains(t, err.Error(), "price")
}
func TestValidatePlanRequired_ZeroValidityDays(t *testing.T) {
err := validatePlanRequired("Pro", 1, 9.99, 0, "days")
require.Error(t, err)
require.Contains(t, err.Error(), "validity days")
}
func TestValidatePlanRequired_NegativeValidityDays(t *testing.T) {
err := validatePlanRequired("Pro", 1, 9.99, -7, "days")
require.Error(t, err)
require.Contains(t, err.Error(), "validity days")
}
func TestValidatePlanRequired_EmptyValidityUnit(t *testing.T) {
err := validatePlanRequired("Pro", 1, 9.99, 30, "")
require.Error(t, err)
require.Contains(t, err.Error(), "validity unit")
}
func TestValidatePlanRequired_WhitespaceValidityUnit(t *testing.T) {
err := validatePlanRequired("Pro", 1, 9.99, 30, " ")
require.Error(t, err)
require.Contains(t, err.Error(), "validity unit")
}
func TestValidatePlanRequired_NameValidatedFirst(t *testing.T) {
// When multiple fields are invalid, name should be reported first
// (follows the order of checks in the function).
err := validatePlanRequired("", 0, 0, 0, "")
require.Error(t, err)
require.Contains(t, err.Error(), "plan name")
}
func TestValidatePlanRequired_TrimmedValidName(t *testing.T) {
// Whitespace-surrounded but non-empty name is accepted (trimmed check only
// rejects pure whitespace).
err := validatePlanRequired(" Pro ", 1, 9.99, 30, "days")
require.NoError(t, err)
}