Files
kra-new/internal/data/gift/gift_test.go
T

88 lines
2.9 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); !errors.Is(err, bizgift.ErrSendNotAllowed) {
t.Fatalf("unsupported quantity error = %v", err)
}
var before ledger.WalletPO
if err = db.Where("user_id = ?", 1).First(&before).Error; err != nil || before.DiamondBalance != 100 {
t.Fatalf("wallet changed after rejected send: 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 != 50 || after.TotalSpentDiamonds != 50 || sends != 1 {
t.Fatalf("atomic send result wallet=%+v sends=%d", after, sends)
}
}