package model import ( "fmt" "testing" "time" "gorm.io/driver/sqlite" "gorm.io/gorm" ) func TestCreateMessageAssignsMonotonicSequence(t *testing.T) { db, err := gorm.Open(sqlite.Open(fmt.Sprintf("file:kefu_message_%d?mode=memory&cache=shared", time.Now().UnixNano())), &gorm.Config{}) if err != nil { t.Fatalf("打开测试数据库失败: %v", err) } if err := Migrate(db); err != nil { t.Fatalf("迁移测试数据库失败: %v", err) } DB = db tenant := Tenant{Name: "消息测试租户", Status: "normal"} if err := DB.Create(&tenant).Error; err != nil { t.Fatalf("创建租户失败: %v", err) } customer := Customer{TenantID: tenant.ID, Name: "测试客户"} if err := DB.Create(&customer).Error; err != nil { t.Fatalf("创建客户失败: %v", err) } session := Session{TenantID: tenant.ID, CustomerID: customer.ID, Status: "active", Priority: "normal"} if err := DB.Create(&session).Error; err != nil { t.Fatalf("创建会话失败: %v", err) } first := Message{SessionID: session.ID, SenderType: "visitor", Content: "第一条", Type: "text", SentAt: time.Now()} second := Message{SessionID: session.ID, SenderType: "agent", Content: "第二条", Type: "text", SentAt: time.Now()} if err := CreateMessage(&first); err != nil { t.Fatalf("创建第一条消息失败: %v", err) } if err := CreateMessage(&second); err != nil { t.Fatalf("创建第二条消息失败: %v", err) } if first.Seq != 1 || second.Seq != 2 { t.Fatalf("消息序号异常: first=%d second=%d", first.Seq, second.Seq) } duplicate := Message{SessionID: session.ID, SenderType: "agent", Content: "重复序号", Type: "text", Seq: 2, SentAt: time.Now()} if err := DB.Create(&duplicate).Error; err == nil { t.Fatal("重复会话消息序号未被唯一索引拦截") } }