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

330 lines
7.3 KiB
Go

package services
import (
"testing"
"time"
"go.uber.org/zap"
)
func TestNewAudioTranscodeService(t *testing.T) {
logger := zap.NewNop()
service := NewAudioTranscodeService("", logger)
if service == nil {
t.Error("NewAudioTranscodeService() returned nil")
}
if service.logger == nil {
t.Error("NewAudioTranscodeService() returned service with nil logger")
}
if service.ffmpegPath == "" {
t.Error("NewAudioTranscodeService() should set default ffmpeg path")
}
}
func TestAudioTranscodeService_GetSupportedFormats(t *testing.T) {
service := NewAudioTranscodeService("", zap.NewNop())
formats := service.GetSupportedFormats()
if len(formats) == 0 {
t.Error("GetSupportedFormats() returned empty list")
}
// Check that common formats are included
expectedFormats := []AudioFormat{FormatMP3, FormatAAC, FormatFLAC, FormatOGG, FormatWAV}
for _, expected := range expectedFormats {
found := false
for _, format := range formats {
if format == expected {
found = true
break
}
}
if !found {
t.Errorf("GetSupportedFormats() missing format: %s", expected)
}
}
}
func TestAudioTranscodeService_ValidateFormat(t *testing.T) {
service := NewAudioTranscodeService("", zap.NewNop())
tests := []struct {
name string
format AudioFormat
expected bool
}{
{
name: "valid MP3 format",
format: FormatMP3,
expected: true,
},
{
name: "valid AAC format",
format: FormatAAC,
expected: true,
},
{
name: "valid FLAC format",
format: FormatFLAC,
expected: true,
},
{
name: "invalid format",
format: AudioFormat("invalid"),
expected: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := service.ValidateFormat(tt.format)
if result != tt.expected {
t.Errorf("ValidateFormat(%s) = %v, want %v", tt.format, result, tt.expected)
}
})
}
}
func TestAudioTranscodeService_getCodecForFormat(t *testing.T) {
service := NewAudioTranscodeService("", zap.NewNop())
tests := []struct {
name string
format AudioFormat
expected string
}{
{
name: "MP3 codec",
format: FormatMP3,
expected: "libmp3lame",
},
{
name: "AAC codec",
format: FormatAAC,
expected: "aac",
},
{
name: "FLAC codec",
format: FormatFLAC,
expected: "flac",
},
{
name: "OGG codec",
format: FormatOGG,
expected: "libvorbis",
},
{
name: "WAV codec",
format: FormatWAV,
expected: "pcm_s16le",
},
{
name: "M4A codec",
format: FormatM4A,
expected: "aac",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := service.getCodecForFormat(tt.format)
if result != tt.expected {
t.Errorf("getCodecForFormat(%s) = %s, want %s", tt.format, result, tt.expected)
}
})
}
}
func TestAudioTranscodeService_getBitrateForQuality(t *testing.T) {
service := NewAudioTranscodeService("", zap.NewNop())
tests := []struct {
name string
quality AudioQuality
format AudioFormat
expected int
}{
{
name: "low quality MP3",
quality: QualityLow,
format: FormatMP3,
expected: 96,
},
{
name: "low quality AAC",
quality: QualityLow,
format: FormatAAC,
expected: 64,
},
{
name: "medium quality MP3",
quality: QualityMedium,
format: FormatMP3,
expected: 192,
},
{
name: "medium quality AAC",
quality: QualityMedium,
format: FormatAAC,
expected: 128,
},
{
name: "high quality MP3",
quality: QualityHigh,
format: FormatMP3,
expected: 320,
},
{
name: "high quality AAC",
quality: QualityHigh,
format: FormatAAC,
expected: 256,
},
{
name: "lossless FLAC",
quality: QualityLossless,
format: FormatFLAC,
expected: 0,
},
{
name: "lossless WAV",
quality: QualityLossless,
format: FormatWAV,
expected: 0,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := service.getBitrateForQuality(tt.quality, tt.format)
if result != tt.expected {
t.Errorf("getBitrateForQuality(%s, %s) = %d, want %d", tt.quality, tt.format, result, tt.expected)
}
})
}
}
func TestTranscodeOptions_Defaults(t *testing.T) {
options := TranscodeOptions{}
// Test that defaults are applied in Transcode method
if options.Format == "" {
options.Format = FormatMP3
}
if options.Timeout == 0 {
options.Timeout = 5 * time.Minute
}
if options.Format != FormatMP3 {
t.Errorf("Expected default format MP3, got %v", options.Format)
}
if options.Timeout != 5*time.Minute {
t.Errorf("Expected default timeout 5 minutes, got %v", options.Timeout)
}
}
func TestAudioTranscodeService_buildFFmpegArgs(t *testing.T) {
service := NewAudioTranscodeService("", zap.NewNop())
tests := []struct {
name string
input string
output string
options TranscodeOptions
bitrate int
checkFn func([]string) bool
}{
{
name: "MP3 with bitrate",
input: "input.mp3",
output: "output.mp3",
options: TranscodeOptions{
Format: FormatMP3,
},
bitrate: 192,
checkFn: func(args []string) bool {
hasCodec := false
hasBitrate := false
for i, arg := range args {
if arg == "-codec:a" && i+1 < len(args) && args[i+1] == "libmp3lame" {
hasCodec = true
}
if arg == "-b:a" && i+1 < len(args) && args[i+1] == "192k" {
hasBitrate = true
}
}
return hasCodec && hasBitrate
},
},
{
name: "FLAC with compression",
input: "input.wav",
output: "output.flac",
options: TranscodeOptions{
Format: FormatFLAC,
},
bitrate: 0,
checkFn: func(args []string) bool {
hasCodec := false
hasCompression := false
for i, arg := range args {
if arg == "-codec:a" && i+1 < len(args) && args[i+1] == "flac" {
hasCodec = true
}
if arg == "-compression_level" && i+1 < len(args) && args[i+1] == "5" {
hasCompression = true
}
}
return hasCodec && hasCompression
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
args := service.buildFFmpegArgs(tt.input, tt.output, tt.options, tt.bitrate)
if !tt.checkFn(args) {
t.Errorf("buildFFmpegArgs() did not produce expected arguments")
}
})
}
}
// Note: Full integration tests would require:
// 1. FFmpeg installed on the system
// 2. Test audio files (MP3, WAV, FLAC, etc.)
// 3. Verification of transcoded output files
// 4. Performance testing with large files
//
// Example integration test structure:
// func TestAudioTranscodeService_Transcode_Integration(t *testing.T) {
// // Skip if FFmpeg not available
// service := NewAudioTranscodeService("", zap.NewNop())
// ctx := context.Background()
// if !service.IsFFmpegAvailable(ctx) {
// t.Skip("FFmpeg not available")
// }
//
// // Create test audio file
// testFile := createTestAudioFile(t)
// defer os.Remove(testFile)
//
// options := TranscodeOptions{
// Format: FormatMP3,
// Quality: QualityMedium,
// }
//
// result, err := service.Transcode(ctx, testFile, options)
// if err != nil {
// t.Fatalf("Transcode() error = %v", err)
// }
//
// if result.Format != FormatMP3 {
// t.Errorf("Transcode() format = %v, want %v", result.Format, FormatMP3)
// }
//
// if result.FileSize == 0 {
// t.Error("Transcode() produced empty file")
// }
// }