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

169 lines
4.3 KiB
Go

package services
import (
"testing"
"time"
"go.uber.org/zap"
)
func TestNewS3StorageService(t *testing.T) {
tests := []struct {
name string
cfg S3Config
wantErr bool
}{
{
name: "valid config with bucket",
cfg: S3Config{
Bucket: "test-bucket",
Region: "us-east-1",
Logger: zap.NewNop(),
},
wantErr: false,
},
{
name: "missing bucket",
cfg: S3Config{
Region: "us-east-1",
Logger: zap.NewNop(),
},
wantErr: true,
},
{
name: "default region",
cfg: S3Config{
Bucket: "test-bucket",
Logger: zap.NewNop(),
},
wantErr: false,
},
{
name: "with custom endpoint",
cfg: S3Config{
Bucket: "test-bucket",
Region: "us-east-1",
Endpoint: "http://localhost:9000",
Logger: zap.NewNop(),
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Note: Ces tests ne peuvent pas réellement se connecter à S3 sans credentials
// Ils testent principalement la validation de configuration
// Pour des tests d'intégration réels, il faudrait utiliser un mock ou un service local comme MinIO
service, err := NewS3StorageService(tt.cfg)
if (err != nil) != tt.wantErr {
t.Errorf("NewS3StorageService() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !tt.wantErr && service == nil {
t.Error("NewS3StorageService() returned nil service without error")
}
})
}
}
func TestS3StorageService_GetPublicURL(t *testing.T) {
tests := []struct {
name string
service *S3StorageService
key string
expected string
}{
{
name: "AWS S3 standard URL",
service: &S3StorageService{
bucket: "test-bucket",
region: "us-east-1",
endpoint: "",
},
key: "tracks/user123/track456/file.mp3",
expected: "https://test-bucket.s3.us-east-1.amazonaws.com/tracks/user123/track456/file.mp3",
},
{
name: "MinIO custom endpoint URL",
service: &S3StorageService{
bucket: "test-bucket",
region: "us-east-1",
endpoint: "http://localhost:9000",
},
key: "tracks/user123/track456/file.mp3",
expected: "http://localhost:9000/test-bucket/tracks/user123/track456/file.mp3",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
url := tt.service.GetPublicURL(tt.key)
if url != tt.expected {
t.Errorf("GetPublicURL() = %v, want %v", url, tt.expected)
}
})
}
}
func TestS3Config_Defaults(t *testing.T) {
cfg := S3Config{
Bucket: "test-bucket",
Logger: zap.NewNop(),
}
service, err := NewS3StorageService(cfg)
if err == nil {
// Si le service est créé, vérifier les valeurs par défaut
if service.region != "us-east-1" {
t.Errorf("Expected default region 'us-east-1', got %s", service.region)
}
if service.urlExpiry != time.Hour {
t.Errorf("Expected default URL expiry 1h, got %v", service.urlExpiry)
}
}
// Note: Le service peut échouer si le bucket n'existe pas, ce qui est normal
_ = err
}
// TestS3StorageService_InterfaceCompliance vérifie que S3StorageService implémente bien l'interface S3Service
func TestS3StorageService_InterfaceCompliance(t *testing.T) {
var _ S3Service = (*S3StorageService)(nil)
}
// Note: Les tests d'intégration réels nécessiteraient:
// 1. Un service S3 local (MinIO) ou des credentials AWS de test
// 2. Des mocks pour le client S3
// 3. Un contexte de test avec timeout
//
// Exemple de test d'intégration (à implémenter avec MinIO):
// func TestS3StorageService_UploadFile_Integration(t *testing.T) {
// cfg := S3Config{
// Bucket: "test-bucket",
// Region: "us-east-1",
// Endpoint: "http://localhost:9000", // MinIO
// AccessKey: "minioadmin",
// SecretKey: "minioadmin",
// Logger: zap.NewNop(),
// }
// service, err := NewS3StorageService(cfg)
// if err != nil {
// t.Skip("S3 service not available for integration test")
// return
// }
//
// ctx := context.Background()
// testData := []byte("test file content")
// key := "test/key.txt"
//
// url, err := service.UploadFile(ctx, testData, key, "text/plain")
// if err != nil {
// t.Fatalf("UploadFile() error = %v", err)
// }
// if url == "" {
// t.Error("UploadFile() returned empty URL")
// }
//
// // Cleanup
// defer service.DeleteFile(ctx, key)
// }