feat(conversations): align unread count payloads

This commit is contained in:
2026-06-07 02:37:14 +08:00
parent 3a71001cb9
commit 8591fe1d33
6 changed files with 292 additions and 38 deletions
@@ -1,6 +1,7 @@
package v1
import (
"errors"
"net/http"
"strconv"
"strings"
@@ -1035,11 +1036,15 @@ func (h *ConversationHandler) UnreadCounts(c *gin.Context) {
return
}
payload, svcErr := h.conversationSvc.GetUnreadCounts(c.Request.Context(), accountID)
payload, svcErr := h.conversationSvc.GetUnreadCounts(c.Request.Context(), accountID, currentUserID(c))
if svcErr != nil {
if errors.Is(svcErr, service.ErrConversationUnreadCountsFeatureNotEnabled) {
c.JSON(http.StatusForbidden, gin.H{"error": svcErr.Error()})
return
}
handleServiceError(c, svcErr)
return
}
response.OK(c, payload)
c.JSON(http.StatusOK, gin.H{"payload": payload})
}
@@ -49,6 +49,7 @@ type ConversationHandlerTestSuite struct {
db *gorm.DB
testAccount *model.Account
testConv *model.Conversation
testUser *model.User
}
func (s *ConversationHandlerTestSuite) SetupSuite() {
@@ -72,19 +73,28 @@ func (s *ConversationHandlerTestSuite) SetupSuite() {
&model.Message{},
&model.Attachment{},
&model.InboxMember{},
&model.AccountUser{},
&model.CustomRole{},
&model.Team{},
&model.TeamMember{},
&model.Tag{},
&model.ConversationLabel{},
)
s.Require().NoError(err)
// Create test account
account := &model.Account{Name: "ConvHandlerTestOrg", Locale: "en", Active: true}
account := &model.Account{Name: "ConvHandlerTestOrg", Locale: "en", Active: true, FeatureFlags: `{"conversation_unread_counts":true}`}
s.Require().NoError(db.Create(account).Error)
s.testAccount = account
user := &model.User{Name: "Conv Handler User", Email: "conv-handler@example.com"}
s.Require().NoError(db.Create(user).Error)
s.Require().NoError(db.Create(&model.AccountUser{AccountID: account.ID, UserID: user.ID, Role: "administrator"}).Error)
s.testUser = user
// Create inbox and contact
inbox := &model.Inbox{AccountID: account.ID, Name: "ConvHandlerTestInbox", ChannelType: "web_widget", ChannelID: 1}
s.Require().NoError(db.Create(inbox).Error)
s.Require().NoError(db.Create(&model.InboxMember{InboxID: inbox.ID, UserID: user.ID}).Error)
contact := &model.Contact{AccountID: account.ID, Name: "ConvHandlerTestContact"}
s.Require().NoError(db.Create(contact).Error)
@@ -110,6 +120,10 @@ func (s *ConversationHandlerTestSuite) SetupSuite() {
// Setup router
r := gin.New()
r.Use(func(c *gin.Context) {
c.Set("user_id", user.ID)
c.Next()
})
s.router = r
// Register routes
@@ -406,6 +420,8 @@ func (s *ConversationHandlerTestSuite) TestUpdateCustomAttributes_ConversationNo
// ========== UnreadCounts Handler Tests ==========
func (s *ConversationHandlerTestSuite) TestUnreadCounts_Success() {
s.Require().NoError(s.db.Model(s.testAccount).Update("feature_flags", `{"conversation_unread_counts":true}`).Error)
w := httptest.NewRecorder()
req, _ := http.NewRequest("GET", s.accountURL()+"/conversations/unread_counts", nil)
s.router.ServeHTTP(w, req)
@@ -413,16 +429,31 @@ func (s *ConversationHandlerTestSuite) TestUnreadCounts_Success() {
assert.Equal(s.T(), http.StatusOK, w.Code)
var resp struct {
Success bool `json:"success"`
Data struct {
Payload struct {
Inboxes map[string]int64 `json:"inboxes"`
Labels map[string]int64 `json:"labels"`
Teams map[string]int64 `json:"teams"`
} `json:"data"`
} `json:"payload"`
}
err := json.Unmarshal(w.Body.Bytes(), &resp)
assert.NoError(s.T(), err)
assert.True(s.T(), resp.Success)
assert.NotContains(s.T(), w.Body.String(), "success")
assert.NotNil(s.T(), resp.Payload.Inboxes)
}
func (s *ConversationHandlerTestSuite) TestUnreadCounts_FeatureDisabled() {
account := &model.Account{Name: "Unread Disabled", Locale: "en", Active: true}
s.Require().NoError(s.db.Create(account).Error)
s.Require().NoError(s.db.Create(&model.AccountUser{AccountID: account.ID, UserID: s.testUser.ID, Role: "administrator"}).Error)
w := httptest.NewRecorder()
req, _ := http.NewRequest("GET", "/api/v1/accounts/"+strconv.FormatUint(uint64(account.ID), 10)+"/conversations/unread_counts", nil)
s.router.ServeHTTP(w, req)
assert.Equal(s.T(), http.StatusForbidden, w.Code)
var resp map[string]any
s.Require().NoError(json.Unmarshal(w.Body.Bytes(), &resp))
assert.Equal(s.T(), "Conversation unread counts feature not enabled for this account", resp["error"])
}
func (s *ConversationHandlerTestSuite) TestUnreadCounts_InvalidAccountID() {