feat(campaigns): derive chatwoot scheduling
This commit is contained in:
@@ -141,6 +141,12 @@ func (s *CampaignHandlerTestSuite) accountURL() string {
|
||||
return "/api/v1/accounts/" + strconv.FormatUint(uint64(s.account.ID), 10) + "/campaigns"
|
||||
}
|
||||
|
||||
func (s *CampaignHandlerTestSuite) seedInbox(channelType string) *model.Inbox {
|
||||
inbox := &model.Inbox{AccountID: s.account.ID, Name: "Campaign " + channelType + " Inbox", ChannelType: channelType, ChannelID: 1}
|
||||
s.Require().NoError(s.db.Create(inbox).Error)
|
||||
return inbox
|
||||
}
|
||||
|
||||
// Helper: seed a campaign directly into the DB for Get/List/Delete/Update tests
|
||||
func (s *CampaignHandlerTestSuite) seedCampaign(title, message, campaignType string) *campaign.Campaign {
|
||||
c := &campaign.Campaign{
|
||||
@@ -256,12 +262,13 @@ func (s *CampaignHandlerTestSuite) TestGet_Unauthorized() {
|
||||
// ========== Create Tests ==========
|
||||
|
||||
func (s *CampaignHandlerTestSuite) TestCreate_Success() {
|
||||
smsInbox := s.seedInbox("Channel::Sms")
|
||||
body := map[string]interface{}{
|
||||
"inbox_id": s.inbox.ID,
|
||||
"inbox_id": smsInbox.ID,
|
||||
"title": "New Campaign",
|
||||
"message": "Hello from campaign",
|
||||
"campaign_type": "one_off",
|
||||
"enabled": true,
|
||||
"scheduled_at": "2026-06-07T10:30:00Z",
|
||||
"audience": []map[string]interface{}{{"type": "Label", "id": 1}},
|
||||
"trigger_rules": map[string]interface{}{"url": "https://example.com"},
|
||||
"template_params": map[string]interface{}{"name": "value"},
|
||||
@@ -281,11 +288,40 @@ func (s *CampaignHandlerTestSuite) TestCreate_Success() {
|
||||
s.NotContains(resp, "data")
|
||||
s.Equal("New Campaign", resp["title"])
|
||||
s.Equal(float64(s.account.ID), resp["account_id"])
|
||||
s.Equal("one_off", resp["campaign_type"])
|
||||
s.Equal(float64(1780828200), resp["scheduled_at"])
|
||||
s.Greater(resp["id"].(float64), float64(0))
|
||||
s.NotNil(resp["inbox"])
|
||||
s.Contains(resp, "audience")
|
||||
s.Contains(resp, "template_params")
|
||||
}
|
||||
|
||||
func (s *CampaignHandlerTestSuite) TestCreate_LiveChatDefaultsOngoingWithoutCampaignType() {
|
||||
body := map[string]interface{}{
|
||||
"inbox_id": s.inbox.ID,
|
||||
"title": "Live Chat Campaign",
|
||||
"message": "Hello from live chat",
|
||||
"enabled": true,
|
||||
"scheduled_at": "2026-06-07T10:30:00Z",
|
||||
"trigger_rules": map[string]interface{}{"url": "https://example.com", "time_on_page": 10},
|
||||
}
|
||||
bodyBytes := marshalNested("campaign", body)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("POST", s.accountURL(), bytes.NewReader(bodyBytes))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
s.router.ServeHTTP(w, req)
|
||||
|
||||
s.Equal(http.StatusOK, w.Code)
|
||||
|
||||
var resp map[string]interface{}
|
||||
s.Require().NoError(json.Unmarshal(w.Body.Bytes(), &resp))
|
||||
s.Equal("Live Chat Campaign", resp["title"])
|
||||
s.Equal("ongoing", resp["campaign_type"])
|
||||
s.NotContains(resp, "scheduled_at")
|
||||
s.NotContains(resp, "audience")
|
||||
}
|
||||
|
||||
func (s *CampaignHandlerTestSuite) TestCreate_ValidationError() {
|
||||
// Missing required fields (title, message, inbox_id)
|
||||
body := map[string]interface{}{
|
||||
@@ -335,10 +371,13 @@ func (s *CampaignHandlerTestSuite) TestCreate_Unauthorized() {
|
||||
|
||||
func (s *CampaignHandlerTestSuite) TestUpdate_Success() {
|
||||
c := s.seedCampaign("Original Title", "Original message", "ongoing")
|
||||
smsInbox := s.seedInbox("Channel::Sms")
|
||||
|
||||
body := map[string]interface{}{
|
||||
"title": "Updated Title",
|
||||
"message": "Updated message",
|
||||
"title": "Updated Title",
|
||||
"message": "Updated message",
|
||||
"inbox_id": smsInbox.ID,
|
||||
"scheduled_at": "2026-06-07T10:30:00Z",
|
||||
}
|
||||
bodyBytes := marshalNested("campaign", body)
|
||||
|
||||
@@ -353,6 +392,14 @@ func (s *CampaignHandlerTestSuite) TestUpdate_Success() {
|
||||
s.Require().NoError(json.Unmarshal(w.Body.Bytes(), &resp))
|
||||
s.NotContains(resp, "success")
|
||||
s.Equal("Updated Title", resp["title"])
|
||||
s.Equal("one_off", resp["campaign_type"])
|
||||
s.Equal(float64(1780828200), resp["scheduled_at"])
|
||||
|
||||
var updated campaign.Campaign
|
||||
s.Require().NoError(s.db.First(&updated, c.ID).Error)
|
||||
s.Equal(smsInbox.ID, updated.InboxID)
|
||||
s.Require().NotNil(updated.ScheduledAt)
|
||||
s.Equal(int64(1780828200), updated.ScheduledAt.Unix())
|
||||
}
|
||||
|
||||
func (s *CampaignHandlerTestSuite) TestUpdate_NotFound() {
|
||||
|
||||
Reference in New Issue
Block a user