package business import ( "context" "errors" "fmt" "path/filepath" "testing" "github.com/glebarez/sqlite" "gorm.io/gorm" "kra/internal/biz/business" ) type channelDatabases struct{ platform *gorm.DB } func (d channelDatabases) Database(name string) (*gorm.DB, error) { if name == "lx" { return d.platform, nil } return nil, errors.New("数据源未配置") } func TestChannelWriteIsAtomicInNamedPlatformDatabase(t *testing.T) { db, err := gorm.Open(sqlite.Open(filepath.Join(t.TempDir(), "platform.db")), &gorm.Config{}) if err != nil { t.Fatal(err) } pool, _ := db.DB() t.Cleanup(func() { _ = pool.Close() }) if err := db.AutoMigrate(&platformChannelPO{}, &channelSettlementPO{}); err != nil { t.Fatal(err) } for _, sql := range []string{"CREATE UNIQUE INDEX channel_account ON tab_promote(account)", "CREATE TABLE tab_promote_business(id INTEGER PRIMARY KEY,promote_ids TEXT)", "INSERT INTO tab_promote_business VALUES(14,'5,6')"} { if err := db.Exec(sql).Error; err != nil { t.Fatal(err) } } repo := NewChannelWriteRepo(channelDatabases{db}) input := &business.ChannelWrite{ChannelCreate: business.ChannelCreate{SourceDB: "lx", Account: "中文渠道", Password: "encoded-password", BusierID: 14, RegisterType: 1}, Status: -3, Level: 1, SettlementDays: 7, CreatedUnix: 1000, NextCountUnix: 605800} id, err := repo.Create(context.Background(), input) if err != nil { t.Fatal(err) } var channel platformChannelPO if err := db.First(&channel, id).Error; err != nil { t.Fatal(err) } if channel.Status != -3 || channel.PromoteLevel != 1 || channel.ParentID != 0 || channel.TopPromoteID != 0 || channel.Password != "encoded-password" || channel.CreateTime != 1000 || channel.RegisterType != 1 { t.Fatalf("源平台渠道默认字段错误: %+v", channel) } var settlement channelSettlementPO if err := db.Where("promote_id = ?", id).First(&settlement).Error; err != nil { t.Fatal(err) } if settlement.TimeType != 0 || settlement.DayPeriod != 7 || settlement.NextCountTime != 605800 || settlement.PromoteAccount != "中文渠道" { t.Fatalf("结算周期字段错误: %+v", settlement) } var related string db.Table("tab_promote_business").Select("promote_ids").Where("id=14").Scan(&related) if related != fmt.Sprintf("5,6,%d", id) { t.Fatal("追加关系覆盖了已有渠道") } if _, err := repo.Create(context.Background(), input); err != business.ErrChannelExists { t.Fatal("重复账号没有拒绝") } if err := db.Exec("DROP TABLE tab_promote_settlement_time").Error; err != nil { t.Fatal(err) } input.Account = "rollback" if _, err := repo.Create(context.Background(), input); err == nil { t.Fatal("缺结算表应回滚") } var count int64 db.Model(&platformChannelPO{}).Count(&count) if count != 1 { t.Fatal("创建失败留下了渠道") } var after string db.Table("tab_promote_business").Select("promote_ids").Where("id=14").Scan(&after) if after != related { t.Fatal("创建失败仍改动关联") } input.SourceDB = "hw" if _, err := repo.Create(context.Background(), input); err != business.ErrPlatformUnavailable { t.Fatal("未配置平台不应回退到其他数据源") } }