S SmartDocs
Chuỗi bài: Go go 98 dòng · Cập nhật 2026-04-18

payment_test.go

Go/payment-gateway-challenge/internal/validation/payment_test.go

package validation

import (
	"strings"
	"testing"
	"time"
)

func TestValidateProcessRequest_OK(t *testing.T) {
	allowed := []string{"USD", "GBP", "EUR"}
	now := time.Date(2026, 4, 1, 0, 0, 0, 0, time.UTC)
	req := ProcessPaymentRequest{
		CardNumber:  "4242424242424242",
		ExpiryMonth: 12,
		ExpiryYear:  2030,
		Currency:    "usd",
		Amount:      1050,
		CVV:         "123",
	}
	if errs := ValidateProcessRequest(req, allowed, now); len(errs) != 0 {
		t.Fatalf("expected no errors, got %v", errs)
	}
}

func TestValidateProcessRequest_RejectedCases(t *testing.T) {
	allowed := []string{"USD"}
	now := time.Date(2026, 6, 15, 0, 0, 0, 0, time.UTC)

	cases := []struct {
		name string
		req  ProcessPaymentRequest
		want string // substring of one error
	}{
		{
			name: "short pan",
			req: ProcessPaymentRequest{
				CardNumber: "123", ExpiryMonth: 12, ExpiryYear: 2030, Currency: "USD", Amount: 1, CVV: "123",
			},
			want: "14 and 19",
		},
		{
			name: "non numeric pan",
			req: ProcessPaymentRequest{
				CardNumber: "424242424242424a", ExpiryMonth: 12, ExpiryYear: 2030, Currency: "USD", Amount: 1, CVV: "123",
			},
			want: "numeric",
		},
		{
			name: "bad currency",
			req: ProcessPaymentRequest{
				CardNumber: "4242424242424242", ExpiryMonth: 12, ExpiryYear: 2030, Currency: "JPY", Amount: 1, CVV: "123",
			},
			want: "currency",
		},
		{
			name: "expired",
			req: ProcessPaymentRequest{
				CardNumber: "4242424242424242", ExpiryMonth: 1, ExpiryYear: 2020, Currency: "USD", Amount: 1, CVV: "123",
			},
			want: "expired",
		},
		{
			name: "cvv too short",
			req: ProcessPaymentRequest{
				CardNumber: "4242424242424242", ExpiryMonth: 12, ExpiryYear: 2030, Currency: "USD", Amount: 1, CVV: "12",
			},
			want: "cvv",
		},
	}
	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			errs := ValidateProcessRequest(tc.req, allowed, now)
			if len(errs) == 0 {
				t.Fatal("expected errors")
			}
			joined := errs[0]
			for _, e := range errs[1:] {
				joined += " " + e
			}
			// crude: ensure our expected keyword appears somewhere in messages
			if !strings.Contains(strings.ToLower(joined), strings.ToLower(tc.want)) {
				t.Fatalf("errors %v do not mention %q", errs, tc.want)
			}
		})
	}
}

func TestMaskPAN(t *testing.T) {
	if got := MaskPAN("8877", 16); got != "************8877" {
		t.Fatalf("got %q", got)
	}
}

func TestLastFourDigits(t *testing.T) {
	if got := LastFourDigits("2222405343248877"); got != "8877" {
		t.Fatalf("got %q", got)
	}
}

Bài viết liên quan