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

331 lines
9.4 KiB
Go
Raw Normal View History

2025-12-03 19:29:37 +00:00
package services
import (
"bytes"
"mime/multipart"
"net/http"
"testing"
"github.com/stretchr/testify/assert"
)
// createTestAudioFileHeader crée un FileHeader pour les tests
func createTestAudioFileHeader(filename string, data []byte) *multipart.FileHeader {
body := new(bytes.Buffer)
writer := multipart.NewWriter(body)
part, err := writer.CreateFormFile("file", filename)
if err != nil {
return nil
}
if _, err := part.Write(data); err != nil {
return nil
}
writer.Close()
req, err := http.NewRequest("POST", "/test", body)
if err != nil {
return nil
}
req.Header.Set("Content-Type", writer.FormDataContentType())
// Parse multipart form
if err := req.ParseMultipartForm(10 << 20); err != nil {
return nil
}
formFile := req.MultipartForm.File["file"]
if len(formFile) == 0 {
return nil
}
return formFile[0]
}
func TestTrackValidationService_ValidateFormat_MP3(t *testing.T) {
service := NewTrackValidationService()
// MP3 avec ID3v2
mp3Data := []byte{'I', 'D', '3', 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
fileHeader := createTestAudioFileHeader("test.mp3", mp3Data)
assert.NotNil(t, fileHeader)
err := service.ValidateFormat(fileHeader)
assert.NoError(t, err)
}
func TestTrackValidationService_ValidateFormat_MP3_MPEG(t *testing.T) {
service := NewTrackValidationService()
// MP3 avec MPEG frame sync
mp3Data := []byte{0xFF, 0xFB, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
fileHeader := createTestAudioFileHeader("test.mp3", mp3Data)
assert.NotNil(t, fileHeader)
err := service.ValidateFormat(fileHeader)
assert.NoError(t, err)
}
func TestTrackValidationService_ValidateFormat_FLAC(t *testing.T) {
service := NewTrackValidationService()
// FLAC
flacData := []byte{'f', 'L', 'a', 'C', 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00}
fileHeader := createTestAudioFileHeader("test.flac", flacData)
assert.NotNil(t, fileHeader)
err := service.ValidateFormat(fileHeader)
assert.NoError(t, err)
}
func TestTrackValidationService_ValidateFormat_WAV(t *testing.T) {
service := NewTrackValidationService()
// WAV
wavData := []byte{'R', 'I', 'F', 'F', 0x00, 0x00, 0x00, 0x00, 'W', 'A', 'V', 'E'}
fileHeader := createTestAudioFileHeader("test.wav", wavData)
assert.NotNil(t, fileHeader)
err := service.ValidateFormat(fileHeader)
assert.NoError(t, err)
}
func TestTrackValidationService_ValidateFormat_OGG(t *testing.T) {
service := NewTrackValidationService()
// OGG
oggData := []byte{'O', 'g', 'g', 'S', 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
fileHeader := createTestAudioFileHeader("test.ogg", oggData)
assert.NotNil(t, fileHeader)
err := service.ValidateFormat(fileHeader)
assert.NoError(t, err)
}
func TestTrackValidationService_ValidateFormat_Invalid(t *testing.T) {
service := NewTrackValidationService()
// Fichier invalide
invalidData := []byte("not an audio file")
fileHeader := createTestAudioFileHeader("test.txt", invalidData)
assert.NotNil(t, fileHeader)
err := service.ValidateFormat(fileHeader)
assert.Error(t, err)
assert.Contains(t, err.Error(), "invalid audio file format")
}
func TestTrackValidationService_ValidateFileSize_Valid(t *testing.T) {
service := NewTrackValidationService()
data := make([]byte, 10*1024*1024) // 10MB
fileHeader := createTestAudioFileHeader("test.mp3", data)
assert.NotNil(t, fileHeader)
err := service.ValidateFileSize(fileHeader)
assert.NoError(t, err)
}
func TestTrackValidationService_ValidateFileSize_TooLarge(t *testing.T) {
service := NewTrackValidationService()
data := make([]byte, 101*1024*1024) // 101MB
fileHeader := createTestAudioFileHeader("test.mp3", data)
assert.NotNil(t, fileHeader)
err := service.ValidateFileSize(fileHeader)
assert.Error(t, err)
assert.Contains(t, err.Error(), "file size exceeds maximum")
}
func TestTrackValidationService_ValidateFileSize_Empty(t *testing.T) {
service := NewTrackValidationService()
data := []byte{}
fileHeader := createTestAudioFileHeader("test.mp3", data)
assert.NotNil(t, fileHeader)
err := service.ValidateFileSize(fileHeader)
assert.Error(t, err)
assert.Contains(t, err.Error(), "file is empty")
}
func TestTrackValidationService_ValidateDuration_Valid(t *testing.T) {
service := NewTrackValidationService()
// Durée valide (30 secondes)
err := service.ValidateDuration(30)
assert.NoError(t, err)
// Durée valide (1 seconde - minimum)
err = service.ValidateDuration(1)
assert.NoError(t, err)
// Durée valide (3 heures - maximum)
err = service.ValidateDuration(MaxTrackDuration)
assert.NoError(t, err)
}
func TestTrackValidationService_ValidateDuration_TooShort(t *testing.T) {
service := NewTrackValidationService()
// Durée trop courte
err := service.ValidateDuration(0)
assert.Error(t, err)
assert.Contains(t, err.Error(), "too short")
}
func TestTrackValidationService_ValidateDuration_TooLong(t *testing.T) {
service := NewTrackValidationService()
// Durée trop longue
err := service.ValidateDuration(MaxTrackDuration + 1)
assert.Error(t, err)
assert.Contains(t, err.Error(), "too long")
}
func TestTrackValidationService_ValidateCodec_Valid(t *testing.T) {
service := NewTrackValidationService()
validCodecs := []string{"mp3", "MP3", "flac", "FLAC", "pcm", "vorbis", "aac", "AAC"}
for _, codec := range validCodecs {
err := service.ValidateCodec(codec)
assert.NoError(t, err, "codec %s should be valid", codec)
}
}
func TestTrackValidationService_ValidateCodec_Invalid(t *testing.T) {
service := NewTrackValidationService()
// Codec invalide
err := service.ValidateCodec("invalid_codec")
assert.Error(t, err)
assert.Contains(t, err.Error(), "unsupported codec")
}
func TestTrackValidationService_ValidateCodec_Empty(t *testing.T) {
service := NewTrackValidationService()
// Codec vide
err := service.ValidateCodec("")
assert.Error(t, err)
assert.Contains(t, err.Error(), "codec is required")
}
func TestTrackValidationService_ValidateTrackFile_Success(t *testing.T) {
service := NewTrackValidationService()
// Créer un fichier MP3 valide
mp3Data := []byte{'I', 'D', '3', 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
fileHeader := createTestAudioFileHeader("test.mp3", mp3Data)
assert.NotNil(t, fileHeader)
result, err := service.ValidateTrackFile(fileHeader, 180, "mp3")
assert.NoError(t, err)
assert.NotNil(t, result)
assert.True(t, result.Valid)
assert.Equal(t, "mp3", result.Codec)
assert.Equal(t, 180, result.Duration)
}
func TestTrackValidationService_ValidateTrackFile_InvalidFormat(t *testing.T) {
service := NewTrackValidationService()
// Fichier invalide
invalidData := []byte("not an audio file")
fileHeader := createTestAudioFileHeader("test.txt", invalidData)
assert.NotNil(t, fileHeader)
result, err := service.ValidateTrackFile(fileHeader, 180, "mp3")
assert.Error(t, err)
assert.NotNil(t, result)
assert.False(t, result.Valid)
assert.NotEmpty(t, result.Errors)
}
func TestTrackValidationService_ValidateTrackFile_InvalidSize(t *testing.T) {
service := NewTrackValidationService()
// Fichier trop grand
largeData := make([]byte, 101*1024*1024) // 101MB
fileHeader := createTestAudioFileHeader("test.mp3", largeData)
assert.NotNil(t, fileHeader)
result, err := service.ValidateTrackFile(fileHeader, 180, "mp3")
assert.Error(t, err)
assert.NotNil(t, result)
assert.False(t, result.Valid)
}
func TestTrackValidationService_ValidateTrackFile_InvalidDuration(t *testing.T) {
service := NewTrackValidationService()
// Fichier valide mais durée invalide
mp3Data := []byte{'I', 'D', '3', 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
fileHeader := createTestAudioFileHeader("test.mp3", mp3Data)
assert.NotNil(t, fileHeader)
// Durée trop longue
result, err := service.ValidateTrackFile(fileHeader, MaxTrackDuration+1, "mp3")
assert.Error(t, err)
assert.NotNil(t, result)
assert.False(t, result.Valid)
// Durée trop courte (0) est ignorée par ValidateTrackFile (considérée comme non fournie)
// Donc on ne teste pas le cas 0 ici qui retourne valide par design (optionalité)
2025-12-03 19:29:37 +00:00
}
func TestTrackValidationService_ValidateTrackFile_InvalidCodec(t *testing.T) {
service := NewTrackValidationService()
// Fichier valide mais codec invalide
mp3Data := []byte{'I', 'D', '3', 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
fileHeader := createTestAudioFileHeader("test.mp3", mp3Data)
assert.NotNil(t, fileHeader)
result, err := service.ValidateTrackFile(fileHeader, 180, "invalid_codec")
assert.Error(t, err)
assert.NotNil(t, result)
assert.False(t, result.Valid)
}
func TestTrackValidationService_DetectFormat(t *testing.T) {
service := NewTrackValidationService()
tests := []struct {
name string
data []byte
expected string
}{
{
name: "MP3 ID3v2",
data: []byte{'I', 'D', '3', 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
expected: "audio/mpeg",
},
{
name: "FLAC",
data: []byte{'f', 'L', 'a', 'C', 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00},
expected: "audio/flac",
},
{
name: "WAV",
data: []byte{'R', 'I', 'F', 'F', 0x00, 0x00, 0x00, 0x00, 'W', 'A', 'V', 'E'},
expected: "audio/wav",
},
{
name: "OGG",
data: []byte{'O', 'g', 'g', 'S', 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
expected: "audio/ogg",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
fileHeader := createTestAudioFileHeader("test."+tt.name, tt.data)
assert.NotNil(t, fileHeader)
format := service.detectFormat(fileHeader)
assert.Equal(t, tt.expected, format)
})
}
}