feat(dashboard-apps): align chatwoot payloads

This commit is contained in:
2026-06-06 13:03:16 +08:00
parent 11e5537f9b
commit 75f0e809a5
9 changed files with 312 additions and 71 deletions
@@ -117,14 +117,22 @@ func (s *DashboardAppHandlerTestSuite) TestCreate_Success() {
c.Next()
}, s.handler.Create)
// Chatwoot requires nested {dashboard_app: {title: "...", content: [...]}}
body := `{"dashboard_app": {"title": "Test Dashboard App", "content": [{"type": "frame", "url": "https://example.com/widget"}]}}`
// The reused Chatwoot frontend sends a raw payload; Rails wraps it into
// dashboard_app server-side, so GoChat accepts both shapes.
body := `{"title": "Test Dashboard App", "content": [{"type": "frame", "url": "https://example.com/widget"}]}`
w := httptest.NewRecorder()
req, _ := http.NewRequest("POST", fmt.Sprintf("/api/v1/accounts/%d/dashboard_apps", s.account.ID), bytes.NewBufferString(body))
req.Header.Set("Content-Type", "application/json")
r.ServeHTTP(w, req)
assert.Equal(s.T(), http.StatusCreated, w.Code)
assert.Equal(s.T(), http.StatusOK, w.Code)
var payload map[string]any
s.Require().NoError(json.Unmarshal(w.Body.Bytes(), &payload))
assert.NotContains(s.T(), payload, "success")
assert.NotContains(s.T(), payload, "data")
assert.Equal(s.T(), "Test Dashboard App", payload["title"])
assert.NotContains(s.T(), payload, "account_id")
assert.NotContains(s.T(), payload, "updated_at")
}
func (s *DashboardAppHandlerTestSuite) TestGet_Success() {
@@ -144,6 +152,42 @@ func (s *DashboardAppHandlerTestSuite) TestGet_Success() {
s.T().Logf("Get response: status=%d, body=%s", w.Code, w.Body.String())
assert.Equal(s.T(), http.StatusOK, w.Code)
var payload map[string]any
s.Require().NoError(json.Unmarshal(w.Body.Bytes(), &payload))
assert.NotContains(s.T(), payload, "success")
assert.NotContains(s.T(), payload, "data")
assert.Equal(s.T(), "Seed App", payload["title"])
assert.Contains(s.T(), payload, "created_at")
assert.NotContains(s.T(), payload, "account_id")
}
func (s *DashboardAppHandlerTestSuite) TestPatch_RawPayloadAndAccountScope() {
r := gin.New()
r.PATCH("/api/v1/accounts/:account_id/dashboard_apps/:dashboard_app_id", s.handler.Patch)
seedApp, err := s.handler.svc.Create(context.Background(), s.account.ID, &s.user.ID, &service.CreateDashboardAppRequest{
Title: "Before",
Content: json.RawMessage(`[{"type":"frame","url":"https://example.com/before"}]`),
})
s.Require().NoError(err)
body := `{"title":"After","content":[{"type":"frame","url":"https://example.com/after"}]}`
w := httptest.NewRecorder()
req, _ := http.NewRequest("PATCH", fmt.Sprintf("/api/v1/accounts/%d/dashboard_apps/%d", s.account.ID, seedApp.ID), bytes.NewBufferString(body))
req.Header.Set("Content-Type", "application/json")
r.ServeHTTP(w, req)
assert.Equal(s.T(), http.StatusOK, w.Code)
var payload map[string]any
s.Require().NoError(json.Unmarshal(w.Body.Bytes(), &payload))
assert.Equal(s.T(), "After", payload["title"])
assert.NotContains(s.T(), payload, "success")
w = httptest.NewRecorder()
req, _ = http.NewRequest("PATCH", fmt.Sprintf("/api/v1/accounts/%d/dashboard_apps/%d", s.account.ID+100, seedApp.ID), bytes.NewBufferString(body))
req.Header.Set("Content-Type", "application/json")
r.ServeHTTP(w, req)
assert.Equal(s.T(), http.StatusNotFound, w.Code)
}
func (s *DashboardAppHandlerTestSuite) TestDelete_Success() {
@@ -162,4 +206,4 @@ func (s *DashboardAppHandlerTestSuite) TestDelete_Success() {
// Chatwoot: head :no_content → 204
assert.Equal(s.T(), http.StatusNoContent, w.Code)
}
}