remove test files
This commit is contained in:
parent
ab320fd708
commit
1c30d900d7
|
|
@ -149,18 +149,6 @@ Training session video selection
|
|||
|
||||
---
|
||||
|
||||
## Test Files Created
|
||||
|
||||
**Test files for isolated module testing:**
|
||||
- `test-campaign-manager.html` - Campaign progression tests
|
||||
- `test-preference-manager.html` - Preference system tests
|
||||
- `test-library-manager.html` - Library tagging/search tests
|
||||
- `test-academy-ui.html` - UI component tests
|
||||
|
||||
**Note:** Test files require manual script loading (Academy modules not auto-initialized). This is expected - the main `training-academy.html` page has proper initialization.
|
||||
|
||||
---
|
||||
|
||||
## Phase 1 Deliverables Summary
|
||||
|
||||
| Component | File | Lines | Status |
|
||||
|
|
|
|||
16
index.html
16
index.html
|
|
@ -196,22 +196,6 @@
|
|||
<span class="cassie-icon"></span>
|
||||
<span class="feature-text">Library</span>
|
||||
</button>
|
||||
<button class="hero-feature btn-feature" id="test-campaign-btn" onclick="window.location.href='test-campaign-manager.html'" style="background: linear-gradient(135deg, #8338ec, #ff006e);">
|
||||
<span class="feature-icon">🧪</span>
|
||||
<span class="feature-text">Test Campaign</span>
|
||||
</button>
|
||||
<button class="hero-feature btn-feature" id="test-preferences-btn" onclick="window.location.href='test-preference-manager.html'" style="background: linear-gradient(135deg, #ff006e, #8338ec);">
|
||||
<span class="feature-icon">🎯</span>
|
||||
<span class="feature-text">Test Preferences</span>
|
||||
</button>
|
||||
<button class="hero-feature btn-feature" id="test-library-btn" onclick="window.location.href='test-library-manager.html'" style="background: linear-gradient(135deg, #8338ec, #ff006e);">
|
||||
<span class="feature-icon">📚</span>
|
||||
<span class="feature-text">Test Library</span>
|
||||
</button>
|
||||
<button class="hero-feature btn-feature" id="test-academy-ui-btn" onclick="window.location.href='test-academy-ui.html'" style="background: linear-gradient(135deg, #ff006e, #8338ec);">
|
||||
<span class="feature-icon">🎓</span>
|
||||
<span class="feature-text">Test Academy UI</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,200 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Academy UI Integration Test</title>
|
||||
<link rel="stylesheet" href="src/styles/academy-ui.css">
|
||||
<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;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
.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);
|
||||
}
|
||||
|
||||
.status-box {
|
||||
padding: 15px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 20px;
|
||||
font-family: 'Courier New', monospace;
|
||||
}
|
||||
|
||||
.status-box.success {
|
||||
background: rgba(0, 255, 136, 0.1);
|
||||
border: 1px solid #00ff88;
|
||||
color: #00ff88;
|
||||
}
|
||||
|
||||
.status-box.info {
|
||||
background: rgba(131, 56, 236, 0.1);
|
||||
border: 1px solid #8338ec;
|
||||
color: #8338ec;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>🎓 Academy UI Integration Test</h1>
|
||||
|
||||
<div class="test-section">
|
||||
<h2>Manual Tests</h2>
|
||||
<div class="button-group">
|
||||
<button onclick="setupSampleData()">📦 Setup Sample Data</button>
|
||||
<button onclick="showLevelSelect()">📋 Show Level Select</button>
|
||||
<button onclick="testCheckpointModal(1)">🎯 Test L1 Checkpoint</button>
|
||||
<button onclick="testCheckpointModal(5)">⚡ Test L5 Checkpoint</button>
|
||||
<button onclick="testCheckpointModal(10)">💫 Test L10 Checkpoint</button>
|
||||
<button onclick="resetData()">🔄 Reset Data</button>
|
||||
</div>
|
||||
<div id="output"></div>
|
||||
</div>
|
||||
|
||||
<!-- Academy Setup Container (where UI will render) -->
|
||||
<div id="academy-setup"></div>
|
||||
</div>
|
||||
|
||||
<!-- Load Dependencies -->
|
||||
<script src="src/data/gameData.js"></script>
|
||||
<script src="src/features/academy/campaignManager.js"></script>
|
||||
<script src="src/features/academy/preferenceManager.js"></script>
|
||||
<script src="src/features/academy/libraryManager.js"></script>
|
||||
<script src="src/features/academy/academyUI.js"></script>
|
||||
|
||||
<script>
|
||||
function setupSampleData() {
|
||||
console.log('📦 Setting up sample data...');
|
||||
|
||||
// Unlock first 10 levels
|
||||
for (let i = 1; i <= 10; i++) {
|
||||
if (i <= 7) {
|
||||
// Complete first 7 levels
|
||||
window.campaignManager.startLevel(i);
|
||||
window.campaignManager.completeLevel(i, { duration: 600 });
|
||||
}
|
||||
}
|
||||
|
||||
// Add sample preferences
|
||||
window.preferenceManager.updateCategoryPreferences('contentThemes', {
|
||||
edging: true,
|
||||
denial: true,
|
||||
pov: true
|
||||
}, 1);
|
||||
|
||||
window.preferenceManager.updateCategoryPreferences('intensity', {
|
||||
visualIntensity: 4,
|
||||
mentalIntensity: 3,
|
||||
taskDifficulty: 3
|
||||
}, 5);
|
||||
|
||||
// Add sample library items
|
||||
const sampleFiles = [
|
||||
{ path: 'assets/pornstars/video1.mp4', tags: ['solo', 'pov', 'professional'], rating: 5 },
|
||||
{ path: 'assets/pornstars/video2.mp4', tags: ['couples', 'hd', 'hardcore'], rating: 4 },
|
||||
{ path: 'assets/feet/video1.mp4', tags: ['feet', 'pov', 'fetish'], rating: 4 },
|
||||
{ path: 'assets/hentai/video1.mp4', tags: ['hentai', 'animated'], rating: 3 },
|
||||
{ path: 'assets/BBC/video1.mp4', tags: ['bbc', 'couples'], rating: 5 }
|
||||
];
|
||||
|
||||
sampleFiles.forEach(file => {
|
||||
window.libraryManager.addMediaItem(file.path, {
|
||||
tags: file.tags,
|
||||
rating: file.rating
|
||||
});
|
||||
});
|
||||
|
||||
showOutput('✅ Sample data created: 7 levels complete, preferences set, 5 media items added', 'success');
|
||||
}
|
||||
|
||||
function showLevelSelect() {
|
||||
console.log('📋 Showing level select screen...');
|
||||
window.academyUI.showLevelSelect();
|
||||
showOutput('✅ Level select screen displayed', 'success');
|
||||
}
|
||||
|
||||
function testCheckpointModal(levelNum) {
|
||||
console.log(`⚡ Testing checkpoint modal for Level ${levelNum}...`);
|
||||
window.academyUI.showCheckpointModal(levelNum);
|
||||
showOutput(`✅ Checkpoint modal shown for Level ${levelNum}`, 'success');
|
||||
}
|
||||
|
||||
function resetData() {
|
||||
if (confirm('Reset all academy data?')) {
|
||||
window.campaignManager.resetProgress();
|
||||
window.preferenceManager.resetPreferences();
|
||||
window.libraryManager.resetLibrary();
|
||||
|
||||
// Clear the academy setup container
|
||||
const setupContainer = document.getElementById('academy-setup');
|
||||
if (setupContainer) {
|
||||
setupContainer.innerHTML = '';
|
||||
}
|
||||
|
||||
showOutput('🔄 All data reset', 'info');
|
||||
}
|
||||
}
|
||||
|
||||
function showOutput(message, type = 'info') {
|
||||
const outputDiv = document.getElementById('output');
|
||||
outputDiv.innerHTML = `<div class="status-box ${type}">${message}</div>`;
|
||||
}
|
||||
|
||||
// Initialize on load
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
showOutput('🎓 Academy UI Integration ready. Click "Setup Sample Data" to begin.', 'info');
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,293 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Campaign Manager Test - Subphase 1.1</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
max-width: 800px;
|
||||
margin: 50px auto;
|
||||
padding: 20px;
|
||||
background: #1a1a1a;
|
||||
color: #e0e0e0;
|
||||
}
|
||||
.test-section {
|
||||
background: #2a2a2a;
|
||||
padding: 20px;
|
||||
margin: 20px 0;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #333;
|
||||
}
|
||||
h1 { color: #ff006e; }
|
||||
h2 { color: #8338ec; margin-top: 0; }
|
||||
button {
|
||||
background: linear-gradient(135deg, #ff006e, #8338ec);
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 10px 20px;
|
||||
margin: 5px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
}
|
||||
button:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 8px rgba(255, 0, 110, 0.4);
|
||||
}
|
||||
.status {
|
||||
padding: 10px;
|
||||
margin: 10px 0;
|
||||
border-radius: 4px;
|
||||
background: #333;
|
||||
}
|
||||
.success { border-left: 4px solid #06ffa5; }
|
||||
.error { border-left: 4px solid #ff006e; }
|
||||
.info { border-left: 4px solid #8338ec; }
|
||||
pre {
|
||||
background: #0a0a0a;
|
||||
padding: 10px;
|
||||
border-radius: 4px;
|
||||
overflow-x: auto;
|
||||
}
|
||||
.test-result {
|
||||
margin: 10px 0;
|
||||
padding: 8px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.pass { background: #06ffa533; border-left: 4px solid #06ffa5; }
|
||||
.fail { background: #ff006e33; border-left: 4px solid #ff006e; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>🎓 Campaign Manager Test - Subphase 1.1</h1>
|
||||
|
||||
<div class="test-section">
|
||||
<h2>Campaign Progression System</h2>
|
||||
<p>Testing basic level unlocking, completion tracking, and failure states.</p>
|
||||
|
||||
<button onclick="runAllTests()">🧪 Run All Tests</button>
|
||||
<button onclick="resetProgress()">🔄 Reset Progress</button>
|
||||
<button onclick="showProgress()">📊 Show Progress</button>
|
||||
|
||||
<div id="test-results"></div>
|
||||
</div>
|
||||
|
||||
<div class="test-section">
|
||||
<h2>Manual Testing</h2>
|
||||
<button onclick="startLevel(1)">Start Level 1</button>
|
||||
<button onclick="completeLevel(1)">Complete Level 1</button>
|
||||
<button onclick="failLevel(1, 'cumming')">Fail Level 1 (cumming)</button>
|
||||
<button onclick="startLevel(2)">Start Level 2 (should fail if L1 not complete)</button>
|
||||
|
||||
<div id="manual-results"></div>
|
||||
</div>
|
||||
|
||||
<div class="test-section">
|
||||
<h2>Current Progress</h2>
|
||||
<div id="progress-display"></div>
|
||||
</div>
|
||||
|
||||
<!-- Load dependencies -->
|
||||
<script src="src/data/gameData.js"></script>
|
||||
<script src="src/features/academy/campaignManager.js"></script>
|
||||
<script>
|
||||
// campaignManager is now available globally
|
||||
|
||||
// Test functions
|
||||
window.runAllTests = function() {
|
||||
const results = document.getElementById('test-results');
|
||||
results.innerHTML = '<h3>Running Tests...</h3>';
|
||||
|
||||
const tests = [];
|
||||
|
||||
// Test 1: Initial state
|
||||
campaignManager.resetProgress();
|
||||
const stats = campaignManager.getProgressStats();
|
||||
tests.push({
|
||||
name: 'Initial state - L1 unlocked, L2 locked',
|
||||
pass: stats.currentLevel === 1 && stats.highestUnlockedLevel === 1,
|
||||
details: `Current: ${stats.currentLevel}, Highest: ${stats.highestUnlockedLevel}`
|
||||
});
|
||||
|
||||
// Test 2: Can start L1
|
||||
const l1Start = campaignManager.startLevel(1);
|
||||
tests.push({
|
||||
name: 'Can start Level 1',
|
||||
pass: l1Start !== null && l1Start.levelNum === 1,
|
||||
details: l1Start ? `Started ${l1Start.arc} arc` : 'Failed to start'
|
||||
});
|
||||
|
||||
// Test 3: Cannot start L2 before completing L1
|
||||
const l2Locked = campaignManager.startLevel(2);
|
||||
tests.push({
|
||||
name: 'Cannot start Level 2 (locked)',
|
||||
pass: l2Locked === null,
|
||||
details: l2Locked === null ? 'Correctly blocked' : 'ERROR: Started locked level'
|
||||
});
|
||||
|
||||
// Test 4: Complete L1
|
||||
const l1Complete = campaignManager.completeLevel(1, { duration: 300 });
|
||||
tests.push({
|
||||
name: 'Complete Level 1 unlocks Level 2',
|
||||
pass: l1Complete.nextLevelUnlocked && l1Complete.nextLevel === 2,
|
||||
details: `Next level: ${l1Complete.nextLevel}, Unlocked: ${l1Complete.nextLevelUnlocked}`
|
||||
});
|
||||
|
||||
// Test 5: Can now start L2
|
||||
const l2Start = campaignManager.startLevel(2);
|
||||
tests.push({
|
||||
name: 'Can start Level 2 after completing L1',
|
||||
pass: l2Start !== null && l2Start.levelNum === 2,
|
||||
details: l2Start ? `Started level ${l2Start.levelNum}` : 'Failed to start'
|
||||
});
|
||||
|
||||
// Test 6: Fail L2
|
||||
campaignManager.failLevel(2, 'cumming');
|
||||
const statsAfterFail = campaignManager.getProgressStats();
|
||||
tests.push({
|
||||
name: 'Failing L2 allows restart',
|
||||
pass: statsAfterFail.failedAttempts > 0,
|
||||
details: `Failed attempts: ${statsAfterFail.failedAttempts}`
|
||||
});
|
||||
|
||||
// Test 7: Progress persists
|
||||
const beforeReload = campaignManager.getProgressStats();
|
||||
// Simulate reload by getting fresh data
|
||||
const savedData = JSON.parse(localStorage.getItem('webGame-data'));
|
||||
tests.push({
|
||||
name: 'Progress persists in localStorage',
|
||||
pass: savedData.academyProgress !== undefined && savedData.academyProgress.highestUnlockedLevel === 2,
|
||||
details: `Highest unlocked: ${savedData.academyProgress.highestUnlockedLevel}`
|
||||
});
|
||||
|
||||
// Test 8: Arc detection
|
||||
const l1Arc = campaignManager.getArcForLevel(1);
|
||||
const l6Arc = campaignManager.getArcForLevel(6);
|
||||
tests.push({
|
||||
name: 'Arc detection works',
|
||||
pass: l1Arc === 'Foundation' && l6Arc === 'Feature Discovery',
|
||||
details: `L1: ${l1Arc}, L6: ${l6Arc}`
|
||||
});
|
||||
|
||||
// Test 9: Checkpoint detection
|
||||
const isCheckpoint1 = campaignManager.isCheckpointLevel(1);
|
||||
const isCheckpoint2 = campaignManager.isCheckpointLevel(2);
|
||||
const isCheckpoint5 = campaignManager.isCheckpointLevel(5);
|
||||
tests.push({
|
||||
name: 'Checkpoint detection works',
|
||||
pass: isCheckpoint1 && !isCheckpoint2 && isCheckpoint5,
|
||||
details: `L1: ${isCheckpoint1}, L2: ${isCheckpoint2}, L5: ${isCheckpoint5}`
|
||||
});
|
||||
|
||||
// Display results
|
||||
let html = '<h3>Test Results</h3>';
|
||||
let passed = 0;
|
||||
let failed = 0;
|
||||
|
||||
tests.forEach(test => {
|
||||
if (test.pass) passed++;
|
||||
else failed++;
|
||||
|
||||
html += `
|
||||
<div class="test-result ${test.pass ? 'pass' : 'fail'}">
|
||||
<strong>${test.pass ? '✅' : '❌'} ${test.name}</strong><br>
|
||||
<small>${test.details}</small>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
html += `<div class="status ${failed === 0 ? 'success' : 'error'}">
|
||||
<strong>Results: ${passed}/${tests.length} tests passed</strong>
|
||||
</div>`;
|
||||
|
||||
results.innerHTML = html;
|
||||
|
||||
// Update progress display
|
||||
showProgress();
|
||||
};
|
||||
|
||||
window.resetProgress = function() {
|
||||
campaignManager.resetProgress();
|
||||
document.getElementById('manual-results').innerHTML =
|
||||
'<div class="status success">✅ Progress reset to Level 1</div>';
|
||||
showProgress();
|
||||
};
|
||||
|
||||
window.startLevel = function(levelNum) {
|
||||
const result = campaignManager.startLevel(levelNum);
|
||||
const resultsDiv = document.getElementById('manual-results');
|
||||
|
||||
if (result) {
|
||||
resultsDiv.innerHTML = `
|
||||
<div class="status success">
|
||||
✅ Started Level ${result.levelNum}<br>
|
||||
Arc: ${result.arc}<br>
|
||||
Checkpoint: ${result.isCheckpoint}
|
||||
</div>
|
||||
`;
|
||||
} else {
|
||||
resultsDiv.innerHTML = `
|
||||
<div class="status error">
|
||||
❌ Cannot start Level ${levelNum} - Level is locked
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
showProgress();
|
||||
};
|
||||
|
||||
window.completeLevel = function(levelNum) {
|
||||
const result = campaignManager.completeLevel(levelNum, { duration: 300 });
|
||||
const resultsDiv = document.getElementById('manual-results');
|
||||
|
||||
resultsDiv.innerHTML = `
|
||||
<div class="status success">
|
||||
✅ Level ${result.levelCompleted} completed!<br>
|
||||
${result.nextLevelUnlocked ? `🔓 Level ${result.nextLevel} unlocked!` : ''}<br>
|
||||
${result.arcComplete ? `🎉 ${result.completedArc} Arc complete!` : ''}
|
||||
</div>
|
||||
`;
|
||||
showProgress();
|
||||
};
|
||||
|
||||
window.failLevel = function(levelNum, reason) {
|
||||
campaignManager.failLevel(levelNum, reason);
|
||||
const resultsDiv = document.getElementById('manual-results');
|
||||
|
||||
resultsDiv.innerHTML = `
|
||||
<div class="status error">
|
||||
❌ Level ${levelNum} failed (${reason})<br>
|
||||
You can restart this level.
|
||||
</div>
|
||||
`;
|
||||
showProgress();
|
||||
};
|
||||
|
||||
window.showProgress = function() {
|
||||
const stats = campaignManager.getProgressStats();
|
||||
const progress = window.gameData.academyProgress;
|
||||
|
||||
document.getElementById('progress-display').innerHTML = `
|
||||
<pre>${JSON.stringify(stats, null, 2)}</pre>
|
||||
<h3>Full Progress Data:</h3>
|
||||
<pre>${JSON.stringify(progress, null, 2)}</pre>
|
||||
`;
|
||||
};
|
||||
|
||||
// Initial display
|
||||
showProgress();
|
||||
|
||||
console.log('✅ Campaign Manager Test Page Ready');
|
||||
console.log('📝 Run runAllTests() to execute automated tests');
|
||||
</script>
|
||||
|
||||
<!-- Electron preload (if needed) -->
|
||||
<script>
|
||||
// Check if running in Electron
|
||||
if (typeof require !== 'undefined') {
|
||||
console.log('🖥️ Running in Electron');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,609 +0,0 @@
|
|||
<!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>
|
||||
|
|
@ -1,526 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Preference 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;
|
||||
}
|
||||
|
||||
.preference-editor {
|
||||
background: #2a2a2a;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.pref-category {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.pref-category h3 {
|
||||
color: #ff006e;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.checkbox-group {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.checkbox-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
cursor: pointer;
|
||||
padding: 5px;
|
||||
border-radius: 4px;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
|
||||
.checkbox-label:hover {
|
||||
background: rgba(255, 0, 110, 0.1);
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.slider-container {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.slider-label {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
input[type="range"] {
|
||||
width: 100%;
|
||||
height: 6px;
|
||||
border-radius: 3px;
|
||||
background: #444;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
input[type="range"]::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border-radius: 50%;
|
||||
background: #ff006e;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
input[type="range"]::-moz-range-thumb {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border-radius: 50%;
|
||||
background: #ff006e;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>🎯 Preference 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="showPreferences()">📊 Show Current Preferences</button>
|
||||
<button onclick="testCheckpointModal(1)">🎬 Test L1 Checkpoint</button>
|
||||
<button onclick="testCheckpointModal(5)">🎯 Test L5 Checkpoint</button>
|
||||
<button onclick="testCheckpointModal(10)">⚡ Test L10 Checkpoint</button>
|
||||
<button onclick="simulatePreferenceUpdate()">✏️ Simulate Update</button>
|
||||
<button onclick="testContentFilter()">🔍 Show Content Filter</button>
|
||||
<button onclick="showStats()">📈 Show Stats</button>
|
||||
<button onclick="resetPreferences()">🔄 Reset All</button>
|
||||
</div>
|
||||
<div id="manual-output"></div>
|
||||
</div>
|
||||
|
||||
<!-- Interactive Preference Editor -->
|
||||
<div class="test-section">
|
||||
<h2>Interactive Preference Editor</h2>
|
||||
<div id="preference-editor"></div>
|
||||
</div>
|
||||
|
||||
<!-- Progress Display -->
|
||||
<div class="test-section">
|
||||
<h2>Current State</h2>
|
||||
<div id="progress-display" class="json-display"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Load Dependencies -->
|
||||
<script src="src/data/gameData.js"></script>
|
||||
<script src="src/features/academy/preferenceManager.js"></script>
|
||||
|
||||
<script>
|
||||
// Test runner
|
||||
function runAllTests() {
|
||||
const tests = [
|
||||
testInitialization,
|
||||
testCategoryUpdate,
|
||||
testBulkUpdate,
|
||||
testContentFilter,
|
||||
testCheckpointDetection,
|
||||
testFeatureDiscovery,
|
||||
testBoundaries,
|
||||
testPersistence,
|
||||
testStats,
|
||||
testReset
|
||||
];
|
||||
|
||||
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 prefs = window.preferenceManager.getPreferences();
|
||||
const hasAllCategories = prefs.contentThemes && prefs.visualPreferences &&
|
||||
prefs.intensity && prefs.captionTone &&
|
||||
prefs.audioPreferences && prefs.sessionDuration &&
|
||||
prefs.featurePreferences && prefs.boundaries;
|
||||
|
||||
return {
|
||||
name: 'Initialization Test',
|
||||
pass: hasAllCategories && prefs.version === 1,
|
||||
message: hasAllCategories ? 'All 8 categories initialized correctly' : 'Missing categories'
|
||||
};
|
||||
}
|
||||
|
||||
// Test 2: Category Update
|
||||
function testCategoryUpdate() {
|
||||
const success = window.preferenceManager.updateCategoryPreferences('contentThemes', {
|
||||
edging: true,
|
||||
denial: true
|
||||
}, 1);
|
||||
|
||||
const prefs = window.preferenceManager.getCategoryPreferences('contentThemes');
|
||||
|
||||
return {
|
||||
name: 'Category Update Test',
|
||||
pass: success && prefs.edging === true && prefs.denial === true,
|
||||
message: success ? 'Successfully updated contentThemes' : 'Update failed'
|
||||
};
|
||||
}
|
||||
|
||||
// Test 3: Bulk Update
|
||||
function testBulkUpdate() {
|
||||
const updates = {
|
||||
contentThemes: { gooning: true },
|
||||
intensity: { visualIntensity: 4 }
|
||||
};
|
||||
|
||||
const success = window.preferenceManager.updateMultipleCategories(updates, 5);
|
||||
const prefs = window.preferenceManager.getPreferences();
|
||||
|
||||
return {
|
||||
name: 'Bulk Update Test',
|
||||
pass: success && prefs.contentThemes.gooning === true && prefs.intensity.visualIntensity === 4,
|
||||
message: success ? 'Successfully updated multiple categories' : 'Bulk update failed'
|
||||
};
|
||||
}
|
||||
|
||||
// Test 4: Content Filter
|
||||
function testContentFilter() {
|
||||
const filter = window.preferenceManager.getContentFilter();
|
||||
const hasRequiredFields = filter.themes && filter.visuals && filter.intensity && filter.exclude;
|
||||
|
||||
return {
|
||||
name: 'Content Filter Test',
|
||||
pass: hasRequiredFields && Array.isArray(filter.themes),
|
||||
message: hasRequiredFields ? 'Content filter generated correctly' : 'Filter generation failed'
|
||||
};
|
||||
}
|
||||
|
||||
// Test 5: Checkpoint Detection
|
||||
function testCheckpointDetection() {
|
||||
const isL1Checkpoint = window.preferenceManager.isCheckpointLevel(1);
|
||||
const isL5Checkpoint = window.preferenceManager.isCheckpointLevel(5);
|
||||
const isL3NotCheckpoint = !window.preferenceManager.isCheckpointLevel(3);
|
||||
|
||||
return {
|
||||
name: 'Checkpoint Detection Test',
|
||||
pass: isL1Checkpoint && isL5Checkpoint && isL3NotCheckpoint,
|
||||
message: 'Correctly identifies checkpoint levels (1,5,10,15,20,25)'
|
||||
};
|
||||
}
|
||||
|
||||
// Test 6: Feature Discovery
|
||||
function testFeatureDiscovery() {
|
||||
window.preferenceManager.discoverFeature('webcam');
|
||||
window.preferenceManager.discoverFeature('tts');
|
||||
|
||||
const discovered = window.preferenceManager.getDiscoveredFeatures();
|
||||
|
||||
return {
|
||||
name: 'Feature Discovery Test',
|
||||
pass: discovered.includes('webcam') && discovered.includes('tts'),
|
||||
message: `Discovered ${discovered.length} features: ${discovered.join(', ')}`
|
||||
};
|
||||
}
|
||||
|
||||
// Test 7: Boundaries
|
||||
function testBoundaries() {
|
||||
window.preferenceManager.addHardLimit('extreme-content');
|
||||
const prefs = window.preferenceManager.getPreferences();
|
||||
const hasLimit = prefs.boundaries.hardLimits.includes('extreme-content');
|
||||
|
||||
return {
|
||||
name: 'Boundaries Test',
|
||||
pass: hasLimit,
|
||||
message: hasLimit ? 'Hard limit added successfully' : 'Failed to add hard limit'
|
||||
};
|
||||
}
|
||||
|
||||
// Test 8: Persistence
|
||||
function testPersistence() {
|
||||
window.preferenceManager.updateCategoryPreferences('visualPreferences', { pov: true });
|
||||
const beforeSave = window.preferenceManager.getCategoryPreferences('visualPreferences').pov;
|
||||
|
||||
// Simulate reload
|
||||
const savedData = JSON.parse(localStorage.getItem('webGame-data'));
|
||||
const afterLoad = savedData.academyPreferences.visualPreferences.pov;
|
||||
|
||||
return {
|
||||
name: 'Persistence Test',
|
||||
pass: beforeSave === true && afterLoad === true,
|
||||
message: beforeSave === afterLoad ? 'Preferences persist to localStorage' : 'Persistence failed'
|
||||
};
|
||||
}
|
||||
|
||||
// Test 9: Stats
|
||||
function testStats() {
|
||||
const stats = window.preferenceManager.getPreferenceStats();
|
||||
const hasRequiredStats = stats.hasOwnProperty('totalCheckpoints') &&
|
||||
stats.hasOwnProperty('activeThemes') &&
|
||||
stats.hasOwnProperty('averageIntensity');
|
||||
|
||||
return {
|
||||
name: 'Statistics Test',
|
||||
pass: hasRequiredStats,
|
||||
message: `Generated stats: ${stats.activeThemes} themes, avg intensity ${stats.averageIntensity}`
|
||||
};
|
||||
}
|
||||
|
||||
// Test 10: Reset
|
||||
function testReset() {
|
||||
const beforeReset = window.preferenceManager.getPreferences().contentThemes.edging;
|
||||
window.preferenceManager.resetPreferences();
|
||||
const afterReset = window.preferenceManager.getPreferences().contentThemes.edging;
|
||||
|
||||
return {
|
||||
name: 'Reset Test',
|
||||
pass: beforeReset === true && afterReset === false,
|
||||
message: afterReset === false ? 'Preferences reset to defaults' : 'Reset failed'
|
||||
};
|
||||
}
|
||||
|
||||
// Manual testing functions
|
||||
function showPreferences() {
|
||||
const prefs = window.preferenceManager.getPreferences();
|
||||
const outputDiv = document.getElementById('manual-output');
|
||||
outputDiv.innerHTML = `<div class="status-box info">Current Preferences:</div>` +
|
||||
`<div class="json-display">${JSON.stringify(prefs, null, 2)}</div>`;
|
||||
}
|
||||
|
||||
function testCheckpointModal(level) {
|
||||
const config = window.preferenceManager.getCheckpointModalConfig(level);
|
||||
const outputDiv = document.getElementById('manual-output');
|
||||
|
||||
if (config) {
|
||||
outputDiv.innerHTML = `<div class="status-box success">
|
||||
<strong>Level ${level} Checkpoint Config:</strong><br>
|
||||
Title: ${config.title}<br>
|
||||
Description: ${config.description}<br>
|
||||
Categories to show: ${config.categories.join(', ')}<br>
|
||||
Is Initial: ${config.isInitial}
|
||||
</div>`;
|
||||
} else {
|
||||
outputDiv.innerHTML = `<div class="status-box error">Level ${level} is not a checkpoint</div>`;
|
||||
}
|
||||
}
|
||||
|
||||
function simulatePreferenceUpdate() {
|
||||
const updates = {
|
||||
contentThemes: { worship: true, femdom: true },
|
||||
intensity: { mentalIntensity: 4, taskDifficulty: 3 },
|
||||
captionTone: { commanding: true, seductive: true }
|
||||
};
|
||||
|
||||
window.preferenceManager.updateMultipleCategories(updates, 10);
|
||||
|
||||
const outputDiv = document.getElementById('manual-output');
|
||||
outputDiv.innerHTML = `<div class="status-box success">
|
||||
Simulated L10 checkpoint update:<br>
|
||||
- Enabled worship & femdom themes<br>
|
||||
- Set mental intensity to 4<br>
|
||||
- Enabled commanding & seductive tones
|
||||
</div>`;
|
||||
}
|
||||
|
||||
function testContentFilter() {
|
||||
const filter = window.preferenceManager.getContentFilter();
|
||||
const outputDiv = document.getElementById('manual-output');
|
||||
outputDiv.innerHTML = `<div class="status-box info">Generated Content Filter:</div>` +
|
||||
`<div class="json-display">${JSON.stringify(filter, null, 2)}</div>`;
|
||||
}
|
||||
|
||||
function showStats() {
|
||||
const stats = window.preferenceManager.getPreferenceStats();
|
||||
const outputDiv = document.getElementById('manual-output');
|
||||
outputDiv.innerHTML = `<div class="status-box info">Preference Statistics:</div>` +
|
||||
`<div class="json-display">${JSON.stringify(stats, null, 2)}</div>`;
|
||||
}
|
||||
|
||||
function resetPreferences() {
|
||||
if (confirm('Reset all preferences to defaults?')) {
|
||||
window.preferenceManager.resetPreferences();
|
||||
const outputDiv = document.getElementById('manual-output');
|
||||
outputDiv.innerHTML = `<div class="status-box success">All preferences reset to defaults</div>`;
|
||||
updateProgressDisplay();
|
||||
}
|
||||
}
|
||||
|
||||
function updateProgressDisplay() {
|
||||
const prefs = window.preferenceManager.getPreferences();
|
||||
document.getElementById('progress-display').textContent = JSON.stringify(prefs, null, 2);
|
||||
}
|
||||
|
||||
// Initialize on load
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
updateProgressDisplay();
|
||||
|
||||
// Auto-refresh progress display every 2 seconds
|
||||
setInterval(updateProgressDisplay, 2000);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Reference in New Issue