Files
Charon/backend/internal/api/handlers/notification_handler_test.go

153 lines
4.6 KiB
Go

package handlers_test
import (
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"github.com/gin-gonic/gin"
"github.com/stretchr/testify/assert"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
"github.com/Wikid82/charon/backend/internal/api/handlers"
"github.com/Wikid82/charon/backend/internal/models"
"github.com/Wikid82/charon/backend/internal/services"
)
func setupNotificationTestDB() *gorm.DB {
// Use openTestDB helper via temporary t trick
// Since this function lacks t param, keep calling openTestDB with a dummy testing.T
// But to avoid changing many callers, we'll reuse openTestDB by creating a short-lived testing.T wrapper isn't possible.
// Instead, set WAL and busy timeout using a simple gorm.Open with shared memory but minimal changes.
db, err := gorm.Open(sqlite.Open("file::memory:?cache=shared&_journal_mode=WAL&_busy_timeout=5000"), &gorm.Config{})
if err != nil {
panic("failed to connect to test database")
}
db.AutoMigrate(&models.Notification{}, &models.NotificationProvider{})
return db
}
func TestNotificationHandler_List(t *testing.T) {
gin.SetMode(gin.TestMode)
db := setupNotificationTestDB()
// Seed data
db.Create(&models.Notification{Title: "Test 1", Message: "Msg 1", Read: false})
db.Create(&models.Notification{Title: "Test 2", Message: "Msg 2", Read: true})
service := services.NewNotificationService(db)
handler := handlers.NewNotificationHandler(service)
router := gin.New()
router.GET("/notifications", handler.List)
// Test List All
w := httptest.NewRecorder()
req, _ := http.NewRequest("GET", "/notifications", nil)
router.ServeHTTP(w, req)
assert.Equal(t, http.StatusOK, w.Code)
var notifications []models.Notification
err := json.Unmarshal(w.Body.Bytes(), &notifications)
assert.NoError(t, err)
assert.Len(t, notifications, 2)
// Test List Unread
w = httptest.NewRecorder()
req, _ = http.NewRequest("GET", "/notifications?unread=true", nil)
router.ServeHTTP(w, req)
assert.Equal(t, http.StatusOK, w.Code)
err = json.Unmarshal(w.Body.Bytes(), &notifications)
assert.NoError(t, err)
assert.Len(t, notifications, 1)
assert.False(t, notifications[0].Read)
}
func TestNotificationHandler_MarkAsRead(t *testing.T) {
gin.SetMode(gin.TestMode)
db := setupNotificationTestDB()
// Seed data
notif := &models.Notification{Title: "Test 1", Message: "Msg 1", Read: false}
db.Create(notif)
service := services.NewNotificationService(db)
handler := handlers.NewNotificationHandler(service)
router := gin.New()
router.POST("/notifications/:id/read", handler.MarkAsRead)
w := httptest.NewRecorder()
req, _ := http.NewRequest("POST", "/notifications/"+notif.ID+"/read", nil)
router.ServeHTTP(w, req)
assert.Equal(t, http.StatusOK, w.Code)
var updated models.Notification
db.First(&updated, "id = ?", notif.ID)
assert.True(t, updated.Read)
}
func TestNotificationHandler_MarkAllAsRead(t *testing.T) {
gin.SetMode(gin.TestMode)
db := setupNotificationTestDB()
// Seed data
db.Create(&models.Notification{Title: "Test 1", Message: "Msg 1", Read: false})
db.Create(&models.Notification{Title: "Test 2", Message: "Msg 2", Read: false})
service := services.NewNotificationService(db)
handler := handlers.NewNotificationHandler(service)
router := gin.New()
router.POST("/notifications/read-all", handler.MarkAllAsRead)
w := httptest.NewRecorder()
req, _ := http.NewRequest("POST", "/notifications/read-all", nil)
router.ServeHTTP(w, req)
assert.Equal(t, http.StatusOK, w.Code)
var count int64
db.Model(&models.Notification{}).Where("read = ?", false).Count(&count)
assert.Equal(t, int64(0), count)
}
func TestNotificationHandler_MarkAllAsRead_Error(t *testing.T) {
gin.SetMode(gin.TestMode)
db := setupNotificationTestDB()
service := services.NewNotificationService(db)
handler := handlers.NewNotificationHandler(service)
r := gin.New()
r.POST("/notifications/read-all", handler.MarkAllAsRead)
// Close DB to force error
sqlDB, _ := db.DB()
sqlDB.Close()
req, _ := http.NewRequest("POST", "/notifications/read-all", nil)
w := httptest.NewRecorder()
r.ServeHTTP(w, req)
assert.Equal(t, http.StatusInternalServerError, w.Code)
}
func TestNotificationHandler_DBError(t *testing.T) {
gin.SetMode(gin.TestMode)
db := setupNotificationTestDB()
service := services.NewNotificationService(db)
handler := handlers.NewNotificationHandler(service)
r := gin.New()
r.POST("/notifications/:id/read", handler.MarkAsRead)
// Close DB to force error
sqlDB, _ := db.DB()
sqlDB.Close()
req, _ := http.NewRequest("POST", "/notifications/1/read", nil)
w := httptest.NewRecorder()
r.ServeHTTP(w, req)
assert.Equal(t, http.StatusInternalServerError, w.Code)
}