feat(conversations): align filter payload basics

This commit is contained in:
2026-06-07 04:13:02 +08:00
parent 50a9160f82
commit 615c071168
4 changed files with 191 additions and 34 deletions
@@ -503,6 +503,10 @@ func (h *ConversationHandler) Filter(c *gin.Context) {
result, svcErr := h.conversationSvc.Filter(c.Request.Context(), accountID, userID, req, p.Offset, p.PerPage)
if svcErr != nil {
if len(req.Payload) > 0 {
c.JSON(http.StatusUnprocessableEntity, gin.H{"error": svcErr.Error()})
return
}
handleServiceError(c, svcErr)
return
}
@@ -1017,6 +1017,83 @@ func (s *ConversationCrudTestSuite) TestFilter_Success() {
assert.Len(s.T(), resp.Payload, 1)
}
func (s *ConversationCrudTestSuite) TestFilter_ChatwootPayloadStatus() {
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)
body, _ := json.Marshal(map[string]interface{}{
"payload": []map[string]interface{}{
{
"attribute_key": "status",
"filter_operator": "equal_to",
"values": []string{"open"},
},
},
})
w := httptest.NewRecorder()
req, _ := http.NewRequest("POST", s.accountURL()+"/conversations/filter", bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
s.router.ServeHTTP(w, req)
assert.Equal(s.T(), http.StatusOK, w.Code)
assert.NotContains(s.T(), w.Body.String(), "data")
var resp struct {
Meta struct {
AllCount int64 `json:"all_count"`
UnassignedCount int64 `json:"unassigned_count"`
} `json:"meta"`
Payload []map[string]interface{} `json:"payload"`
}
s.Require().NoError(json.Unmarshal(w.Body.Bytes(), &resp))
assert.Equal(s.T(), int64(1), resp.Meta.AllCount)
assert.Equal(s.T(), int64(1), resp.Meta.UnassignedCount)
s.Require().Len(resp.Payload, 1)
assert.Equal(s.T(), float64(s.testConv.ID), resp.Payload[0]["id"])
}
func (s *ConversationCrudTestSuite) TestFilter_ChatwootPayloadInvalidAttribute() {
body, _ := json.Marshal(map[string]interface{}{
"payload": []map[string]interface{}{
{
"attribute_key": "phone_number",
"filter_operator": "equal_to",
"values": []string{"open"},
},
},
})
w := httptest.NewRecorder()
req, _ := http.NewRequest("POST", s.accountURL()+"/conversations/filter", bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
s.router.ServeHTTP(w, req)
assert.Equal(s.T(), http.StatusUnprocessableEntity, w.Code)
var resp map[string]string
s.Require().NoError(json.Unmarshal(w.Body.Bytes(), &resp))
assert.Contains(s.T(), resp["error"], "Invalid attribute key - [phone_number]")
}
func (s *ConversationCrudTestSuite) TestFilter_ChatwootPayloadInvalidOperator() {
body, _ := json.Marshal(map[string]interface{}{
"payload": []map[string]interface{}{
{
"attribute_key": "status",
"filter_operator": "eq",
"values": []string{"open"},
},
},
})
w := httptest.NewRecorder()
req, _ := http.NewRequest("POST", s.accountURL()+"/conversations/filter", bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
s.router.ServeHTTP(w, req)
assert.Equal(s.T(), http.StatusUnprocessableEntity, w.Code)
var resp map[string]string
s.Require().NoError(json.Unmarshal(w.Body.Bytes(), &resp))
assert.Equal(s.T(), "Invalid operator. The allowed operators for status are [equal_to,not_equal_to].", resp["error"])
}
func (s *ConversationCrudTestSuite) TestFilter_InvalidAccountID() {
body, _ := json.Marshal(map[string]interface{}{
"status": "open",