feat(capacity): align chatwoot inbox capacity limits
This commit is contained in:
@@ -1,13 +1,15 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gochat/gochat/internal/model"
|
||||
|
||||
"github.com/gochat/gochat/internal/service"
|
||||
applogger "github.com/gochat/gochat/pkg/logger"
|
||||
"github.com/gochat/gochat/pkg/pagination"
|
||||
"github.com/gochat/gochat/pkg/response"
|
||||
)
|
||||
|
||||
@@ -31,15 +33,18 @@ func (h *AgentCapacityHandler) List(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
pg := pagination.Parse(c)
|
||||
policies, total, err := h.svc.List(c.Request.Context(), accountID, pg.Page, pg.PerPage)
|
||||
policies, _, err := h.svc.List(c.Request.Context(), accountID, 1, 1000)
|
||||
if err != nil {
|
||||
applogger.L().Errorf("List agent capacity policies for account %d: %v", accountID, err)
|
||||
handleServiceError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
response.OKWithMeta(c, policies, pg.Page, pg.PerPage, total)
|
||||
payload := make([]gin.H, 0, len(policies))
|
||||
for i := range policies {
|
||||
payload = append(payload, serializeAgentCapacityPolicy(&policies[i]))
|
||||
}
|
||||
c.JSON(http.StatusOK, payload)
|
||||
}
|
||||
|
||||
// Create creates a new agent capacity policy for an account.
|
||||
@@ -52,22 +57,20 @@ func (h *AgentCapacityHandler) Create(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
var wrapper struct {
|
||||
AgentCapacityPolicy service.CreateAgentCapacityPolicyRequest `json:"agent_capacity_policy"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&wrapper); err != nil {
|
||||
req, err := bindAgentCapacityPolicyCreate(c)
|
||||
if err != nil {
|
||||
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrValidation, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
policy, err := h.svc.Create(c.Request.Context(), accountID, wrapper.AgentCapacityPolicy)
|
||||
policy, err := h.svc.Create(c.Request.Context(), accountID, req)
|
||||
if err != nil {
|
||||
applogger.L().Errorf("Create agent capacity policy for account %d: %v", accountID, err)
|
||||
handleServiceError(c, err)
|
||||
handleAgentCapacityError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
response.Created(c, policy)
|
||||
c.JSON(http.StatusOK, serializeAgentCapacityPolicy(policy))
|
||||
}
|
||||
|
||||
// Get returns a single agent capacity policy by ID.
|
||||
@@ -92,7 +95,7 @@ func (h *AgentCapacityHandler) Get(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
response.OK(c, policy)
|
||||
c.JSON(http.StatusOK, serializeAgentCapacityPolicy(policy))
|
||||
}
|
||||
|
||||
// Update updates an existing agent capacity policy.
|
||||
@@ -110,8 +113,8 @@ func (h *AgentCapacityHandler) Update(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
var req service.UpdateAgentCapacityPolicyRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
req, err := bindAgentCapacityPolicyUpdate(c)
|
||||
if err != nil {
|
||||
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrValidation, err.Error())
|
||||
return
|
||||
}
|
||||
@@ -119,11 +122,11 @@ func (h *AgentCapacityHandler) Update(c *gin.Context) {
|
||||
policy, svcErr := h.svc.Update(c.Request.Context(), id, accountID, req)
|
||||
if svcErr != nil {
|
||||
applogger.L().Errorf("Update agent capacity policy %d for account %d: %v", id, accountID, svcErr)
|
||||
handleServiceError(c, svcErr)
|
||||
handleAgentCapacityError(c, svcErr)
|
||||
return
|
||||
}
|
||||
|
||||
response.OK(c, policy)
|
||||
c.JSON(http.StatusOK, serializeAgentCapacityPolicy(policy))
|
||||
}
|
||||
|
||||
// Delete deletes an agent capacity policy.
|
||||
@@ -147,7 +150,153 @@ func (h *AgentCapacityHandler) Delete(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
response.NoContent(c)
|
||||
c.Status(http.StatusOK)
|
||||
}
|
||||
|
||||
func (h *AgentCapacityHandler) CreateInboxLimit(c *gin.Context) {
|
||||
accountID := getAccountID(c)
|
||||
if accountID == 0 {
|
||||
response.AbortWithStatusError(c, http.StatusUnauthorized, response.ErrUnauthorized, "account not identified")
|
||||
return
|
||||
}
|
||||
policyID, err := parseUintParam(c, "id")
|
||||
if err != nil {
|
||||
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid id")
|
||||
return
|
||||
}
|
||||
var req service.CreateInboxCapacityLimitRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrValidation, err.Error())
|
||||
return
|
||||
}
|
||||
limit, svcErr := h.svc.CreateInboxCapacityLimit(c.Request.Context(), policyID, accountID, req)
|
||||
if svcErr != nil {
|
||||
handleAgentCapacityError(c, svcErr)
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, serializeInboxCapacityLimit(limit, false))
|
||||
}
|
||||
|
||||
func (h *AgentCapacityHandler) UpdateInboxLimit(c *gin.Context) {
|
||||
accountID := getAccountID(c)
|
||||
if accountID == 0 {
|
||||
response.AbortWithStatusError(c, http.StatusUnauthorized, response.ErrUnauthorized, "account not identified")
|
||||
return
|
||||
}
|
||||
policyID, err := parseUintParam(c, "id")
|
||||
if err != nil {
|
||||
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid id")
|
||||
return
|
||||
}
|
||||
limitID, err := parseUintParam(c, "limit_id")
|
||||
if err != nil {
|
||||
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid limit id")
|
||||
return
|
||||
}
|
||||
var req service.UpdateInboxCapacityLimitRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrValidation, err.Error())
|
||||
return
|
||||
}
|
||||
limit, svcErr := h.svc.UpdateInboxCapacityLimit(c.Request.Context(), policyID, accountID, limitID, req)
|
||||
if svcErr != nil {
|
||||
handleAgentCapacityError(c, svcErr)
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, serializeInboxCapacityLimit(limit, true))
|
||||
}
|
||||
|
||||
func (h *AgentCapacityHandler) DeleteInboxLimit(c *gin.Context) {
|
||||
accountID := getAccountID(c)
|
||||
if accountID == 0 {
|
||||
response.AbortWithStatusError(c, http.StatusUnauthorized, response.ErrUnauthorized, "account not identified")
|
||||
return
|
||||
}
|
||||
policyID, err := parseUintParam(c, "id")
|
||||
if err != nil {
|
||||
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid id")
|
||||
return
|
||||
}
|
||||
limitID, err := parseUintParam(c, "limit_id")
|
||||
if err != nil {
|
||||
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid limit id")
|
||||
return
|
||||
}
|
||||
if svcErr := h.svc.DeleteInboxCapacityLimit(c.Request.Context(), policyID, accountID, limitID); svcErr != nil {
|
||||
handleAgentCapacityError(c, svcErr)
|
||||
return
|
||||
}
|
||||
c.Status(http.StatusNoContent)
|
||||
}
|
||||
|
||||
func (h *AgentCapacityHandler) ListUsers(c *gin.Context) {
|
||||
accountID := getAccountID(c)
|
||||
if accountID == 0 {
|
||||
response.AbortWithStatusError(c, http.StatusUnauthorized, response.ErrUnauthorized, "account not identified")
|
||||
return
|
||||
}
|
||||
policyID, err := parseUintParam(c, "id")
|
||||
if err != nil {
|
||||
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid id")
|
||||
return
|
||||
}
|
||||
users, svcErr := h.svc.ListUsers(c.Request.Context(), policyID, accountID)
|
||||
if svcErr != nil {
|
||||
handleAgentCapacityError(c, svcErr)
|
||||
return
|
||||
}
|
||||
payload := make([]gin.H, 0, len(users))
|
||||
for i := range users {
|
||||
payload = append(payload, serializeAgentCapacityUser(&users[i], accountID))
|
||||
}
|
||||
c.JSON(http.StatusOK, payload)
|
||||
}
|
||||
|
||||
func (h *AgentCapacityHandler) CreateUser(c *gin.Context) {
|
||||
accountID := getAccountID(c)
|
||||
if accountID == 0 {
|
||||
response.AbortWithStatusError(c, http.StatusUnauthorized, response.ErrUnauthorized, "account not identified")
|
||||
return
|
||||
}
|
||||
policyID, err := parseUintParam(c, "id")
|
||||
if err != nil {
|
||||
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid id")
|
||||
return
|
||||
}
|
||||
var req service.AssignCapacityPolicyUserRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrValidation, err.Error())
|
||||
return
|
||||
}
|
||||
user, svcErr := h.svc.AssignUser(c.Request.Context(), policyID, accountID, req)
|
||||
if svcErr != nil {
|
||||
handleAgentCapacityError(c, svcErr)
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, serializeAgentCapacityUser(user, accountID))
|
||||
}
|
||||
|
||||
func (h *AgentCapacityHandler) DeleteUser(c *gin.Context) {
|
||||
accountID := getAccountID(c)
|
||||
if accountID == 0 {
|
||||
response.AbortWithStatusError(c, http.StatusUnauthorized, response.ErrUnauthorized, "account not identified")
|
||||
return
|
||||
}
|
||||
policyID, err := parseUintParam(c, "id")
|
||||
if err != nil {
|
||||
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid id")
|
||||
return
|
||||
}
|
||||
userID, err := parseUintParam(c, "user_id")
|
||||
if err != nil {
|
||||
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid user id")
|
||||
return
|
||||
}
|
||||
if svcErr := h.svc.RemoveUser(c.Request.Context(), policyID, accountID, userID); svcErr != nil {
|
||||
handleAgentCapacityError(c, svcErr)
|
||||
return
|
||||
}
|
||||
c.Status(http.StatusOK)
|
||||
}
|
||||
|
||||
// RegisterAgentCapacityRoutes registers agent capacity policy routes on a gin.RouterGroup.
|
||||
@@ -158,6 +307,125 @@ func RegisterAgentCapacityRoutes(rg *gin.RouterGroup, h *AgentCapacityHandler) {
|
||||
policies.POST("/", h.Create)
|
||||
policies.GET("/:id", h.Get)
|
||||
policies.PUT("/:id", h.Update)
|
||||
policies.PATCH("/:id", h.Update)
|
||||
policies.DELETE("/:id", h.Delete)
|
||||
policies.GET("/:id/users", h.ListUsers)
|
||||
policies.POST("/:id/users", h.CreateUser)
|
||||
policies.DELETE("/:id/users/:user_id", h.DeleteUser)
|
||||
policies.POST("/:id/inbox_limits", h.CreateInboxLimit)
|
||||
policies.PUT("/:id/inbox_limits/:limit_id", h.UpdateInboxLimit)
|
||||
policies.PATCH("/:id/inbox_limits/:limit_id", h.UpdateInboxLimit)
|
||||
policies.DELETE("/:id/inbox_limits/:limit_id", h.DeleteInboxLimit)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func bindAgentCapacityPolicyCreate(c *gin.Context) (service.CreateAgentCapacityPolicyRequest, error) {
|
||||
var raw map[string]json.RawMessage
|
||||
if err := c.ShouldBindJSON(&raw); err != nil {
|
||||
return service.CreateAgentCapacityPolicyRequest{}, err
|
||||
}
|
||||
var req service.CreateAgentCapacityPolicyRequest
|
||||
if wrapped, ok := raw["agent_capacity_policy"]; ok {
|
||||
return req, json.Unmarshal(wrapped, &req)
|
||||
}
|
||||
buf, err := json.Marshal(raw)
|
||||
if err != nil {
|
||||
return req, err
|
||||
}
|
||||
return req, json.Unmarshal(buf, &req)
|
||||
}
|
||||
|
||||
func bindAgentCapacityPolicyUpdate(c *gin.Context) (service.UpdateAgentCapacityPolicyRequest, error) {
|
||||
var raw map[string]json.RawMessage
|
||||
if err := c.ShouldBindJSON(&raw); err != nil {
|
||||
return service.UpdateAgentCapacityPolicyRequest{}, err
|
||||
}
|
||||
var req service.UpdateAgentCapacityPolicyRequest
|
||||
if wrapped, ok := raw["agent_capacity_policy"]; ok {
|
||||
return req, json.Unmarshal(wrapped, &req)
|
||||
}
|
||||
buf, err := json.Marshal(raw)
|
||||
if err != nil {
|
||||
return req, err
|
||||
}
|
||||
return req, json.Unmarshal(buf, &req)
|
||||
}
|
||||
|
||||
func serializeAgentCapacityPolicy(policy *model.AgentCapacityPolicy) gin.H {
|
||||
limits := make([]gin.H, 0, len(policy.InboxCapacityLimits))
|
||||
for i := range policy.InboxCapacityLimits {
|
||||
limit := policy.InboxCapacityLimits[i]
|
||||
limits = append(limits, gin.H{
|
||||
"id": limit.ID,
|
||||
"inbox_id": limit.InboxID,
|
||||
"conversation_limit": limit.ConversationLimit,
|
||||
})
|
||||
}
|
||||
return gin.H{
|
||||
"id": policy.ID,
|
||||
"name": policy.Name,
|
||||
"description": policy.Description,
|
||||
"exclusion_rules": policy.ExclusionRules,
|
||||
"created_at": policy.CreatedAt.Unix(),
|
||||
"updated_at": policy.UpdatedAt.Unix(),
|
||||
"account_id": policy.AccountID,
|
||||
"assigned_agent_count": len(policy.AccountUsers),
|
||||
"inbox_capacity_limits": limits,
|
||||
}
|
||||
}
|
||||
|
||||
func serializeInboxCapacityLimit(limit *model.InboxCapacityLimit, includeInboxName bool) gin.H {
|
||||
payload := gin.H{
|
||||
"id": limit.ID,
|
||||
"inbox_id": limit.InboxID,
|
||||
"agent_capacity_policy_id": limit.AgentCapacityPolicyID,
|
||||
"conversation_limit": limit.ConversationLimit,
|
||||
"created_at": limit.CreatedAt.Unix(),
|
||||
"updated_at": limit.UpdatedAt.Unix(),
|
||||
}
|
||||
if includeInboxName {
|
||||
payload["inbox_name"] = limit.Inbox.Name
|
||||
}
|
||||
return payload
|
||||
}
|
||||
|
||||
func serializeAgentCapacityUser(user *model.User, accountID uint) gin.H {
|
||||
availableName := user.DisplayName
|
||||
if availableName == "" {
|
||||
availableName = user.Name
|
||||
}
|
||||
if availableName == "" {
|
||||
availableName = user.Email
|
||||
}
|
||||
return gin.H{
|
||||
"access_token": nil,
|
||||
"account_id": accountID,
|
||||
"available_name": availableName,
|
||||
"avatar_url": user.AvatarURL,
|
||||
"confirmed": user.ConfirmedAt != nil,
|
||||
"display_name": user.DisplayName,
|
||||
"message_signature": user.MessageSignature,
|
||||
"email": user.Email,
|
||||
"id": user.ID,
|
||||
"inviter_id": nil,
|
||||
"name": user.Name,
|
||||
"provider": user.Provider,
|
||||
"pubsub_token": user.PubsubToken,
|
||||
"role": user.Role,
|
||||
"ui_settings": user.UISettings,
|
||||
"uid": user.UID,
|
||||
"type": user.Type,
|
||||
}
|
||||
}
|
||||
|
||||
func handleAgentCapacityError(c *gin.Context, err error) {
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
lower := strings.ToLower(err.Error())
|
||||
if strings.Contains(lower, "already been assigned") || strings.Contains(lower, "greater than or equal") {
|
||||
response.AbortWithStatusError(c, http.StatusUnprocessableEntity, response.ErrValidation, err.Error())
|
||||
return
|
||||
}
|
||||
handleServiceError(c, err)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
@@ -31,7 +33,7 @@ func (s *AgentCapacityHandlerTestSuite) SetupSuite() {
|
||||
Logger: logger.Default.LogMode(logger.Silent),
|
||||
})
|
||||
s.Require().NoError(err)
|
||||
s.Require().NoError(db.AutoMigrate(&model.Account{}, &model.User{}, &model.AgentCapacityPolicy{}))
|
||||
s.Require().NoError(db.AutoMigrate(&model.Account{}, &model.User{}, &model.AccountUser{}, &model.Inbox{}, &model.AgentCapacityPolicy{}, &model.InboxCapacityLimit{}))
|
||||
s.db = db
|
||||
|
||||
repo := repository.NewAgentCapacityPolicyRepo(db)
|
||||
@@ -130,4 +132,79 @@ func (s *AgentCapacityHandlerTestSuite) TestDelete_BadRequest_InvalidID() {
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(s.T(), http.StatusBadRequest, w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *AgentCapacityHandlerTestSuite) TestChatwootPolicyInboxLimitAndUserFlow() {
|
||||
r := gin.New()
|
||||
api := r.Group("/api/v1/accounts/:account_id")
|
||||
RegisterAgentCapacityRoutes(api, s.handler)
|
||||
|
||||
inbox := &model.Inbox{AccountID: s.account.ID, Name: "Priority", ChannelType: "web_widget"}
|
||||
s.Require().NoError(s.db.Create(inbox).Error)
|
||||
user := &model.User{AccountID: s.account.ID, Name: "Capacity Agent", Email: "capacity-agent@example.com", Password: "secret", Role: "agent"}
|
||||
s.Require().NoError(s.db.Create(user).Error)
|
||||
s.Require().NoError(s.db.Create(&model.AccountUser{AccountID: s.account.ID, UserID: user.ID, Role: "agent"}).Error)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
body := `{"agent_capacity_policy":{"name":"Priority policy","description":"VIP","exclusion_rules":{"exclude_older_than_hours":24,"excluded_labels":["spam"]}}}`
|
||||
req, _ := http.NewRequest(http.MethodPost, fmt.Sprintf("/api/v1/accounts/%d/agent_capacity_policies/", s.account.ID), bytes.NewBufferString(body))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
r.ServeHTTP(w, req)
|
||||
s.Require().Equal(http.StatusOK, w.Code)
|
||||
var policy map[string]any
|
||||
s.Require().NoError(json.Unmarshal(w.Body.Bytes(), &policy))
|
||||
s.Require().NotContains(policy, "success")
|
||||
s.Require().Equal("Priority policy", policy["name"])
|
||||
s.Require().Equal(float64(0), policy["assigned_agent_count"])
|
||||
policyID := uint(policy["id"].(float64))
|
||||
|
||||
w = httptest.NewRecorder()
|
||||
body = fmt.Sprintf(`{"inbox_id":%d,"conversation_limit":7}`, inbox.ID)
|
||||
req, _ = http.NewRequest(http.MethodPost, fmt.Sprintf("/api/v1/accounts/%d/agent_capacity_policies/%d/inbox_limits", s.account.ID, policyID), bytes.NewBufferString(body))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
r.ServeHTTP(w, req)
|
||||
s.Require().Equal(http.StatusOK, w.Code)
|
||||
var limit map[string]any
|
||||
s.Require().NoError(json.Unmarshal(w.Body.Bytes(), &limit))
|
||||
s.Require().Equal(float64(inbox.ID), limit["inbox_id"])
|
||||
s.Require().Equal(float64(7), limit["conversation_limit"])
|
||||
limitID := uint(limit["id"].(float64))
|
||||
|
||||
w = httptest.NewRecorder()
|
||||
req, _ = http.NewRequest(http.MethodPost, fmt.Sprintf("/api/v1/accounts/%d/agent_capacity_policies/%d/inbox_limits", s.account.ID, policyID), bytes.NewBufferString(body))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
r.ServeHTTP(w, req)
|
||||
s.Require().Equal(http.StatusUnprocessableEntity, w.Code)
|
||||
|
||||
w = httptest.NewRecorder()
|
||||
req, _ = http.NewRequest(http.MethodPut, fmt.Sprintf("/api/v1/accounts/%d/agent_capacity_policies/%d/inbox_limits/%d", s.account.ID, policyID, limitID), bytes.NewBufferString(`{"conversation_limit":11}`))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
r.ServeHTTP(w, req)
|
||||
s.Require().Equal(http.StatusOK, w.Code)
|
||||
s.Require().NoError(json.Unmarshal(w.Body.Bytes(), &limit))
|
||||
s.Require().Equal(float64(11), limit["conversation_limit"])
|
||||
s.Require().Equal("Priority", limit["inbox_name"])
|
||||
|
||||
w = httptest.NewRecorder()
|
||||
body = fmt.Sprintf(`{"user_id":%d}`, user.ID)
|
||||
req, _ = http.NewRequest(http.MethodPost, fmt.Sprintf("/api/v1/accounts/%d/agent_capacity_policies/%d/users", s.account.ID, policyID), bytes.NewBufferString(body))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
r.ServeHTTP(w, req)
|
||||
s.Require().Equal(http.StatusOK, w.Code)
|
||||
var assigned map[string]any
|
||||
s.Require().NoError(json.Unmarshal(w.Body.Bytes(), &assigned))
|
||||
s.Require().Equal(float64(user.ID), assigned["id"])
|
||||
|
||||
w = httptest.NewRecorder()
|
||||
req, _ = http.NewRequest(http.MethodGet, fmt.Sprintf("/api/v1/accounts/%d/agent_capacity_policies/%d", s.account.ID, policyID), nil)
|
||||
r.ServeHTTP(w, req)
|
||||
s.Require().Equal(http.StatusOK, w.Code)
|
||||
s.Require().NoError(json.Unmarshal(w.Body.Bytes(), &policy))
|
||||
s.Require().Equal(float64(1), policy["assigned_agent_count"])
|
||||
s.Require().Len(policy["inbox_capacity_limits"].([]any), 1)
|
||||
|
||||
w = httptest.NewRecorder()
|
||||
req, _ = http.NewRequest(http.MethodDelete, fmt.Sprintf("/api/v1/accounts/%d/agent_capacity_policies/%d/inbox_limits/%d", s.account.ID, policyID, limitID), nil)
|
||||
r.ServeHTTP(w, req)
|
||||
s.Require().Equal(http.StatusNoContent, w.Code)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user