test(parity): add api smoke assertions

This commit is contained in:
2026-06-05 14:22:28 +08:00
parent f5b3279a82
commit 7e920699ac
4 changed files with 284 additions and 42 deletions
+58 -24
View File
@@ -107,17 +107,20 @@ func closeDB(db *gorm.DB) {
}
type smokeSeedSummary struct {
AdminEmail string `json:"admin_email"`
AdminPassword string `json:"admin_password"`
AccountID uint `json:"account_id"`
InboxID uint `json:"inbox_id"`
ContactID uint `json:"contact_id"`
ConversationID uint `json:"conversation_id"`
ConversationUID string `json:"conversation_uuid"`
SlaPolicyID uint `json:"sla_policy_id"`
CustomRoleID uint `json:"custom_role_id"`
CapacityPolicyID uint `json:"capacity_policy_id"`
CaptainAssistantID uint `json:"captain_assistant_id"`
AdminEmail string `json:"admin_email"`
AdminPassword string `json:"admin_password"`
AccountID uint `json:"account_id"`
InboxID uint `json:"inbox_id"`
ContactID uint `json:"contact_id"`
CompanyID uint `json:"company_id"`
ConversationID uint `json:"conversation_id"`
ConversationDisplayID uint `json:"conversation_display_id"`
ConversationUID string `json:"conversation_uuid"`
CsatMessageID uint `json:"csat_message_id"`
SlaPolicyID uint `json:"sla_policy_id"`
CustomRoleID uint `json:"custom_role_id"`
CapacityPolicyID uint `json:"capacity_policy_id"`
CaptainAssistantID uint `json:"captain_assistant_id"`
}
func seedSmokeData(ctx context.Context, db *gorm.DB) (*smokeSeedSummary, error) {
@@ -150,17 +153,30 @@ func seedSmokeData(ctx context.Context, db *gorm.DB) (*smokeSeedSummary, error)
}
inbox := &model.Inbox{}
if err := db.WithContext(ctx).Where("account_id = ? AND name = ?", account.ID, inboxName).FirstOrCreate(inbox, model.Inbox{AccountID: account.ID, Name: inboxName, ChannelType: "web_widget", Enabled: true, EnableAutoAssignment: true, GreetingEnabled: true, GreetingMessage: "Hello from GoChat", EnableEmailCollect: true, CsatSurveyEnabled: true, Timezone: "UTC", AllowMessagesAfterResolved: true, SenderNameType: "friendly_name", ChannelConfig: `{"website_url":"http://localhost:3036","website_token":"gochat-smoke-widget-token","widget_color":"#1f93ff"}`}).Error; err != nil {
channelConfig := `{"website_url":"http://localhost:3036","website_token":"gochat-smoke-widget-token","widget_color":"#1f93ff"}`
csatConfig := `{"display_type":"emoji","message":"Rate this chat"}`
if err := db.WithContext(ctx).Where("account_id = ? AND name = ?", account.ID, inboxName).FirstOrCreate(inbox, model.Inbox{AccountID: account.ID, Name: inboxName, ChannelType: "web_widget", Enabled: true, EnableAutoAssignment: true, GreetingEnabled: true, GreetingMessage: "Hello from GoChat", EnableEmailCollect: true, CsatSurveyEnabled: true, CsatConfig: csatConfig, Timezone: "UTC", AllowMessagesAfterResolved: true, SenderNameType: "friendly_name", ChannelConfig: channelConfig}).Error; err != nil {
return nil, fmt.Errorf("seed inbox: %w", err)
}
if err := db.WithContext(ctx).Model(inbox).Updates(map[string]any{"enabled": true, "csat_survey_enabled": true, "csat_config": csatConfig, "channel_config": channelConfig}).Error; err != nil {
return nil, fmt.Errorf("update inbox smoke settings: %w", err)
}
if err := db.WithContext(ctx).Where("inbox_id = ? AND user_id = ?", inbox.ID, admin.ID).FirstOrCreate(&model.InboxMember{}, model.InboxMember{InboxID: inbox.ID, UserID: admin.ID, Role: "administrator"}).Error; err != nil {
return nil, fmt.Errorf("seed inbox member: %w", err)
}
company := &model.Company{}
if err := db.WithContext(ctx).Where("account_id = ? AND name = ?", account.ID, "Smoke Company").FirstOrCreate(company, model.Company{AccountID: account.ID, Name: "Smoke Company", Domain: "gochat.local", WebsiteURL: "https://gochat.local", CustomAttributes: datatypes.JSON([]byte(`{"tier":"enterprise"}`))}).Error; err != nil {
return nil, fmt.Errorf("seed company: %w", err)
}
contact := &model.Contact{}
if err := db.WithContext(ctx).Where("account_id = ? AND email = ?", account.ID, "customer@gochat.local").FirstOrCreate(contact, model.Contact{AccountID: account.ID, Name: "Smoke Customer", Email: "customer@gochat.local", Identifier: "gochat-smoke-customer", ContactType: "lead", AdditionalAttributes: datatypes.JSON([]byte(`{}`)), CustomAttributes: datatypes.JSON([]byte(`{"plan":"enterprise"}`))}).Error; err != nil {
if err := db.WithContext(ctx).Where("account_id = ? AND email = ?", account.ID, "customer@gochat.local").FirstOrCreate(contact, model.Contact{AccountID: account.ID, CompanyID: &company.ID, Name: "Smoke Customer", Email: "customer@gochat.local", Identifier: "gochat-smoke-customer", ContactType: "lead", AdditionalAttributes: datatypes.JSON([]byte(`{}`)), CustomAttributes: datatypes.JSON([]byte(`{"plan":"enterprise"}`))}).Error; err != nil {
return nil, fmt.Errorf("seed contact: %w", err)
}
if err := db.WithContext(ctx).Model(contact).Updates(map[string]any{"company_id": company.ID}).Error; err != nil {
return nil, fmt.Errorf("update contact company: %w", err)
}
contactInbox := &model.ContactInbox{}
if err := db.WithContext(ctx).Where("contact_id = ? AND inbox_id = ?", contact.ID, inbox.ID).FirstOrCreate(contactInbox, model.ContactInbox{ContactID: contact.ID, InboxID: inbox.ID, SourceID: "gochat-smoke-source", PubsubToken: "gochat-smoke-contact-pubsub"}).Error; err != nil {
return nil, fmt.Errorf("seed contact inbox: %w", err)
@@ -172,10 +188,20 @@ func seedSmokeData(ctx context.Context, db *gorm.DB) (*smokeSeedSummary, error)
if err := db.WithContext(ctx).Where("account_id = ? AND inbox_id = ? AND contact_id = ?", account.ID, inbox.ID, contact.ID).FirstOrCreate(conversation, model.Conversation{AccountID: account.ID, InboxID: inbox.ID, ContactID: contact.ID, ContactInboxID: &contactInbox.ID, DisplayID: &displayID, AssigneeID: &admin.ID, Status: "open", Priority: "medium", ChannelType: "web_widget", Channel: "web_widget", Labels: "vip", LastActivityAt: &lastActivity}).Error; err != nil {
return nil, fmt.Errorf("seed conversation: %w", err)
}
if err := seedMessage(ctx, db, conversation, inbox.ID, contact.ID, "incoming", "Hello, I need help with my order."); err != nil {
if err := db.WithContext(ctx).Model(conversation).Updates(map[string]any{"contact_inbox_id": contactInbox.ID, "display_id": displayID, "assignee_id": admin.ID, "status": "open", "priority": "medium", "channel_type": "web_widget", "channel": "web_widget", "labels": "vip", "last_activity_at": lastActivity}).Error; err != nil {
return nil, fmt.Errorf("update smoke conversation: %w", err)
}
conversation.ContactInboxID = &contactInbox.ID
conversation.DisplayID = &displayID
conversation.AssigneeID = &admin.ID
if _, err := seedMessage(ctx, db, conversation, inbox.ID, contact.ID, "incoming", "text", "Hello, I need help with my order."); err != nil {
return nil, err
}
if err := seedMessage(ctx, db, conversation, inbox.ID, admin.ID, "outgoing", "I can help with that."); err != nil {
if _, err := seedMessage(ctx, db, conversation, inbox.ID, admin.ID, "outgoing", "text", "I can help with that."); err != nil {
return nil, err
}
csatMessage, err := seedMessage(ctx, db, conversation, inbox.ID, admin.ID, "template", "input_csat", "Rate this chat")
if err != nil {
return nil, err
}
@@ -204,26 +230,34 @@ func seedSmokeData(ctx context.Context, db *gorm.DB) (*smokeSeedSummary, error)
return nil, fmt.Errorf("seed captain assistant: %w", err)
}
return &smokeSeedSummary{AdminEmail: adminEmail, AdminPassword: adminPassword, AccountID: account.ID, InboxID: inbox.ID, ContactID: contact.ID, ConversationID: conversation.ID, ConversationUID: conversation.UUID, SlaPolicyID: sla.ID, CustomRoleID: customRole.ID, CapacityPolicyID: capacity.ID, CaptainAssistantID: assistant.ID}, nil
conversationDisplayID := uint(0)
if conversation.DisplayID != nil {
conversationDisplayID = *conversation.DisplayID
}
return &smokeSeedSummary{AdminEmail: adminEmail, AdminPassword: adminPassword, AccountID: account.ID, InboxID: inbox.ID, ContactID: contact.ID, CompanyID: company.ID, ConversationID: conversation.ID, ConversationDisplayID: conversationDisplayID, ConversationUID: conversation.UUID, CsatMessageID: csatMessage.ID, SlaPolicyID: sla.ID, CustomRoleID: customRole.ID, CapacityPolicyID: capacity.ID, CaptainAssistantID: assistant.ID}, nil
}
func seedMessage(ctx context.Context, db *gorm.DB, conversation *model.Conversation, inboxID, senderID uint, messageType, content string) error {
func seedMessage(ctx context.Context, db *gorm.DB, conversation *model.Conversation, inboxID, senderID uint, messageType, contentType, content string) (*model.Message, error) {
message := &model.Message{}
var count int64
if err := db.WithContext(ctx).Model(&model.Message{}).Where("conversation_id = ? AND content = ?", conversation.ID, content).Count(&count).Error; err != nil {
return fmt.Errorf("check message: %w", err)
return nil, fmt.Errorf("check message: %w", err)
}
if count > 0 {
return nil
if err := db.WithContext(ctx).Where("conversation_id = ? AND content = ?", conversation.ID, content).First(message).Error; err != nil {
return nil, fmt.Errorf("load existing message: %w", err)
}
return message, nil
}
senderType := "contact"
if messageType == "outgoing" {
if messageType == "outgoing" || messageType == "template" {
senderType = "user"
}
msg := &model.Message{AccountID: conversation.AccountID, InboxID: inboxID, ConversationID: conversation.ID, SenderID: &senderID, SenderType: senderType, MessageType: messageType, ContentType: "text", Content: content, Status: "sent"}
if err := db.WithContext(ctx).Create(msg).Error; err != nil {
return fmt.Errorf("seed message: %w", err)
message = &model.Message{AccountID: conversation.AccountID, InboxID: inboxID, ConversationID: conversation.ID, SenderID: &senderID, SenderType: senderType, MessageType: messageType, ContentType: contentType, Content: content, Status: "sent", ContentAttributes: datatypes.JSON([]byte(`{"display_type":"emoji"}`))}
if err := db.WithContext(ctx).Create(message).Error; err != nil {
return nil, fmt.Errorf("seed message: %w", err)
}
return nil
return message, nil
}
func getenvDefault(key, fallback string) string {