rekordbox-viewer/test-complete-setup.js
Geert Rademakes 7306bfe32a docs: Add comprehensive testing guide and test script
- Add TESTING_GUIDE.md with step-by-step testing instructions
- Add test-complete-setup.js for automated setup verification
- Cover all aspects: infrastructure, XML import, file upload, matching, playback, export
- Include troubleshooting section and expected results
- Provide verification checklist and success criteria

The testing guide covers 7 phases of testing from basic setup
to advanced features, ensuring complete validation of the
S3 music storage and matching system.
2025-08-06 14:13:45 +02:00

239 lines
7.5 KiB
JavaScript
Executable File
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env node
/**
* Complete S3 Music Storage Test Script
* Tests all aspects of the S3 music storage system
*/
import { S3Client, ListBucketsCommand, HeadBucketCommand } from '@aws-sdk/client-s3';
import { AudioMetadataService } from './packages/backend/src/services/audioMetadataService.js';
const S3_ENDPOINT = process.env.S3_ENDPOINT || 'http://localhost:9000';
const S3_ACCESS_KEY_ID = process.env.S3_ACCESS_KEY_ID || 'minioadmin';
const S3_SECRET_ACCESS_KEY = process.env.S3_SECRET_ACCESS_KEY || 'minioadmin';
const S3_BUCKET_NAME = process.env.S3_BUCKET_NAME || 'music-files';
console.log('🧪 Testing Complete S3 Music Storage Setup\n');
// Test 1: S3 Connection
async function testS3Connection() {
console.log('1⃣ Testing S3 Connection...');
try {
const s3Client = new S3Client({
endpoint: S3_ENDPOINT,
region: 'us-east-1',
credentials: {
accessKeyId: S3_ACCESS_KEY_ID,
secretAccessKey: S3_SECRET_ACCESS_KEY,
},
forcePathStyle: true,
});
// Test connection
await s3Client.send(new ListBucketsCommand({}));
console.log(' ✅ S3 connection successful');
// Test bucket access
await s3Client.send(new HeadBucketCommand({ Bucket: S3_BUCKET_NAME }));
console.log(' ✅ Bucket access verified');
return true;
} catch (error) {
console.log(' ❌ S3 connection failed:', error.message);
return false;
}
}
// Test 2: Audio Metadata Service
async function testAudioMetadataService() {
console.log('\n2⃣ Testing Audio Metadata Service...');
try {
const audioService = new AudioMetadataService();
// Test supported formats
const supportedFormats = ['mp3', 'wav', 'flac', 'm4a', 'aac'];
for (const format of supportedFormats) {
const isSupported = audioService.isAudioFile(`test.${format}`);
console.log(` ${isSupported ? '✅' : '❌'} ${format.toUpperCase()} format: ${isSupported ? 'Supported' : 'Not supported'}`);
}
console.log(' ✅ Audio metadata service initialized');
return true;
} catch (error) {
console.log(' ❌ Audio metadata service failed:', error.message);
return false;
}
}
// Test 3: Environment Variables
function testEnvironmentVariables() {
console.log('\n3⃣ Testing Environment Variables...');
const requiredVars = [
'S3_ENDPOINT',
'S3_ACCESS_KEY_ID',
'S3_SECRET_ACCESS_KEY',
'S3_BUCKET_NAME'
];
let allPresent = true;
for (const varName of requiredVars) {
const value = process.env[varName];
if (value) {
console.log(`${varName}: ${varName.includes('SECRET') ? '***' : value}`);
} else {
console.log(`${varName}: Not set`);
allPresent = false;
}
}
return allPresent;
}
// Test 4: Port Availability
async function testPortAvailability() {
console.log('\n4⃣ Testing Port Availability...');
const ports = [
{ port: 3000, service: 'Backend API' },
{ port: 5173, service: 'Frontend Dev Server' },
{ port: 9000, service: 'MinIO' },
{ port: 27017, service: 'MongoDB' }
];
const net = await import('net');
for (const { port, service } of ports) {
try {
const socket = new net.Socket();
const isAvailable = await new Promise((resolve) => {
socket.setTimeout(1000);
socket.on('connect', () => {
socket.destroy();
resolve(false); // Port is in use
});
socket.on('timeout', () => {
socket.destroy();
resolve(true); // Port is available
});
socket.on('error', () => {
resolve(true); // Port is available
});
socket.connect(port, 'localhost');
});
console.log(` ${isAvailable ? '❌' : '✅'} Port ${port} (${service}): ${isAvailable ? 'Available' : 'In Use'}`);
} catch (error) {
console.log(` ❌ Port ${port} (${service}): Error checking`);
}
}
}
// Test 5: API Endpoints
async function testAPIEndpoints() {
console.log('\n5⃣ Testing API Endpoints...');
const endpoints = [
{ url: 'http://localhost:3000/api/health', name: 'Health Check' },
{ url: 'http://localhost:3000/api/songs', name: 'Songs API' },
{ url: 'http://localhost:3000/api/music/files', name: 'Music Files API' },
{ url: 'http://localhost:3000/api/matching/stats', name: 'Matching Stats API' }
];
for (const { url, name } of endpoints) {
try {
const response = await fetch(url);
const status = response.status;
console.log(` ${status === 200 ? '✅' : '❌'} ${name}: ${status}`);
} catch (error) {
console.log(`${name}: Connection failed`);
}
}
}
// Test 6: Docker Services
async function testDockerServices() {
console.log('\n6⃣ Testing Docker Services...');
try {
const { exec } = await import('child_process');
const { promisify } = await import('util');
const execAsync = promisify(exec);
const { stdout } = await execAsync('docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"');
const lines = stdout.trim().split('\n').slice(1); // Skip header
const expectedServices = ['minio', 'mongodb'];
for (const service of expectedServices) {
const isRunning = lines.some(line => line.includes(service));
console.log(` ${isRunning ? '✅' : '❌'} ${service}: ${isRunning ? 'Running' : 'Not running'}`);
}
return true;
} catch (error) {
console.log(' ❌ Docker check failed:', error.message);
return false;
}
}
// Main test runner
async function runAllTests() {
console.log('🚀 Starting Complete S3 Music Storage Tests\n');
const tests = [
{ name: 'Environment Variables', fn: testEnvironmentVariables },
{ name: 'Docker Services', fn: testDockerServices },
{ name: 'S3 Connection', fn: testS3Connection },
{ name: 'Audio Metadata Service', fn: testAudioMetadataService },
{ name: 'Port Availability', fn: testPortAvailability },
{ name: 'API Endpoints', fn: testAPIEndpoints }
];
const results = [];
for (const test of tests) {
try {
const result = await test.fn();
results.push({ name: test.name, passed: result });
} catch (error) {
console.log(`${test.name} failed with error:`, error.message);
results.push({ name: test.name, passed: false });
}
}
// Summary
console.log('\n📊 Test Summary:');
console.log('================');
const passed = results.filter(r => r.passed).length;
const total = results.length;
for (const result of results) {
console.log(`${result.passed ? '✅' : '❌'} ${result.name}`);
}
console.log(`\n🎯 Overall Result: ${passed}/${total} tests passed`);
if (passed === total) {
console.log('\n🎉 All tests passed! Your S3 music storage system is ready for testing.');
console.log('\n📋 Next steps:');
console.log(' 1. Start backend: cd packages/backend && npm run dev');
console.log(' 2. Start frontend: cd packages/frontend && npm run dev');
console.log(' 3. Open browser: http://localhost:5173');
console.log(' 4. Follow the testing guide: TESTING_GUIDE.md');
} else {
console.log('\n⚠ Some tests failed. Please check the issues above before proceeding.');
console.log('\n🔧 Troubleshooting:');
console.log(' 1. Ensure Docker is running');
console.log(' 2. Start services: docker-compose -f docker-compose.dev.yml up -d');
console.log(' 3. Check environment variables');
console.log(' 4. Install dependencies: npm install in both packages');
}
}
// Run tests
runAllTests().catch(console.error);