Align GoChat with Chatwoot frontend contracts
This commit is contained in:
@@ -143,6 +143,7 @@ func (s *ConversationHandlerTestSuite) SetupSuite() {
|
||||
conversations.GET("/:conversation_id/attachments", handler.ListAttachments)
|
||||
conversations.GET("/:conversation_id/reporting_events", handler.ReportingEvents)
|
||||
conversations.POST("/:conversation_id/toggle_typing", handler.ToggleTyping)
|
||||
conversations.POST("/:conversation_id/toggle_typing_status", handler.ToggleTyping)
|
||||
conversations.POST("/:conversation_id/update_last_seen", handler.UpdateLastSeen)
|
||||
conversations.DELETE("/:conversation_id", handler.Delete)
|
||||
}
|
||||
@@ -316,6 +317,47 @@ func (s *ConversationHandlerTestSuite) TestUnread_Success() {
|
||||
assert.Equal(s.T(), s.testConv.ID, resp.ID)
|
||||
}
|
||||
|
||||
func (s *ConversationHandlerTestSuite) TestUnread_DisplayIDRouteSetsLastSeenBeforeIncoming() {
|
||||
displayID := uint(909)
|
||||
s.Require().NoError(s.db.Model(s.testConv).Update("display_id", displayID).Error)
|
||||
incomingCreatedAt := time.Now().Add(-10 * time.Minute)
|
||||
oldSeen := incomingCreatedAt.Add(5 * time.Minute).Unix()
|
||||
s.Require().NoError(s.db.Model(s.testConv).Updates(map[string]any{
|
||||
"agent_last_seen_at": oldSeen,
|
||||
"assignee_last_seen_at": oldSeen,
|
||||
}).Error)
|
||||
message := &model.Message{
|
||||
AccountID: s.testAccount.ID,
|
||||
InboxID: s.testInbox.ID,
|
||||
ConversationID: s.testConv.ID,
|
||||
MessageType: string(model.MessageTypeIncoming),
|
||||
Content: "unread transition",
|
||||
ContentType: "text",
|
||||
SenderType: "contact",
|
||||
}
|
||||
s.Require().NoError(s.db.Create(message).Error)
|
||||
s.Require().NoError(s.db.Model(message).Updates(map[string]any{"created_at": incomingCreatedAt, "updated_at": incomingCreatedAt}).Error)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("POST", s.accountURL()+"/conversations/"+strconv.FormatUint(uint64(displayID), 10)+"/unread", nil)
|
||||
s.router.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(s.T(), http.StatusOK, w.Code, w.Body.String())
|
||||
var resp map[string]any
|
||||
s.Require().NoError(json.Unmarshal(w.Body.Bytes(), &resp))
|
||||
assert.Equal(s.T(), float64(displayID), resp["id"])
|
||||
assert.Equal(s.T(), incomingCreatedAt.Add(-time.Second).Unix(), int64(resp["agent_last_seen_at"].(float64)))
|
||||
assert.Equal(s.T(), incomingCreatedAt.Add(-time.Second).Unix(), int64(resp["assignee_last_seen_at"].(float64)))
|
||||
assert.NotContains(s.T(), resp, "success")
|
||||
|
||||
var stored model.Conversation
|
||||
s.Require().NoError(s.db.First(&stored, s.testConv.ID).Error)
|
||||
s.Require().NotNil(stored.AgentLastSeenAt)
|
||||
s.Require().NotNil(stored.AssigneeLastSeenAt)
|
||||
assert.Equal(s.T(), incomingCreatedAt.Add(-time.Second).Unix(), *stored.AgentLastSeenAt)
|
||||
assert.Equal(s.T(), incomingCreatedAt.Add(-time.Second).Unix(), *stored.AssigneeLastSeenAt)
|
||||
}
|
||||
|
||||
func (s *ConversationHandlerTestSuite) TestUnread_InvalidAccountID() {
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("POST", "/api/v1/accounts/invalid/conversations/1/unread", nil)
|
||||
@@ -799,6 +841,15 @@ func (s *ConversationHandlerTestSuite) TestToggleTyping_MissingFieldsIsNoopSucce
|
||||
assert.Empty(s.T(), w.Body.String())
|
||||
}
|
||||
|
||||
func (s *ConversationHandlerTestSuite) TestToggleTypingStatus_ChatwootRouteSuccess() {
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("POST", fmt.Sprintf("/api/v1/accounts/%d/conversations/%d/toggle_typing_status", s.testAccount.ID, s.testConv.ID), bytes.NewBufferString(`{"typing_status":"typing_on","is_private":false}`))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
s.router.ServeHTTP(w, req)
|
||||
assert.Equal(s.T(), http.StatusOK, w.Code)
|
||||
assert.Empty(s.T(), w.Body.String())
|
||||
}
|
||||
|
||||
func (s *ConversationHandlerTestSuite) TestToggleTyping_EmptyBodyIsNoopSuccess() {
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("POST", fmt.Sprintf("/api/v1/accounts/%d/conversations/%d/toggle_typing", s.testAccount.ID, s.testConv.ID), nil)
|
||||
@@ -839,6 +890,33 @@ func (s *ConversationHandlerTestSuite) TestUpdateLastSeen_SuccessMarksNotificati
|
||||
assert.NotNil(s.T(), updatedNotification.ReadAt)
|
||||
}
|
||||
|
||||
func (s *ConversationHandlerTestSuite) TestUpdateLastSeen_DisplayIDRouteMarksNotificationRead() {
|
||||
displayID := uint(910)
|
||||
s.Require().NoError(s.db.Model(s.testConv).Update("display_id", displayID).Error)
|
||||
oldSeen := time.Now().Add(-2 * time.Hour).Unix()
|
||||
s.Require().NoError(s.db.Model(s.testConv).Update("agent_last_seen_at", oldSeen).Error)
|
||||
s.Require().NoError(s.db.Create(&model.Message{AccountID: s.testAccount.ID, InboxID: s.testInbox.ID, ConversationID: s.testConv.ID, MessageType: string(model.MessageTypeIncoming), Content: "new display-id message"}).Error)
|
||||
accountID := s.testAccount.ID
|
||||
notification := &model.Notification{UserID: s.testUser.ID, AccountID: &accountID, NotificationType: "assigned_conversation_new_message", PrimaryActorType: "Conversation", PrimaryActorID: s.testConv.ID}
|
||||
s.Require().NoError(s.db.Create(notification).Error)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("POST", fmt.Sprintf("/api/v1/accounts/%d/conversations/%d/update_last_seen", s.testAccount.ID, displayID), nil)
|
||||
s.router.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(s.T(), http.StatusOK, w.Code)
|
||||
assert.Empty(s.T(), w.Body.String())
|
||||
|
||||
var conversation model.Conversation
|
||||
s.Require().NoError(s.db.First(&conversation, s.testConv.ID).Error)
|
||||
s.Require().NotNil(conversation.AgentLastSeenAt)
|
||||
assert.Greater(s.T(), *conversation.AgentLastSeenAt, oldSeen)
|
||||
|
||||
var updatedNotification model.Notification
|
||||
s.Require().NoError(s.db.First(&updatedNotification, notification.ID).Error)
|
||||
assert.NotNil(s.T(), updatedNotification.ReadAt)
|
||||
}
|
||||
|
||||
func (s *ConversationHandlerTestSuite) TestUpdateLastSeen_InvalidAccountID() {
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("POST", "/api/v1/accounts/abc/conversations/1/update_last_seen", nil)
|
||||
|
||||
Reference in New Issue
Block a user