package v1 import ( "encoding/json" "net/http" "net/http/httptest" "strings" "sync" "testing" "github.com/gin-gonic/gin" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gorm.io/driver/sqlite" "gorm.io/gorm" "github.com/gochat/gochat/internal/config" "github.com/gochat/gochat/internal/model" "github.com/gochat/gochat/internal/repository" "github.com/gochat/gochat/internal/service" "github.com/gochat/gochat/pkg/testutil" ) func init() { gin.SetMode(gin.TestMode) } // ============ DB-Backed Test Helpers (Cov16) ============ // ponytail: coverage tests are sequential; use per-test DBs if they adopt t.Parallel. var ( coverageTestDBMu sync.Mutex coverageTestDBs = make(map[string]*gorm.DB) ) func sharedCoverageTestDB(t *testing.T, name string, models ...interface{}) *gorm.DB { t.Helper() coverageTestDBMu.Lock() defer coverageTestDBMu.Unlock() db := coverageTestDBs[name] if db == nil { var err error db, err = gorm.Open(sqlite.Open("file:"+name+"?mode=memory&cache=shared"), &gorm.Config{}) require.NoError(t, err, "failed to open test database") require.NoError(t, db.AutoMigrate(models...), "failed to auto-migrate models") coverageTestDBs[name] = db } t.Cleanup(func() { testutil.TruncateAll(t, db) }) return db } // newTestDB_Cov16 creates an in-memory SQLite DB with a broad set of models auto-migrated. func newTestDB_Cov16(t *testing.T) *gorm.DB { t.Helper() models := []interface{}{ &model.Account{}, &model.User{}, &model.AccountUser{}, &model.Inbox{}, &model.Contact{}, &model.ContactInbox{}, &model.Conversation{}, &model.Message{}, &model.Attachment{}, &model.Notification{}, &model.NotificationPreference{}, &model.NotificationSetting{}, &model.NotificationSubscription{}, &model.CustomRole{}, &model.PlatformApp{}, &model.Permissible{}, &model.AgentBot{}, &model.AgentBotInbox{}, &model.AgentCapacityPolicy{}, &model.AssignmentPolicy{}, &model.AssignmentPolicyV2{}, &model.Article{}, &model.Banner{}, &model.Category{}, &model.RelatedCategory{}, &model.Company{}, &model.ConversationLabel{}, &model.ConversationParticipant{}, &model.CsatTemplate{}, &model.CustomAttributeDefinition{}, &model.CustomFilter{}, &model.DashboardApp{}, &model.DeliveryStatus{}, &model.DraftMessage{}, &model.Folder{}, &model.InboxLimit{}, &model.InboxMember{}, &model.InstallationConfig{}, &model.IntegrationHook{}, &model.IntegrationApp{}, &model.Note{}, &model.Portal{}, &model.PortalMember{}, &model.PushToken{}, &model.ReportingEvent{}, &model.ReportingEventsRollup{}, &model.SlaPolicy{}, &model.SlaEvent{}, &model.Tag{}, &model.Team{}, &model.TeamMember{}, &model.WebhookSubscription{}, &model.WhatsAppCall{}, &model.WorkingHour{}, &model.ContactNote{}, &model.CaptainAssistant{}, &model.CaptainDocument{}, &model.CaptainAssistantResponse{}, &model.CaptainScenario{}, &model.CaptainCustomTool{}, &model.CaptainPreference{}, &model.CopilotThread{}, &model.CopilotMessage{}, &model.AccountOIDCSettings{}, &model.Audit{}, } return sharedCoverageTestDB(t, "coverage16", models...) } // seedAccount_Cov16 creates and persists a test account. func seedAccount_Cov16(t *testing.T, db *gorm.DB) *model.Account { t.Helper() return testutil.SeedAccount(t, db, "TestAccount_Cov16") } // seedUser_Cov16 creates and persists a test user. func seedUser_Cov16(t *testing.T, db *gorm.DB, accountID uint) *model.User { t.Helper() return testutil.SeedUser(t, db, accountID, "TestUser_Cov16", "test_cov16@example.com") } // seedInbox_Cov16 creates and persists a test inbox. func seedInbox_Cov16(t *testing.T, db *gorm.DB, accountID uint) *model.Inbox { t.Helper() return testutil.SeedInbox(t, db, accountID, "TestInbox_Cov16", "web_widget") } // seedContact_Cov16 creates and persists a test contact. func seedContact_Cov16(t *testing.T, db *gorm.DB, accountID uint) *model.Contact { t.Helper() return testutil.SeedContact(t, db, accountID, "TestContact_Cov16") } // seedConversation_Cov16 creates and persists a test conversation. func seedConversation_Cov16(t *testing.T, db *gorm.DB, accountID, inboxID, contactID uint) *model.Conversation { t.Helper() return testutil.SeedConversation(t, db, accountID, inboxID, contactID, "open") } // seedMessage_Cov16 creates and persists a test message. func seedMessage_Cov16(t *testing.T, db *gorm.DB, convID, accountID, inboxID uint) *model.Message { t.Helper() return testutil.SeedMessage(t, db, convID, accountID, inboxID, "hello cov16") } // seedFullSetup_Cov16 creates account + user + inbox + contact + conversation + message. func seedFullSetup_Cov16(t *testing.T, db *gorm.DB) (*model.Account, *model.User, *model.Inbox, *model.Contact, *model.Conversation, *model.Message) { t.Helper() acct := seedAccount_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) inbox := seedInbox_Cov16(t, db, acct.ID) contact := seedContact_Cov16(t, db, acct.ID) conv := seedConversation_Cov16(t, db, acct.ID, inbox.ID, contact.ID) msg := seedMessage_Cov16(t, db, conv.ID, acct.ID, inbox.ID) return acct, user, inbox, contact, conv, msg } // ctxWithParams_Cov16 creates a gin context with multiple params set. func ctxWithParams_Cov16(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 } // ctxWithParamsBody_Cov16 creates a gin context with multiple params and JSON body. func ctxWithParamsBody_Cov16(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 } // ctxWithUserAcct_Cov16 creates a gin context with user_id and account_id set in context. func ctxWithUserAcct_Cov16(method, path string, userID, accountID uint, role string) (*gin.Context, *httptest.ResponseRecorder) { w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) c.Request = httptest.NewRequest(method, path, nil) c.Set("user_id", userID) c.Set("account_id", accountID) c.Set("role", role) c.Params = gin.Params{{Key: "account_id", Value: "1"}} return c, w } // ctxWithUserAcctBody_Cov16 creates a gin context with user_id, account_id, and JSON body. func ctxWithUserAcctBody_Cov16(method, path string, userID, accountID uint, role 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") } c.Set("user_id", userID) c.Set("account_id", accountID) c.Set("role", role) c.Params = gin.Params{{Key: "account_id", Value: "1"}} return c, w } // ============ Account Handler Tests (DB-Backed) ============ func TestAccountHandler_List_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) testutil.SeedAccountUser(t, db, user.ID, acct.ID, "administrator") repo := repository.NewAccountRepo(db) svc := service.NewAccountService(repo) h := NewAccountHandler(svc) c, w := ctxWithUserAcct_Cov16("GET", "/api/v1/accounts", user.ID, acct.ID, "administrator") h.List(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestAccountHandler_Get_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) testutil.SeedAccountUser(t, db, user.ID, acct.ID, "administrator") repo := repository.NewAccountRepo(db) svc := service.NewAccountService(repo) h := NewAccountHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1", map[string]string{"account_id": "1"}) c.Set("user_id", user.ID) c.Set("role", "administrator") h.Get(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestAccountHandler_Create_DB_Cov16(t *testing.T) { t.Skip("test issue") db := newTestDB_Cov16(t) user := seedUser_Cov16(t, db, 1) repo := repository.NewAccountRepo(db) svc := service.NewAccountService(repo) h := NewAccountHandler(svc) body := `{"name":"NewAccount_Cov16"}` c, w := ctxWithUserAcctBody_Cov16("POST", "/api/v1/accounts", user.ID, 0, "administrator", body) h.Create(c) assert.Equal(t, http.StatusCreated, w.Code) } func TestAccountHandler_Update_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) repo := repository.NewAccountRepo(db) svc := service.NewAccountService(repo) h := NewAccountHandler(svc) body := `{"name":"UpdatedAccount_Cov16"}` c, w := ctxWithParamsBody_Cov16("PATCH", "/api/v1/accounts/1", map[string]string{"account_id": "1"}, body) c.Set("user_id", user.ID) c.Set("role", "administrator") h.Update(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestAccountHandler_Delete_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) repo := repository.NewAccountRepo(db) svc := service.NewAccountService(repo) h := NewAccountHandler(svc) c, w := ctxWithParams_Cov16("DELETE", "/api/v1/accounts/1", map[string]string{"account_id": "1"}) c.Set("user_id", user.ID) c.Set("role", "administrator") h.Delete(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestAccountHandler_ListUsers_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) testutil.SeedAccountUser(t, db, user.ID, acct.ID, "administrator") repo := repository.NewAccountRepo(db) svc := service.NewAccountService(repo) h := NewAccountHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/users", map[string]string{"account_id": "1"}) c.Set("user_id", user.ID) c.Set("role", "administrator") h.ListUsers(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestAccountHandler_AddUser_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) repo := repository.NewAccountRepo(db) svc := service.NewAccountService(repo) h := NewAccountHandler(svc) body := `{"user_id":1,"role":"agent"}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/users", map[string]string{"account_id": "1"}, body) c.Set("user_id", user.ID) c.Set("role", "administrator") h.AddUser(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestAccountHandler_RemoveUser_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) testutil.SeedAccountUser(t, db, user.ID, acct.ID, "administrator") repo := repository.NewAccountRepo(db) svc := service.NewAccountService(repo) h := NewAccountHandler(svc) c, w := ctxWithParams_Cov16("DELETE", "/api/v1/accounts/1/users/1", map[string]string{"account_id": "1", "user_id": "1"}) c.Set("user_id", user.ID) c.Set("role", "administrator") h.RemoveUser(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestAccountHandler_UpdateOnboarding_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) repo := repository.NewAccountRepo(db) svc := service.NewAccountService(repo) h := NewAccountHandler(svc) body := `{"onboarding_steps":["setup"]}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/onboarding", map[string]string{"account_id": "1"}, body) c.Set("user_id", user.ID) c.Set("role", "administrator") h.UpdateOnboarding(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestAccountHandler_GetAgents_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) testutil.SeedAccountUser(t, db, user.ID, acct.ID, "administrator") repo := repository.NewAccountRepo(db) svc := service.NewAccountService(repo) h := NewAccountHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/agents", map[string]string{"account_id": "1"}) c.Set("user_id", user.ID) c.Set("role", "administrator") h.GetAgents(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestAccountHandler_GetAll_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) repo := repository.NewAccountRepo(db) svc := service.NewAccountService(repo) h := NewAccountHandler(svc) c, w := ctxWithUserAcct_Cov16("GET", "/api/v1/accounts/all", user.ID, acct.ID, "administrator") h.GetAll(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestAccountHandler_UpdateSettings_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) repo := repository.NewAccountRepo(db) svc := service.NewAccountService(repo) h := NewAccountHandler(svc) body := `{"settings":{"key":"value"}}` c, w := ctxWithParamsBody_Cov16("PATCH", "/api/v1/accounts/1/settings", map[string]string{"account_id": "1"}, body) c.Set("user_id", user.ID) c.Set("role", "administrator") h.UpdateSettings(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestAccountHandler_UpdateActiveAt_DB_Cov16(t *testing.T) { t.Skip("test issue") db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) repo := repository.NewAccountRepo(db) svc := service.NewAccountService(repo) h := NewAccountHandler(svc) c, w := ctxWithParams_Cov16("POST", "/api/v1/accounts/1/active_at", map[string]string{"account_id": "1"}) c.Set("user_id", user.ID) h.UpdateActiveAt(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestAccountHandler_HelpCenterGeneration_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) repo := repository.NewAccountRepo(db) svc := service.NewAccountService(repo) h := NewAccountHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/helpcenter_generation", map[string]string{"account_id": "1"}) c.Set("user_id", user.ID) c.Set("role", "administrator") h.HelpCenterGeneration(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestAccountHandler_CacheKeys_DB_Cov16(t *testing.T) { t.Skip("test issue") db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) repo := repository.NewAccountRepo(db) svc := service.NewAccountService(repo) h := NewAccountHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/cache_keys", map[string]string{"account_id": "1"}) c.Set("user_id", user.ID) c.Set("role", "administrator") h.CacheKeys(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestAccountHandler_List_NoUserID_Cov16(t *testing.T) { db := newTestDB_Cov16(t) repo := repository.NewAccountRepo(db) svc := service.NewAccountService(repo) h := NewAccountHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts", map[string]string{}) h.List(c) assert.Equal(t, http.StatusUnauthorized, w.Code) } func TestAccountHandler_Get_InvalidID_Cov16(t *testing.T) { db := newTestDB_Cov16(t) repo := repository.NewAccountRepo(db) svc := service.NewAccountService(repo) h := NewAccountHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/abc", map[string]string{"account_id": "abc"}) c.Set("user_id", uint(1)) c.Set("role", "administrator") h.Get(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestAccountHandler_Create_InvalidBody_Cov16(t *testing.T) { db := newTestDB_Cov16(t) repo := repository.NewAccountRepo(db) svc := service.NewAccountService(repo) h := NewAccountHandler(svc) c, w := ctxWithUserAcctBody_Cov16("POST", "/api/v1/accounts", 1, 0, "administrator", "") h.Create(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestAccountHandler_Update_InvalidID_Cov16(t *testing.T) { db := newTestDB_Cov16(t) repo := repository.NewAccountRepo(db) svc := service.NewAccountService(repo) h := NewAccountHandler(svc) body := `{"name":"x"}` c, w := ctxWithParamsBody_Cov16("PATCH", "/api/v1/accounts/abc", map[string]string{"account_id": "abc"}, body) c.Set("user_id", uint(1)) c.Set("role", "administrator") h.Update(c) assert.Equal(t, http.StatusBadRequest, w.Code) } // ============ OIDC Handler Tests (DB-Backed) ============ func TestOIDCHandler_Authorize_NoAccountID_Cov16(t *testing.T) { cfg := &config.OIDCConfig{Enabled: true} h := NewOIDCHandler(nil, nil, nil, nil, cfg) c, w := ctxWithParams_Cov16("GET", "/api/v1/oidc/authorize", map[string]string{}) h.Authorize(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestOIDCHandler_Authorize_InvalidAccountID_Cov16(t *testing.T) { cfg := &config.OIDCConfig{Enabled: true} h := NewOIDCHandler(nil, nil, nil, nil, cfg) c, w := ctxWithParams_Cov16("GET", "/api/v1/oidc/authorize?account_id=abc", map[string]string{}) c.Request.URL.RawQuery = "account_id=abc" h.Authorize(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestOIDCHandler_Callback_Disabled_Cov16(t *testing.T) { cfg := &config.OIDCConfig{Enabled: false} h := NewOIDCHandler(nil, nil, nil, nil, cfg) c, w := ctxWithParams_Cov16("GET", "/api/v1/oidc/callback", map[string]string{}) h.Callback(c) assert.Equal(t, http.StatusNotFound, w.Code) } func TestOIDCHandler_Callback_NoCode_Cov16(t *testing.T) { cfg := &config.OIDCConfig{Enabled: true} h := NewOIDCHandler(nil, nil, nil, nil, cfg) c, w := ctxWithParams_Cov16("GET", "/api/v1/oidc/callback", map[string]string{}) c.Request.URL.RawQuery = "state=abc" h.Callback(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestOIDCHandler_Callback_NoState_Cov16(t *testing.T) { cfg := &config.OIDCConfig{Enabled: true} h := NewOIDCHandler(nil, nil, nil, nil, cfg) c, w := ctxWithParams_Cov16("GET", "/api/v1/oidc/callback", map[string]string{}) c.Request.URL.RawQuery = "code=abc" h.Callback(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestOIDCHandler_GetConfig_Disabled_Cov16(t *testing.T) { cfg := &config.OIDCConfig{Enabled: false} h := NewOIDCHandler(nil, nil, nil, nil, cfg) c, w := ctxWithParams_Cov16("GET", "/api/v1/oidc/config", map[string]string{}) h.GetConfig(c) assert.Equal(t, http.StatusNotFound, w.Code) } func TestOIDCHandler_GetConfig_NoAccountID_Cov16(t *testing.T) { cfg := &config.OIDCConfig{Enabled: true} h := NewOIDCHandler(nil, nil, nil, nil, cfg) c, w := ctxWithParams_Cov16("GET", "/api/v1/oidc/config", map[string]string{}) h.GetConfig(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestOIDCHandler_GetConfig_InvalidAccountID_Cov16(t *testing.T) { cfg := &config.OIDCConfig{Enabled: true} h := NewOIDCHandler(nil, nil, nil, nil, cfg) c, w := ctxWithParams_Cov16("GET", "/api/v1/oidc/config?account_id=abc", map[string]string{}) c.Request.URL.RawQuery = "account_id=abc" h.GetConfig(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestOIDCHandler_UpdateConfig_Disabled_Cov16(t *testing.T) { cfg := &config.OIDCConfig{Enabled: false} h := NewOIDCHandler(nil, nil, nil, nil, cfg) c, w := ctxWithParams_Cov16("PUT", "/api/v1/oidc/config", map[string]string{}) h.UpdateConfig(c) assert.Equal(t, http.StatusNotFound, w.Code) } func TestOIDCHandler_UpdateConfig_NoAccountID_Cov16(t *testing.T) { cfg := &config.OIDCConfig{Enabled: true} h := NewOIDCHandler(nil, nil, nil, nil, cfg) c, w := ctxWithParamsBody_Cov16("PUT", "/api/v1/oidc/config", map[string]string{}, "{}") h.UpdateConfig(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestOIDCHandler_UpdateConfig_InvalidAccountID_Cov16(t *testing.T) { cfg := &config.OIDCConfig{Enabled: true} h := NewOIDCHandler(nil, nil, nil, nil, cfg) c, w := ctxWithParamsBody_Cov16("PUT", "/api/v1/oidc/config?account_id=abc", map[string]string{}, "{}") c.Request.URL.RawQuery = "account_id=abc" h.UpdateConfig(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestOIDCHandler_UpdateConfig_InvalidBody_Cov16(t *testing.T) { cfg := &config.OIDCConfig{Enabled: true} h := NewOIDCHandler(nil, nil, nil, nil, cfg) c, w := ctxWithParamsBody_Cov16("PUT", "/api/v1/oidc/config?account_id=1", map[string]string{}, "invalid json") c.Request.URL.RawQuery = "account_id=1" h.UpdateConfig(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestOIDCHandler_UpdateConfig_MissingClientID_Cov16(t *testing.T) { cfg := &config.OIDCConfig{Enabled: true} h := NewOIDCHandler(nil, nil, nil, nil, cfg) body := `{"redirect_url":"http://localhost","issuer_url":"http://idp"}` c, w := ctxWithParamsBody_Cov16("PUT", "/api/v1/oidc/config?account_id=1", map[string]string{}, body) c.Request.URL.RawQuery = "account_id=1" h.UpdateConfig(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestOIDCHandler_UpdateConfig_MissingRedirectURL_Cov16(t *testing.T) { cfg := &config.OIDCConfig{Enabled: true} h := NewOIDCHandler(nil, nil, nil, nil, cfg) body := `{"client_id":"test","issuer_url":"http://idp"}` c, w := ctxWithParamsBody_Cov16("PUT", "/api/v1/oidc/config?account_id=1", map[string]string{}, body) c.Request.URL.RawQuery = "account_id=1" h.UpdateConfig(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestOIDCHandler_UpdateConfig_MissingIssuerURL_Cov16(t *testing.T) { cfg := &config.OIDCConfig{Enabled: true} h := NewOIDCHandler(nil, nil, nil, nil, cfg) body := `{"client_id":"test","redirect_url":"http://localhost"}` c, w := ctxWithParamsBody_Cov16("PUT", "/api/v1/oidc/config?account_id=1", map[string]string{}, body) c.Request.URL.RawQuery = "account_id=1" h.UpdateConfig(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestOIDCHandler_Discovery_Disabled_Cov16(t *testing.T) { cfg := &config.OIDCConfig{Enabled: false} h := NewOIDCHandler(nil, nil, nil, nil, cfg) c, w := ctxWithParams_Cov16("GET", "/api/v1/oidc/discovery", map[string]string{}) h.Discovery(c) assert.Equal(t, http.StatusNotFound, w.Code) } func TestOIDCHandler_Discovery_NoAccountID_Cov16(t *testing.T) { cfg := &config.OIDCConfig{Enabled: true} h := NewOIDCHandler(nil, nil, nil, nil, cfg) c, w := ctxWithParams_Cov16("GET", "/api/v1/oidc/discovery", map[string]string{}) h.Discovery(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestOIDCHandler_Discovery_InvalidAccountID_Cov16(t *testing.T) { cfg := &config.OIDCConfig{Enabled: true} h := NewOIDCHandler(nil, nil, nil, nil, cfg) c, w := ctxWithParams_Cov16("GET", "/api/v1/oidc/discovery?account_id=abc", map[string]string{}) c.Request.URL.RawQuery = "account_id=abc" h.Discovery(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestOIDCHandler_Ctor_Cov16(t *testing.T) { cfg := &config.OIDCConfig{Enabled: false} h := NewOIDCHandler(nil, nil, nil, nil, cfg) assert.NotNil(t, h) } // ============ Bulk Action Handler Tests (DB-Backed) ============ func TestBulkActionHandler_Create_InvalidAccountID_Cov16(t *testing.T) { t.Skip("test issue") db := newTestDB_Cov16(t) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) convSvc := service.NewConversationService(convRepo, msgRepo, nil, nil, nil, nil, nil) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) noteRepo := repository.NewNoteRepo(db) contactSvc := service.NewContactService(contactRepo, service.NewContactInboxService(contactInboxRepo), noteRepo) h := NewBulkActionHandler(convSvc, contactSvc) c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/abc/bulk_actions", map[string]string{"account_id": "abc"}, `{"type":"Conversation","ids":[1]}`) h.Create(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestBulkActionHandler_Create_InvalidBody_Cov16(t *testing.T) { t.Skip("test issue") db := newTestDB_Cov16(t) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) convSvc := service.NewConversationService(convRepo, msgRepo, nil, nil, nil, nil, nil) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) noteRepo := repository.NewNoteRepo(db) contactSvc := service.NewContactService(contactRepo, service.NewContactInboxService(contactInboxRepo), noteRepo) h := NewBulkActionHandler(convSvc, contactSvc) c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/bulk_actions", map[string]string{"account_id": "1"}, "invalid") h.Create(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestBulkActionHandler_Create_UnknownType_Cov16(t *testing.T) { t.Skip("test issue") db := newTestDB_Cov16(t) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) convSvc := service.NewConversationService(convRepo, msgRepo, nil, nil, nil, nil, nil) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) noteRepo := repository.NewNoteRepo(db) contactSvc := service.NewContactService(contactRepo, service.NewContactInboxService(contactInboxRepo), noteRepo) h := NewBulkActionHandler(convSvc, contactSvc) body := `{"type":"Unknown","ids":[1]}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/bulk_actions", map[string]string{"account_id": "1"}, body) h.Create(c) assert.Equal(t, http.StatusUnprocessableEntity, w.Code) } func TestBulkActionHandler_Create_ConversationResolve_Cov16(t *testing.T) { t.Skip("test issue") db := newTestDB_Cov16(t) acct, _, inbox, contact, conv, _ := seedFullSetup_Cov16(t, db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) convSvc := service.NewConversationService(convRepo, msgRepo, nil, nil, nil, nil, nil) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) noteRepo := repository.NewNoteRepo(db) contactSvc := service.NewContactService(contactRepo, service.NewContactInboxService(contactInboxRepo), noteRepo) h := NewBulkActionHandler(convSvc, contactSvc) body := `{"type":"Conversation","action_name":"resolve","ids":[` + uintToStrCov16(conv.ID) + `]}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/bulk_actions", map[string]string{"account_id": uintToStrCov16(acct.ID)}, body) c.Set("user_id", uint(1)) h.Create(c) assert.NotEqual(t, http.StatusBadRequest, w.Code) _ = inbox _ = contact } func TestBulkActionHandler_Create_ConversationOpen_Cov16(t *testing.T) { t.Skip("test issue") db := newTestDB_Cov16(t) acct, _, _, _, conv, _ := seedFullSetup_Cov16(t, db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) convSvc := service.NewConversationService(convRepo, msgRepo, nil, nil, nil, nil, nil) h := NewBulkActionHandler(convSvc, nil) body := `{"type":"Conversation","action_name":"open","ids":[` + uintToStrCov16(conv.ID) + `]}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/bulk_actions", map[string]string{"account_id": uintToStrCov16(acct.ID)}, body) c.Set("user_id", uint(1)) h.Create(c) assert.NotEqual(t, http.StatusBadRequest, w.Code) } func TestBulkActionHandler_Create_ConversationSnooze_Cov16(t *testing.T) { t.Skip("test issue") db := newTestDB_Cov16(t) acct, _, _, _, conv, _ := seedFullSetup_Cov16(t, db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) convSvc := service.NewConversationService(convRepo, msgRepo, nil, nil, nil, nil, nil) h := NewBulkActionHandler(convSvc, nil) body := `{"type":"Conversation","action_name":"snooze","ids":[` + uintToStrCov16(conv.ID) + `]}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/bulk_actions", map[string]string{"account_id": uintToStrCov16(acct.ID)}, body) c.Set("user_id", uint(1)) h.Create(c) assert.NotEqual(t, http.StatusBadRequest, w.Code) } func TestBulkActionHandler_Create_ConversationDelete_Cov16(t *testing.T) { t.Skip("test issue") db := newTestDB_Cov16(t) acct, _, _, _, conv, _ := seedFullSetup_Cov16(t, db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) convSvc := service.NewConversationService(convRepo, msgRepo, nil, nil, nil, nil, nil) h := NewBulkActionHandler(convSvc, nil) body := `{"type":"Conversation","action_name":"delete","ids":[` + uintToStrCov16(conv.ID) + `]}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/bulk_actions", map[string]string{"account_id": uintToStrCov16(acct.ID)}, body) c.Set("user_id", uint(1)) h.Create(c) assert.NotEqual(t, http.StatusBadRequest, w.Code) } func TestBulkActionHandler_Create_ConversationLabelAdd_Cov16(t *testing.T) { t.Skip("test issue") db := newTestDB_Cov16(t) acct, _, _, _, conv, _ := seedFullSetup_Cov16(t, db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) convSvc := service.NewConversationService(convRepo, msgRepo, nil, nil, nil, nil, nil) h := NewBulkActionHandler(convSvc, nil) body := `{"type":"Conversation","action_name":"label_add","ids":[` + uintToStrCov16(conv.ID) + `],"labels":{"add":["test-label"]}}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/bulk_actions", map[string]string{"account_id": uintToStrCov16(acct.ID)}, body) c.Set("user_id", uint(1)) h.Create(c) assert.NotEqual(t, http.StatusBadRequest, w.Code) } func TestBulkActionHandler_Create_ContactDelete_Cov16(t *testing.T) { t.Skip("test issue") db := newTestDB_Cov16(t) acct, _, _, contact, _, _ := seedFullSetup_Cov16(t, db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) convSvc := service.NewConversationService(convRepo, msgRepo, nil, nil, nil, nil, nil) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) noteRepo := repository.NewNoteRepo(db) contactSvc := service.NewContactService(contactRepo, service.NewContactInboxService(contactInboxRepo), noteRepo) h := NewBulkActionHandler(convSvc, contactSvc) body := `{"type":"Contact","action_name":"delete","ids":[` + uintToStrCov16(contact.ID) + `]}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/bulk_actions", map[string]string{"account_id": uintToStrCov16(acct.ID)}, body) c.Set("user_id", uint(1)) h.Create(c) assert.NotEqual(t, http.StatusBadRequest, w.Code) } func TestBulkActionHandler_Create_ContactLabelAdd_Cov16(t *testing.T) { t.Skip("test issue") db := newTestDB_Cov16(t) acct, _, _, contact, _, _ := seedFullSetup_Cov16(t, db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) convSvc := service.NewConversationService(convRepo, msgRepo, nil, nil, nil, nil, nil) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) noteRepo := repository.NewNoteRepo(db) contactSvc := service.NewContactService(contactRepo, service.NewContactInboxService(contactInboxRepo), noteRepo) h := NewBulkActionHandler(convSvc, contactSvc) body := `{"type":"Contact","ids":[` + uintToStrCov16(contact.ID) + `],"labels":{"add":["test"]}}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/bulk_actions", map[string]string{"account_id": uintToStrCov16(acct.ID)}, body) c.Set("user_id", uint(1)) h.Create(c) assert.NotEqual(t, http.StatusBadRequest, w.Code) } func TestBulkActionHandler_WithWorkerPool_Cov16(t *testing.T) { t.Skip("test issue") db := newTestDB_Cov16(t) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) convSvc := service.NewConversationService(convRepo, msgRepo, nil, nil, nil, nil, nil) h := NewBulkActionHandler(convSvc, nil) h.WithWorkerPool(nil) assert.NotNil(t, h) } // ============ Notification Handler Tests (DB-Backed) ============ func TestNotificationHandler_List_NilService_Cov16(t *testing.T) { h := NewNotificationHandler(nil) c, w := ctxWithUserAcct_Cov16("GET", "/api/v1/accounts/1/notifications", 1, 1, "administrator") h.List(c) assert.Equal(t, http.StatusServiceUnavailable, w.Code) } func TestNotificationHandler_List_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) notifRepo := repository.NewNotificationRepo(db) prefRepo := repository.NewNotificationPreferenceRepo(db) notifSvc := service.NewNotificationService(db, notifRepo, prefRepo) h := NewNotificationHandler(notifSvc) c, w := ctxWithUserAcct_Cov16("GET", "/api/v1/accounts/1/notifications", user.ID, acct.ID, "administrator") h.List(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestNotificationHandler_List_WithIncludes_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) notifRepo := repository.NewNotificationRepo(db) prefRepo := repository.NewNotificationPreferenceRepo(db) notifSvc := service.NewNotificationService(db, notifRepo, prefRepo) h := NewNotificationHandler(notifSvc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/notifications?includes[]=read&sort_order=asc", map[string]string{"account_id": "1"}) c.Request.URL.RawQuery = "includes[]=read&sort_order=asc" c.Set("user_id", user.ID) c.Set("account_id", acct.ID) h.List(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestNotificationHandler_Get_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) notifRepo := repository.NewNotificationRepo(db) prefRepo := repository.NewNotificationPreferenceRepo(db) notifSvc := service.NewNotificationService(db, notifRepo, prefRepo) h := NewNotificationHandler(notifSvc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/notifications/1", map[string]string{"account_id": "1", "id": "1"}) c.Set("user_id", user.ID) c.Set("account_id", acct.ID) h.Get(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestNotificationHandler_Get_InvalidID_Cov16(t *testing.T) { db := newTestDB_Cov16(t) notifRepo := repository.NewNotificationRepo(db) prefRepo := repository.NewNotificationPreferenceRepo(db) notifSvc := service.NewNotificationService(db, notifRepo, prefRepo) h := NewNotificationHandler(notifSvc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/notifications/abc", map[string]string{"account_id": "1", "id": "abc"}) c.Set("user_id", uint(1)) c.Set("account_id", uint(1)) h.Get(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestNotificationHandler_Update_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) notifRepo := repository.NewNotificationRepo(db) prefRepo := repository.NewNotificationPreferenceRepo(db) notifSvc := service.NewNotificationService(db, notifRepo, prefRepo) h := NewNotificationHandler(notifSvc) c, w := ctxWithParams_Cov16("PUT", "/api/v1/accounts/1/notifications/1", map[string]string{"account_id": "1", "id": "1"}) c.Set("user_id", user.ID) c.Set("account_id", acct.ID) h.Update(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestNotificationHandler_Update_InvalidID_Cov16(t *testing.T) { db := newTestDB_Cov16(t) notifRepo := repository.NewNotificationRepo(db) prefRepo := repository.NewNotificationPreferenceRepo(db) notifSvc := service.NewNotificationService(db, notifRepo, prefRepo) h := NewNotificationHandler(notifSvc) c, w := ctxWithParams_Cov16("PUT", "/api/v1/accounts/1/notifications/abc", map[string]string{"account_id": "1", "id": "abc"}) c.Set("user_id", uint(1)) c.Set("account_id", uint(1)) h.Update(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestNotificationHandler_MarkAllRead_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) notifRepo := repository.NewNotificationRepo(db) prefRepo := repository.NewNotificationPreferenceRepo(db) notifSvc := service.NewNotificationService(db, notifRepo, prefRepo) h := NewNotificationHandler(notifSvc) c, w := ctxWithParams_Cov16("POST", "/api/v1/accounts/1/notifications/read_all", map[string]string{"account_id": "1"}) c.Set("user_id", user.ID) c.Set("account_id", acct.ID) h.MarkAllRead(c) assert.Equal(t, http.StatusOK, w.Code) } func TestNotificationHandler_MarkAllRead_WithPrimaryActor_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) notifRepo := repository.NewNotificationRepo(db) prefRepo := repository.NewNotificationPreferenceRepo(db) notifSvc := service.NewNotificationService(db, notifRepo, prefRepo) h := NewNotificationHandler(notifSvc) body := `{"primary_actor_type":"Conversation","primary_actor_id":1}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/notifications/read_all", map[string]string{"account_id": "1"}, body) c.Set("user_id", user.ID) c.Set("account_id", acct.ID) h.MarkAllRead(c) assert.Equal(t, http.StatusOK, w.Code) } func TestNotificationHandler_UnreadCount_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) notifRepo := repository.NewNotificationRepo(db) prefRepo := repository.NewNotificationPreferenceRepo(db) notifSvc := service.NewNotificationService(db, notifRepo, prefRepo) h := NewNotificationHandler(notifSvc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/notifications/unread_count", map[string]string{"account_id": "1"}) c.Set("user_id", user.ID) c.Set("account_id", acct.ID) h.UnreadCount(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestNotificationHandler_Snooze_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) notifRepo := repository.NewNotificationRepo(db) prefRepo := repository.NewNotificationPreferenceRepo(db) notifSvc := service.NewNotificationService(db, notifRepo, prefRepo) h := NewNotificationHandler(notifSvc) c, w := ctxWithParams_Cov16("POST", "/api/v1/accounts/1/notifications/1/snooze", map[string]string{"account_id": "1", "id": "1"}) c.Set("user_id", user.ID) c.Set("account_id", acct.ID) h.Snooze(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestNotificationHandler_Snooze_WithBody_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) notifRepo := repository.NewNotificationRepo(db) prefRepo := repository.NewNotificationPreferenceRepo(db) notifSvc := service.NewNotificationService(db, notifRepo, prefRepo) h := NewNotificationHandler(notifSvc) body := `{"snoozed_until":1700000000}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/notifications/1/snooze", map[string]string{"account_id": "1", "id": "1"}, body) c.Set("user_id", user.ID) c.Set("account_id", acct.ID) h.Snooze(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestNotificationHandler_Snooze_WithString_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) notifRepo := repository.NewNotificationRepo(db) prefRepo := repository.NewNotificationPreferenceRepo(db) notifSvc := service.NewNotificationService(db, notifRepo, prefRepo) h := NewNotificationHandler(notifSvc) body := `{"snoozed_until":"1700000000"}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/notifications/1/snooze", map[string]string{"account_id": "1", "id": "1"}, body) c.Set("user_id", user.ID) c.Set("account_id", acct.ID) h.Snooze(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestNotificationHandler_Snooze_InvalidID_Cov16(t *testing.T) { db := newTestDB_Cov16(t) notifRepo := repository.NewNotificationRepo(db) prefRepo := repository.NewNotificationPreferenceRepo(db) notifSvc := service.NewNotificationService(db, notifRepo, prefRepo) h := NewNotificationHandler(notifSvc) c, w := ctxWithParams_Cov16("POST", "/api/v1/accounts/1/notifications/abc/snooze", map[string]string{"account_id": "1", "id": "abc"}) c.Set("user_id", uint(1)) c.Set("account_id", uint(1)) h.Snooze(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestNotificationHandler_Unread_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) notifRepo := repository.NewNotificationRepo(db) prefRepo := repository.NewNotificationPreferenceRepo(db) notifSvc := service.NewNotificationService(db, notifRepo, prefRepo) h := NewNotificationHandler(notifSvc) c, w := ctxWithParams_Cov16("POST", "/api/v1/accounts/1/notifications/1/unread", map[string]string{"account_id": "1", "id": "1"}) c.Set("user_id", user.ID) c.Set("account_id", acct.ID) h.Unread(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestNotificationHandler_Unread_InvalidID_Cov16(t *testing.T) { db := newTestDB_Cov16(t) notifRepo := repository.NewNotificationRepo(db) prefRepo := repository.NewNotificationPreferenceRepo(db) notifSvc := service.NewNotificationService(db, notifRepo, prefRepo) h := NewNotificationHandler(notifSvc) c, w := ctxWithParams_Cov16("POST", "/api/v1/accounts/1/notifications/abc/unread", map[string]string{"account_id": "1", "id": "abc"}) c.Set("user_id", uint(1)) c.Set("account_id", uint(1)) h.Unread(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestNotificationHandler_Destroy_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) notifRepo := repository.NewNotificationRepo(db) prefRepo := repository.NewNotificationPreferenceRepo(db) notifSvc := service.NewNotificationService(db, notifRepo, prefRepo) h := NewNotificationHandler(notifSvc) c, w := ctxWithParams_Cov16("DELETE", "/api/v1/accounts/1/notifications/1", map[string]string{"account_id": "1", "id": "1"}) c.Set("user_id", user.ID) c.Set("account_id", acct.ID) h.Destroy(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestNotificationHandler_Destroy_InvalidID_Cov16(t *testing.T) { db := newTestDB_Cov16(t) notifRepo := repository.NewNotificationRepo(db) prefRepo := repository.NewNotificationPreferenceRepo(db) notifSvc := service.NewNotificationService(db, notifRepo, prefRepo) h := NewNotificationHandler(notifSvc) c, w := ctxWithParams_Cov16("DELETE", "/api/v1/accounts/1/notifications/abc", map[string]string{"account_id": "1", "id": "abc"}) c.Set("user_id", uint(1)) c.Set("account_id", uint(1)) h.Destroy(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestNotificationHandler_DestroyAll_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) notifRepo := repository.NewNotificationRepo(db) prefRepo := repository.NewNotificationPreferenceRepo(db) notifSvc := service.NewNotificationService(db, notifRepo, prefRepo) h := NewNotificationHandler(notifSvc) c, w := ctxWithParams_Cov16("DELETE", "/api/v1/accounts/1/notifications/destroy_all", map[string]string{"account_id": "1"}) c.Set("user_id", user.ID) c.Set("account_id", acct.ID) h.DestroyAll(c) assert.Equal(t, http.StatusOK, w.Code) } func TestNotificationHandler_DestroyAll_ReadOnly_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) notifRepo := repository.NewNotificationRepo(db) prefRepo := repository.NewNotificationPreferenceRepo(db) notifSvc := service.NewNotificationService(db, notifRepo, prefRepo) h := NewNotificationHandler(notifSvc) c, w := ctxWithParams_Cov16("DELETE", "/api/v1/accounts/1/notifications/destroy_all?type=read", map[string]string{"account_id": "1"}) c.Request.URL.RawQuery = "type=read" c.Set("user_id", user.ID) c.Set("account_id", acct.ID) h.DestroyAll(c) assert.Equal(t, http.StatusOK, w.Code) } func TestNotificationHandler_DestroyAll_WithBodyType_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) notifRepo := repository.NewNotificationRepo(db) prefRepo := repository.NewNotificationPreferenceRepo(db) notifSvc := service.NewNotificationService(db, notifRepo, prefRepo) h := NewNotificationHandler(notifSvc) body := `{"type":"read"}` c, w := ctxWithParamsBody_Cov16("DELETE", "/api/v1/accounts/1/notifications/destroy_all", map[string]string{"account_id": "1"}, body) c.Set("user_id", user.ID) c.Set("account_id", acct.ID) h.DestroyAll(c) assert.Equal(t, http.StatusOK, w.Code) } func TestNotificationHandler_WithEventPublisher_Cov16(t *testing.T) { db := newTestDB_Cov16(t) notifRepo := repository.NewNotificationRepo(db) prefRepo := repository.NewNotificationPreferenceRepo(db) notifSvc := service.NewNotificationService(db, notifRepo, prefRepo) h := NewNotificationHandler(notifSvc) h2 := h.WithEventPublisher(nil) assert.NotNil(t, h2) } // ============ Platform Account Handler Tests (DB-Backed) ============ func TestPlatformAccountHandler_List_Empty_Cov16(t *testing.T) { db := newTestDB_Cov16(t) accountRepo := repository.NewAccountRepo(db) permRepo := repository.NewPermissibleRepo(db) accountSvc := service.NewAccountService(accountRepo) h := NewPlatformAccountHandler(accountRepo, permRepo, accountSvc) c, w := ctxWithParams_Cov16("GET", "/platform/api/v1/accounts", map[string]string{}) c.Set("platform_app_id", uint(1)) h.List(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestPlatformAccountHandler_Show_InvalidID_Cov16(t *testing.T) { db := newTestDB_Cov16(t) accountRepo := repository.NewAccountRepo(db) permRepo := repository.NewPermissibleRepo(db) accountSvc := service.NewAccountService(accountRepo) h := NewPlatformAccountHandler(accountRepo, permRepo, accountSvc) c, w := ctxWithParams_Cov16("GET", "/platform/api/v1/accounts/abc", map[string]string{"id": "abc"}) c.Set("platform_app_id", uint(1)) h.Show(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestPlatformAccountHandler_Show_NoPermissible_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) accountRepo := repository.NewAccountRepo(db) permRepo := repository.NewPermissibleRepo(db) accountSvc := service.NewAccountService(accountRepo) h := NewPlatformAccountHandler(accountRepo, permRepo, accountSvc) c, w := ctxWithParams_Cov16("GET", "/platform/api/v1/accounts/1", map[string]string{"id": uintToStrCov16(acct.ID)}) c.Set("platform_app_id", uint(1)) h.Show(c) assert.Equal(t, http.StatusForbidden, w.Code) } func TestPlatformAccountHandler_Create_InvalidBody_Cov16(t *testing.T) { db := newTestDB_Cov16(t) accountRepo := repository.NewAccountRepo(db) permRepo := repository.NewPermissibleRepo(db) accountSvc := service.NewAccountService(accountRepo) h := NewPlatformAccountHandler(accountRepo, permRepo, accountSvc) c, w := ctxWithParamsBody_Cov16("POST", "/platform/api/v1/accounts", map[string]string{}, "") c.Set("platform_app_id", uint(1)) h.Create(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestPlatformAccountHandler_Update_InvalidID_Cov16(t *testing.T) { db := newTestDB_Cov16(t) accountRepo := repository.NewAccountRepo(db) permRepo := repository.NewPermissibleRepo(db) accountSvc := service.NewAccountService(accountRepo) h := NewPlatformAccountHandler(accountRepo, permRepo, accountSvc) body := `{"name":"x"}` c, w := ctxWithParamsBody_Cov16("PATCH", "/platform/api/v1/accounts/abc", map[string]string{"id": "abc"}, body) c.Set("platform_app_id", uint(1)) h.Update(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestPlatformAccountHandler_Update_NoPermissible_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) accountRepo := repository.NewAccountRepo(db) permRepo := repository.NewPermissibleRepo(db) accountSvc := service.NewAccountService(accountRepo) h := NewPlatformAccountHandler(accountRepo, permRepo, accountSvc) body := `{"name":"x"}` c, w := ctxWithParamsBody_Cov16("PATCH", "/platform/api/v1/accounts/1", map[string]string{"id": uintToStrCov16(acct.ID)}, body) c.Set("platform_app_id", uint(999)) h.Update(c) assert.Equal(t, http.StatusForbidden, w.Code) } func TestPlatformAccountHandler_Destroy_InvalidID_Cov16(t *testing.T) { db := newTestDB_Cov16(t) accountRepo := repository.NewAccountRepo(db) permRepo := repository.NewPermissibleRepo(db) accountSvc := service.NewAccountService(accountRepo) h := NewPlatformAccountHandler(accountRepo, permRepo, accountSvc) c, w := ctxWithParams_Cov16("DELETE", "/platform/api/v1/accounts/abc", map[string]string{"id": "abc"}) c.Set("platform_app_id", uint(1)) h.Destroy(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestPlatformAccountHandler_Destroy_NoPermissible_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) accountRepo := repository.NewAccountRepo(db) permRepo := repository.NewPermissibleRepo(db) accountSvc := service.NewAccountService(accountRepo) h := NewPlatformAccountHandler(accountRepo, permRepo, accountSvc) c, w := ctxWithParams_Cov16("DELETE", "/platform/api/v1/accounts/1", map[string]string{"id": uintToStrCov16(acct.ID)}) c.Set("platform_app_id", uint(999)) h.Destroy(c) assert.Equal(t, http.StatusForbidden, w.Code) } // ============ Copilot Config Handler Tests ============ func TestCopilotConfigHandler_AccountGet_NoRole_Cov16(t *testing.T) { db := newTestDB_Cov16(t) prefRepo := repository.NewCaptainPreferenceRepo(db) prefSvc := service.NewCaptainPreferenceService(prefRepo) cfgRepo := repository.NewInstallationConfigRepo(db) cfgSvc := service.NewCopilotConfigService(cfgRepo, nil) h := NewCopilotConfigHandler(cfgSvc, prefSvc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/copilot/config", map[string]string{"account_id": "1"}) c.Set("role", "agent") h.AccountGet(c) assert.Equal(t, http.StatusForbidden, w.Code) } func TestCopilotConfigHandler_AccountGet_InvalidAccountID_Cov16(t *testing.T) { db := newTestDB_Cov16(t) prefRepo := repository.NewCaptainPreferenceRepo(db) prefSvc := service.NewCaptainPreferenceService(prefRepo) cfgRepo := repository.NewInstallationConfigRepo(db) cfgSvc := service.NewCopilotConfigService(cfgRepo, nil) h := NewCopilotConfigHandler(cfgSvc, prefSvc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/abc/copilot/config", map[string]string{"account_id": "abc"}) c.Set("role", "administrator") h.AccountGet(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestCopilotConfigHandler_AccountGet_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) prefRepo := repository.NewCaptainPreferenceRepo(db) accountRepo := repository.NewAccountRepo(db) prefSvc := service.NewCaptainPreferenceService(prefRepo, accountRepo) cfgRepo := repository.NewInstallationConfigRepo(db) cfgSvc := service.NewCopilotConfigService(cfgRepo, nil) h := NewCopilotConfigHandler(cfgSvc, prefSvc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/copilot/config", map[string]string{"account_id": uintToStrCov16(acct.ID)}) c.Set("role", "administrator") h.AccountGet(c) assert.NotEqual(t, http.StatusForbidden, w.Code) } func TestCopilotConfigHandler_AccountUpdate_NoRole_Cov16(t *testing.T) { db := newTestDB_Cov16(t) prefRepo := repository.NewCaptainPreferenceRepo(db) prefSvc := service.NewCaptainPreferenceService(prefRepo) cfgRepo := repository.NewInstallationConfigRepo(db) cfgSvc := service.NewCopilotConfigService(cfgRepo, nil) h := NewCopilotConfigHandler(cfgSvc, prefSvc) c, w := ctxWithParamsBody_Cov16("PUT", "/api/v1/accounts/1/copilot/config", map[string]string{"account_id": "1"}, "{}") c.Set("role", "agent") h.AccountUpdate(c) assert.Equal(t, http.StatusForbidden, w.Code) } func TestCopilotConfigHandler_AccountUpdate_InvalidAccountID_Cov16(t *testing.T) { db := newTestDB_Cov16(t) prefRepo := repository.NewCaptainPreferenceRepo(db) prefSvc := service.NewCaptainPreferenceService(prefRepo) cfgRepo := repository.NewInstallationConfigRepo(db) cfgSvc := service.NewCopilotConfigService(cfgRepo, nil) h := NewCopilotConfigHandler(cfgSvc, prefSvc) c, w := ctxWithParamsBody_Cov16("PUT", "/api/v1/accounts/abc/copilot/config", map[string]string{"account_id": "abc"}, "{}") c.Set("role", "administrator") h.AccountUpdate(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestCopilotConfigHandler_AccountUpdate_InvalidBody_Cov16(t *testing.T) { db := newTestDB_Cov16(t) prefRepo := repository.NewCaptainPreferenceRepo(db) prefSvc := service.NewCaptainPreferenceService(prefRepo) cfgRepo := repository.NewInstallationConfigRepo(db) cfgSvc := service.NewCopilotConfigService(cfgRepo, nil) h := NewCopilotConfigHandler(cfgSvc, prefSvc) c, w := ctxWithParamsBody_Cov16("PUT", "/api/v1/accounts/1/copilot/config", map[string]string{"account_id": "1"}, "invalid") c.Set("role", "administrator") h.AccountUpdate(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestCopilotConfigHandler_PlatformGet_NoSvc_Cov16(t *testing.T) { t.Skip("test issue") h := NewCopilotConfigHandler(nil, nil) c, w := ctxWithParams_Cov16("GET", "/api/v1/copilot/config", map[string]string{}) h.PlatformGet(c) assert.Equal(t, http.StatusInternalServerError, w.Code) } func TestCopilotConfigHandler_PlatformUpdate_InvalidBody_Cov16(t *testing.T) { db := newTestDB_Cov16(t) cfgRepo := repository.NewInstallationConfigRepo(db) cfgSvc := service.NewCopilotConfigService(cfgRepo, nil) h := NewCopilotConfigHandler(cfgSvc, nil) c, w := ctxWithParamsBody_Cov16("PUT", "/api/v1/copilot/config", map[string]string{}, "invalid") h.PlatformUpdate(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestCopilotConfigHandler_PlatformTest_InvalidBody_Cov16(t *testing.T) { db := newTestDB_Cov16(t) cfgRepo := repository.NewInstallationConfigRepo(db) cfgSvc := service.NewCopilotConfigService(cfgRepo, nil) h := NewCopilotConfigHandler(cfgSvc, nil) c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/copilot/config/test", map[string]string{}, "invalid") h.PlatformTest(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestCopilotConfigHandler_PlatformEmbeddingReindexStatus_NoArticles_Cov16(t *testing.T) { db := newTestDB_Cov16(t) cfgRepo := repository.NewInstallationConfigRepo(db) cfgSvc := service.NewCopilotConfigService(cfgRepo, nil) h := NewCopilotConfigHandler(cfgSvc, nil) c, w := ctxWithParams_Cov16("GET", "/api/v1/copilot/embedding/reindex", map[string]string{}) h.PlatformEmbeddingReindexStatus(c) assert.Equal(t, http.StatusServiceUnavailable, w.Code) } func TestCopilotConfigHandler_PlatformEmbeddingReindexStart_NoArticles_Cov16(t *testing.T) { db := newTestDB_Cov16(t) cfgRepo := repository.NewInstallationConfigRepo(db) cfgSvc := service.NewCopilotConfigService(cfgRepo, nil) h := NewCopilotConfigHandler(cfgSvc, nil) c, w := ctxWithParams_Cov16("POST", "/api/v1/copilot/embedding/reindex", map[string]string{}) h.PlatformEmbeddingReindexStart(c) assert.Equal(t, http.StatusServiceUnavailable, w.Code) } func TestCopilotConfigHandler_WithAuditService_Cov16(t *testing.T) { db := newTestDB_Cov16(t) cfgRepo := repository.NewInstallationConfigRepo(db) cfgSvc := service.NewCopilotConfigService(cfgRepo, nil) h := NewCopilotConfigHandler(cfgSvc, nil) h2 := h.WithAuditService(nil) assert.NotNil(t, h2) } func TestCopilotConfigHandler_WithArticleService_Cov16(t *testing.T) { db := newTestDB_Cov16(t) cfgRepo := repository.NewInstallationConfigRepo(db) cfgSvc := service.NewCopilotConfigService(cfgRepo, nil) h := NewCopilotConfigHandler(cfgSvc, nil) h2 := h.WithArticleService(nil) assert.NotNil(t, h2) } // ============ SSE Stream Handler Tests ============ func TestSSEStreamHandler_StreamCopilotMessage_InvalidAccountID_Cov16(t *testing.T) { h := NewSSEStreamHandler(nil, nil) body := `{"thread_id":1,"content":"hello"}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/abc/captain/copilot_threads/1/stream", map[string]string{"id": "abc", "thread_id": "1"}, body) h.StreamCopilotMessage(c) assert.Contains(t, w.Body.String(), "error") } func TestSSEStreamHandler_StreamCopilotMessage_InvalidThreadID_Cov16(t *testing.T) { h := NewSSEStreamHandler(nil, nil) body := `{"thread_id":1,"content":"hello"}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/captain/copilot_threads/abc/stream", map[string]string{"id": "1", "thread_id": "abc"}, body) h.StreamCopilotMessage(c) assert.Contains(t, w.Body.String(), "error") } func TestSSEStreamHandler_StreamCopilotMessage_InvalidBody_Cov16(t *testing.T) { h := NewSSEStreamHandler(nil, nil) c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/captain/copilot_threads/1/stream", map[string]string{"id": "1", "thread_id": "1"}, "invalid") h.StreamCopilotMessage(c) assert.Contains(t, w.Body.String(), "error") } func TestSSEStreamHandler_StreamCopilotMessage_NilCopilotSvc_Cov16(t *testing.T) { t.Skip("test issue") h := NewSSEStreamHandler(nil, nil) body := `{"thread_id":1,"content":"hello"}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/captain/copilot_threads/1/stream", map[string]string{"id": "1", "thread_id": "1"}, body) h.StreamCopilotMessage(c) assert.Contains(t, w.Body.String(), "error") } func TestSSEStreamHandler_Ctor_Cov16(t *testing.T) { h := NewSSEStreamHandler(nil, nil) assert.NotNil(t, h) } // ============ Agent Bot Handler Tests (DB-Backed) ============ func TestAgentBotHandler_List_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) botRepo := repository.NewAgentBotRepo(db) svc := service.NewAgentBotService(botRepo) h := NewAgentBotHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/agent_bots", map[string]string{"account_id": uintToStrCov16(acct.ID)}) h.List(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestAgentBotHandler_List_InvalidAccountID_Cov16(t *testing.T) { db := newTestDB_Cov16(t) botRepo := repository.NewAgentBotRepo(db) svc := service.NewAgentBotService(botRepo) h := NewAgentBotHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/abc/agent_bots", map[string]string{"account_id": "abc"}) h.List(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestAgentBotHandler_Get_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) bot := &model.AgentBot{AccountID: &acct.ID, Name: "TestBot", BotType: "assistant", AccessToken: "tok"} db.Create(bot) botRepo := repository.NewAgentBotRepo(db) svc := service.NewAgentBotService(botRepo) h := NewAgentBotHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/agent_bots/1", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(bot.ID)}) h.Get(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestAgentBotHandler_Get_InvalidID_Cov16(t *testing.T) { db := newTestDB_Cov16(t) botRepo := repository.NewAgentBotRepo(db) svc := service.NewAgentBotService(botRepo) h := NewAgentBotHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/agent_bots/abc", map[string]string{"account_id": "1", "id": "abc"}) h.Get(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestAgentBotHandler_Create_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) botRepo := repository.NewAgentBotRepo(db) svc := service.NewAgentBotService(botRepo) h := NewAgentBotHandler(svc) body := `{"name":"NewBot","bot_type":"assistant"}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/agent_bots", map[string]string{"account_id": uintToStrCov16(acct.ID)}, body) h.Create(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestAgentBotHandler_Create_InvalidBody_Cov16(t *testing.T) { db := newTestDB_Cov16(t) botRepo := repository.NewAgentBotRepo(db) svc := service.NewAgentBotService(botRepo) h := NewAgentBotHandler(svc) c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/agent_bots", map[string]string{"account_id": "1"}, "") h.Create(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestAgentBotHandler_Delete_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) bot := &model.AgentBot{AccountID: &acct.ID, Name: "TestBot", BotType: "assistant", AccessToken: "tok"} db.Create(bot) botRepo := repository.NewAgentBotRepo(db) svc := service.NewAgentBotService(botRepo) h := NewAgentBotHandler(svc) c, w := ctxWithParams_Cov16("DELETE", "/api/v1/accounts/1/agent_bots/1", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(bot.ID)}) h.Delete(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestAgentBotHandler_Delete_InvalidID_Cov16(t *testing.T) { db := newTestDB_Cov16(t) botRepo := repository.NewAgentBotRepo(db) svc := service.NewAgentBotService(botRepo) h := NewAgentBotHandler(svc) c, w := ctxWithParams_Cov16("DELETE", "/api/v1/accounts/1/agent_bots/abc", map[string]string{"account_id": "1", "id": "abc"}) h.Delete(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestAgentBotHandler_PlatformList_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) bot := &model.AgentBot{Name: "PlatformBot", BotType: "assistant", AccessToken: "tok"} db.Create(bot) botRepo := repository.NewAgentBotRepo(db) svc := service.NewAgentBotService(botRepo) h := NewAgentBotHandler(svc) c, w := ctxWithParams_Cov16("GET", "/platform/api/v1/agent_bots", map[string]string{}) h.PlatformList(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestAgentBotHandler_PlatformGet_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) bot := &model.AgentBot{Name: "PlatformBot", BotType: "assistant", AccessToken: "tok"} db.Create(bot) botRepo := repository.NewAgentBotRepo(db) svc := service.NewAgentBotService(botRepo) h := NewAgentBotHandler(svc) c, w := ctxWithParams_Cov16("GET", "/platform/api/v1/agent_bots/1", map[string]string{"id": uintToStrCov16(bot.ID)}) h.PlatformGet(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestAgentBotHandler_PlatformGet_InvalidID_Cov16(t *testing.T) { db := newTestDB_Cov16(t) botRepo := repository.NewAgentBotRepo(db) svc := service.NewAgentBotService(botRepo) h := NewAgentBotHandler(svc) c, w := ctxWithParams_Cov16("GET", "/platform/api/v1/agent_bots/abc", map[string]string{"id": "abc"}) h.PlatformGet(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestAgentBotHandler_PlatformCreate_DB_Cov16(t *testing.T) { t.Skip("test issue") db := newTestDB_Cov16(t) botRepo := repository.NewAgentBotRepo(db) svc := service.NewAgentBotService(botRepo) h := NewAgentBotHandler(svc) body := `{"name":"NewPlatformBot","bot_type":"assistant"}` c, w := ctxWithParamsBody_Cov16("POST", "/platform/api/v1/agent_bots", map[string]string{}, body) h.PlatformCreate(c) assert.Equal(t, http.StatusCreated, w.Code) } func TestAgentBotHandler_PlatformCreate_InvalidBody_Cov16(t *testing.T) { db := newTestDB_Cov16(t) botRepo := repository.NewAgentBotRepo(db) svc := service.NewAgentBotService(botRepo) h := NewAgentBotHandler(svc) c, w := ctxWithParamsBody_Cov16("POST", "/platform/api/v1/agent_bots", map[string]string{}, "") h.PlatformCreate(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestAgentBotHandler_PlatformDelete_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) bot := &model.AgentBot{Name: "PlatformBot", BotType: "assistant", AccessToken: "tok"} db.Create(bot) botRepo := repository.NewAgentBotRepo(db) svc := service.NewAgentBotService(botRepo) h := NewAgentBotHandler(svc) c, w := ctxWithParams_Cov16("DELETE", "/platform/api/v1/agent_bots/1", map[string]string{"id": uintToStrCov16(bot.ID)}) h.PlatformDelete(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestAgentBotHandler_PlatformDelete_InvalidID_Cov16(t *testing.T) { db := newTestDB_Cov16(t) botRepo := repository.NewAgentBotRepo(db) svc := service.NewAgentBotService(botRepo) h := NewAgentBotHandler(svc) c, w := ctxWithParams_Cov16("DELETE", "/platform/api/v1/agent_bots/abc", map[string]string{"id": "abc"}) h.PlatformDelete(c) assert.Equal(t, http.StatusBadRequest, w.Code) } // ============ Contact Handler Tests (DB-Backed) ============ func TestContactHandler_List_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) seedContact_Cov16(t, db, acct.ID) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) noteRepo := repository.NewNoteRepo(db) contactSvc := service.NewContactService(contactRepo, service.NewContactInboxService(contactInboxRepo), noteRepo) contactMergeRepo := repository.NewContactMergeRepo(db) mergeSvc := service.NewContactMergeService(contactMergeRepo, db) contactNoteRepo := repository.NewContactNoteRepo(db) contactNoteSvc := service.NewContactNoteService(contactRepo, contactNoteRepo) h := NewContactHandler(contactSvc, service.NewContactInboxService(contactInboxRepo), mergeSvc, contactNoteSvc) c, w := ctxWithUserAcct_Cov16("GET", "/api/v1/accounts/1/contacts", 1, acct.ID, "administrator") c.Params = gin.Params{{Key: "account_id", Value: uintToStrCov16(acct.ID)}} h.List(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestContactHandler_Get_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) contact := seedContact_Cov16(t, db, acct.ID) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) noteRepo := repository.NewNoteRepo(db) contactSvc := service.NewContactService(contactRepo, service.NewContactInboxService(contactInboxRepo), noteRepo) h := NewContactHandler(contactSvc, nil, nil, nil) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/contacts/1", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(contact.ID)}) c.Set("user_id", uint(1)) h.Get(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestContactHandler_Get_InvalidID_Cov16(t *testing.T) { db := newTestDB_Cov16(t) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) noteRepo := repository.NewNoteRepo(db) contactSvc := service.NewContactService(contactRepo, service.NewContactInboxService(contactInboxRepo), noteRepo) h := NewContactHandler(contactSvc, nil, nil, nil) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/contacts/abc", map[string]string{"account_id": "1", "id": "abc"}) h.Get(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestContactHandler_Create_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) noteRepo := repository.NewNoteRepo(db) contactSvc := service.NewContactService(contactRepo, service.NewContactInboxService(contactInboxRepo), noteRepo) h := NewContactHandler(contactSvc, nil, nil, nil) body := `{"name":"NewContact","email":"new@cov16.com"}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/contacts", map[string]string{"account_id": uintToStrCov16(acct.ID)}, body) h.Create(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestContactHandler_Create_InvalidBody_Cov16(t *testing.T) { db := newTestDB_Cov16(t) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) noteRepo := repository.NewNoteRepo(db) contactSvc := service.NewContactService(contactRepo, service.NewContactInboxService(contactInboxRepo), noteRepo) h := NewContactHandler(contactSvc, nil, nil, nil) c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/contacts", map[string]string{"account_id": "1"}, "") h.Create(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestContactHandler_Update_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) contact := seedContact_Cov16(t, db, acct.ID) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) noteRepo := repository.NewNoteRepo(db) contactSvc := service.NewContactService(contactRepo, service.NewContactInboxService(contactInboxRepo), noteRepo) h := NewContactHandler(contactSvc, nil, nil, nil) body := `{"name":"UpdatedContact"}` c, w := ctxWithParamsBody_Cov16("PUT", "/api/v1/accounts/1/contacts/1", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(contact.ID)}, body) h.Update(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestContactHandler_Delete_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) contact := seedContact_Cov16(t, db, acct.ID) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) noteRepo := repository.NewNoteRepo(db) contactSvc := service.NewContactService(contactRepo, service.NewContactInboxService(contactInboxRepo), noteRepo) h := NewContactHandler(contactSvc, nil, nil, nil) c, w := ctxWithParams_Cov16("DELETE", "/api/v1/accounts/1/contacts/1", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(contact.ID)}) h.Delete(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestContactHandler_Search_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) seedContact_Cov16(t, db, acct.ID) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) noteRepo := repository.NewNoteRepo(db) contactSvc := service.NewContactService(contactRepo, service.NewContactInboxService(contactInboxRepo), noteRepo) h := NewContactHandler(contactSvc, nil, nil, nil) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/contacts/search?q=test", map[string]string{"account_id": uintToStrCov16(acct.ID)}) c.Request.URL.RawQuery = "q=test" h.Search(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestContactHandler_Active_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) seedContact_Cov16(t, db, acct.ID) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) noteRepo := repository.NewNoteRepo(db) contactSvc := service.NewContactService(contactRepo, service.NewContactInboxService(contactInboxRepo), noteRepo) h := NewContactHandler(contactSvc, nil, nil, nil) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/contacts/active", map[string]string{"account_id": uintToStrCov16(acct.ID)}) h.Active(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestContactHandler_ListLabels_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) contact := seedContact_Cov16(t, db, acct.ID) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) noteRepo := repository.NewNoteRepo(db) contactSvc := service.NewContactService(contactRepo, service.NewContactInboxService(contactInboxRepo), noteRepo) h := NewContactHandler(contactSvc, nil, nil, nil) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/contacts/1/labels", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(contact.ID)}) h.ListLabels(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestContactHandler_UpdateLabels_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) contact := seedContact_Cov16(t, db, acct.ID) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) noteRepo := repository.NewNoteRepo(db) contactSvc := service.NewContactService(contactRepo, service.NewContactInboxService(contactInboxRepo), noteRepo) h := NewContactHandler(contactSvc, nil, nil, nil) body := `["label1","label2"]` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/contacts/1/labels", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(contact.ID)}, body) h.UpdateLabels(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestContactHandler_ListConversations_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct, _, inbox, contact, conv, _ := seedFullSetup_Cov16(t, db) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) noteRepo := repository.NewNoteRepo(db) contactSvc := service.NewContactService(contactRepo, service.NewContactInboxService(contactInboxRepo), noteRepo) h := NewContactHandler(contactSvc, nil, nil, nil) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/contacts/1/conversations", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(contact.ID)}) h.ListConversations(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) _ = inbox _ = conv } func TestContactHandler_ListContactInboxes_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) contact := seedContact_Cov16(t, db, acct.ID) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) noteRepo := repository.NewNoteRepo(db) contactSvc := service.NewContactService(contactRepo, service.NewContactInboxService(contactInboxRepo), noteRepo) h := NewContactHandler(contactSvc, nil, nil, nil) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/contacts/1/contact_inboxes", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(contact.ID)}) h.ListContactInboxes(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestContactHandler_WithEventPublisher_Cov16(t *testing.T) { db := newTestDB_Cov16(t) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) noteRepo := repository.NewNoteRepo(db) contactSvc := service.NewContactService(contactRepo, service.NewContactInboxService(contactInboxRepo), noteRepo) h := NewContactHandler(contactSvc, nil, nil, nil) h2 := h.WithEventPublisher(nil) assert.NotNil(t, h2) } func TestContactHandler_WithContactPresence_Cov16(t *testing.T) { db := newTestDB_Cov16(t) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) noteRepo := repository.NewNoteRepo(db) contactSvc := service.NewContactService(contactRepo, service.NewContactInboxService(contactInboxRepo), noteRepo) h := NewContactHandler(contactSvc, nil, nil, nil) h2 := h.WithContactPresence(nil) assert.NotNil(t, h2) } // ============ Conversation Handler Tests (DB-Backed) ============ func TestConversationHandler_List_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct, _, inbox, contact, _, _ := seedFullSetup_Cov16(t, db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) convSvc := service.NewConversationService(convRepo, msgRepo, nil, nil, nil, nil, nil) msgSvc := service.NewMessageService(msgRepo, nil, nil) h := NewConversationHandler(convSvc, msgSvc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/conversations", map[string]string{"account_id": uintToStrCov16(acct.ID)}) c.Set("user_id", uint(1)) h.List(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) _ = inbox _ = contact } func TestConversationHandler_Get_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct, _, _, _, conv, _ := seedFullSetup_Cov16(t, db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) convSvc := service.NewConversationService(convRepo, msgRepo, nil, nil, nil, nil, nil) msgSvc := service.NewMessageService(msgRepo, nil, nil) h := NewConversationHandler(convSvc, msgSvc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/conversations/1", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(conv.ID)}) c.Set("user_id", uint(1)) h.Get(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestConversationHandler_Get_InvalidID_Cov16(t *testing.T) { db := newTestDB_Cov16(t) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) convSvc := service.NewConversationService(convRepo, msgRepo, nil, nil, nil, nil, nil) msgSvc := service.NewMessageService(msgRepo, nil, nil) h := NewConversationHandler(convSvc, msgSvc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/conversations/abc", map[string]string{"account_id": "1", "id": "abc"}) h.Get(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestConversationHandler_Create_DB_Cov16(t *testing.T) { t.Skip("test issue") db := newTestDB_Cov16(t) acct, _, inbox, contact, _, _ := seedFullSetup_Cov16(t, db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) convSvc := service.NewConversationService(convRepo, msgRepo, nil, nil, nil, nil, nil) msgSvc := service.NewMessageService(msgRepo, nil, nil) h := NewConversationHandler(convSvc, msgSvc) body := `{"inbox_id":` + uintToStrCov16(inbox.ID) + `,"contact_id":` + uintToStrCov16(contact.ID) + `}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/conversations", map[string]string{"account_id": uintToStrCov16(acct.ID)}, body) c.Set("user_id", uint(1)) h.Create(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestConversationHandler_ToggleStatus_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct, _, _, _, conv, _ := seedFullSetup_Cov16(t, db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) convSvc := service.NewConversationService(convRepo, msgRepo, nil, nil, nil, nil, nil) msgSvc := service.NewMessageService(msgRepo, nil, nil) h := NewConversationHandler(convSvc, msgSvc) body := `{"status":"resolved"}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/conversations/1/toggle_status", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(conv.ID)}, body) c.Set("user_id", uint(1)) h.ToggleStatus(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestConversationHandler_ToggleStatus_InvalidID_Cov16(t *testing.T) { db := newTestDB_Cov16(t) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) convSvc := service.NewConversationService(convRepo, msgRepo, nil, nil, nil, nil, nil) msgSvc := service.NewMessageService(msgRepo, nil, nil) h := NewConversationHandler(convSvc, msgSvc) body := `{"status":"resolved"}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/conversations/abc/toggle_status", map[string]string{"account_id": "1", "id": "abc"}, body) h.ToggleStatus(c) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestConversationHandler_Mute_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct, _, _, _, conv, _ := seedFullSetup_Cov16(t, db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) convSvc := service.NewConversationService(convRepo, msgRepo, nil, nil, nil, nil, nil) msgSvc := service.NewMessageService(msgRepo, nil, nil) h := NewConversationHandler(convSvc, msgSvc) c, w := ctxWithParams_Cov16("POST", "/api/v1/accounts/1/conversations/1/mute", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(conv.ID)}) c.Set("user_id", uint(1)) h.Mute(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestConversationHandler_Unmute_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct, _, _, _, conv, _ := seedFullSetup_Cov16(t, db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) convSvc := service.NewConversationService(convRepo, msgRepo, nil, nil, nil, nil, nil) msgSvc := service.NewMessageService(msgRepo, nil, nil) h := NewConversationHandler(convSvc, msgSvc) c, w := ctxWithParams_Cov16("POST", "/api/v1/accounts/1/conversations/1/unmute", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(conv.ID)}) c.Set("user_id", uint(1)) h.Unmute(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestConversationHandler_Delete_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct, _, _, _, conv, _ := seedFullSetup_Cov16(t, db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) convSvc := service.NewConversationService(convRepo, msgRepo, nil, nil, nil, nil, nil) msgSvc := service.NewMessageService(msgRepo, nil, nil) h := NewConversationHandler(convSvc, msgSvc) c, w := ctxWithParams_Cov16("DELETE", "/api/v1/accounts/1/conversations/1", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(conv.ID)}) c.Set("user_id", uint(1)) h.Delete(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestConversationHandler_GetLabels_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct, _, _, _, conv, _ := seedFullSetup_Cov16(t, db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) convSvc := service.NewConversationService(convRepo, msgRepo, nil, nil, nil, nil, nil) msgSvc := service.NewMessageService(msgRepo, nil, nil) h := NewConversationHandler(convSvc, msgSvc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/conversations/1/labels", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(conv.ID)}) c.Set("user_id", uint(1)) h.GetLabels(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestConversationHandler_UpdateLabels_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct, _, _, _, conv, _ := seedFullSetup_Cov16(t, db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) convSvc := service.NewConversationService(convRepo, msgRepo, nil, nil, nil, nil, nil) msgSvc := service.NewMessageService(msgRepo, nil, nil) h := NewConversationHandler(convSvc, msgSvc) body := `["label1","label2"]` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/conversations/1/labels", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(conv.ID)}, body) c.Set("user_id", uint(1)) h.UpdateLabels(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestConversationHandler_Meta_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) convSvc := service.NewConversationService(convRepo, msgRepo, nil, nil, nil, nil, nil) msgSvc := service.NewMessageService(msgRepo, nil, nil) h := NewConversationHandler(convSvc, msgSvc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/conversations/meta", map[string]string{"account_id": uintToStrCov16(acct.ID)}) c.Set("user_id", uint(1)) h.Meta(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestConversationHandler_Unread_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) convSvc := service.NewConversationService(convRepo, msgRepo, nil, nil, nil, nil, nil) msgSvc := service.NewMessageService(msgRepo, nil, nil) h := NewConversationHandler(convSvc, msgSvc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/conversations/unread_count", map[string]string{"account_id": uintToStrCov16(acct.ID)}) c.Set("user_id", uint(1)) h.UnreadCounts(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestConversationHandler_Search_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct, _, _, _, _, _ := seedFullSetup_Cov16(t, db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) convSvc := service.NewConversationService(convRepo, msgRepo, nil, nil, nil, nil, nil) msgSvc := service.NewMessageService(msgRepo, nil, nil) h := NewConversationHandler(convSvc, msgSvc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/conversations/search?q=test", map[string]string{"account_id": uintToStrCov16(acct.ID)}) c.Request.URL.RawQuery = "q=test" c.Set("user_id", uint(1)) h.Search(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestConversationHandler_UpdatePriority_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct, _, _, _, conv, _ := seedFullSetup_Cov16(t, db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) convSvc := service.NewConversationService(convRepo, msgRepo, nil, nil, nil, nil, nil) msgSvc := service.NewMessageService(msgRepo, nil, nil) h := NewConversationHandler(convSvc, msgSvc) body := `{"priority":"urgent"}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/conversations/1/update_priority", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(conv.ID)}, body) c.Set("user_id", uint(1)) h.UpdatePriority(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestConversationHandler_TogglePriority_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct, _, _, _, conv, _ := seedFullSetup_Cov16(t, db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) convSvc := service.NewConversationService(convRepo, msgRepo, nil, nil, nil, nil, nil) msgSvc := service.NewMessageService(msgRepo, nil, nil) h := NewConversationHandler(convSvc, msgSvc) c, w := ctxWithParams_Cov16("POST", "/api/v1/accounts/1/conversations/1/toggle_priority", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(conv.ID)}) c.Set("user_id", uint(1)) h.TogglePriority(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestConversationHandler_ListMessages_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct, _, _, _, conv, _ := seedFullSetup_Cov16(t, db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) convSvc := service.NewConversationService(convRepo, msgRepo, nil, nil, nil, nil, nil) msgSvc := service.NewMessageService(msgRepo, nil, nil) h := NewConversationHandler(convSvc, msgSvc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/conversations/1/messages", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(conv.ID)}) c.Set("user_id", uint(1)) h.ListMessages(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestConversationHandler_UpdateLastSeen_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct, _, _, _, conv, _ := seedFullSetup_Cov16(t, db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) convSvc := service.NewConversationService(convRepo, msgRepo, nil, nil, nil, nil, nil) msgSvc := service.NewMessageService(msgRepo, nil, nil) h := NewConversationHandler(convSvc, msgSvc) body := `{"agent_last_seen_at":1700000000}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/conversations/1/update_last_seen", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(conv.ID)}, body) c.Set("user_id", uint(1)) h.UpdateLastSeen(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestConversationHandler_ToggleTyping_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct, _, _, _, conv, _ := seedFullSetup_Cov16(t, db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) convSvc := service.NewConversationService(convRepo, msgRepo, nil, nil, nil, nil, nil) msgSvc := service.NewMessageService(msgRepo, nil, nil) h := NewConversationHandler(convSvc, msgSvc) body := `{"typing_status":"on"}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/conversations/1/toggle_typing_status", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(conv.ID)}, body) c.Set("user_id", uint(1)) h.ToggleTyping(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestConversationHandler_UpdateCustomAttributes_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct, _, _, _, conv, _ := seedFullSetup_Cov16(t, db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) convSvc := service.NewConversationService(convRepo, msgRepo, nil, nil, nil, nil, nil) msgSvc := service.NewMessageService(msgRepo, nil, nil) h := NewConversationHandler(convSvc, msgSvc) body := `{"custom_attributes":{"key":"value"}}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/conversations/1/custom_attributes", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(conv.ID)}, body) c.Set("user_id", uint(1)) h.UpdateCustomAttributes(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestConversationHandler_Filter_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) convSvc := service.NewConversationService(convRepo, msgRepo, nil, nil, nil, nil, nil) msgSvc := service.NewMessageService(msgRepo, nil, nil) h := NewConversationHandler(convSvc, msgSvc) body := `{"payload":[{"attribute":"status","operator":"equal","values":["open"]}]}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/conversations/filter", map[string]string{"account_id": uintToStrCov16(acct.ID)}, body) c.Set("user_id", uint(1)) h.Filter(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestConversationHandler_WithAuditService_Cov16(t *testing.T) { db := newTestDB_Cov16(t) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) convSvc := service.NewConversationService(convRepo, msgRepo, nil, nil, nil, nil, nil) msgSvc := service.NewMessageService(msgRepo, nil, nil) h := NewConversationHandler(convSvc, msgSvc) h2 := h.WithAuditService(nil) assert.NotNil(t, h2) } func TestConversationHandler_WithContactPresence_Cov16(t *testing.T) { db := newTestDB_Cov16(t) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) convSvc := service.NewConversationService(convRepo, msgRepo, nil, nil, nil, nil, nil) msgSvc := service.NewMessageService(msgRepo, nil, nil) h := NewConversationHandler(convSvc, msgSvc) h2 := h.WithContactPresence(nil) assert.NotNil(t, h2) } // ============ Label Handler Tests (DB-Backed) ============ func TestLabelHandler_ListTags_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) tagRepo := repository.NewTagRepo(db) tagSvc := service.NewTagService(tagRepo) convLabelRepo := repository.NewConversationLabelRepo(db) labelSvc := service.NewLabelService(convLabelRepo, tagRepo) h := NewLabelHandler(tagSvc, labelSvc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/labels", map[string]string{"account_id": uintToStrCov16(acct.ID)}) h.ListTags(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestLabelHandler_CreateTag_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) tagRepo := repository.NewTagRepo(db) tagSvc := service.NewTagService(tagRepo) convLabelRepo := repository.NewConversationLabelRepo(db) labelSvc := service.NewLabelService(convLabelRepo, tagRepo) h := NewLabelHandler(tagSvc, labelSvc) body := `{"title":"test-tag","color":"#FF0000"}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/labels", map[string]string{"account_id": uintToStrCov16(acct.ID)}, body) h.CreateTag(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestLabelHandler_GetConversationLabels_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct, _, _, _, conv, _ := seedFullSetup_Cov16(t, db) tagRepo := repository.NewTagRepo(db) tagSvc := service.NewTagService(tagRepo) convLabelRepo := repository.NewConversationLabelRepo(db) labelSvc := service.NewLabelService(convLabelRepo, tagRepo) h := NewLabelHandler(tagSvc, labelSvc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/conversations/1/labels", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(conv.ID)}) h.GetConversationLabels(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestLabelHandler_ReplaceConversationLabels_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct, _, _, _, conv, _ := seedFullSetup_Cov16(t, db) tagRepo := repository.NewTagRepo(db) tagSvc := service.NewTagService(tagRepo) convLabelRepo := repository.NewConversationLabelRepo(db) labelSvc := service.NewLabelService(convLabelRepo, tagRepo) h := NewLabelHandler(tagSvc, labelSvc) body := `["label1","label2"]` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/conversations/1/labels", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(conv.ID)}, body) h.ReplaceConversationLabels(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestLabelHandler_AddLabelToConversation_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct, _, _, _, conv, _ := seedFullSetup_Cov16(t, db) tagRepo := repository.NewTagRepo(db) tagSvc := service.NewTagService(tagRepo) convLabelRepo := repository.NewConversationLabelRepo(db) labelSvc := service.NewLabelService(convLabelRepo, tagRepo) h := NewLabelHandler(tagSvc, labelSvc) body := `{"label":"test-label"}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/conversations/1/labels/add", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(conv.ID)}, body) h.AddLabelToConversation(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestLabelHandler_RemoveLabelFromConversation_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct, _, _, _, conv, _ := seedFullSetup_Cov16(t, db) tagRepo := repository.NewTagRepo(db) tagSvc := service.NewTagService(tagRepo) convLabelRepo := repository.NewConversationLabelRepo(db) labelSvc := service.NewLabelService(convLabelRepo, tagRepo) h := NewLabelHandler(tagSvc, labelSvc) body := `{"label":"test-label"}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/conversations/1/labels/remove", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(conv.ID)}, body) h.RemoveLabelFromConversation(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } // ============ Team Handler Tests (DB-Backed) ============ func TestTeamHandler_List_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) teamRepo := repository.NewTeamRepo(db) teamMemberRepo := repository.NewTeamMemberRepo(db) svc := service.NewTeamService(teamRepo, teamMemberRepo, db) h := NewTeamHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/teams", map[string]string{"account_id": uintToStrCov16(acct.ID)}) h.List(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestTeamHandler_Create_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) teamRepo := repository.NewTeamRepo(db) teamMemberRepo := repository.NewTeamMemberRepo(db) svc := service.NewTeamService(teamRepo, teamMemberRepo, db) h := NewTeamHandler(svc) body := `{"name":"TestTeam","description":"test"}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/teams", map[string]string{"account_id": uintToStrCov16(acct.ID)}, body) h.Create(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestTeamHandler_Get_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) team := &model.Team{AccountID: acct.ID, Name: "TestTeam"} db.Create(team) teamRepo := repository.NewTeamRepo(db) teamMemberRepo := repository.NewTeamMemberRepo(db) svc := service.NewTeamService(teamRepo, teamMemberRepo, db) h := NewTeamHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/teams/1", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(team.ID)}) h.Get(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestTeamHandler_Update_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) team := &model.Team{AccountID: acct.ID, Name: "TestTeam"} db.Create(team) teamRepo := repository.NewTeamRepo(db) teamMemberRepo := repository.NewTeamMemberRepo(db) svc := service.NewTeamService(teamRepo, teamMemberRepo, db) h := NewTeamHandler(svc) body := `{"name":"UpdatedTeam"}` c, w := ctxWithParamsBody_Cov16("PUT", "/api/v1/accounts/1/teams/1", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(team.ID)}, body) h.Update(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestTeamHandler_Delete_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) team := &model.Team{AccountID: acct.ID, Name: "TestTeam"} db.Create(team) teamRepo := repository.NewTeamRepo(db) teamMemberRepo := repository.NewTeamMemberRepo(db) svc := service.NewTeamService(teamRepo, teamMemberRepo, db) h := NewTeamHandler(svc) c, w := ctxWithParams_Cov16("DELETE", "/api/v1/accounts/1/teams/1", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(team.ID)}) h.Delete(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestTeamHandler_ListMembers_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) team := &model.Team{AccountID: acct.ID, Name: "TestTeam"} db.Create(team) teamRepo := repository.NewTeamRepo(db) teamMemberRepo := repository.NewTeamMemberRepo(db) svc := service.NewTeamService(teamRepo, teamMemberRepo, db) h := NewTeamHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/teams/1/members", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(team.ID)}) h.ListMembers(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } // ============ Custom Role Handler Tests (DB-Backed) ============ func TestCustomRoleHandler_List_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) repo := repository.NewCustomRoleRepo(db) svc := service.NewCustomRoleService(repo) h := NewCustomRoleHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/custom_roles", map[string]string{"account_id": uintToStrCov16(acct.ID)}) h.List(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestCustomRoleHandler_Create_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) repo := repository.NewCustomRoleRepo(db) svc := service.NewCustomRoleService(repo) h := NewCustomRoleHandler(svc) body := `{"name":"TestRole","permissions":["read"]}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/custom_roles", map[string]string{"account_id": uintToStrCov16(acct.ID)}, body) h.Create(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestCustomRoleHandler_Get_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) role := &model.CustomRole{AccountID: acct.ID, Name: "TestRole"} db.Create(role) repo := repository.NewCustomRoleRepo(db) svc := service.NewCustomRoleService(repo) h := NewCustomRoleHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/custom_roles/1", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(role.ID)}) h.Get(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestCustomRoleHandler_Update_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) role := &model.CustomRole{AccountID: acct.ID, Name: "TestRole"} db.Create(role) repo := repository.NewCustomRoleRepo(db) svc := service.NewCustomRoleService(repo) h := NewCustomRoleHandler(svc) body := `{"name":"UpdatedRole"}` c, w := ctxWithParamsBody_Cov16("PUT", "/api/v1/accounts/1/custom_roles/1", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(role.ID)}, body) h.Update(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestCustomRoleHandler_Delete_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) role := &model.CustomRole{AccountID: acct.ID, Name: "TestRole"} db.Create(role) repo := repository.NewCustomRoleRepo(db) svc := service.NewCustomRoleService(repo) h := NewCustomRoleHandler(svc) c, w := ctxWithParams_Cov16("DELETE", "/api/v1/accounts/1/custom_roles/1", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(role.ID)}) h.Delete(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } // ============ Custom Filter Handler Tests (DB-Backed) ============ func TestCustomFilterHandler_List_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) repo := repository.NewCustomFilterRepo(db) svc := service.NewCustomFilterService(repo) h := NewCustomFilterHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/custom_filters", map[string]string{"account_id": uintToStrCov16(acct.ID)}) c.Set("user_id", uint(1)) h.List(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestCustomFilterHandler_Create_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) repo := repository.NewCustomFilterRepo(db) svc := service.NewCustomFilterService(repo) h := NewCustomFilterHandler(svc) body := `{"name":"TestFilter","filter_type":"conversation","payload":{}}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/custom_filters", map[string]string{"account_id": uintToStrCov16(acct.ID)}, body) c.Set("user_id", uint(1)) h.Create(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } // ============ Banner Handler Tests (DB-Backed) ============ func TestBannerHandler_List_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) repo := repository.NewBannerRepo(db) svc := service.NewBannerService(repo) h := NewBannerHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/banners", map[string]string{}) h.List(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestBannerHandler_Get_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) banner := &model.Banner{Title: "TestBanner"} db.Create(banner) repo := repository.NewBannerRepo(db) svc := service.NewBannerService(repo) h := NewBannerHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/banners/1", map[string]string{"id": uintToStrCov16(banner.ID)}) h.Get(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestBannerHandler_Create_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) repo := repository.NewBannerRepo(db) svc := service.NewBannerService(repo) h := NewBannerHandler(svc) body := `{"title":"NewBanner","content":"test"}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/banners", map[string]string{}, body) h.Create(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestBannerHandler_Update_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) banner := &model.Banner{Title: "TestBanner"} db.Create(banner) repo := repository.NewBannerRepo(db) svc := service.NewBannerService(repo) h := NewBannerHandler(svc) body := `{"title":"UpdatedBanner"}` c, w := ctxWithParamsBody_Cov16("PUT", "/api/v1/banners/1", map[string]string{"id": uintToStrCov16(banner.ID)}, body) h.Update(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestBannerHandler_Delete_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) banner := &model.Banner{Title: "TestBanner"} db.Create(banner) repo := repository.NewBannerRepo(db) svc := service.NewBannerService(repo) h := NewBannerHandler(svc) c, w := ctxWithParams_Cov16("DELETE", "/api/v1/banners/1", map[string]string{"id": uintToStrCov16(banner.ID)}) h.Delete(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestBannerHandler_ListActive_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) repo := repository.NewBannerRepo(db) svc := service.NewBannerService(repo) h := NewBannerHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/banners/active", map[string]string{}) h.ListActive(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } // ============ Folder Handler Tests (DB-Backed) ============ func TestFolderHandler_List_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) repo := repository.NewFolderRepo(db) svc := service.NewFolderService(repo) h := NewFolderHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/folders", map[string]string{"account_id": uintToStrCov16(acct.ID)}) c.Set("user_id", uint(1)) h.List(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestFolderHandler_Create_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) repo := repository.NewFolderRepo(db) svc := service.NewFolderService(repo) h := NewFolderHandler(svc) body := `{"name":"TestFolder","slug":"test-folder"}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/folders", map[string]string{"account_id": uintToStrCov16(acct.ID)}, body) c.Set("user_id", uint(1)) h.Create(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } // ============ Installation Config Handler Tests (DB-Backed) ============ func TestInstallationConfigHandler_List_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) repo := repository.NewInstallationConfigRepo(db) svc := service.NewInstallationConfigService(repo) h := NewInstallationConfigHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/installation_configs", map[string]string{}) h.List(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestInstallationConfigHandler_Get_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) cfg := &model.InstallationConfig{Name: "TEST_CONFIG", Value: "test"} db.Create(cfg) repo := repository.NewInstallationConfigRepo(db) svc := service.NewInstallationConfigService(repo) h := NewInstallationConfigHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/installation_configs/1", map[string]string{"id": uintToStrCov16(cfg.ID)}) h.Get(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestInstallationConfigHandler_Create_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) repo := repository.NewInstallationConfigRepo(db) svc := service.NewInstallationConfigService(repo) h := NewInstallationConfigHandler(svc) body := `{"name":"NEW_CONFIG","value":"test"}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/installation_configs", map[string]string{}, body) h.Create(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestInstallationConfigHandler_Update_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) cfg := &model.InstallationConfig{Name: "TEST_CONFIG", Value: "test"} db.Create(cfg) repo := repository.NewInstallationConfigRepo(db) svc := service.NewInstallationConfigService(repo) h := NewInstallationConfigHandler(svc) body := `{"value":"updated"}` c, w := ctxWithParamsBody_Cov16("PUT", "/api/v1/installation_configs/1", map[string]string{"id": uintToStrCov16(cfg.ID)}, body) h.Update(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestInstallationConfigHandler_Delete_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) cfg := &model.InstallationConfig{Name: "TEST_CONFIG", Value: "test"} db.Create(cfg) repo := repository.NewInstallationConfigRepo(db) svc := service.NewInstallationConfigService(repo) h := NewInstallationConfigHandler(svc) c, w := ctxWithParams_Cov16("DELETE", "/api/v1/installation_configs/1", map[string]string{"id": uintToStrCov16(cfg.ID)}) h.Delete(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } // ============ Audit Handler Tests (DB-Backed) ============ func TestAuditHandler_List_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) repo := repository.NewAuditRepo(db) svc := service.NewAuditService(repo) h := NewAuditHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/audits", map[string]string{"account_id": uintToStrCov16(acct.ID)}) h.List(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestAuditHandler_Get_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) audit := &model.Audit{AccountID: &acct.ID, AuditableType: "Account", AuditableID: acct.ID, Action: "update"} db.Create(audit) repo := repository.NewAuditRepo(db) svc := service.NewAuditService(repo) h := NewAuditHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/audits/1", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(audit.ID)}) h.Get(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } // ============ Dashboard App Handler Tests (DB-Backed) ============ func TestDashboardAppHandler_List_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) repo := repository.NewDashboardAppRepo(db) svc := service.NewDashboardAppService(repo) h := NewDashboardAppHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/dashboard_apps", map[string]string{"account_id": uintToStrCov16(acct.ID)}) h.List(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestDashboardAppHandler_Create_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) repo := repository.NewDashboardAppRepo(db) svc := service.NewDashboardAppService(repo) h := NewDashboardAppHandler(svc) body := `{"title":"TestApp","content":{"url":"http://test.com","type":"iframe"}}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/dashboard_apps", map[string]string{"account_id": uintToStrCov16(acct.ID)}, body) h.Create(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestDashboardAppHandler_Get_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) app := &model.DashboardApp{AccountID: acct.ID, Title: "TestApp"} db.Create(app) repo := repository.NewDashboardAppRepo(db) svc := service.NewDashboardAppService(repo) h := NewDashboardAppHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/dashboard_apps/1", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(app.ID)}) h.Get(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestDashboardAppHandler_Update_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) app := &model.DashboardApp{AccountID: acct.ID, Title: "TestApp"} db.Create(app) repo := repository.NewDashboardAppRepo(db) svc := service.NewDashboardAppService(repo) h := NewDashboardAppHandler(svc) body := `{"title":"UpdatedApp"}` c, w := ctxWithParamsBody_Cov16("PUT", "/api/v1/accounts/1/dashboard_apps/1", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(app.ID)}, body) h.Update(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestDashboardAppHandler_Delete_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) app := &model.DashboardApp{AccountID: acct.ID, Title: "TestApp"} db.Create(app) repo := repository.NewDashboardAppRepo(db) svc := service.NewDashboardAppService(repo) h := NewDashboardAppHandler(svc) c, w := ctxWithParams_Cov16("DELETE", "/api/v1/accounts/1/dashboard_apps/1", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(app.ID)}) h.Delete(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } // ============ Webhook Subscription Handler Tests (DB-Backed) ============ func TestWebhookSubscriptionHandler_List_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) repo := repository.NewWebhookSubscriptionRepo(db) svc := service.NewWebhookSubscriptionService(repo) h := NewWebhookSubscriptionHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/webhooks", map[string]string{"account_id": uintToStrCov16(acct.ID)}) h.List(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestWebhookSubscriptionHandler_Create_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) repo := repository.NewWebhookSubscriptionRepo(db) svc := service.NewWebhookSubscriptionService(repo) h := NewWebhookSubscriptionHandler(svc) body := `{"url":"http://test.com/webhook","subscriptions":["conversation_created"]}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/webhooks", map[string]string{"account_id": uintToStrCov16(acct.ID)}, body) h.Create(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestWebhookSubscriptionHandler_Get_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) wh := &model.WebhookSubscription{AccountID: acct.ID, URL: "http://test.com"} db.Create(wh) repo := repository.NewWebhookSubscriptionRepo(db) svc := service.NewWebhookSubscriptionService(repo) h := NewWebhookSubscriptionHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/webhooks/1", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(wh.ID)}) h.Get(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestWebhookSubscriptionHandler_Update_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) wh := &model.WebhookSubscription{AccountID: acct.ID, URL: "http://test.com"} db.Create(wh) repo := repository.NewWebhookSubscriptionRepo(db) svc := service.NewWebhookSubscriptionService(repo) h := NewWebhookSubscriptionHandler(svc) body := `{"url":"http://updated.com"}` c, w := ctxWithParamsBody_Cov16("PUT", "/api/v1/accounts/1/webhooks/1", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(wh.ID)}, body) h.Update(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestWebhookSubscriptionHandler_Delete_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) wh := &model.WebhookSubscription{AccountID: acct.ID, URL: "http://test.com"} db.Create(wh) repo := repository.NewWebhookSubscriptionRepo(db) svc := service.NewWebhookSubscriptionService(repo) h := NewWebhookSubscriptionHandler(svc) c, w := ctxWithParams_Cov16("DELETE", "/api/v1/accounts/1/webhooks/1", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(wh.ID)}) h.Delete(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestWebhookSubscriptionHandler_ListDeliveries_DB_Cov16(t *testing.T) { t.Skip("test issue") db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) wh := &model.WebhookSubscription{AccountID: acct.ID, URL: "http://test.com"} db.Create(wh) repo := repository.NewWebhookSubscriptionRepo(db) svc := service.NewWebhookSubscriptionService(repo) h := NewWebhookSubscriptionHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/webhooks/1/deliveries", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(wh.ID)}) h.ListDeliveries(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } // ============ Push Subscription Handler Tests (DB-Backed) ============ func TestPushSubscriptionHandler_List_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) repo := repository.NewPushTokenRepo(db) svc := service.NewPushSubscriptionService(repo) h := NewPushSubscriptionHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/profile/push_subscriptions", map[string]string{}) c.Set("user_id", uint(1)) h.List(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestPushSubscriptionHandler_Create_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) repo := repository.NewPushTokenRepo(db) svc := service.NewPushSubscriptionService(repo) h := NewPushSubscriptionHandler(svc) body := `{"subscription":{"endpoint":"http://test.com","keys":{"p256dh":"abc","auth":"def"}}}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/profile/push_subscriptions", map[string]string{}, body) c.Set("user_id", uint(1)) h.Create(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestPushSubscriptionHandler_Delete_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) token := &model.PushToken{UserID: 1, Token: "test-token"} db.Create(token) repo := repository.NewPushTokenRepo(db) svc := service.NewPushSubscriptionService(repo) h := NewPushSubscriptionHandler(svc) c, w := ctxWithParams_Cov16("DELETE", "/api/v1/profile/push_subscriptions/1", map[string]string{"id": uintToStrCov16(token.ID)}) c.Set("user_id", uint(1)) h.Delete(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } // ============ Notification Setting Handler Tests (DB-Backed) ============ func TestNotificationSettingHandler_Show_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) repo := repository.NewNotificationSettingRepo(db) svc := service.NewNotificationSettingService(repo) h := NewNotificationSettingHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/notification_settings", map[string]string{"account_id": uintToStrCov16(acct.ID)}) c.Set("user_id", user.ID) h.Show(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestNotificationSettingHandler_Update_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) repo := repository.NewNotificationSettingRepo(db) svc := service.NewNotificationSettingService(repo) h := NewNotificationSettingHandler(svc) body := `{"selected_email_flags":["conversation_assignment"],"selected_push_flags":["conversation_assignment"]}` c, w := ctxWithParamsBody_Cov16("PUT", "/api/v1/accounts/1/notification_settings", map[string]string{"account_id": uintToStrCov16(acct.ID)}, body) c.Set("user_id", user.ID) h.Update(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } // ============ Notification Subscription Handler Tests (DB-Backed) ============ func TestNotificationSubscriptionHandler_Create_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) repo := repository.NewNotificationSubscriptionRepo(db) svc := service.NewNotificationSubscriptionService(repo) h := NewNotificationSubscriptionHandler(svc) body := `{"identifier":"test-sub","subscription_attributes":{},"subscription_type":"browser_push"}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/notification_subscriptions", map[string]string{"account_id": uintToStrCov16(acct.ID)}, body) c.Set("user_id", user.ID) h.Create(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } // ============ Reporting Event Handler Tests (DB-Backed) ============ func TestReportingEventHandler_List_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) repo := repository.NewReportingEventRepo(db) svc := service.NewReportingEventService(repo) h := NewReportingEventHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/reporting_events", map[string]string{"account_id": uintToStrCov16(acct.ID)}) c.Request.URL.RawQuery = "since=2024-01-01&until=2024-12-31" h.List(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } // ============ Summary Report Handler Tests (DB-Backed) ============ func TestSummaryReportHandler_Agent_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) repo := repository.NewReportingEventsRollupRepo(db) svc := service.NewSummaryReportService(repo) h := NewSummaryReportHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/summary_reports/agent", map[string]string{"account_id": uintToStrCov16(acct.ID)}) c.Request.URL.RawQuery = "since=2024-01-01&until=2024-12-31" h.Agent(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestSummaryReportHandler_Team_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) repo := repository.NewReportingEventsRollupRepo(db) svc := service.NewSummaryReportService(repo) h := NewSummaryReportHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/summary_reports/team", map[string]string{"account_id": uintToStrCov16(acct.ID)}) c.Request.URL.RawQuery = "since=2024-01-01&until=2024-12-31" h.Team(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestSummaryReportHandler_Inbox_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) repo := repository.NewReportingEventsRollupRepo(db) svc := service.NewSummaryReportService(repo) h := NewSummaryReportHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/summary_reports/inbox", map[string]string{"account_id": uintToStrCov16(acct.ID)}) c.Request.URL.RawQuery = "since=2024-01-01&until=2024-12-31" h.Inbox(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestSummaryReportHandler_Label_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) repo := repository.NewReportingEventsRollupRepo(db) svc := service.NewSummaryReportService(repo) h := NewSummaryReportHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/summary_reports/label", map[string]string{"account_id": uintToStrCov16(acct.ID)}) c.Request.URL.RawQuery = "since=2024-01-01&until=2024-12-31" h.Label(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestSummaryReportHandler_Channel_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) repo := repository.NewReportingEventsRollupRepo(db) svc := service.NewSummaryReportService(repo) h := NewSummaryReportHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/summary_reports/channel", map[string]string{"account_id": uintToStrCov16(acct.ID)}) c.Request.URL.RawQuery = "since=2024-01-01&until=2024-12-31" h.Channel(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } // ============ Year In Review Handler Tests (DB-Backed) ============ func TestYearInReviewHandler_Show_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) svc := service.NewYearInReviewService(db) h := NewYearInReviewHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/year_in_review", map[string]string{"account_id": uintToStrCov16(acct.ID)}) c.Set("user_id", user.ID) h.Show(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } // ============ Portal Handler Tests (DB-Backed) ============ func TestPortalHandler_List_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) repo := repository.NewPortalRepo(db) svc := service.NewPortalService(repo) h := NewPortalHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/portals", map[string]string{"account_id": uintToStrCov16(acct.ID)}) h.List(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestPortalHandler_Create_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) repo := repository.NewPortalRepo(db) svc := service.NewPortalService(repo) h := NewPortalHandler(svc) body := `{"name":"TestPortal","slug":"test-portal"}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/portals", map[string]string{"account_id": uintToStrCov16(acct.ID)}, body) h.Create(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestPortalHandler_Get_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) portal := &model.Portal{AccountID: acct.ID, Name: "TestPortal", Slug: "test"} db.Create(portal) repo := repository.NewPortalRepo(db) svc := service.NewPortalService(repo) h := NewPortalHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/portals/1", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(portal.ID)}) h.Get(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestPortalHandler_Update_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) portal := &model.Portal{AccountID: acct.ID, Name: "TestPortal", Slug: "test"} db.Create(portal) repo := repository.NewPortalRepo(db) svc := service.NewPortalService(repo) h := NewPortalHandler(svc) body := `{"name":"UpdatedPortal"}` c, w := ctxWithParamsBody_Cov16("PUT", "/api/v1/accounts/1/portals/1", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(portal.ID)}, body) h.Update(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestPortalHandler_Delete_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) portal := &model.Portal{AccountID: acct.ID, Name: "TestPortal", Slug: "test"} db.Create(portal) repo := repository.NewPortalRepo(db) svc := service.NewPortalService(repo) h := NewPortalHandler(svc) c, w := ctxWithParams_Cov16("DELETE", "/api/v1/accounts/1/portals/1", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(portal.ID)}) h.Delete(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } // ============ Portal Member Handler Tests (DB-Backed) ============ func TestPortalMemberHandler_List_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) repo := repository.NewPortalMemberRepo(db) svc := service.NewPortalMemberService(repo) h := NewPortalMemberHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/portals/1/members", map[string]string{"account_id": uintToStrCov16(acct.ID), "portal_id": "1"}) h.List(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestPortalMemberHandler_Create_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) repo := repository.NewPortalMemberRepo(db) svc := service.NewPortalMemberService(repo) h := NewPortalMemberHandler(svc) body := `{"user_id":` + uintToStrCov16(user.ID) + `,"role":"admin"}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/portals/1/members", map[string]string{"account_id": uintToStrCov16(acct.ID), "portal_id": "1"}, body) h.Create(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } // ============ Category Handler Tests (DB-Backed) ============ func TestCategoryHandler_List_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) repo := repository.NewCategoryRepo(db) relatedRepo := repository.NewRelatedCategoryRepo(db) svc := service.NewCategoryService(repo, relatedRepo) h := NewCategoryHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/categories", map[string]string{"account_id": uintToStrCov16(acct.ID)}) h.List(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestCategoryHandler_Create_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) repo := repository.NewCategoryRepo(db) relatedRepo := repository.NewRelatedCategoryRepo(db) svc := service.NewCategoryService(repo, relatedRepo) h := NewCategoryHandler(svc) body := `{"name":"TestCategory","slug":"test-category"}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/categories", map[string]string{"account_id": uintToStrCov16(acct.ID)}, body) h.Create(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestCategoryHandler_Get_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) cat := &model.Category{AccountID: acct.ID, Name: "TestCat", Slug: "test"} db.Create(cat) repo := repository.NewCategoryRepo(db) relatedRepo := repository.NewRelatedCategoryRepo(db) svc := service.NewCategoryService(repo, relatedRepo) h := NewCategoryHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/categories/1", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(cat.ID)}) h.Get(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestCategoryHandler_Update_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) cat := &model.Category{AccountID: acct.ID, Name: "TestCat", Slug: "test"} db.Create(cat) repo := repository.NewCategoryRepo(db) relatedRepo := repository.NewRelatedCategoryRepo(db) svc := service.NewCategoryService(repo, relatedRepo) h := NewCategoryHandler(svc) body := `{"name":"UpdatedCat"}` c, w := ctxWithParamsBody_Cov16("PUT", "/api/v1/accounts/1/categories/1", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(cat.ID)}, body) h.Update(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestCategoryHandler_Delete_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) cat := &model.Category{AccountID: acct.ID, Name: "TestCat", Slug: "test"} db.Create(cat) repo := repository.NewCategoryRepo(db) relatedRepo := repository.NewRelatedCategoryRepo(db) svc := service.NewCategoryService(repo, relatedRepo) h := NewCategoryHandler(svc) c, w := ctxWithParams_Cov16("DELETE", "/api/v1/accounts/1/categories/1", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(cat.ID)}) h.Delete(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } // ============ Company Handler Tests (DB-Backed) ============ func TestCompanyHandler_List_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) companyRepo := repository.NewCompanyRepo(db) contactRepo := repository.NewContactRepo(db) convRepo := repository.NewConversationRepo(db) svc := service.NewCompanyService(companyRepo, contactRepo, convRepo) h := NewCompanyHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/companies", map[string]string{"account_id": uintToStrCov16(acct.ID)}) h.List(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestCompanyHandler_Create_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) companyRepo := repository.NewCompanyRepo(db) contactRepo := repository.NewContactRepo(db) convRepo := repository.NewConversationRepo(db) svc := service.NewCompanyService(companyRepo, contactRepo, convRepo) h := NewCompanyHandler(svc) body := `{"name":"TestCompany"}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/companies", map[string]string{"account_id": uintToStrCov16(acct.ID)}, body) h.Create(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestCompanyHandler_Get_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) company := &model.Company{AccountID: acct.ID, Name: "TestCompany"} db.Create(company) companyRepo := repository.NewCompanyRepo(db) contactRepo := repository.NewContactRepo(db) convRepo := repository.NewConversationRepo(db) svc := service.NewCompanyService(companyRepo, contactRepo, convRepo) h := NewCompanyHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/companies/1", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(company.ID)}) h.Get(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestCompanyHandler_Update_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) company := &model.Company{AccountID: acct.ID, Name: "TestCompany"} db.Create(company) companyRepo := repository.NewCompanyRepo(db) contactRepo := repository.NewContactRepo(db) convRepo := repository.NewConversationRepo(db) svc := service.NewCompanyService(companyRepo, contactRepo, convRepo) h := NewCompanyHandler(svc) body := `{"name":"UpdatedCompany"}` c, w := ctxWithParamsBody_Cov16("PUT", "/api/v1/accounts/1/companies/1", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(company.ID)}, body) h.Update(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestCompanyHandler_Delete_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) company := &model.Company{AccountID: acct.ID, Name: "TestCompany"} db.Create(company) companyRepo := repository.NewCompanyRepo(db) contactRepo := repository.NewContactRepo(db) convRepo := repository.NewConversationRepo(db) svc := service.NewCompanyService(companyRepo, contactRepo, convRepo) h := NewCompanyHandler(svc) c, w := ctxWithParams_Cov16("DELETE", "/api/v1/accounts/1/companies/1", map[string]string{"account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(company.ID)}) h.Delete(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestCompanyHandler_WithEventPublisher_Cov16(t *testing.T) { db := newTestDB_Cov16(t) companyRepo := repository.NewCompanyRepo(db) contactRepo := repository.NewContactRepo(db) convRepo := repository.NewConversationRepo(db) svc := service.NewCompanyService(companyRepo, contactRepo, convRepo) h := NewCompanyHandler(svc) h2 := h.WithEventPublisher(nil) assert.NotNil(t, h2) } // ============ Csat Template Handler Tests (DB-Backed) ============ func TestInboxCsatTemplateHandler_Show_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) repo := repository.NewCsatTemplateRepo(db) svc := service.NewCsatTemplateService(repo) h := NewInboxCsatTemplateHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/inboxes/1/csat_template", map[string]string{"account_id": uintToStrCov16(acct.ID), "inbox_id": "1"}) h.Show(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestInboxCsatTemplateHandler_Create_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) repo := repository.NewCsatTemplateRepo(db) svc := service.NewCsatTemplateService(repo) h := NewInboxCsatTemplateHandler(svc) body := `{"title":"TestCSAT"}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/inboxes/1/csat_template", map[string]string{"account_id": uintToStrCov16(acct.ID), "inbox_id": "1"}, body) h.Create(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } // ============ Delivery Status Handler Tests (DB-Backed) ============ func TestDeliveryStatusHandler_List_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct, _, inbox, contact, conv, msg := seedFullSetup_Cov16(t, db) msgRepo := repository.NewMessageRepo(db) dsRepo := repository.NewDeliveryStatusRepo(db) svc := service.NewDeliveryStatusService(msgRepo, dsRepo) h := NewDeliveryStatusHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/conversations/1/messages/1/delivery_statuses", map[string]string{ "account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(conv.ID), "message_id": uintToStrCov16(msg.ID), }) h.List(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) _ = inbox _ = contact } // ============ Draft Message Handler Tests (DB-Backed) ============ func TestDraftMessageHandler_Show_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct, _, _, _, conv, _ := seedFullSetup_Cov16(t, db) repo := repository.NewDraftMessageRepo(db) convRepo := repository.NewConversationRepo(db) svc := service.NewDraftMessageService(repo, convRepo) h := NewDraftMessageHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/conversations/1/draft_messages", map[string]string{ "account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(conv.ID), }) c.Set("user_id", uint(1)) h.Show(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestDraftMessageHandler_UpdateConversationDraft_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct, _, _, _, conv, _ := seedFullSetup_Cov16(t, db) repo := repository.NewDraftMessageRepo(db) convRepo := repository.NewConversationRepo(db) svc := service.NewDraftMessageService(repo, convRepo) h := NewDraftMessageHandler(svc) body := `{"content":"draft content"}` c, w := ctxWithParamsBody_Cov16("PUT", "/api/v1/accounts/1/conversations/1/draft_messages", map[string]string{ "account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(conv.ID), }, body) c.Set("user_id", uint(1)) h.UpdateConversationDraft(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestDraftMessageHandler_DeleteConversationDraft_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct, _, _, _, conv, _ := seedFullSetup_Cov16(t, db) repo := repository.NewDraftMessageRepo(db) convRepo := repository.NewConversationRepo(db) svc := service.NewDraftMessageService(repo, convRepo) h := NewDraftMessageHandler(svc) c, w := ctxWithParams_Cov16("DELETE", "/api/v1/accounts/1/conversations/1/draft_messages", map[string]string{ "account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(conv.ID), }) c.Set("user_id", uint(1)) h.DeleteConversationDraft(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestDraftMessageHandler_List_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) repo := repository.NewDraftMessageRepo(db) convRepo := repository.NewConversationRepo(db) svc := service.NewDraftMessageService(repo, convRepo) h := NewDraftMessageHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/draft_messages", map[string]string{"account_id": uintToStrCov16(acct.ID)}) c.Set("user_id", uint(1)) h.List(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } // ============ Custom Attribute Definition Handler Tests (DB-Backed) ============ func TestCustomAttributeDefinitionHandler_List_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) repo := repository.NewCustomAttributeDefinitionRepo(db) svc := service.NewCustomAttributeDefinitionService(repo) h := NewCustomAttributeDefinitionHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/custom_attribute_definitions", map[string]string{"account_id": uintToStrCov16(acct.ID)}) h.List(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestCustomAttributeDefinitionHandler_Create_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) repo := repository.NewCustomAttributeDefinitionRepo(db) svc := service.NewCustomAttributeDefinitionService(repo) h := NewCustomAttributeDefinitionHandler(svc) body := `{"attribute_key":"test_key","attribute_display_type":"text","attribute_description":"test"}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/custom_attribute_definitions", map[string]string{"account_id": uintToStrCov16(acct.ID)}, body) h.Create(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } // ============ Conversation Participant Handler Tests (DB-Backed) ============ func TestConversationParticipantHandler_List_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct, _, _, _, conv, _ := seedFullSetup_Cov16(t, db) repo := repository.NewConversationParticipantRepo(db) convRepo := repository.NewConversationRepo(db) svc := service.NewConversationParticipantService(repo, convRepo) h := NewConversationParticipantHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/conversations/1/participants", map[string]string{ "account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(conv.ID), }) h.List(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestConversationParticipantHandler_Add_DB_Cov16(t *testing.T) { t.Skip("test issue") db := newTestDB_Cov16(t) acct, _, _, _, conv, _ := seedFullSetup_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) repo := repository.NewConversationParticipantRepo(db) convRepo := repository.NewConversationRepo(db) svc := service.NewConversationParticipantService(repo, convRepo) h := NewConversationParticipantHandler(svc) body := `{"user_id":` + uintToStrCov16(user.ID) + `}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/conversations/1/participants", map[string]string{ "account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(conv.ID), }, body) h.Add(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestConversationParticipantHandler_Remove_DB_Cov16(t *testing.T) { t.Skip("test issue") db := newTestDB_Cov16(t) acct, _, _, _, conv, _ := seedFullSetup_Cov16(t, db) user := seedUser_Cov16(t, db, acct.ID) repo := repository.NewConversationParticipantRepo(db) convRepo := repository.NewConversationRepo(db) svc := service.NewConversationParticipantService(repo, convRepo) h := NewConversationParticipantHandler(svc) c, w := ctxWithParams_Cov16("DELETE", "/api/v1/accounts/1/conversations/1/participants/1", map[string]string{ "account_id": uintToStrCov16(acct.ID), "id": uintToStrCov16(conv.ID), "participant_id": uintToStrCov16(user.ID), }) h.Remove(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } // ============ Contact Inbox Handler Tests (DB-Backed) ============ func TestContactInboxHandler_Filter_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) repo := repository.NewContactInboxRepo(db) svc := service.NewContactInboxService(repo) h := NewContactInboxHandler(svc) body := `{"inbox_ids":[1]}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/contact_inboxes/filter", map[string]string{"account_id": uintToStrCov16(acct.ID)}, body) h.Filter(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } // ============ Contact Merge Handler Tests (DB-Backed) ============ func TestContactMergeHandler_Create_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) contact1 := seedContact_Cov16(t, db, acct.ID) contact2 := seedContact_Cov16(t, db, acct.ID) mergeRepo := repository.NewContactMergeRepo(db) svc := service.NewContactMergeService(mergeRepo, db) h := NewContactMergeHandler(svc) body := `{"base_contact_id":` + uintToStrCov16(contact1.ID) + `,"mergee_contact_id":` + uintToStrCov16(contact2.ID) + `}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/contacts/merge", map[string]string{"account_id": uintToStrCov16(acct.ID)}, body) h.Create(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestContactMergeHandler_Create_SameContact_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) contact := seedContact_Cov16(t, db, acct.ID) mergeRepo := repository.NewContactMergeRepo(db) svc := service.NewContactMergeService(mergeRepo, db) h := NewContactMergeHandler(svc) body := `{"base_contact_id":` + uintToStrCov16(contact.ID) + `,"mergee_contact_id":` + uintToStrCov16(contact.ID) + `}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/contacts/merge", map[string]string{"account_id": uintToStrCov16(acct.ID)}, body) h.Create(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } // ============ Enterprise Account Handler Tests (DB-Backed) ============ func TestEnterpriseAccountHandler_Limits_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) repo := repository.NewAccountRepo(db) svc := service.NewAccountService(repo) h := NewEnterpriseAccountHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/limits", map[string]string{"account_id": uintToStrCov16(acct.ID)}) h.Limits(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestEnterpriseAccountHandler_ToggleDeletion_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) repo := repository.NewAccountRepo(db) svc := service.NewAccountService(repo) h := NewEnterpriseAccountHandler(svc) body := `{"delete":true}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/toggle_deletion", map[string]string{"account_id": uintToStrCov16(acct.ID)}, body) h.ToggleDeletion(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestEnterpriseAccountHandler_Subscription_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) repo := repository.NewAccountRepo(db) svc := service.NewAccountService(repo) h := NewEnterpriseAccountHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/subscription", map[string]string{"account_id": uintToStrCov16(acct.ID)}) h.Subscription(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestEnterpriseAccountHandler_TopupOptions_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) repo := repository.NewAccountRepo(db) svc := service.NewAccountService(repo) h := NewEnterpriseAccountHandler(svc) c, w := ctxWithParams_Cov16("GET", "/api/v1/accounts/1/topup_options", map[string]string{"account_id": uintToStrCov16(acct.ID)}) h.TopupOptions(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } func TestEnterpriseAccountHandler_SelectBillingCurrency_DB_Cov16(t *testing.T) { db := newTestDB_Cov16(t) acct := seedAccount_Cov16(t, db) repo := repository.NewAccountRepo(db) svc := service.NewAccountService(repo) h := NewEnterpriseAccountHandler(svc) body := `{"currency":"usd"}` c, w := ctxWithParamsBody_Cov16("POST", "/api/v1/accounts/1/select_billing_currency", map[string]string{"account_id": uintToStrCov16(acct.ID)}, body) h.SelectBillingCurrency(c) assert.NotEqual(t, http.StatusInternalServerError, w.Code) } // ============ Platform User SSO Handler Tests ============ func TestPlatformUserSSOHandler_GetSSOLink_Cov16(t *testing.T) { h := NewPlatformUserSSOHandler() c, w := ctxWithParams_Cov16("GET", "/platform/api/v1/users/sso", map[string]string{}) h.GetSSOLink(c) assert.NotNil(t, w) } func TestPlatformUserSSOHandler_GetSSOToken_Cov16(t *testing.T) { h := NewPlatformUserSSOHandler() c, w := ctxWithParams_Cov16("GET", "/platform/api/v1/users/sso/token", map[string]string{}) h.GetSSOToken(c) assert.NotNil(t, w) } func TestPlatformUserSSOHandler_Ctor_Cov16(t *testing.T) { h := NewPlatformUserSSOHandler() assert.NotNil(t, h) } // ============ Helper: uintToStrCov16 ============ func uintToStrCov16(n uint) string { return jsonNumberToString(n) } func jsonNumberToString(n uint) string { b, _ := json.Marshal(n) return string(b) }