veza/veza-backend-api/internal/services/analytics_aggregation_service_test.go

218 lines
5.4 KiB
Go
Raw Normal View History

package services
import (
"context"
"testing"
"time"
"go.uber.org/zap"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
func TestNewAnalyticsAggregationService(t *testing.T) {
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
if err != nil {
t.Fatalf("Failed to open database: %v", err)
}
logger := zap.NewNop()
service := NewAnalyticsAggregationService(db, logger)
if service == nil {
t.Error("NewAnalyticsAggregationService() returned nil")
}
if service.db == nil {
t.Error("NewAnalyticsAggregationService() returned service with nil db")
}
if service.logger == nil {
t.Error("NewAnalyticsAggregationService() returned service with nil logger")
}
}
func TestAnalyticsAggregationPeriod_Constants(t *testing.T) {
tests := []struct {
name string
period AnalyticsAggregationPeriod
expected string
}{
{
name: "hour period",
period: AnalyticsPeriodHour,
expected: "hour",
},
{
name: "day period",
period: AnalyticsPeriodDay,
expected: "day",
},
{
name: "week period",
period: AnalyticsPeriodWeek,
expected: "week",
},
{
name: "month period",
period: AnalyticsPeriodMonth,
expected: "month",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if string(tt.period) != tt.expected {
t.Errorf("Period = %v, want %v", tt.period, tt.expected)
}
})
}
}
func TestEventAggregationParams_Validation(t *testing.T) {
now := time.Now()
params := EventAggregationParams{
StartDate: now.Add(-7 * 24 * time.Hour),
EndDate: now,
Period: AnalyticsPeriodDay,
}
// Test that invalid period would be caught in AggregateEvents
invalidPeriod := AnalyticsAggregationPeriod("invalid")
params.Period = invalidPeriod
// This would fail validation in AggregateEvents
if params.Period == AnalyticsPeriodDay || params.Period == AnalyticsPeriodWeek ||
params.Period == AnalyticsPeriodMonth || params.Period == AnalyticsPeriodHour {
t.Error("Invalid period should not match valid periods")
}
}
func TestMin(t *testing.T) {
tests := []struct {
name string
a int
b int
expected int
}{
{
name: "a < b",
a: 5,
b: 10,
expected: 5,
},
{
name: "a > b",
a: 10,
b: 5,
expected: 5,
},
{
name: "a == b",
a: 5,
b: 5,
expected: 5,
},
{
name: "negative values",
a: -5,
b: -10,
expected: -10,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := min(tt.a, tt.b)
if result != tt.expected {
t.Errorf("min(%d, %d) = %d, want %d", tt.a, tt.b, result, tt.expected)
}
})
}
}
func TestGetEventCounts_EmptyParams(t *testing.T) {
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
if err != nil {
t.Fatalf("Failed to open database: %v", err)
}
service := NewAnalyticsAggregationService(db, zap.NewNop())
ctx := context.Background()
now := time.Now()
counts, err := service.GetEventCounts(ctx, now.Add(-7*24*time.Hour), now, []string{})
if err != nil {
// Expected to fail with empty database, but should not panic
if counts != nil {
t.Error("GetEventCounts() should return nil counts on error")
}
}
}
func TestGetTopEvents_EmptyParams(t *testing.T) {
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
if err != nil {
t.Fatalf("Failed to open database: %v", err)
}
service := NewAnalyticsAggregationService(db, zap.NewNop())
ctx := context.Background()
now := time.Now()
results, err := service.GetTopEvents(ctx, now.Add(-7*24*time.Hour), now, 10)
if err != nil {
// Expected to fail with empty database, but should not panic
if results != nil {
t.Error("GetTopEvents() should return nil results on error")
}
} else {
// If no error, results should be empty slice, not nil
if results == nil {
t.Error("GetTopEvents() should return empty slice, not nil")
}
}
}
// Note: Full integration tests would require:
// 1. A real PostgreSQL database with analytics_events table
// 2. Test data (analytics events with various event names, user IDs, payloads)
// 3. Verification of aggregation queries
// 4. Performance testing with large datasets
//
// Example integration test structure:
// func TestAnalyticsAggregationService_AggregateEvents_Integration(t *testing.T) {
// // Setup test database
// db := setupTestDB(t)
// defer cleanupTestDB(t, db)
//
// // Create test data
// userID1 := uuid.New()
// userID2 := uuid.New()
// createTestAnalyticsEvents(t, db, []AnalyticsEvent{
// {EventName: "track_play", UserID: &userID1, Payload: `{"track_id": "123"}`},
// {EventName: "track_play", UserID: &userID2, Payload: `{"track_id": "123"}`},
// {EventName: "user_login", UserID: &userID1, Payload: `{"ip": "1.2.3.4"}`},
// })
//
// service := NewAnalyticsAggregationService(db, zap.NewNop())
//
// ctx := context.Background()
// params := EventAggregationParams{
// StartDate: time.Now().Add(-7 * 24 * time.Hour),
// EndDate: time.Now(),
// Period: AnalyticsPeriodDay,
// }
//
// summary, err := service.AggregateEvents(ctx, params)
// if err != nil {
// t.Fatalf("AggregateEvents() error = %v", err)
// }
//
// if summary.TotalEvents == 0 {
// t.Error("AggregateEvents() returned zero total events")
// }
//
// if len(summary.Results) == 0 {
// t.Error("AggregateEvents() returned no results")
// }
// }