feat(conversations): align index finder filters
This commit is contained in:
@@ -61,30 +61,26 @@ func (h *ConversationHandler) List(c *gin.Context) {
|
||||
|
||||
p := pagination.Parse(c)
|
||||
|
||||
// Support status filter via query param
|
||||
status := c.Query("status")
|
||||
var conversations []model.Conversation
|
||||
var total int64
|
||||
|
||||
if status != "" {
|
||||
result, count, svcErr := h.conversationSvc.ListByStatus(c.Request.Context(), accountID, status, p.Offset, p.PerPage)
|
||||
if svcErr != nil {
|
||||
handleServiceError(c, svcErr)
|
||||
return
|
||||
}
|
||||
conversations = result
|
||||
total = count
|
||||
} else {
|
||||
result, count, svcErr := h.conversationSvc.ListByAccount(c.Request.Context(), accountID, p.Offset, p.PerPage)
|
||||
if svcErr != nil {
|
||||
handleServiceError(c, svcErr)
|
||||
return
|
||||
}
|
||||
conversations = result
|
||||
total = count
|
||||
var params service.FilterParams
|
||||
if err := c.ShouldBindQuery(¶ms); err != nil {
|
||||
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrValidation, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, serializeConversationList(c.Request.Context(), h.conversationSvc.DB(), conversations, total))
|
||||
result, svcErr := h.conversationSvc.ListWithFinder(c.Request.Context(), accountID, getUserID(c), params, p.Offset, p.PerPage)
|
||||
if svcErr != nil {
|
||||
handleServiceError(c, svcErr)
|
||||
return
|
||||
}
|
||||
|
||||
payload := serializeConversationList(c.Request.Context(), h.conversationSvc.DB(), result.Conversations, result.Count.AllCount)
|
||||
payload.Data.Meta = chatwootConversationCounts{
|
||||
MineCount: result.Count.MineCount,
|
||||
AssignedCount: result.Count.AssignedCount,
|
||||
UnassignedCount: result.Count.UnassignedCount,
|
||||
AllCount: result.Count.AllCount,
|
||||
}
|
||||
c.JSON(http.StatusOK, payload)
|
||||
}
|
||||
|
||||
// Create creates a new conversation.
|
||||
|
||||
@@ -222,6 +222,9 @@ func (s *ConversationCrudTestSuite) TestList_Success() {
|
||||
}
|
||||
|
||||
func (s *ConversationCrudTestSuite) TestList_WithStatusFilter() {
|
||||
resolved := &model.Conversation{AccountID: s.testAccount.ID, InboxID: s.testInbox.ID, ContactID: s.testContact.ID, Status: "resolved", ChannelType: "web_widget", Channel: "web_widget"}
|
||||
s.Require().NoError(s.db.Create(resolved).Error)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("GET", s.accountURL()+"/conversations?status=open", nil)
|
||||
s.router.ServeHTTP(w, req)
|
||||
@@ -240,6 +243,81 @@ func (s *ConversationCrudTestSuite) TestList_WithStatusFilter() {
|
||||
assert.Equal(s.T(), int64(1), resp.Data.Meta.AllCount)
|
||||
}
|
||||
|
||||
func (s *ConversationCrudTestSuite) TestList_DefaultsToOpenStatus() {
|
||||
resolved := &model.Conversation{AccountID: s.testAccount.ID, InboxID: s.testInbox.ID, ContactID: s.testContact.ID, Status: "resolved", ChannelType: "web_widget", Channel: "web_widget"}
|
||||
s.Require().NoError(s.db.Create(resolved).Error)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("GET", s.accountURL()+"/conversations", nil)
|
||||
s.router.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(s.T(), http.StatusOK, w.Code)
|
||||
var resp struct {
|
||||
Data struct {
|
||||
Meta struct {
|
||||
AllCount int64 `json:"all_count"`
|
||||
} `json:"meta"`
|
||||
Payload []map[string]interface{} `json:"payload"`
|
||||
} `json:"data"`
|
||||
}
|
||||
s.Require().NoError(json.Unmarshal(w.Body.Bytes(), &resp))
|
||||
assert.Equal(s.T(), int64(1), resp.Data.Meta.AllCount)
|
||||
assert.Len(s.T(), resp.Data.Payload, 1)
|
||||
}
|
||||
|
||||
func (s *ConversationCrudTestSuite) TestList_AppliesFinderFiltersAfterCounts() {
|
||||
assigneeID := uint(42)
|
||||
assigned := &model.Conversation{AccountID: s.testAccount.ID, InboxID: s.testInbox.ID, ContactID: s.testContact.ID, AssigneeID: &assigneeID, Status: "open", Labels: "vip", ChannelType: "web_widget", Channel: "web_widget"}
|
||||
s.Require().NoError(s.db.Create(assigned).Error)
|
||||
unmatched := &model.Conversation{AccountID: s.testAccount.ID, InboxID: s.testInbox.ID, ContactID: s.testContact.ID, Status: "open", Labels: "standard", ChannelType: "web_widget", Channel: "web_widget"}
|
||||
s.Require().NoError(s.db.Create(unmatched).Error)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("GET", s.accountURL()+"/conversations?labels=vip&assignee_type=assigned", nil)
|
||||
s.router.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(s.T(), http.StatusOK, w.Code)
|
||||
var resp struct {
|
||||
Data struct {
|
||||
Meta struct {
|
||||
AssignedCount int64 `json:"assigned_count"`
|
||||
UnassignedCount int64 `json:"unassigned_count"`
|
||||
AllCount int64 `json:"all_count"`
|
||||
} `json:"meta"`
|
||||
Payload []map[string]interface{} `json:"payload"`
|
||||
} `json:"data"`
|
||||
}
|
||||
s.Require().NoError(json.Unmarshal(w.Body.Bytes(), &resp))
|
||||
assert.Equal(s.T(), int64(1), resp.Data.Meta.AllCount)
|
||||
assert.Equal(s.T(), int64(1), resp.Data.Meta.AssignedCount)
|
||||
assert.Equal(s.T(), int64(0), resp.Data.Meta.UnassignedCount)
|
||||
assert.Len(s.T(), resp.Data.Payload, 1)
|
||||
}
|
||||
|
||||
func (s *ConversationCrudTestSuite) TestList_QuerySkipsStatusFilter() {
|
||||
resolved := &model.Conversation{AccountID: s.testAccount.ID, InboxID: s.testInbox.ID, ContactID: s.testContact.ID, Status: "resolved", ChannelType: "web_widget", Channel: "web_widget"}
|
||||
s.Require().NoError(s.db.Create(resolved).Error)
|
||||
s.Require().NoError(s.db.Create(&model.Message{AccountID: s.testAccount.ID, InboxID: s.testInbox.ID, ConversationID: s.testConv.ID, Content: "needle open", MessageType: string(model.MessageTypeIncoming)}).Error)
|
||||
s.Require().NoError(s.db.Create(&model.Message{AccountID: s.testAccount.ID, InboxID: s.testInbox.ID, ConversationID: resolved.ID, Content: "needle resolved", MessageType: string(model.MessageTypeOutgoing)}).Error)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("GET", s.accountURL()+"/conversations?q=needle&status=open", nil)
|
||||
s.router.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(s.T(), http.StatusOK, w.Code)
|
||||
var resp struct {
|
||||
Data struct {
|
||||
Meta struct {
|
||||
AllCount int64 `json:"all_count"`
|
||||
} `json:"meta"`
|
||||
Payload []map[string]interface{} `json:"payload"`
|
||||
} `json:"data"`
|
||||
}
|
||||
s.Require().NoError(json.Unmarshal(w.Body.Bytes(), &resp))
|
||||
assert.Equal(s.T(), int64(2), resp.Data.Meta.AllCount)
|
||||
assert.Len(s.T(), resp.Data.Payload, 2)
|
||||
}
|
||||
|
||||
func (s *ConversationCrudTestSuite) TestList_InvalidAccountID() {
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("GET", "/api/v1/accounts/invalid/conversations", nil)
|
||||
|
||||
Reference in New Issue
Block a user