- Move phase/plan docs into docs/ - Move legacy node:test files into tests/legacy/ with README - Remove .backup file, test audit artifacts, and unused AI prompt/skill files - Remove broken iOS GitHub workflows (reference missing MovieMapper-iOS/)
444 lines
14 KiB
JavaScript
444 lines
14 KiB
JavaScript
// 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!'); |