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

381 lines
9 KiB
Go

package services
import (
"context"
"fmt"
"testing"
"time"
"go.uber.org/zap"
)
func TestNewCDNService(t *testing.T) {
config := CDNConfig{
Provider: CDNProviderCloudFront,
BaseURL: "https://d1234567890.cloudfront.net",
Enabled: true,
Logger: zap.NewNop(),
}
service := NewCDNService(config)
if service == nil {
t.Error("NewCDNService() returned nil")
}
if service.logger == nil {
t.Error("NewCDNService() returned service with nil logger")
}
if service.config.Provider != CDNProviderCloudFront {
t.Errorf("NewCDNService() provider = %v, want %v", service.config.Provider, CDNProviderCloudFront)
}
}
func TestCDNService_GetURL(t *testing.T) {
tests := []struct {
name string
config CDNConfig
path string
expected string
}{
{
name: "CloudFront enabled",
config: CDNConfig{
Provider: CDNProviderCloudFront,
BaseURL: "https://d1234567890.cloudfront.net",
Enabled: true,
Logger: zap.NewNop(),
},
path: "/audio/track123.mp3",
expected: "https://d1234567890.cloudfront.net/audio/track123.mp3",
},
{
name: "CDN disabled",
config: CDNConfig{
Provider: CDNProviderCloudFront,
BaseURL: "https://d1234567890.cloudfront.net",
Enabled: false,
Logger: zap.NewNop(),
},
path: "/audio/track123.mp3",
expected: "/audio/track123.mp3",
},
{
name: "None provider",
config: CDNConfig{
Provider: CDNProviderNone,
BaseURL: "https://d1234567890.cloudfront.net",
Enabled: true,
Logger: zap.NewNop(),
},
path: "/audio/track123.mp3",
expected: "/audio/track123.mp3",
},
{
name: "Path without leading slash",
config: CDNConfig{
Provider: CDNProviderCloudFront,
BaseURL: "https://d1234567890.cloudfront.net",
Enabled: true,
Logger: zap.NewNop(),
},
path: "audio/track123.mp3",
expected: "https://d1234567890.cloudfront.net/audio/track123.mp3",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
service := NewCDNService(tt.config)
result := service.GetURL(tt.path)
if result != tt.expected {
t.Errorf("GetURL(%s) = %s, want %s", tt.path, result, tt.expected)
}
})
}
}
func TestCDNService_GetAssetURL(t *testing.T) {
config := CDNConfig{
Provider: CDNProviderCloudFront,
BaseURL: "https://d1234567890.cloudfront.net",
Enabled: true,
Logger: zap.NewNop(),
}
service := NewCDNService(config)
url := service.GetAssetURL("js", "app.js")
expected := "https://d1234567890.cloudfront.net/assets/js/app.js"
if url != expected {
t.Errorf("GetAssetURL() = %s, want %s", url, expected)
}
}
func TestCDNService_GetAudioURL(t *testing.T) {
config := CDNConfig{
Provider: CDNProviderCloudFront,
BaseURL: "https://d1234567890.cloudfront.net",
Enabled: true,
Logger: zap.NewNop(),
}
service := NewCDNService(config)
url := service.GetAudioURL("track-123", "audio.mp3")
expected := "https://d1234567890.cloudfront.net/audio/track-123/audio.mp3"
if url != expected {
t.Errorf("GetAudioURL() = %s, want %s", url, expected)
}
}
func TestCDNService_GetHLSURL(t *testing.T) {
config := CDNConfig{
Provider: CDNProviderCloudFront,
BaseURL: "https://d1234567890.cloudfront.net",
Enabled: true,
Logger: zap.NewNop(),
}
service := NewCDNService(config)
url := service.GetHLSURL("track-123", "master.m3u8")
expected := "https://d1234567890.cloudfront.net/hls/track-123/master.m3u8"
if url != expected {
t.Errorf("GetHLSURL() = %s, want %s", url, expected)
}
}
func TestCDNService_GetImageURL(t *testing.T) {
config := CDNConfig{
Provider: CDNProviderCloudFront,
BaseURL: "https://d1234567890.cloudfront.net",
Enabled: true,
Logger: zap.NewNop(),
}
service := NewCDNService(config)
url := service.GetImageURL("avatars", "user-123.jpg")
expected := "https://d1234567890.cloudfront.net/images/avatars/user-123.jpg"
if url != expected {
t.Errorf("GetImageURL() = %s, want %s", url, expected)
}
}
func TestCDNService_IsEnabled(t *testing.T) {
tests := []struct {
name string
config CDNConfig
expected bool
}{
{
name: "enabled CloudFront",
config: CDNConfig{
Provider: CDNProviderCloudFront,
Enabled: true,
Logger: zap.NewNop(),
},
expected: true,
},
{
name: "disabled",
config: CDNConfig{
Provider: CDNProviderCloudFront,
Enabled: false,
Logger: zap.NewNop(),
},
expected: false,
},
{
name: "none provider",
config: CDNConfig{
Provider: CDNProviderNone,
Enabled: true,
Logger: zap.NewNop(),
},
expected: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
service := NewCDNService(tt.config)
result := service.IsEnabled()
if result != tt.expected {
t.Errorf("IsEnabled() = %v, want %v", result, tt.expected)
}
})
}
}
func TestCDNService_GetProvider(t *testing.T) {
config := CDNConfig{
Provider: CDNProviderCloudflare,
Enabled: true,
Logger: zap.NewNop(),
}
service := NewCDNService(config)
provider := service.GetProvider()
if provider != CDNProviderCloudflare {
t.Errorf("GetProvider() = %v, want %v", provider, CDNProviderCloudflare)
}
}
func TestCDNService_GetBaseURL(t *testing.T) {
expectedURL := "https://d1234567890.cloudfront.net"
config := CDNConfig{
Provider: CDNProviderCloudFront,
BaseURL: expectedURL,
Enabled: true,
Logger: zap.NewNop(),
}
service := NewCDNService(config)
baseURL := service.GetBaseURL()
if baseURL != expectedURL {
t.Errorf("GetBaseURL() = %s, want %s", baseURL, expectedURL)
}
}
func TestCDNService_GetCacheHeaders(t *testing.T) {
tests := []struct {
name string
config CDNConfig
expectedHeader string
}{
{
name: "CloudFront enabled",
config: CDNConfig{
Provider: CDNProviderCloudFront,
Enabled: true,
Logger: zap.NewNop(),
},
expectedHeader: "public, max-age=31536000, immutable",
},
{
name: "Cloudflare enabled",
config: CDNConfig{
Provider: CDNProviderCloudflare,
Enabled: true,
Logger: zap.NewNop(),
},
expectedHeader: "public, max-age=31536000, immutable",
},
{
name: "CDN disabled",
config: CDNConfig{
Provider: CDNProviderCloudFront,
Enabled: false,
Logger: zap.NewNop(),
},
expectedHeader: "no-cache",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
service := NewCDNService(tt.config)
headers := service.GetCacheHeaders()
cacheControl := headers["Cache-Control"]
if cacheControl != tt.expectedHeader {
t.Errorf("GetCacheHeaders() Cache-Control = %s, want %s", cacheControl, tt.expectedHeader)
}
})
}
}
func TestCDNService_InvalidateCache(t *testing.T) {
config := CDNConfig{
Provider: CDNProviderGeneric,
BaseURL: "https://cdn.example.com",
Enabled: true,
Logger: zap.NewNop(),
}
service := NewCDNService(config)
ctx := context.Background()
paths := []string{"/audio/track1.mp3", "/audio/track2.mp3"}
err := service.InvalidateCache(ctx, paths)
if err != nil {
t.Errorf("InvalidateCache() error = %v", err)
}
}
func TestCDNService_BatchInvalidate(t *testing.T) {
config := CDNConfig{
Provider: CDNProviderGeneric,
BaseURL: "https://cdn.example.com",
Enabled: true,
Logger: zap.NewNop(),
}
service := NewCDNService(config)
ctx := context.Background()
paths := make([]string, 25)
for i := 0; i < 25; i++ {
paths[i] = fmt.Sprintf("/audio/track%d.mp3", i)
}
err := service.BatchInvalidate(ctx, paths, 10)
if err != nil {
t.Errorf("BatchInvalidate() error = %v", err)
}
}
func TestCDNService_GenerateSignedURL(t *testing.T) {
config := CDNConfig{
Provider: CDNProviderCloudFront,
BaseURL: "https://d1234567890.cloudfront.net",
Enabled: true,
Logger: zap.NewNop(),
}
service := NewCDNService(config)
url, err := service.GenerateSignedURL("/audio/track123.mp3", time.Hour)
if err != nil {
t.Errorf("GenerateSignedURL() error = %v", err)
}
if url == "" {
t.Error("GenerateSignedURL() returned empty URL")
}
}
// Note: Full integration tests would require:
// 1. Real CDN provider credentials
// 2. Actual CDN distribution/zone
// 3. Verification of cache invalidation
// 4. Testing of signed URL generation
//
// Example integration test structure:
// func TestCDNService_InvalidateCache_Integration(t *testing.T) {
// // Skip if CDN not configured
// if os.Getenv("CDN_ENABLED") != "true" {
// t.Skip("CDN not configured")
// }
//
// config := CDNConfig{
// Provider: CDNProviderCloudFront,
// BaseURL: os.Getenv("CDN_BASE_URL"),
// DistributionID: os.Getenv("CDN_DISTRIBUTION_ID"),
// APIKey: os.Getenv("CDN_API_KEY"),
// Enabled: true,
// Logger: zap.NewNop(),
// }
//
// service := NewCDNService(config)
// ctx := context.Background()
//
// paths := []string{"/test/path1.mp3", "/test/path2.mp3"}
// err := service.InvalidateCache(ctx, paths)
// if err != nil {
// t.Fatalf("InvalidateCache() error = %v", err)
// }
//
// // Verify invalidation was successful (check CDN API)
// }