Files
kra-new/internal/data/gift/gift_test.go
T
2026-09-22 12:04:22 +08:00

119 lines
3.8 KiB
Go

package gift
import (
"context"
"errors"
"testing"
bizgift "kra/internal/biz/gift"
"kra/internal/data/ledger"
"github.com/glebarez/sqlite"
"gorm.io/gorm"
)
type testProvider struct{ db *gorm.DB }
func (p testProvider) DB() *gorm.DB { return p.db }
func openGiftTestDB(t *testing.T) *gorm.DB {
t.Helper()
db, err := gorm.Open(sqlite.Open("file:"+t.Name()+"?mode=memory&cache=shared"), &gorm.Config{})
if err != nil {
t.Fatal(err)
}
if err = db.AutoMigrate(&giftPO{}, &ledger.WalletPO{}, &ledger.GiftSendPO{}, &ledger.SettingPO{}); err != nil {
t.Fatal(err)
}
for _, statement := range []string{
`CREATE TABLE sys_users (id integer primary key, username text, nick_name text)`,
`CREATE TABLE live_rooms (id integer primary key, name text, anchor_user_id integer, enabled numeric, deleted_at datetime)`,
} {
if err = db.Exec(statement).Error; err != nil {
t.Fatal(err)
}
}
return db
}
func TestGiftRepoProtectsLastEnabledGift(t *testing.T) {
db := openGiftTestDB(t)
repo := NewRepo(testProvider{db: db})
item, err := repo.Save(context.Background(), &bizgift.Gift{Name: "Rose", Icon: "rose", Price: 1, Tiers: []int{1}, Enabled: true})
if err != nil {
t.Fatal(err)
}
if err = repo.SetEnabled(context.Background(), item.ID, false); !errors.Is(err, bizgift.ErrLastEnabled) {
t.Fatalf("disable last gift error = %v", err)
}
if err = repo.Delete(context.Background(), item.ID); !errors.Is(err, bizgift.ErrLastEnabled) {
t.Fatalf("delete last gift error = %v", err)
}
}
func TestGiftRepoSendUsesTierAndDebitsAtomically(t *testing.T) {
db := openGiftTestDB(t)
repo := NewRepo(testProvider{db: db})
if err := db.Exec(`INSERT INTO sys_users(id,username,nick_name) VALUES (1,'viewer','Viewer'),(2,'anchor','Anchor')`).Error; err != nil {
t.Fatal(err)
}
if err := db.Exec(`INSERT INTO live_rooms(id,name,anchor_user_id,enabled) VALUES (7,'Room',2,1)`).Error; err != nil {
t.Fatal(err)
}
if err := db.Create(&ledger.WalletPO{UserID: 1, DiamondBalance: 100}).Error; err != nil {
t.Fatal(err)
}
item, err := repo.Save(context.Background(), &bizgift.Gift{Name: "Star", Icon: "star", Price: 5, Tiers: []int{1, 10}, Enabled: true})
if err != nil {
t.Fatal(err)
}
if _, err = repo.Send(context.Background(), 1, 7, item.ID, 2); err != nil {
t.Fatalf("custom quantity should be accepted: %v", err)
}
var before ledger.WalletPO
if err = db.Where("user_id = ?", 1).First(&before).Error; err != nil || before.DiamondBalance != 90 {
t.Fatalf("wallet did not debit custom quantity: wallet=%+v err=%v", before, err)
}
if _, err = repo.Send(context.Background(), 1, 7, item.ID, 10); err != nil {
t.Fatal(err)
}
var after ledger.WalletPO
var sends int64
db.Where("user_id = ?", 1).First(&after)
db.Model(&ledger.GiftSendPO{}).Count(&sends)
if after.DiamondBalance != 40 || after.TotalSpentDiamonds != 60 || sends != 2 {
t.Fatalf("atomic send result wallet=%+v sends=%d", after, sends)
}
}
func TestSeedDefaultCatalogAddsMissingGiftsWithoutOverwriting(t *testing.T) {
db := openGiftTestDB(t)
custom := giftPO{Name: "玫瑰", Icon: "custom", Price: 99, Description: "admin configured", Tiers: "[1]", Sort: 88, Enabled: false}
if err := db.Create(&custom).Error; err != nil {
t.Fatal(err)
}
if err := db.Model(&giftPO{}).Where("id = ?", custom.ID).Update("enabled", false).Error; err != nil {
t.Fatal(err)
}
if err := seedDefaultCatalog(db); err != nil {
t.Fatal(err)
}
if err := seedDefaultCatalog(db); err != nil {
t.Fatal(err)
}
var count int64
if err := db.Model(&giftPO{}).Count(&count).Error; err != nil {
t.Fatal(err)
}
if count != 24 {
t.Fatalf("gift count = %d, want 24", count)
}
var rose giftPO
if err := db.Where("name = ?", "玫瑰").First(&rose).Error; err != nil {
t.Fatal(err)
}
if rose.Icon != "custom" || rose.Price != 99 || rose.Sort != 88 || rose.Enabled {
t.Fatalf("existing gift was overwritten: %+v", rose)
}
}