feat(conversations): align filter query operators

This commit is contained in:
2026-06-07 04:21:45 +08:00
parent 615c071168
commit f43ca571c2
3 changed files with 102 additions and 8 deletions
@@ -1052,6 +1052,69 @@ func (s *ConversationCrudTestSuite) TestFilter_ChatwootPayloadStatus() {
assert.Equal(s.T(), float64(s.testConv.ID), resp.Payload[0]["id"])
}
func (s *ConversationCrudTestSuite) TestFilter_ChatwootPayloadQueryOperatorChain() {
primaryID := uint(12345)
s.testConv.Status = "open"
s.testConv.Priority = "urgent"
s.testConv.DisplayID = &primaryID
s.Require().NoError(s.db.Save(s.testConv).Error)
secondaryID := uint(67890)
secondary := &model.Conversation{AccountID: s.testAccount.ID, InboxID: s.testInbox.ID, ContactID: s.testContact.ID, DisplayID: &secondaryID, Status: "resolved", Priority: "low", ChannelType: "web_widget", Channel: "web_widget"}
s.Require().NoError(s.db.Create(secondary).Error)
nonMatchingID := uint(11111)
nonMatching := &model.Conversation{AccountID: s.testAccount.ID, InboxID: s.testInbox.ID, ContactID: s.testContact.ID, DisplayID: &nonMatchingID, Status: "resolved", Priority: "low", ChannelType: "web_widget", Channel: "web_widget"}
s.Require().NoError(s.db.Create(nonMatching).Error)
body, _ := json.Marshal(map[string]interface{}{
"payload": []map[string]interface{}{
{"attribute_key": "status", "filter_operator": "equal_to", "values": []string{"open"}, "query_operator": "OR"},
{"attribute_key": "priority", "filter_operator": "equal_to", "values": []string{"low"}, "query_operator": "AND"},
{"attribute_key": "display_id", "filter_operator": "equal_to", "values": []string{"67890"}},
},
})
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)
var resp struct {
Meta struct {
AllCount int64 `json:"all_count"`
} `json:"meta"`
Payload []map[string]interface{} `json:"payload"`
}
s.Require().NoError(json.Unmarshal(w.Body.Bytes(), &resp))
assert.Equal(s.T(), int64(2), resp.Meta.AllCount)
s.Require().Len(resp.Payload, 2)
ids := []float64{resp.Payload[0]["id"].(float64), resp.Payload[1]["id"].(float64)}
assert.ElementsMatch(s.T(), []float64{float64(primaryID), float64(secondaryID)}, ids)
}
func (s *ConversationCrudTestSuite) TestFilter_ChatwootPayloadInvalidQueryOperator() {
body, _ := json.Marshal(map[string]interface{}{
"payload": []map[string]interface{}{
{
"attribute_key": "status",
"filter_operator": "equal_to",
"values": []string{"open"},
"query_operator": "XOR",
},
},
})
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(), "Query operator must be either \"AND\" or \"OR\".", resp["error"])
}
func (s *ConversationCrudTestSuite) TestFilter_ChatwootPayloadInvalidAttribute() {
body, _ := json.Marshal(map[string]interface{}{
"payload": []map[string]interface{}{