feat(sla): align sla policy payloads

This commit is contained in:
2026-06-05 07:03:01 +08:00
parent be9c8f1f93
commit 95224faa34
2 changed files with 71 additions and 7 deletions
+30 -6
View File
@@ -6,6 +6,7 @@ import (
"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/response"
@@ -45,7 +46,7 @@ func (h *SlaPolicyHandler) Create(c *gin.Context) {
return
}
response.Created(c, policy)
c.JSON(http.StatusOK, gin.H{"payload": serializeSlaPolicy(policy)})
}
// Get retrieves a SLA policy by ID.
@@ -70,7 +71,7 @@ func (h *SlaPolicyHandler) Get(c *gin.Context) {
return
}
response.OK(c, policy)
c.JSON(http.StatusOK, gin.H{"payload": serializeSlaPolicy(policy)})
}
// List retrieves all SLA policies for an account.
@@ -89,7 +90,7 @@ func (h *SlaPolicyHandler) List(c *gin.Context) {
return
}
response.OK(c, policies)
c.JSON(http.StatusOK, gin.H{"payload": serializeSlaPolicies(policies)})
}
// Update updates a SLA policy.
@@ -121,7 +122,7 @@ func (h *SlaPolicyHandler) Update(c *gin.Context) {
return
}
response.OK(c, policy)
c.JSON(http.StatusOK, gin.H{"payload": serializeSlaPolicy(policy)})
}
// Delete deletes a SLA policy.
@@ -146,8 +147,31 @@ func (h *SlaPolicyHandler) Delete(c *gin.Context) {
return
}
// Chatwoot returns head :ok (200) on destroy — not 204 NoContent
c.JSON(http.StatusOK, gin.H{"success": true})
// Chatwoot returns head :ok (200) on destroy.
c.Status(http.StatusOK)
}
func serializeSlaPolicies(policies []model.SlaPolicy) []map[string]any {
payload := make([]map[string]any, 0, len(policies))
for i := range policies {
payload = append(payload, serializeSlaPolicy(&policies[i]))
}
return payload
}
func serializeSlaPolicy(policy *model.SlaPolicy) map[string]any {
if policy == nil {
return map[string]any{}
}
return map[string]any{
"id": policy.ID,
"name": policy.Name,
"description": policy.Description,
"first_response_time_threshold": policy.FirstResponseTimeThreshold,
"next_response_time_threshold": policy.NextResponseTimeThreshold,
"resolution_time_threshold": policy.ResolutionTimeThreshold,
"only_during_business_hours": policy.OnlyDuringBusinessHours,
}
}
// GetAppliedSlaMetrics retrieves SLA metrics for a conversation.
@@ -117,6 +117,19 @@ func TestSlaPolicyHandler_List_Success(t *testing.T) {
router.ServeHTTP(w, req)
assert.Equal(t, http.StatusOK, w.Code)
var got map[string]interface{}
require.NoError(t, json.Unmarshal(w.Body.Bytes(), &got))
assert.NotContains(t, got, "success")
require.IsType(t, []interface{}{}, got["payload"])
payload := got["payload"].([]interface{})
require.Len(t, payload, 2)
first := payload[0].(map[string]interface{})
assert.Equal(t, "Policy-A", first["name"])
assert.Equal(t, float64(10), first["first_response_time_threshold"])
assert.NotContains(t, first, "created_at")
assert.NotContains(t, first, "account_id")
}
func TestSlaPolicyHandler_List_NoAccountID(t *testing.T) {
@@ -156,7 +169,17 @@ func TestSlaPolicyHandler_Create_Success(t *testing.T) {
req.Header.Set("Content-Type", "application/json")
router.ServeHTTP(w, req)
assert.Equal(t, http.StatusCreated, w.Code)
assert.Equal(t, http.StatusOK, w.Code)
var got map[string]interface{}
require.NoError(t, json.Unmarshal(w.Body.Bytes(), &got))
assert.NotContains(t, got, "success")
payload := got["payload"].(map[string]interface{})
assert.Equal(t, "New SLA", payload["name"])
assert.Equal(t, "desc", payload["description"])
assert.Equal(t, float64(30), payload["first_response_time_threshold"])
assert.NotContains(t, payload, "created_at")
assert.NotContains(t, payload, "account_id")
}
func TestSlaPolicyHandler_Create_ValidationError(t *testing.T) {
@@ -226,6 +249,15 @@ func TestSlaPolicyHandler_Get_Success(t *testing.T) {
router.ServeHTTP(w, req)
assert.Equal(t, http.StatusOK, w.Code)
var got map[string]interface{}
require.NoError(t, json.Unmarshal(w.Body.Bytes(), &got))
assert.NotContains(t, got, "success")
payload := got["payload"].(map[string]interface{})
assert.Equal(t, "GetTest", payload["name"])
assert.Equal(t, float64(10), payload["first_response_time_threshold"])
assert.NotContains(t, payload, "created_at")
assert.NotContains(t, payload, "account_id")
}
func TestSlaPolicyHandler_Get_InvalidID(t *testing.T) {
@@ -271,6 +303,13 @@ func TestSlaPolicyHandler_Update_Success(t *testing.T) {
router.ServeHTTP(w, req)
assert.Equal(t, http.StatusOK, w.Code)
var got map[string]interface{}
require.NoError(t, json.Unmarshal(w.Body.Bytes(), &got))
assert.NotContains(t, got, "success")
payload := got["payload"].(map[string]interface{})
assert.Equal(t, "Updated Name", payload["name"])
assert.Equal(t, float64(45), payload["first_response_time_threshold"])
}
func TestSlaPolicyHandler_Update_NoAccountID(t *testing.T) {
@@ -318,6 +357,7 @@ func TestSlaPolicyHandler_Delete_Success(t *testing.T) {
// Chatwoot returns head :ok (200) on destroy, not 204
assert.Equal(t, http.StatusOK, w.Code)
assert.Empty(t, w.Body.String())
}
func TestSlaPolicyHandler_Delete_NoAccountID(t *testing.T) {