Initial sanitized code sync

This commit is contained in:
zqq61
2026-03-15 20:48:19 +08:00
commit 17ee51ba04
126 changed files with 22546 additions and 0 deletions

View File

@@ -0,0 +1,220 @@
package card
import (
"context"
"testing"
"gpt-plus/internal/db"
"github.com/glebarez/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
func setupCardTestDB(t *testing.T) *gorm.DB {
t.Helper()
d, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{
Logger: logger.Default.LogMode(logger.Silent),
})
if err != nil {
t.Fatalf("open db: %v", err)
}
d.AutoMigrate(&db.SystemConfig{}, &db.Card{}, &db.CardCode{})
db.DB = d
return d
}
func insertCard(t *testing.T, d *gorm.DB, number, status string, maxBinds int) *db.Card {
t.Helper()
card := &db.Card{
NumberHash: db.HashSHA256(number),
NumberEnc: number, // no encryption in test (key not set)
CVCEnc: "123",
ExpMonth: "12", ExpYear: "2030",
Name: "Test", Country: "US",
Status: status, MaxBinds: maxBinds,
}
d.Create(card)
return card
}
func TestGetCardReturnsActiveCard(t *testing.T) {
d := setupCardTestDB(t)
insertCard(t, d, "4111111111111111", "active", 3)
prov := NewDBCardProvider(DBCardProviderConfig{DB: d})
card, err := prov.GetCard(context.Background())
if err != nil {
t.Fatalf("GetCard: %v", err)
}
if card.Number != "4111111111111111" {
t.Fatalf("number = %q", card.Number)
}
}
func TestGetCardActivatesAvailable(t *testing.T) {
d := setupCardTestDB(t)
insertCard(t, d, "4242424242424242", "available", 1)
prov := NewDBCardProvider(DBCardProviderConfig{DB: d})
card, err := prov.GetCard(context.Background())
if err != nil {
t.Fatalf("GetCard: %v", err)
}
if card.Number != "4242424242424242" {
t.Fatalf("number = %q", card.Number)
}
var dbCard db.Card
d.First(&dbCard, "number_hash = ?", db.HashSHA256("4242424242424242"))
if dbCard.Status != "active" {
t.Fatalf("card should now be active, got %q", dbCard.Status)
}
}
func TestGetCardNoCardsReturnsError(t *testing.T) {
d := setupCardTestDB(t)
prov := NewDBCardProvider(DBCardProviderConfig{DB: d})
_, err := prov.GetCard(context.Background())
if err == nil {
t.Fatal("expected error when no cards")
}
}
func TestReportResultSuccessIncrementsBind(t *testing.T) {
d := setupCardTestDB(t)
insertCard(t, d, "5555555555554444", "active", 3)
prov := NewDBCardProvider(DBCardProviderConfig{DB: d})
card, _ := prov.GetCard(context.Background())
err := prov.ReportResult(context.Background(), card, true)
if err != nil {
t.Fatalf("ReportResult: %v", err)
}
var dbCard db.Card
d.First(&dbCard, "number_hash = ?", db.HashSHA256("5555555555554444"))
if dbCard.BindCount != 1 {
t.Fatalf("bind_count = %d, want 1", dbCard.BindCount)
}
if dbCard.Status != "active" {
t.Fatalf("still active when under max_binds, got %q", dbCard.Status)
}
}
func TestReportResultExhaustsCard(t *testing.T) {
d := setupCardTestDB(t)
c := insertCard(t, d, "6011111111111117", "active", 1)
// Pre-set to 0, so one success = 1 = maxBinds → exhausted
_ = c
prov := NewDBCardProvider(DBCardProviderConfig{DB: d})
card, _ := prov.GetCard(context.Background())
prov.ReportResult(context.Background(), card, true)
var dbCard db.Card
d.First(&dbCard, "number_hash = ?", db.HashSHA256("6011111111111117"))
if dbCard.Status != "exhausted" {
t.Fatalf("status = %q, want exhausted", dbCard.Status)
}
}
func TestReportResultExhaustedActivatesNext(t *testing.T) {
d := setupCardTestDB(t)
insertCard(t, d, "1111000011110000", "active", 1)
insertCard(t, d, "2222000022220000", "available", 5)
prov := NewDBCardProvider(DBCardProviderConfig{DB: d})
card, _ := prov.GetCard(context.Background())
prov.ReportResult(context.Background(), card, true) // exhaust first
// Now GetCard should return the second card
next, err := prov.GetCard(context.Background())
if err != nil {
t.Fatalf("GetCard after exhaust: %v", err)
}
if next.Number != "2222000022220000" {
t.Fatalf("next card = %q, want 2222000022220000", next.Number)
}
}
func TestReportResultRejectedCard(t *testing.T) {
d := setupCardTestDB(t)
insertCard(t, d, "3333000033330000", "active", 5)
prov := NewDBCardProvider(DBCardProviderConfig{DB: d})
card, _ := prov.GetCard(context.Background())
prov.ReportResult(context.Background(), card, false)
var dbCard db.Card
d.First(&dbCard, "number_hash = ?", db.HashSHA256("3333000033330000"))
if dbCard.Status != "rejected" {
t.Fatalf("status = %q, want rejected", dbCard.Status)
}
if dbCard.LastError == "" {
t.Fatal("last_error should be set")
}
}
func TestDefaultCountryAndCurrency(t *testing.T) {
prov := NewDBCardProvider(DBCardProviderConfig{})
if prov.defaultCountry != "US" {
t.Fatalf("defaultCountry = %q, want US", prov.defaultCountry)
}
if prov.defaultCurrency != "USD" {
t.Fatalf("defaultCurrency = %q, want USD", prov.defaultCurrency)
}
}
func TestToCardInfoAppliesDefaults(t *testing.T) {
d := setupCardTestDB(t)
prov := NewDBCardProvider(DBCardProviderConfig{
DB: d,
DefaultAddress: "123 Main St",
DefaultCity: "NYC",
DefaultState: "NY",
DefaultPostalCode: "10001",
})
card := &db.Card{
NumberEnc: "4111111111111111",
CVCEnc: "123",
ExpMonth: "12", ExpYear: "2030",
Name: "Test", Country: "US",
}
info, err := prov.toCardInfo(card)
if err != nil {
t.Fatalf("toCardInfo: %v", err)
}
if info.Address != "123 Main St" {
t.Fatalf("address = %q, want default", info.Address)
}
if info.City != "NYC" || info.State != "NY" || info.PostalCode != "10001" {
t.Fatalf("defaults not applied: %+v", info)
}
}
func TestSingleActiveCardPolicy(t *testing.T) {
d := setupCardTestDB(t)
insertCard(t, d, "AAAA000000001111", "active", 5)
insertCard(t, d, "BBBB000000002222", "available", 5)
// Verify only one active
var count int64
d.Model(&db.Card{}).Where("status = ?", "active").Count(&count)
if count != 1 {
t.Fatalf("active count = %d, want 1", count)
}
prov := NewDBCardProvider(DBCardProviderConfig{DB: d})
card, _ := prov.GetCard(context.Background())
if card.Number != "AAAA000000001111" {
t.Fatalf("should return the active card, got %q", card.Number)
}
}