package v1 // coverage28_test.go — additional handler coverage tests. // Focus: agent, csat_survey, custom_attribute_definition, inbox, contact, // conversation, article, team, automation_rule, macro handlers. // Strategy: DB-backed services + param-parsing + body-binding + error-path branches. import ( "net/http" "net/http/httptest" "strconv" "strings" "testing" "github.com/gin-gonic/gin" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gorm.io/gorm" "github.com/gochat/gochat/internal/automation" "github.com/gochat/gochat/internal/repository" "github.com/gochat/gochat/internal/service" ) // ============================================================ // Helpers (Cov28) // ============================================================ func newTestDB_Cov28(t *testing.T) *gorm.DB { t.Helper() db := newTestDB_Cov19(t) // Also migrate automation tables require.NoError(t, db.AutoMigrate( &automation.AutomationRule{}, &automation.Macro{}, &automation.CsatSurveyResponse{}, &automation.AutomationExecution{}, ), "failed to auto-migrate automation models") return db } func uitoaCov28(n uint) string { return strconv.FormatUint(uint64(n), 10) } func ctxCov28(method, path string, params map[string]string) (*gin.Context, *httptest.ResponseRecorder) { w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) c.Request = httptest.NewRequest(method, path, nil) for k, v := range params { c.Params = append(c.Params, gin.Param{Key: k, Value: v}) } return c, w } func ctxBodyCov28(method, path string, params map[string]string, body string) (*gin.Context, *httptest.ResponseRecorder) { w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) c.Request = httptest.NewRequest(method, path, strings.NewReader(body)) if body != "" { c.Request.Header.Set("Content-Type", "application/json") } for k, v := range params { c.Params = append(c.Params, gin.Param{Key: k, Value: v}) } return c, w } func ctxAuthCov28(method, path string, params map[string]string, userID, accountID uint, role string) (*gin.Context, *httptest.ResponseRecorder) { c, w := ctxCov28(method, path, params) c.Set("user_id", userID) c.Set("account_id", accountID) c.Set("role", role) return c, w } func ctxAuthBodyCov28(method, path string, params map[string]string, userID, accountID uint, role, body string) (*gin.Context, *httptest.ResponseRecorder) { c, w := ctxBodyCov28(method, path, params, body) c.Set("user_id", userID) c.Set("account_id", accountID) c.Set("role", role) return c, w } func safeCallCov28(t *testing.T, name string, w *httptest.ResponseRecorder, fn func()) { t.Helper() _ = w defer func() { if r := recover(); r != nil { t.Logf("[%s] recovered: %v", name, r) } }() fn() } // Service constructor helpers (Cov28) func newCsatSvcCov28(db *gorm.DB) *automation.CsatSurveyService { return automation.NewCsatSurveyService(&cov27DBProvider{db: db}) } func newAgentSvcCov28(db *gorm.DB) *service.AgentService { return service.NewAgentService(repository.NewAgentRepo(db), db) } // Seed helpers (Cov28) func seedCsatResponseCov28(t *testing.T, db *gorm.DB, accountID, conversationID, contactID uint) *automation.CsatSurveyResponse { t.Helper() resp := automation.CsatSurveyResponse{ AccountID: accountID, ConversationID: conversationID, ContactID: contactID, Rating: 5, FeedbackMessage: "Great service", } require.NoError(t, db.Create(&resp).Error) return &resp } // ============================================================ // AgentHandler Tests (25 tests) // ============================================================ func TestAgentHandler_List_DB_Cov28(t *testing.T) { db := newTestDB_Cov28(t) acc := seedAccount_Cov19(t, db) seedUser_Cov19(t, db, acc.ID) h := NewAgentHandler(newAgentSvcCov28(db)) c, w := ctxAuthCov28("GET", "/api/v1/accounts/"+uitoaCov28(acc.ID)+"/agents", map[string]string{"account_id": uitoaCov28(acc.ID)}, 1, acc.ID, "administrator") safeCallCov28(t, "AgentList_DB", w, func() { h.List(c) }) } func TestAgentHandler_List_NoAccountID_Cov28(t *testing.T) { db := newTestDB_Cov28(t) h := NewAgentHandler(newAgentSvcCov28(db)) c, w := ctxCov28("GET", "/api/v1/accounts/0/agents", nil) h.List(c) assert.Equal(t, http.StatusUnauthorized, w.Code) } func TestAgentHandler_Get_InvalidAgentID_Cov28(t *testing.T) { db := newTestDB_Cov28(t) acc := seedAccount_Cov19(t, db) h := NewAgentHandler(newAgentSvcCov28(db)) c, w := ctxAuthCov28("GET", "/api/v1/accounts/"+uitoaCov28(acc.ID)+"/agents/abc", map[string]string{"account_id": uitoaCov28(acc.ID), "agent_id": "abc"}, 1, acc.ID, "administrator") h.Get(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestAgentHandler_Get_NoAccountID_Cov28(t *testing.T) { db := newTestDB_Cov28(t) h := NewAgentHandler(newAgentSvcCov28(db)) c, w := ctxCov28("GET", "/api/v1/accounts/0/agents/1", map[string]string{"agent_id": "1"}) h.Get(c) assert.Equal(t, http.StatusUnauthorized, w.Code) } func TestAgentHandler_Get_DB_Cov28(t *testing.T) { db := newTestDB_Cov28(t) acc := seedAccount_Cov19(t, db) user := seedUser_Cov19(t, db, acc.ID) h := NewAgentHandler(newAgentSvcCov28(db)) c, w := ctxAuthCov28("GET", "/api/v1/accounts/"+uitoaCov28(acc.ID)+"/agents/"+uitoaCov28(user.ID), map[string]string{"account_id": uitoaCov28(acc.ID), "agent_id": uitoaCov28(user.ID)}, 1, acc.ID, "administrator") safeCallCov28(t, "AgentGet_DB", w, func() { h.Get(c) }) } func TestAgentHandler_Create_NoAccountID_Cov28(t *testing.T) { db := newTestDB_Cov28(t) h := NewAgentHandler(newAgentSvcCov28(db)) c, w := ctxBodyCov28("POST", "/api/v1/accounts/0/agents", nil, `{}`) h.Create(c) assert.Equal(t, http.StatusUnauthorized, w.Code) } func TestAgentHandler_Create_NoUserID_Cov28(t *testing.T) { db := newTestDB_Cov28(t) acc := seedAccount_Cov19(t, db) h := NewAgentHandler(newAgentSvcCov28(db)) c, w := ctxBodyCov28("POST", "/api/v1/accounts/"+uitoaCov28(acc.ID)+"/agents", map[string]string{"account_id": uitoaCov28(acc.ID)}, `{"email":"test@cov28.com","name":"Agent"}`) h.Create(c) assert.Equal(t, http.StatusUnauthorized, w.Code) } func TestAgentHandler_Create_InvalidBody_Cov28(t *testing.T) { db := newTestDB_Cov28(t) acc := seedAccount_Cov19(t, db) h := NewAgentHandler(newAgentSvcCov28(db)) c, w := ctxAuthBodyCov28("POST", "/api/v1/accounts/"+uitoaCov28(acc.ID)+"/agents", map[string]string{"account_id": uitoaCov28(acc.ID)}, 1, acc.ID, "administrator", "bad") h.Create(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestAgentHandler_Create_DB_Cov28(t *testing.T) { db := newTestDB_Cov28(t) acc := seedAccount_Cov19(t, db) h := NewAgentHandler(newAgentSvcCov28(db)) body := `{"agent":{"email":"newagent@cov28.com","name":"NewAgent","role":"agent"}}` c, w := ctxAuthBodyCov28("POST", "/api/v1/accounts/"+uitoaCov28(acc.ID)+"/agents", map[string]string{"account_id": uitoaCov28(acc.ID)}, 1, acc.ID, "administrator", body) safeCallCov28(t, "AgentCreate_DB", w, func() { h.Create(c) }) } func TestAgentHandler_Create_RawBody_Cov28(t *testing.T) { db := newTestDB_Cov28(t) acc := seedAccount_Cov19(t, db) h := NewAgentHandler(newAgentSvcCov28(db)) body := `{"email":"rawagent@cov28.com","name":"RawAgent","role":"agent"}` c, w := ctxAuthBodyCov28("POST", "/api/v1/accounts/"+uitoaCov28(acc.ID)+"/agents", map[string]string{"account_id": uitoaCov28(acc.ID)}, 1, acc.ID, "administrator", body) safeCallCov28(t, "AgentCreate_Raw", w, func() { h.Create(c) }) } func TestAgentHandler_Create_EmptyBody_Cov28(t *testing.T) { db := newTestDB_Cov28(t) acc := seedAccount_Cov19(t, db) h := NewAgentHandler(newAgentSvcCov28(db)) c, w := ctxAuthBodyCov28("POST", "/api/v1/accounts/"+uitoaCov28(acc.ID)+"/agents", map[string]string{"account_id": uitoaCov28(acc.ID)}, 1, acc.ID, "administrator", "") h.Create(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestAgentHandler_Update_NoAccountID_Cov28(t *testing.T) { db := newTestDB_Cov28(t) h := NewAgentHandler(newAgentSvcCov28(db)) c, w := ctxBodyCov28("PUT", "/api/v1/accounts/0/agents/1", map[string]string{"agent_id": "1"}, `{}`) h.Update(c) assert.Equal(t, http.StatusUnauthorized, w.Code) } func TestAgentHandler_Update_InvalidAgentID_Cov28(t *testing.T) { db := newTestDB_Cov28(t) acc := seedAccount_Cov19(t, db) h := NewAgentHandler(newAgentSvcCov28(db)) c, w := ctxAuthBodyCov28("PUT", "/api/v1/accounts/"+uitoaCov28(acc.ID)+"/agents/abc", map[string]string{"account_id": uitoaCov28(acc.ID), "agent_id": "abc"}, 1, acc.ID, "administrator", `{}`) h.Update(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestAgentHandler_Update_InvalidBody_Cov28(t *testing.T) { db := newTestDB_Cov28(t) acc := seedAccount_Cov19(t, db) user := seedUser_Cov19(t, db, acc.ID) h := NewAgentHandler(newAgentSvcCov28(db)) c, w := ctxAuthBodyCov28("PUT", "/api/v1/accounts/"+uitoaCov28(acc.ID)+"/agents/"+uitoaCov28(user.ID), map[string]string{"account_id": uitoaCov28(acc.ID), "agent_id": uitoaCov28(user.ID)}, 1, acc.ID, "administrator", "bad") h.Update(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestAgentHandler_Update_DB_Cov28(t *testing.T) { db := newTestDB_Cov28(t) acc := seedAccount_Cov19(t, db) user := seedUser_Cov19(t, db, acc.ID) h := NewAgentHandler(newAgentSvcCov28(db)) body := `{"agent":{"name":"UpdatedAgent"}}` c, w := ctxAuthBodyCov28("PUT", "/api/v1/accounts/"+uitoaCov28(acc.ID)+"/agents/"+uitoaCov28(user.ID), map[string]string{"account_id": uitoaCov28(acc.ID), "agent_id": uitoaCov28(user.ID)}, 1, acc.ID, "administrator", body) safeCallCov28(t, "AgentUpdate_DB", w, func() { h.Update(c) }) } func TestAgentHandler_Delete_NoAccountID_Cov28(t *testing.T) { db := newTestDB_Cov28(t) h := NewAgentHandler(newAgentSvcCov28(db)) c, w := ctxCov28("DELETE", "/api/v1/accounts/0/agents/1", map[string]string{"agent_id": "1"}) h.Delete(c) assert.Equal(t, http.StatusUnauthorized, w.Code) } func TestAgentHandler_Delete_InvalidAgentID_Cov28(t *testing.T) { db := newTestDB_Cov28(t) acc := seedAccount_Cov19(t, db) h := NewAgentHandler(newAgentSvcCov28(db)) c, w := ctxAuthCov28("DELETE", "/api/v1/accounts/"+uitoaCov28(acc.ID)+"/agents/abc", map[string]string{"account_id": uitoaCov28(acc.ID), "agent_id": "abc"}, 1, acc.ID, "administrator") h.Delete(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestAgentHandler_Delete_DB_Cov28(t *testing.T) { db := newTestDB_Cov28(t) acc := seedAccount_Cov19(t, db) user := seedUser_Cov19(t, db, acc.ID) h := NewAgentHandler(newAgentSvcCov28(db)) c, w := ctxAuthCov28("DELETE", "/api/v1/accounts/"+uitoaCov28(acc.ID)+"/agents/"+uitoaCov28(user.ID), map[string]string{"account_id": uitoaCov28(acc.ID), "agent_id": uitoaCov28(user.ID)}, 1, acc.ID, "administrator") safeCallCov28(t, "AgentDelete_DB", w, func() { h.Delete(c) }) } func TestAgentHandler_ResetPassword_NoAccountID_Cov28(t *testing.T) { db := newTestDB_Cov28(t) h := NewAgentHandler(newAgentSvcCov28(db)) c, w := ctxCov28("POST", "/api/v1/accounts/0/agents/1/reset_password", map[string]string{"agent_id": "1"}) h.ResetPassword(c) assert.Equal(t, http.StatusUnauthorized, w.Code) } func TestAgentHandler_ResetPassword_InvalidAgentID_Cov28(t *testing.T) { db := newTestDB_Cov28(t) acc := seedAccount_Cov19(t, db) h := NewAgentHandler(newAgentSvcCov28(db)) c, w := ctxAuthCov28("POST", "/api/v1/accounts/"+uitoaCov28(acc.ID)+"/agents/abc/reset_password", map[string]string{"account_id": uitoaCov28(acc.ID), "agent_id": "abc"}, 1, acc.ID, "administrator") h.ResetPassword(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestAgentHandler_ResetPassword_DB_Cov28(t *testing.T) { db := newTestDB_Cov28(t) acc := seedAccount_Cov19(t, db) user := seedUser_Cov19(t, db, acc.ID) h := NewAgentHandler(newAgentSvcCov28(db)) c, w := ctxAuthCov28("POST", "/api/v1/accounts/"+uitoaCov28(acc.ID)+"/agents/"+uitoaCov28(user.ID)+"/reset_password", map[string]string{"account_id": uitoaCov28(acc.ID), "agent_id": uitoaCov28(user.ID)}, 1, acc.ID, "administrator") safeCallCov28(t, "AgentResetPassword_DB", w, func() { h.ResetPassword(c) }) } func TestAgentHandler_BulkCreate_NoAccountID_Cov28(t *testing.T) { db := newTestDB_Cov28(t) h := NewAgentHandler(newAgentSvcCov28(db)) c, w := ctxBodyCov28("POST", "/api/v1/accounts/0/agents/bulk_create", nil, `{}`) h.BulkCreate(c) assert.Equal(t, http.StatusUnauthorized, w.Code) } func TestAgentHandler_BulkCreate_NoUserID_Cov28(t *testing.T) { db := newTestDB_Cov28(t) acc := seedAccount_Cov19(t, db) h := NewAgentHandler(newAgentSvcCov28(db)) c, w := ctxBodyCov28("POST", "/api/v1/accounts/"+uitoaCov28(acc.ID)+"/agents/bulk_create", map[string]string{"account_id": uitoaCov28(acc.ID)}, `{"emails":["test@cov28.com"]}`) h.BulkCreate(c) assert.Equal(t, http.StatusUnauthorized, w.Code) } func TestAgentHandler_BulkCreate_InvalidBody_Cov28(t *testing.T) { db := newTestDB_Cov28(t) acc := seedAccount_Cov19(t, db) h := NewAgentHandler(newAgentSvcCov28(db)) c, w := ctxAuthBodyCov28("POST", "/api/v1/accounts/"+uitoaCov28(acc.ID)+"/agents/bulk_create", map[string]string{"account_id": uitoaCov28(acc.ID)}, 1, acc.ID, "administrator", "bad") h.BulkCreate(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestAgentHandler_BulkCreate_DB_Cov28(t *testing.T) { db := newTestDB_Cov28(t) acc := seedAccount_Cov19(t, db) h := NewAgentHandler(newAgentSvcCov28(db)) body := `{"emails":["bulk1@cov28.com","bulk2@cov28.com"]}` c, w := ctxAuthBodyCov28("POST", "/api/v1/accounts/"+uitoaCov28(acc.ID)+"/agents/bulk_create", map[string]string{"account_id": uitoaCov28(acc.ID)}, 1, acc.ID, "administrator", body) safeCallCov28(t, "AgentBulkCreate_DB", w, func() { h.BulkCreate(c) }) } // ============================================================ // CsatSurveyHandler Tests (25 tests) // ============================================================ func TestCsatSurveyHandler_List_DB_Cov28(t *testing.T) { db := newTestDB_Cov28(t) acc := seedAccount_Cov19(t, db) inbox := seedInbox_Cov19(t, db, acc.ID) contact := seedContact_Cov19(t, db, acc.ID) conv := seedConversation_Cov19(t, db, acc.ID, inbox.ID, contact.ID) seedCsatResponseCov28(t, db, acc.ID, conv.ID, contact.ID) h := NewCsatSurveyHandler(newCsatSvcCov28(db)) c, w := ctxAuthCov28("GET", "/api/v1/accounts/"+uitoaCov28(acc.ID)+"/csat_survey_responses", map[string]string{"account_id": uitoaCov28(acc.ID)}, 1, acc.ID, "administrator") safeCallCov28(t, "CsatList_DB", w, func() { h.List(c) }) } func TestCsatSurveyHandler_List_InvalidAccountID_Cov28(t *testing.T) { db := newTestDB_Cov28(t) h := NewCsatSurveyHandler(newCsatSvcCov28(db)) c, w := ctxCov28("GET", "/api/v1/accounts/abc/csat_survey_responses", map[string]string{"account_id": "abc"}) h.List(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestCsatSurveyHandler_List_WithFilters_Cov28(t *testing.T) { db := newTestDB_Cov28(t) acc := seedAccount_Cov19(t, db) inbox := seedInbox_Cov19(t, db, acc.ID) contact := seedContact_Cov19(t, db, acc.ID) conv := seedConversation_Cov19(t, db, acc.ID, inbox.ID, contact.ID) seedCsatResponseCov28(t, db, acc.ID, conv.ID, contact.ID) h := NewCsatSurveyHandler(newCsatSvcCov28(db)) c, w := ctxAuthCov28("GET", "/api/v1/accounts/"+uitoaCov28(acc.ID)+"/csat_survey_responses?agent_id=1&inbox_id="+uitoaCov28(inbox.ID)+"&rating=5&page=1&since=1000&until=2000", map[string]string{"account_id": uitoaCov28(acc.ID)}, 1, acc.ID, "administrator") safeCallCov28(t, "CsatList_Filters", w, func() { h.List(c) }) } func TestCsatSurveyHandler_List_WithUserIDs_Cov28(t *testing.T) { db := newTestDB_Cov28(t) acc := seedAccount_Cov19(t, db) inbox := seedInbox_Cov19(t, db, acc.ID) contact := seedContact_Cov19(t, db, acc.ID) conv := seedConversation_Cov19(t, db, acc.ID, inbox.ID, contact.ID) seedCsatResponseCov28(t, db, acc.ID, conv.ID, contact.ID) h := NewCsatSurveyHandler(newCsatSvcCov28(db)) c, w := ctxAuthCov28("GET", "/api/v1/accounts/"+uitoaCov28(acc.ID)+"/csat_survey_responses?user_ids[]=1&user_ids[]=2&user_ids=3,4&team_id=1", map[string]string{"account_id": uitoaCov28(acc.ID)}, 1, acc.ID, "administrator") safeCallCov28(t, "CsatList_UserIDs", w, func() { h.List(c) }) } func TestCsatSurveyHandler_Metrics_DB_Cov28(t *testing.T) { db := newTestDB_Cov28(t) acc := seedAccount_Cov19(t, db) inbox := seedInbox_Cov19(t, db, acc.ID) contact := seedContact_Cov19(t, db, acc.ID) conv := seedConversation_Cov19(t, db, acc.ID, inbox.ID, contact.ID) seedCsatResponseCov28(t, db, acc.ID, conv.ID, contact.ID) h := NewCsatSurveyHandler(newCsatSvcCov28(db)) c, w := ctxAuthCov28("GET", "/api/v1/accounts/"+uitoaCov28(acc.ID)+"/csat_survey_responses/metrics", map[string]string{"account_id": uitoaCov28(acc.ID)}, 1, acc.ID, "administrator") safeCallCov28(t, "CsatMetrics_DB", w, func() { h.Metrics(c) }) } func TestCsatSurveyHandler_Metrics_InvalidAccountID_Cov28(t *testing.T) { db := newTestDB_Cov28(t) h := NewCsatSurveyHandler(newCsatSvcCov28(db)) c, w := ctxCov28("GET", "/api/v1/accounts/abc/csat_survey_responses/metrics", map[string]string{"account_id": "abc"}) h.Metrics(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestCsatSurveyHandler_UpdateReviewNotes_InvalidID_Cov28(t *testing.T) { db := newTestDB_Cov28(t) h := NewCsatSurveyHandler(newCsatSvcCov28(db)) c, w := ctxAuthBodyCov28("POST", "/api/v1/accounts/1/csat_survey_responses/abc/update_review_notes", map[string]string{"id": "abc"}, 1, 1, "administrator", `{"review_notes":"test"}`) h.UpdateReviewNotes(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestCsatSurveyHandler_UpdateReviewNotes_InvalidBody_Cov28(t *testing.T) { db := newTestDB_Cov28(t) h := NewCsatSurveyHandler(newCsatSvcCov28(db)) c, w := ctxAuthBodyCov28("POST", "/api/v1/accounts/1/csat_survey_responses/1/update_review_notes", map[string]string{"id": "1"}, 1, 1, "administrator", "bad") h.UpdateReviewNotes(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestCsatSurveyHandler_UpdateReviewNotes_DB_Cov28(t *testing.T) { db := newTestDB_Cov28(t) acc := seedAccount_Cov19(t, db) inbox := seedInbox_Cov19(t, db, acc.ID) contact := seedContact_Cov19(t, db, acc.ID) conv := seedConversation_Cov19(t, db, acc.ID, inbox.ID, contact.ID) resp := seedCsatResponseCov28(t, db, acc.ID, conv.ID, contact.ID) h := NewCsatSurveyHandler(newCsatSvcCov28(db)) body := `{"csat_review_notes":"good review"}` c, w := ctxAuthBodyCov28("POST", "/api/v1/accounts/"+uitoaCov28(acc.ID)+"/csat_survey_responses/"+uitoaCov28(resp.ID)+"/update_review_notes", map[string]string{"id": uitoaCov28(resp.ID)}, 1, acc.ID, "administrator", body) safeCallCov28(t, "CsatUpdateReviewNotes_DB", w, func() { h.UpdateReviewNotes(c) }) } func TestCsatSurveyHandler_UpdateReviewNotes_AltField_Cov28(t *testing.T) { db := newTestDB_Cov28(t) acc := seedAccount_Cov19(t, db) inbox := seedInbox_Cov19(t, db, acc.ID) contact := seedContact_Cov19(t, db, acc.ID) conv := seedConversation_Cov19(t, db, acc.ID, inbox.ID, contact.ID) resp := seedCsatResponseCov28(t, db, acc.ID, conv.ID, contact.ID) h := NewCsatSurveyHandler(newCsatSvcCov28(db)) body := `{"review_notes":"alt review"}` c, w := ctxAuthBodyCov28("POST", "/api/v1/accounts/"+uitoaCov28(acc.ID)+"/csat_survey_responses/"+uitoaCov28(resp.ID)+"/update_review_notes", map[string]string{"id": uitoaCov28(resp.ID)}, 1, acc.ID, "administrator", body) safeCallCov28(t, "CsatUpdateReviewNotes_Alt", w, func() { h.UpdateReviewNotes(c) }) } func TestCsatSurveyHandler_Update_InvalidAccountID_Cov28(t *testing.T) { db := newTestDB_Cov28(t) h := NewCsatSurveyHandler(newCsatSvcCov28(db)) c, w := ctxBodyCov28("PATCH", "/api/v1/accounts/abc/csat_survey_responses/1", map[string]string{"account_id": "abc", "id": "1"}, `{}`) h.Update(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestCsatSurveyHandler_Update_InvalidID_Cov28(t *testing.T) { db := newTestDB_Cov28(t) acc := seedAccount_Cov19(t, db) h := NewCsatSurveyHandler(newCsatSvcCov28(db)) c, w := ctxAuthBodyCov28("PATCH", "/api/v1/accounts/"+uitoaCov28(acc.ID)+"/csat_survey_responses/abc", map[string]string{"account_id": uitoaCov28(acc.ID), "id": "abc"}, 1, acc.ID, "administrator", `{}`) h.Update(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestCsatSurveyHandler_Update_InvalidBody_Cov28(t *testing.T) { db := newTestDB_Cov28(t) acc := seedAccount_Cov19(t, db) h := NewCsatSurveyHandler(newCsatSvcCov28(db)) c, w := ctxAuthBodyCov28("PATCH", "/api/v1/accounts/"+uitoaCov28(acc.ID)+"/csat_survey_responses/1", map[string]string{"account_id": uitoaCov28(acc.ID), "id": "1"}, 1, acc.ID, "administrator", "bad") h.Update(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestCsatSurveyHandler_Update_DB_Cov28(t *testing.T) { db := newTestDB_Cov28(t) acc := seedAccount_Cov19(t, db) inbox := seedInbox_Cov19(t, db, acc.ID) contact := seedContact_Cov19(t, db, acc.ID) conv := seedConversation_Cov19(t, db, acc.ID, inbox.ID, contact.ID) resp := seedCsatResponseCov28(t, db, acc.ID, conv.ID, contact.ID) h := NewCsatSurveyHandler(newCsatSvcCov28(db)) body := `{"csat_review_notes":"updated notes"}` c, w := ctxAuthBodyCov28("PATCH", "/api/v1/accounts/"+uitoaCov28(acc.ID)+"/csat_survey_responses/"+uitoaCov28(resp.ID), map[string]string{"account_id": uitoaCov28(acc.ID), "id": uitoaCov28(resp.ID)}, 1, acc.ID, "administrator", body) safeCallCov28(t, "CsatUpdate_DB", w, func() { h.Update(c) }) } func TestCsatSurveyHandler_PublicGet_NoUUID_Cov28(t *testing.T) { db := newTestDB_Cov28(t) h := NewCsatSurveyHandler(newCsatSvcCov28(db)) c, w := ctxCov28("GET", "/public/api/v1/conversations//csats", nil) h.PublicGet(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestCsatSurveyHandler_PublicGet_DB_Cov28(t *testing.T) { db := newTestDB_Cov28(t) acc := seedAccount_Cov19(t, db) inbox := seedInbox_Cov19(t, db, acc.ID) contact := seedContact_Cov19(t, db, acc.ID) conv := seedConversation_Cov19(t, db, acc.ID, inbox.ID, contact.ID) seedCsatResponseCov28(t, db, acc.ID, conv.ID, contact.ID) h := NewCsatSurveyHandler(newCsatSvcCov28(db)) c, w := ctxCov28("GET", "/public/api/v1/conversations/"+conv.UUID+"/csats", map[string]string{"conversation_uuid": conv.UUID}) safeCallCov28(t, "CsatPublicGet_DB", w, func() { h.PublicGet(c) }) } func TestCsatSurveyHandler_PublicGet_AltParam_Cov28(t *testing.T) { db := newTestDB_Cov28(t) acc := seedAccount_Cov19(t, db) inbox := seedInbox_Cov19(t, db, acc.ID) contact := seedContact_Cov19(t, db, acc.ID) conv := seedConversation_Cov19(t, db, acc.ID, inbox.ID, contact.ID) seedCsatResponseCov28(t, db, acc.ID, conv.ID, contact.ID) h := NewCsatSurveyHandler(newCsatSvcCov28(db)) c, w := ctxCov28("GET", "/public/api/v1/conversations/"+conv.UUID+"/csats", map[string]string{"id": conv.UUID}) safeCallCov28(t, "CsatPublicGet_Alt", w, func() { h.PublicGet(c) }) } func TestCsatSurveyHandler_PublicUpdate_NoUUID_Cov28(t *testing.T) { db := newTestDB_Cov28(t) h := NewCsatSurveyHandler(newCsatSvcCov28(db)) c, w := ctxBodyCov28("POST", "/public/api/v1/conversations//csats", nil, `{}`) h.PublicUpdate(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestCsatSurveyHandler_PublicUpdate_InvalidBody_Cov28(t *testing.T) { db := newTestDB_Cov28(t) h := NewCsatSurveyHandler(newCsatSvcCov28(db)) c, w := ctxBodyCov28("POST", "/public/api/v1/conversations/uuid/csats", map[string]string{"conversation_uuid": "uuid"}, "bad") h.PublicUpdate(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestCsatSurveyHandler_PublicUpdate_DB_Cov28(t *testing.T) { db := newTestDB_Cov28(t) acc := seedAccount_Cov19(t, db) inbox := seedInbox_Cov19(t, db, acc.ID) contact := seedContact_Cov19(t, db, acc.ID) conv := seedConversation_Cov19(t, db, acc.ID, inbox.ID, contact.ID) seedCsatResponseCov28(t, db, acc.ID, conv.ID, contact.ID) h := NewCsatSurveyHandler(newCsatSvcCov28(db)) body := `{"rating":4,"feedback_message":"good"}` c, w := ctxBodyCov28("POST", "/public/api/v1/conversations/"+conv.UUID+"/csats", map[string]string{"conversation_uuid": conv.UUID}, body) safeCallCov28(t, "CsatPublicUpdate_DB", w, func() { h.PublicUpdate(c) }) } func TestCsatSurveyHandler_PublicUpdate_MessageBody_Cov28(t *testing.T) { db := newTestDB_Cov28(t) acc := seedAccount_Cov19(t, db) inbox := seedInbox_Cov19(t, db, acc.ID) contact := seedContact_Cov19(t, db, acc.ID) conv := seedConversation_Cov19(t, db, acc.ID, inbox.ID, contact.ID) seedCsatResponseCov28(t, db, acc.ID, conv.ID, contact.ID) h := NewCsatSurveyHandler(newCsatSvcCov28(db)) body := `{"message":{"submitted_values":[{"csat_survey_response":{"rating":3,"feedback_message":"ok"}}]}}` c, w := ctxBodyCov28("POST", "/public/api/v1/conversations/"+conv.UUID+"/csats", map[string]string{"conversation_uuid": conv.UUID}, body) safeCallCov28(t, "CsatPublicUpdate_Msg", w, func() { h.PublicUpdate(c) }) } func TestCsatSurveyHandler_Download_InvalidAccountID_Cov28(t *testing.T) { db := newTestDB_Cov28(t) h := NewCsatSurveyHandler(newCsatSvcCov28(db)) c, w := ctxCov28("GET", "/api/v1/accounts/abc/csat_survey_responses/download", map[string]string{"account_id": "abc"}) h.Download(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestCsatSurveyHandler_Download_DB_Cov28(t *testing.T) { db := newTestDB_Cov28(t) acc := seedAccount_Cov19(t, db) inbox := seedInbox_Cov19(t, db, acc.ID) contact := seedContact_Cov19(t, db, acc.ID) conv := seedConversation_Cov19(t, db, acc.ID, inbox.ID, contact.ID) seedCsatResponseCov28(t, db, acc.ID, conv.ID, contact.ID) h := NewCsatSurveyHandler(newCsatSvcCov28(db)) c, w := ctxAuthCov28("GET", "/api/v1/accounts/"+uitoaCov28(acc.ID)+"/csat_survey_responses/download", map[string]string{"account_id": uitoaCov28(acc.ID)}, 1, acc.ID, "administrator") safeCallCov28(t, "CsatDownload_DB", w, func() { h.Download(c) }) } func TestCsatSurveyHandler_Download_WithPeriod_Cov28(t *testing.T) { db := newTestDB_Cov28(t) acc := seedAccount_Cov19(t, db) inbox := seedInbox_Cov19(t, db, acc.ID) contact := seedContact_Cov19(t, db, acc.ID) conv := seedConversation_Cov19(t, db, acc.ID, inbox.ID, contact.ID) seedCsatResponseCov28(t, db, acc.ID, conv.ID, contact.ID) h := NewCsatSurveyHandler(newCsatSvcCov28(db)) c, w := ctxAuthCov28("GET", "/api/v1/accounts/"+uitoaCov28(acc.ID)+"/csat_survey_responses/download?since=1000&until=2000", map[string]string{"account_id": uitoaCov28(acc.ID)}, 1, acc.ID, "administrator") safeCallCov28(t, "CsatDownload_Period", w, func() { h.Download(c) }) }