veza/veza-backend-api/internal/services/notification_service_enhanced_test.go
2026-03-05 23:03:43 +01:00

323 lines
7.9 KiB
Go

package services
import (
"context"
"testing"
"veza-backend-api/internal/models"
"github.com/google/uuid"
"go.uber.org/zap"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
func TestNewEnhancedNotificationService(t *testing.T) {
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
if err != nil {
t.Fatalf("Failed to open database: %v", err)
}
// Auto-migrate
if err := db.AutoMigrate(&models.Notification{}); err != nil {
t.Fatalf("Failed to migrate: %v", err)
}
logger := zap.NewNop()
service := NewEnhancedNotificationService(db, logger)
if service == nil {
t.Error("NewEnhancedNotificationService() returned nil")
}
if service.db == nil {
t.Error("NewEnhancedNotificationService() returned service with nil db")
}
if service.logger == nil {
t.Error("NewEnhancedNotificationService() returned service with nil logger")
}
}
func TestEnhancedNotificationService_CreateNotification(t *testing.T) {
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
if err != nil {
t.Fatalf("Failed to open database: %v", err)
}
if err := db.AutoMigrate(&models.Notification{}); err != nil {
t.Fatalf("Failed to migrate: %v", err)
}
service := NewEnhancedNotificationService(db, zap.NewNop())
ctx := context.Background()
userID := uuid.New()
notification, err := service.CreateNotification(
ctx,
userID,
"test_type",
"Test Title",
"Test Content",
"https://example.com",
)
if err != nil {
t.Fatalf("CreateNotification() error = %v", err)
}
if notification == nil {
t.Error("CreateNotification() returned nil notification")
}
if notification.ID == uuid.Nil {
t.Error("CreateNotification() returned notification with nil ID")
}
if notification.UserID != userID {
t.Errorf("CreateNotification() user_id = %v, want %v", notification.UserID, userID)
}
if notification.Type != "test_type" {
t.Errorf("CreateNotification() type = %v, want test_type", notification.Type)
}
if notification.Read != false {
t.Error("CreateNotification() read should be false")
}
}
func TestEnhancedNotificationService_GetNotifications(t *testing.T) {
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
if err != nil {
t.Fatalf("Failed to open database: %v", err)
}
if err := db.AutoMigrate(&models.Notification{}); err != nil {
t.Fatalf("Failed to migrate: %v", err)
}
service := NewEnhancedNotificationService(db, zap.NewNop())
ctx := context.Background()
userID := uuid.New()
// Create test notifications
for i := 0; i < 5; i++ {
_, err := service.CreateNotification(
ctx,
userID,
"test_type",
"Test Title",
"Test Content",
"",
)
if err != nil {
t.Fatalf("Failed to create test notification: %v", err)
}
}
params := NotificationParams{
UserID: userID,
UnreadOnly: false,
Page: 1,
Limit: 10,
}
result, err := service.GetNotifications(ctx, params)
if err != nil {
t.Fatalf("GetNotifications() error = %v", err)
}
if result == nil {
t.Error("GetNotifications() returned nil result")
}
if result.Total != 5 {
t.Errorf("GetNotifications() total = %d, want 5", result.Total)
}
if len(result.Notifications) != 5 {
t.Errorf("GetNotifications() returned %d notifications, want 5", len(result.Notifications))
}
if result.UnreadCount != 5 {
t.Errorf("GetNotifications() unread_count = %d, want 5", result.UnreadCount)
}
}
func TestEnhancedNotificationService_MarkAsRead(t *testing.T) {
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
if err != nil {
t.Fatalf("Failed to open database: %v", err)
}
if err := db.AutoMigrate(&models.Notification{}); err != nil {
t.Fatalf("Failed to migrate: %v", err)
}
service := NewEnhancedNotificationService(db, zap.NewNop())
ctx := context.Background()
userID := uuid.New()
// Create a notification
notification, err := service.CreateNotification(
ctx,
userID,
"test_type",
"Test Title",
"Test Content",
"",
)
if err != nil {
t.Fatalf("Failed to create notification: %v", err)
}
// Mark as read
err = service.MarkAsRead(ctx, userID, notification.ID)
if err != nil {
t.Fatalf("MarkAsRead() error = %v", err)
}
// Verify it's marked as read
readNotification, err := service.GetNotificationByID(ctx, userID, notification.ID)
if err != nil {
t.Fatalf("GetNotificationByID() error = %v", err)
}
if !readNotification.Read {
t.Error("MarkAsRead() notification is not marked as read")
}
if readNotification.ReadAt == nil {
t.Error("MarkAsRead() read_at is nil")
}
}
func TestEnhancedNotificationService_DeleteNotification(t *testing.T) {
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
if err != nil {
t.Fatalf("Failed to open database: %v", err)
}
if err := db.AutoMigrate(&models.Notification{}); err != nil {
t.Fatalf("Failed to migrate: %v", err)
}
service := NewEnhancedNotificationService(db, zap.NewNop())
ctx := context.Background()
userID := uuid.New()
// Create a notification
notification, err := service.CreateNotification(
ctx,
userID,
"test_type",
"Test Title",
"Test Content",
"",
)
if err != nil {
t.Fatalf("Failed to create notification: %v", err)
}
// Delete the notification
err = service.DeleteNotification(ctx, userID, notification.ID)
if err != nil {
t.Fatalf("DeleteNotification() error = %v", err)
}
// Verify it's deleted
_, err = service.GetNotificationByID(ctx, userID, notification.ID)
if err == nil {
t.Error("DeleteNotification() notification still exists")
}
}
func TestEnhancedNotificationService_GetUnreadCount(t *testing.T) {
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
if err != nil {
t.Fatalf("Failed to open database: %v", err)
}
if err := db.AutoMigrate(&models.Notification{}); err != nil {
t.Fatalf("Failed to migrate: %v", err)
}
service := NewEnhancedNotificationService(db, zap.NewNop())
ctx := context.Background()
userID := uuid.New()
// Create unread notifications
for i := 0; i < 3; i++ {
_, err := service.CreateNotification(
ctx,
userID,
"test_type",
"Test Title",
"Test Content",
"",
)
if err != nil {
t.Fatalf("Failed to create notification: %v", err)
}
}
count, err := service.GetUnreadCount(ctx, userID)
if err != nil {
t.Fatalf("GetUnreadCount() error = %v", err)
}
if count != 3 {
t.Errorf("GetUnreadCount() = %d, want 3", count)
}
}
func TestNotificationParams_Defaults(t *testing.T) {
params := NotificationParams{}
// Test that defaults are applied in GetNotifications method
if params.Page < 1 {
params.Page = 1
}
if params.Limit < 1 {
params.Limit = 20
}
if params.Limit > 100 {
params.Limit = 100
}
if params.Page != 1 {
t.Errorf("Expected default page 1, got %d", params.Page)
}
if params.Limit != 20 {
t.Errorf("Expected default limit 20, got %d", params.Limit)
}
}
// Note: Full integration tests would require:
// 1. A real database with notifications table
// 2. Test data (notifications with various types, read/unread status)
// 3. Verification of pagination, filtering, and deletion
//
// Example integration test structure:
// func TestEnhancedNotificationService_Integration(t *testing.T) {
// // Setup test database
// db := setupTestDB(t)
// defer cleanupTestDB(t, db)
//
// // Create test data
// userID := uuid.New()
// createTestNotifications(t, db, userID, 25) // 25 notifications
//
// service := NewEnhancedNotificationService(db, zap.NewNop())
//
// ctx := context.Background()
// params := NotificationParams{
// UserID: userID,
// Page: 1,
// Limit: 10,
// }
//
// result, err := service.GetNotifications(ctx, params)
// if err != nil {
// t.Fatalf("GetNotifications() error = %v", err)
// }
//
// if result.Total != 25 {
// t.Errorf("GetNotifications() total = %d, want 25", result.Total)
// }
//
// if len(result.Notifications) != 10 {
// t.Errorf("GetNotifications() returned %d notifications, want 10", len(result.Notifications))
// }
// }