// Integration tests for folder navigation const { test } = require('node:test'); const assert = require('assert'); const fs = require('fs'); const path = require('path'); const UIManager = require('./utils/renderer/UIManager'); // Create temporary test directory structure function setupTestDirectory() { const testDir = path.join(__dirname, 'test_integration_dir'); // Create main directory if (!fs.existsSync(testDir)) { fs.mkdirSync(testDir); } // Create subdirectories const subdirs = ['folder1', 'folder2', 'extras', 'behind the scenes']; for (const subdir of subdirs) { const subdirPath = path.join(testDir, subdir); if (!fs.existsSync(subdirPath)) { fs.mkdirSync(subdirPath); } } // Create nested structure const nestedDir = path.join(testDir, 'nested'); if (!fs.existsSync(nestedDir)) { fs.mkdirSync(nestedDir); } const deepDir = path.join(nestedDir, 'deep'); if (!fs.existsSync(deepDir)) { fs.mkdirSync(deepDir); } // Create some mock files fs.writeFileSync(path.join(testDir, 'file1.mp4'), ''); fs.writeFileSync(path.join(testDir, 'file2.mkv'), ''); return testDir; } function cleanupTestDirectory(testDir) { if (fs.existsSync(testDir)) { fs.rmSync(testDir, { recursive: true }); } } test('Full folder navigation workflow', async () => { const testDir = setupTestDirectory(); try { // Verify test directory structure assert.ok(fs.existsSync(testDir), 'Test directory should exist'); const subdirs = ['folder1', 'folder2', 'extras', 'behind the scenes']; for (const subdir of subdirs) { assert.ok(fs.existsSync(path.join(testDir, subdir)), `Subdirectory ${subdir} should exist`); } // Create a mock UIManager const mockUIManager = { currentDirectory: null, selectedDirEl: { textContent: '' }, appState: { navigationStack: [], currentDepth: 0, addToNavigationStack: function(dir) { this.navigationStack.push(dir); this.currentDepth = this.navigationStack.length - 1; }, getNavigationStack: function() { return this.navigationStack; }, goBack: function() { if (this.currentDepth > 0) { this.navigationStack.pop(); this.currentDepth--; return this.navigationStack[this.currentDepth]; } return null; }, canGoBack: function() { return this.currentDepth > 0; } }, scanDirectory: async (dir) => { return { success: true, files: [] }; }, _logAuditEvent: async () => {}, openDirectory: async (directory) => { mockUIManager.appState.addToNavigationStack(directory); mockUIManager.currentDirectory = directory; }, handleFolderClick: async (folderPath, folderName) => { console.log('Folder clicked:', folderName, 'at path:', folderPath); // Validate folder path exists if (!fs.existsSync(folderPath) || !fs.statSync(folderPath).isDirectory()) { console.error('Invalid folder path:', folderPath); return; // Don't navigate } // Open the folder await mockUIManager.openDirectory(folderPath); }, updateBreadcrumbNavigation: function() { // Mock breadcrumb update } }; // Navigate to folder1 await mockUIManager.openDirectory(path.join(testDir, 'folder1')); assert.strictEqual(mockUIManager.currentDirectory, path.join(testDir, 'folder1')); assert.strictEqual(mockUIManager.appState.getNavigationStack().length, 2); // testDir + folder1 // Navigate to folder2 await mockUIManager.openDirectory(path.join(testDir, 'folder2')); assert.strictEqual(mockUIManager.currentDirectory, path.join(testDir, 'folder2')); assert.strictEqual(mockUIManager.appState.getNavigationStack().length, 3); // Navigate to extras await mockUIManager.openDirectory(path.join(testDir, 'extras')); assert.strictEqual(mockUIManager.currentDirectory, path.join(testDir, 'extras')); assert.strictEqual(mockUIManager.appState.getNavigationStack().length, 4); // Go back to folder2 const backDir1 = mockUIManager.appState.goBack(); assert.strictEqual(backDir1, path.join(testDir, 'folder2')); assert.strictEqual(mockUIManager.appState.canGoBack(), true); // Go back to folder1 const backDir2 = mockUIManager.appState.goBack(); assert.strictEqual(backDir2, path.join(testDir, 'folder1')); assert.strictEqual(mockUIManager.appState.canGoBack(), true); // Go back to testDir const backDir3 = mockUIManager.appState.goBack(); assert.strictEqual(backDir3, testDir); assert.strictEqual(mockUIManager.appState.canGoBack(), false); console.log('Full navigation workflow test passed'); } finally { cleanupTestDirectory(testDir); } }); test('Navigation stack preserves history correctly', async () => { const testDir = setupTestDirectory(); try { const mockUIManager = { currentDirectory: null, selectedDirEl: { textContent: '' }, appState: { navigationStack: [], currentDepth: 0, addToNavigationStack: function(dir) { this.navigationStack.push(dir); this.currentDepth = this.navigationStack.length - 1; }, goBack: function() { if (this.currentDepth > 0) { this.navigationStack.pop(); this.currentDepth--; return this.navigationStack[this.currentDepth]; } return null; }, canGoBack: function() { return this.currentDepth > 0; } }, openDirectory: async (directory) => { mockUIManager.appState.addToNavigationStack(directory); mockUIManager.currentDirectory = directory; } }; // Navigate: testDir -> nested -> deep await mockUIManager.openDirectory(path.join(testDir, 'nested')); await mockUIManager.openDirectory(path.join(testDir, 'nested', 'deep')); assert.strictEqual(mockUIManager.appState.getNavigationStack().length, 3); assert.strictEqual(mockUIManager.appState.currentDepth, 2); // Go back to nested mockUIManager.appState.goBack(); assert.strictEqual(mockUIManager.appState.currentDepth, 1); // Navigate to extras (from nested) await mockUIManager.openDirectory(path.join(testDir, 'extras')); // Verify forward history is cleared assert.strictEqual(mockUIManager.appState.getNavigationStack().length, 3); assert.strictEqual(mockUIManager.appState.currentDepth, 2); assert.strictEqual(mockUIManager.appState.getNavigationStack()[2], path.join(testDir, 'extras')); console.log('Navigation stack history preservation test passed'); } finally { cleanupTestDirectory(testDir); } }); test('Audit logging for navigation events', async () => { const testDir = setupTestDirectory(); try { let auditLog = []; const mockUIManager = { currentDirectory: null, selectedDirEl: { textContent: '' }, appState: { navigationStack: [], currentDepth: 0, addToNavigationStack: function(dir) { this.navigationStack.push(dir); this.currentDepth = this.navigationStack.length - 1; } }, scanDirectory: async (dir) => { return { success: true, files: [] }; }, _logAuditEvent: async (action, details) => { auditLog.push({ action, details }); }, openDirectory: async (directory) => { mockUIManager.appState.addToNavigationStack(directory); mockUIManager.currentDirectory = directory; await this._logAuditEvent('navigate_to_directory', { directory: directory, navigationType: 'forward' }); } }; // Navigate to a directory await mockUIManager.openDirectory(path.join(testDir, 'folder1')); // Verify audit log assert.strictEqual(auditLog.length, 1); assert.strictEqual(auditLog[0].action, 'navigate_to_directory'); assert.strictEqual(auditLog[0].details.directory, path.join(testDir, 'folder1')); assert.strictEqual(auditLog[0].details.navigationType, 'forward'); // Navigate back mockUIManager.appState.goBack(); await mockUIManager._logAuditEvent('navigate_back', { fromDirectory: path.join(testDir, 'folder1'), toDirectory: testDir, navigationType: 'back' }); assert.strictEqual(auditLog.length, 2); assert.strictEqual(auditLog[1].action, 'navigate_back'); assert.strictEqual(auditLog[1].details.navigationType, 'back'); console.log('Audit logging test passed'); } finally { cleanupTestDirectory(testDir); } }); test('Special folder navigation', async () => { const testDir = setupTestDirectory(); try { const mockUIManager = { currentDirectory: null, selectedDirEl: { textContent: '' }, appState: { navigationStack: [], currentDepth: 0, addToNavigationStack: function(dir) { this.navigationStack.push(dir); this.currentDepth = this.navigationStack.length - 1; }, canGoBack: function() { return this.currentDepth > 0; } }, openDirectory: async (directory) => { mockUIManager.appState.addToNavigationStack(directory); mockUIManager.currentDirectory = directory; } }; // Navigate to special folders await mockUIManager.openDirectory(path.join(testDir, 'extras')); assert.strictEqual(mockUIManager.currentDirectory, path.join(testDir, 'extras')); await mockUIManager.openDirectory(path.join(testDir, 'behind the scenes')); assert.strictEqual(mockUIManager.currentDirectory, path.join(testDir, 'behind the scenes')); // Verify navigation stack const stack = mockUIManager.appState.getNavigationStack(); assert.ok(stack.includes(path.join(testDir, 'extras'))); assert.ok(stack.includes(path.join(testDir, 'behind the scenes'))); console.log('Special folder navigation test passed'); } finally { cleanupTestDirectory(testDir); } }); test('Navigation with nested directories', async () => { const testDir = setupTestDirectory(); try { const mockUIManager = { currentDirectory: null, selectedDirEl: { textContent: '' }, appState: { navigationStack: [], currentDepth: 0, addToNavigationStack: function(dir) { this.navigationStack.push(dir); this.currentDepth = this.navigationStack.length - 1; }, goBack: function() { if (this.currentDepth > 0) { this.navigationStack.pop(); this.currentDepth--; return this.navigationStack[this.currentDepth]; } return null; }, canGoBack: function() { return this.currentDepth > 0; } }, openDirectory: async (directory) => { mockUIManager.appState.addToNavigationStack(directory); mockUIManager.currentDirectory = directory; } }; // Navigate deeply: testDir -> nested -> deep await mockUIManager.openDirectory(path.join(testDir, 'nested')); await mockUIManager.openDirectory(path.join(testDir, 'nested', 'deep')); assert.strictEqual(mockUIManager.appState.getNavigationStack().length, 3); assert.strictEqual(mockUIManager.appState.currentDepth, 2); // Go back multiple times const back1 = mockUIManager.appState.goBack(); assert.strictEqual(back1, path.join(testDir, 'nested')); assert.strictEqual(mockUIManager.appState.currentDepth, 1); const back2 = mockUIManager.appState.goBack(); assert.strictEqual(back2, testDir); assert.strictEqual(mockUIManager.appState.currentDepth, 0); assert.strictEqual(mockUIManager.appState.canGoBack(), false); console.log('Nested directory navigation test passed'); } finally { cleanupTestDirectory(testDir); } }); test('Error handling for non-existent folders', async () => { const testDir = setupTestDirectory(); try { const mockUIManager = { currentDirectory: testDir, selectedDirEl: { textContent: '' }, appState: { navigationStack: [testDir], currentDepth: 0, addToNavigationStack: function(dir) { this.navigationStack.push(dir); this.currentDepth = this.navigationStack.length - 1; } }, scanDirectory: async (dir) => { return { success: true, files: [] }; }, _logAuditEvent: async () => {}, openDirectory: async (directory) => { mockUIManager.appState.addToNavigationStack(directory); mockUIManager.currentDirectory = directory; } }; // Try to navigate to non-existent folder const nonExistentPath = path.join(testDir, 'non-existent'); const consoleError = console.error; console.error = () => {}; // Suppress error output try { mockUIManager.handleFolderClick(nonExistentPath, 'non-existent'); // Should handle gracefully assert.ok(true, 'Should handle non-existent folder'); } finally { console.error = consoleError; } // Verify navigation stack wasn't modified assert.strictEqual(mockUIManager.appState.getNavigationStack().length, 1); console.log('Error handling test passed'); } finally { cleanupTestDirectory(testDir); } }); console.log('All integration tests passed!');