training-academy/test-library-manager.html

610 lines
21 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Library Manager Test Suite</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: #1a1a1a;
color: #e0e0e0;
padding: 20px;
line-height: 1.6;
}
.container {
max-width: 1400px;
margin: 0 auto;
}
h1 {
text-align: center;
color: #ff006e;
margin-bottom: 30px;
font-size: 2.5em;
}
.test-section {
background: #2a2a2a;
border-radius: 10px;
padding: 20px;
margin-bottom: 20px;
}
.test-section h2 {
color: #8338ec;
margin-bottom: 15px;
font-size: 1.5em;
}
.test-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 10px;
margin-bottom: 20px;
}
.test-result {
padding: 15px;
border-radius: 8px;
background: #1a1a1a;
border-left: 4px solid #666;
}
.test-result.pass {
border-left-color: #00ff88;
background: rgba(0, 255, 136, 0.1);
}
.test-result.fail {
border-left-color: #ff006e;
background: rgba(255, 0, 110, 0.1);
}
.test-result h3 {
font-size: 1em;
margin-bottom: 5px;
}
.test-result.pass h3 { color: #00ff88; }
.test-result.fail h3 { color: #ff006e; }
.test-result p {
font-size: 0.9em;
color: #aaa;
}
.button-group {
display: flex;
gap: 10px;
flex-wrap: wrap;
margin-bottom: 20px;
}
button {
padding: 12px 24px;
border: none;
border-radius: 8px;
background: linear-gradient(135deg, #ff006e, #8338ec);
color: white;
font-weight: bold;
cursor: pointer;
transition: transform 0.2s;
}
button:hover {
transform: translateY(-2px);
}
button:active {
transform: translateY(0);
}
.status-box {
padding: 15px;
border-radius: 8px;
margin-bottom: 20px;
font-family: 'Courier New', monospace;
font-size: 0.9em;
}
.status-box.success {
background: rgba(0, 255, 136, 0.1);
border: 1px solid #00ff88;
color: #00ff88;
}
.status-box.error {
background: rgba(255, 0, 110, 0.1);
border: 1px solid #ff006e;
color: #ff006e;
}
.status-box.info {
background: rgba(131, 56, 236, 0.1);
border: 1px solid #8338ec;
color: #8338ec;
}
.json-display {
background: #0a0a0a;
padding: 15px;
border-radius: 8px;
overflow-x: auto;
white-space: pre-wrap;
word-wrap: break-word;
font-family: 'Courier New', monospace;
font-size: 0.85em;
max-height: 400px;
overflow-y: auto;
}
.media-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 15px;
margin-top: 15px;
}
.media-card {
background: #1a1a1a;
border-radius: 8px;
padding: 15px;
border: 1px solid #333;
}
.media-card h4 {
color: #ff006e;
font-size: 0.9em;
margin-bottom: 10px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.tag-list {
display: flex;
flex-wrap: wrap;
gap: 5px;
margin: 10px 0;
}
.tag {
background: rgba(131, 56, 236, 0.3);
padding: 3px 8px;
border-radius: 4px;
font-size: 0.75em;
color: #8338ec;
}
.rating {
color: #ffb700;
font-size: 0.9em;
}
</style>
</head>
<body>
<div class="container">
<h1>📚 Library Manager Test Suite</h1>
<!-- Automated Tests Section -->
<div class="test-section">
<h2>Automated Tests</h2>
<button onclick="runAllTests()">🧪 Run All Tests</button>
<div id="test-results" class="test-grid"></div>
</div>
<!-- Manual Testing Section -->
<div class="test-section">
<h2>Manual Testing</h2>
<div class="button-group">
<button onclick="syncWithLibrary()">🔄 Sync with Existing Library</button>
<button onclick="addSampleMedia()"> Add Sample Media (Test Only)</button>
<button onclick="testBulkTagging()">🏷️ Test Bulk Tagging</button>
<button onclick="testSearch()">🔍 Test Search</button>
<button onclick="testRatings()">⭐ Test Ratings</button>
<button onclick="testCollections()">📁 Test Collections</button>
<button onclick="showStats()">📈 Show Stats</button>
<button onclick="showAllMedia()">📚 Show All Media</button>
<button onclick="resetLibrary()">🔄 Reset Library</button>
</div>
<div id="manual-output"></div>
</div>
<!-- Library Display -->
<div class="test-section">
<h2>Current Library State</h2>
<div id="library-display" class="json-display"></div>
</div>
</div>
<!-- Load Dependencies -->
<script src="src/data/gameData.js"></script>
<script src="src/features/academy/libraryManager.js"></script>
<script>
// Test runner
function runAllTests() {
const tests = [
testInitialization,
testAddMedia,
testTagging,
testBulkTagging,
testRating,
testFavorites,
testSearch,
testCollections,
testStats,
testPersistence
];
const resultsDiv = document.getElementById('test-results');
resultsDiv.innerHTML = '';
tests.forEach(test => {
const result = test();
const resultDiv = document.createElement('div');
resultDiv.className = `test-result ${result.pass ? 'pass' : 'fail'}`;
resultDiv.innerHTML = `
<h3>${result.pass ? '✓' : '✗'} ${result.name}</h3>
<p>${result.message}</p>
`;
resultsDiv.appendChild(resultDiv);
});
}
// Test 1: Initialization
function testInitialization() {
const library = window.libraryManager.getLibrary();
const hasRequiredFields = library.media && library.tags && library.collections;
return {
name: 'Initialization Test',
pass: hasRequiredFields && library.version === 1,
message: hasRequiredFields ? 'Library initialized with all required structures' : 'Missing fields'
};
}
// Test 2: Add Media
function testAddMedia() {
const success = window.libraryManager.addMediaItem('assets/test/video1.mp4', {
tags: ['edging', 'pov', 'hd'],
rating: 4
});
const library = window.libraryManager.getLibrary();
const item = library.media['assets/test/video1.mp4'];
return {
name: 'Add Media Test',
pass: success && item && item.tags.length === 3,
message: success ? 'Media item added with tags and rating' : 'Failed to add media'
};
}
// Test 3: Tagging
function testTagging() {
window.libraryManager.addMediaItem('assets/test/video2.mp4');
window.libraryManager.addTags('assets/test/video2.mp4', ['femdom', 'worship']);
const library = window.libraryManager.getLibrary();
const item = library.media['assets/test/video2.mp4'];
return {
name: 'Tagging Test',
pass: item.tags.includes('femdom') && item.tags.includes('worship'),
message: 'Tags added successfully'
};
}
// Test 4: Bulk Tagging
function testBulkTagging() {
const files = ['assets/test/video3.mp4', 'assets/test/video4.mp4', 'assets/test/video5.mp4'];
const result = window.libraryManager.bulkAddTags(files, ['compilation', 'pmv']);
return {
name: 'Bulk Tagging Test',
pass: result.filesTagged === 3,
message: `Bulk tagged ${result.filesTagged} files with ${result.tags.length} tags`
};
}
// Test 5: Rating
function testRating() {
window.libraryManager.setRating('assets/test/video1.mp4', 5);
const library = window.libraryManager.getLibrary();
const rating = library.media['assets/test/video1.mp4'].rating;
return {
name: 'Rating Test',
pass: rating === 5,
message: `Rating set to ${rating}/5`
};
}
// Test 6: Favorites
function testFavorites() {
window.libraryManager.addToFavorites('assets/test/video1.mp4');
const library = window.libraryManager.getLibrary();
return {
name: 'Favorites Test',
pass: library.favorites.includes('assets/test/video1.mp4'),
message: 'Item added to favorites'
};
}
// Test 7: Search
function testSearch() {
const results = window.libraryManager.searchMedia({
anyTags: ['edging', 'femdom'],
minRating: 3
});
return {
name: 'Search Test',
pass: results.length > 0,
message: `Found ${results.length} items matching search criteria`
};
}
// Test 8: Collections
function testCollections() {
window.libraryManager.createCollection('My Playlist', [
'assets/test/video1.mp4',
'assets/test/video2.mp4'
]);
const items = window.libraryManager.getCollection('My Playlist');
return {
name: 'Collections Test',
pass: items.length === 2,
message: `Collection created with ${items.length} items`
};
}
// Test 9: Stats
function testStats() {
const stats = window.libraryManager.getLibraryStats();
return {
name: 'Statistics Test',
pass: stats.totalItems > 0 && stats.hasOwnProperty('averageRating'),
message: `${stats.totalItems} items, ${stats.taggedItems} tagged, avg rating ${stats.averageRating}`
};
}
// Test 10: Persistence
function testPersistence() {
window.libraryManager.addMediaItem('assets/test/persistence.mp4', { rating: 3 });
const savedData = JSON.parse(localStorage.getItem('webGame-data'));
const exists = savedData.academyLibrary.media['assets/test/persistence.mp4'] !== undefined;
return {
name: 'Persistence Test',
pass: exists,
message: exists ? 'Library persists to localStorage' : 'Persistence failed'
};
}
// Manual testing functions
function syncWithLibrary() {
const result = window.libraryManager.syncWithExistingLibrary();
const outputDiv = document.getElementById('manual-output');
outputDiv.innerHTML = `<div class="status-box success">
✅ Synced with existing library:<br>
- Total videos: ${result.total}<br>
- New videos: ${result.new}<br>
- Existing videos: ${result.existing}
</div>`;
// Show the media
showAllMedia();
}
function addSampleMedia() {
const sampleFiles = [
{ path: 'assets/pornstars/riley-reid-1.mp4', tags: ['solo', 'pov', 'professional'], rating: 5 },
{ path: 'assets/pornstars/mia-khalifa-2.mp4', tags: ['group', 'hd', 'hardcore'], rating: 4 },
{ path: 'assets/feet/footjob-1.mp4', tags: ['feet', 'pov', 'fetish'], rating: 4 },
{ path: 'assets/hentai/anime-1.mp4', tags: ['hentai', 'animated', 'mindbreak'], rating: 3 },
{ path: 'assets/BBC/interracial-1.mp4', tags: ['bbc', 'couples', 'intense'], rating: 5 }
];
sampleFiles.forEach(file => {
window.libraryManager.addMediaItem(file.path, {
tags: file.tags,
rating: file.rating
});
});
const outputDiv = document.getElementById('manual-output');
outputDiv.innerHTML = `<div class="status-box success">
Added ${sampleFiles.length} sample media items to library
</div>`;
showAllMedia();
}
function testBulkTagging() {
const library = window.libraryManager.getLibrary();
const allFiles = Object.keys(library.media);
if (allFiles.length === 0) {
const outputDiv = document.getElementById('manual-output');
outputDiv.innerHTML = `<div class="status-box error">No media in library. Add sample media first.</div>`;
return;
}
const result = window.libraryManager.bulkAddTags(allFiles.slice(0, 3), ['test-tag', 'bulk-tagged']);
const outputDiv = document.getElementById('manual-output');
outputDiv.innerHTML = `<div class="status-box success">
Bulk tagged ${result.filesTagged} files with tags: ${result.tags.join(', ')}
</div>`;
}
function testSearch() {
const results = window.libraryManager.searchMedia({
anyTags: ['pov', 'solo'],
minRating: 3,
sortBy: 'rating',
limit: 5
});
const outputDiv = document.getElementById('manual-output');
if (results.length === 0) {
outputDiv.innerHTML = `<div class="status-box error">No results found. Add sample media first.</div>`;
return;
}
let html = `<div class="status-box success">Found ${results.length} items</div>`;
html += '<div class="media-grid">';
results.forEach(item => {
html += `
<div class="media-card">
<h4>${item.filePath.split('/').pop()}</h4>
<div class="rating">⭐ ${item.rating}/5</div>
<div class="tag-list">
${item.tags.map(tag => `<span class="tag">${tag}</span>`).join('')}
</div>
</div>
`;
});
html += '</div>';
outputDiv.innerHTML = html;
}
function testRatings() {
const library = window.libraryManager.getLibrary();
const allFiles = Object.keys(library.media);
if (allFiles.length === 0) {
const outputDiv = document.getElementById('manual-output');
outputDiv.innerHTML = `<div class="status-box error">No media in library. Add sample media first.</div>`;
return;
}
// Set random ratings
allFiles.forEach(file => {
window.libraryManager.setRating(file, Math.floor(Math.random() * 5) + 1);
});
const stats = window.libraryManager.getLibraryStats();
const outputDiv = document.getElementById('manual-output');
outputDiv.innerHTML = `<div class="status-box success">
Rated ${stats.ratedItems} items<br>
Average rating: ${stats.averageRating}/5
</div>`;
}
function testCollections() {
const library = window.libraryManager.getLibrary();
const allFiles = Object.keys(library.media);
if (allFiles.length < 3) {
const outputDiv = document.getElementById('manual-output');
outputDiv.innerHTML = `<div class="status-box error">Need at least 3 items. Add sample media first.</div>`;
return;
}
window.libraryManager.createCollection('Test Collection', allFiles.slice(0, 3));
const items = window.libraryManager.getCollection('Test Collection');
const outputDiv = document.getElementById('manual-output');
outputDiv.innerHTML = `<div class="status-box success">
Created collection with ${items.length} items
</div>`;
}
function showStats() {
const stats = window.libraryManager.getLibraryStats();
const outputDiv = document.getElementById('manual-output');
outputDiv.innerHTML = `<div class="status-box info">Library Statistics:</div>` +
`<div class="json-display">${JSON.stringify(stats, null, 2)}</div>`;
}
function showAllMedia() {
const library = window.libraryManager.getLibrary();
const allMedia = Object.values(library.media);
if (allMedia.length === 0) {
const outputDiv = document.getElementById('manual-output');
outputDiv.innerHTML = `<div class="status-box info">Library is empty. Add some media items.</div>`;
return;
}
const outputDiv = document.getElementById('manual-output');
let html = `<div class="status-box info">Total items: ${allMedia.length}</div>`;
html += '<div class="media-grid">';
allMedia.forEach(item => {
html += `
<div class="media-card">
<h4>${item.filePath.split('/').pop()}</h4>
<div class="rating">⭐ ${item.rating}/5</div>
<div class="tag-list">
${item.tags.map(tag => `<span class="tag">${tag}</span>`).join('')}
</div>
<div style="margin-top: 8px; font-size: 0.8em; color: #888;">
Plays: ${item.timesPlayed || 0}
</div>
</div>
`;
});
html += '</div>';
outputDiv.innerHTML = html;
}
function resetLibrary() {
if (confirm('Reset entire library? This will delete all media items and tags.')) {
window.libraryManager.resetLibrary();
const outputDiv = document.getElementById('manual-output');
outputDiv.innerHTML = `<div class="status-box success">Library reset to empty state</div>`;
updateLibraryDisplay();
}
}
function updateLibraryDisplay() {
const library = window.libraryManager.getLibrary();
document.getElementById('library-display').textContent = JSON.stringify(library, null, 2);
}
// Initialize on load
window.addEventListener('DOMContentLoaded', () => {
updateLibraryDisplay();
// Auto-sync with existing library if available
if (window.desktopFileManager) {
setTimeout(() => {
const result = window.libraryManager.syncWithExistingLibrary();
if (result.total > 0) {
const outputDiv = document.getElementById('manual-output');
outputDiv.innerHTML = `<div class="status-box info">
📹 Auto-synced ${result.total} videos from existing library.
Use "🔄 Sync with Existing Library" to refresh.
</div>`;
}
}, 1000);
}
// Auto-refresh progress display every 2 seconds
setInterval(updateLibraryDisplay, 2000);
});
</script>
</body>
</html>