- Enhanced AudioMetadataService with comprehensive NaN handling for all numeric fields - Added validation for year, duration, bitrate, sampleRate, and channels - Improved FLAC format detection and error handling with fallback support - Added detailed logging for S3 sync process with progress tracking and file statistics - Enhanced song matching service with progress indicators and confidence scoring - Added comprehensive logging for auto-match and link operations - Improved error handling and graceful degradation for metadata extraction - Added test scripts for metadata service validation - Updated S3 service to use configuration from s3-config.json file - Added automatic S3 service reload when configuration is updated The S3 importer now provides much better visibility into file processing and song matching operations, making it easier to debug issues and monitor performance. FLAC files are properly handled and invalid metadata values are filtered out to prevent database corruption.
105 lines
3.3 KiB
JavaScript
105 lines
3.3 KiB
JavaScript
import { AudioMetadataService } from './src/services/audioMetadataService.js';
|
||
|
||
async function testMetadataService() {
|
||
console.log('🧪 Testing AudioMetadataService...');
|
||
|
||
const audioService = new AudioMetadataService();
|
||
|
||
// Test 1: NaN handling for numeric values
|
||
console.log('\n📊 Testing NaN handling...');
|
||
|
||
const testCases = [
|
||
{ value: 2023, field: 'year', expected: 2023 },
|
||
{ value: NaN, field: 'year', expected: undefined },
|
||
{ value: 'invalid', field: 'year', expected: undefined },
|
||
{ value: 300, field: 'duration', expected: 300 },
|
||
{ value: -1, field: 'duration', expected: undefined },
|
||
{ value: 320000, field: 'bitrate', expected: 320000 },
|
||
{ value: 44100, field: 'sampleRate', expected: 44100 },
|
||
{ value: 2, field: 'channels', expected: 2 },
|
||
{ value: 10, field: 'channels', expected: undefined }, // Too many channels
|
||
{ value: 1800, field: 'year', expected: undefined }, // Too old
|
||
{ value: 2030, field: 'year', expected: undefined }, // Too future
|
||
];
|
||
|
||
for (const testCase of testCases) {
|
||
const result = audioService['sanitizeNumericValue'](testCase.value, testCase.field);
|
||
const status = result === testCase.expected ? '✅' : '❌';
|
||
console.log(`${status} ${testCase.field}: ${testCase.value} -> ${result} (expected: ${testCase.expected})`);
|
||
}
|
||
|
||
// Test 2: Audio file format detection
|
||
console.log('\n🎵 Testing audio file format detection...');
|
||
|
||
const audioFiles = [
|
||
'song.mp3',
|
||
'track.wav',
|
||
'music.flac',
|
||
'audio.aac',
|
||
'sound.ogg',
|
||
'file.m4a',
|
||
'test.txt',
|
||
'image.jpg',
|
||
'document.pdf'
|
||
];
|
||
|
||
for (const file of audioFiles) {
|
||
const isAudio = audioService.isAudioFile(file);
|
||
const status = isAudio ? '✅' : '❌';
|
||
console.log(`${status} ${file}: ${isAudio ? 'Audio' : 'Not audio'}`);
|
||
}
|
||
|
||
// Test 3: Format mapping
|
||
console.log('\n📋 Testing format mapping...');
|
||
|
||
const formatTests = [
|
||
{ container: 'MPEG', fileName: 'song.mp3', expected: 'MP3' },
|
||
{ container: 'FLAC', fileName: 'track.flac', expected: 'FLAC' },
|
||
{ container: 'WAVE', fileName: 'music.wav', expected: 'WAV' },
|
||
{ container: 'unknown', fileName: 'audio.ogg', expected: 'OGG' },
|
||
{ container: 'unknown', fileName: 'file.xyz', expected: 'UNKNOWN' }
|
||
];
|
||
|
||
for (const test of formatTests) {
|
||
const result = audioService['mapFormatToDisplayName'](test.container, test.fileName);
|
||
const status = result === test.expected ? '✅' : '❌';
|
||
console.log(`${status} ${test.container} + ${test.fileName} -> ${result} (expected: ${test.expected})`);
|
||
}
|
||
|
||
// Test 4: File size formatting
|
||
console.log('\n📏 Testing file size formatting...');
|
||
|
||
const sizeTests = [
|
||
0,
|
||
1024,
|
||
1048576,
|
||
1073741824,
|
||
1099511627776
|
||
];
|
||
|
||
for (const size of sizeTests) {
|
||
const formatted = audioService.formatFileSize(size);
|
||
console.log(`📄 ${size} bytes -> ${formatted}`);
|
||
}
|
||
|
||
// Test 5: Duration formatting
|
||
console.log('\n⏱️ Testing duration formatting...');
|
||
|
||
const durationTests = [
|
||
0,
|
||
61,
|
||
125.5,
|
||
3600,
|
||
NaN,
|
||
null
|
||
];
|
||
|
||
for (const duration of durationTests) {
|
||
const formatted = audioService.formatDuration(duration);
|
||
console.log(`⏱️ ${duration} seconds -> ${formatted}`);
|
||
}
|
||
|
||
console.log('\n🎉 AudioMetadataService tests completed!');
|
||
}
|
||
|
||
testMetadataService().catch(console.error);
|