// Test renderer business logic and state management const { test } = require('node:test'); const assert = require('node:assert'); // Test AppState class test('AppState - should initialize with default values', () => { const AppState = require('./utils/renderer/AppState'); const state = new AppState(); assert.strictEqual(state.getCurrentDirectory(), null); assert.deepStrictEqual(state.getCurrentFiles(), []); assert.strictEqual(state.getCurrentShow(), null); assert.deepStrictEqual(state.getCurrentSeasons(), []); assert.deepStrictEqual(state.getCurrentEpisodes(), []); assert.strictEqual(state.getSelectedSeasonEpisodeCount(), 0); assert.strictEqual(state.isUpdatingEpisodeNumbers, false); // property, not method }); test('AppState - should set and get directory', () => { const AppState = require('./utils/renderer/AppState'); const state = new AppState(); state.setCurrentDirectory('/test/path'); assert.strictEqual(state.getCurrentDirectory(), '/test/path'); }); test('AppState - should set and get files', () => { const AppState = require('./utils/renderer/AppState'); const state = new AppState(); const files = [{ path: '/test/file.mp4', name: 'file.mp4' }]; state.setCurrentFiles(files); assert.deepStrictEqual(state.getCurrentFiles(), files); }); test('AppState - should set and get show', () => { const AppState = require('./utils/renderer/AppState'); const state = new AppState(); const show = { id: 'series-123', name: 'Test Show' }; state.setCurrentShow(show); assert.deepStrictEqual(state.getCurrentShow(), show); }); test('AppState - should reset state', () => { const AppState = require('./utils/renderer/AppState'); const state = new AppState(); state.setCurrentDirectory('/test/path'); state.setCurrentFiles([{ path: '/test/file.mp4' }]); state.setCurrentShow({ id: 'series-123' }); state.reset(); assert.strictEqual(state.getCurrentDirectory(), null); assert.deepStrictEqual(state.getCurrentFiles(), []); assert.strictEqual(state.getCurrentShow(), null); }); // Test EpisodeManager business logic test('EpisodeManager - should get episode range from element', () => { const EpisodeManager = require('./utils/renderer/EpisodeManager'); const manager = new EpisodeManager(); const mockElement = { dataset: { episodeStart: '5', episodeEnd: '7' } }; const range = manager.getEpisodeRange(mockElement); assert.strictEqual(range.start, 5); assert.strictEqual(range.end, 7); }); test('EpisodeManager - should default to single episode', () => { const EpisodeManager = require('./utils/renderer/EpisodeManager'); const manager = new EpisodeManager(); const mockElement = { dataset: {} }; const range = manager.getEpisodeRange(mockElement); assert.strictEqual(range.start, 1); assert.strictEqual(range.end, 1); }); test('EpisodeManager - should calculate total episode count', () => { const EpisodeManager = require('./utils/renderer/EpisodeManager'); const manager = new EpisodeManager(); // Create mock episode element that querySelector can find const mockEpisodeEl1 = { dataset: { episodeStart: '1', episodeEnd: '3' } }; const mockEpisodeEl2 = { dataset: { episodeStart: '4', episodeEnd: '5' } }; // Mock file items with querySelector method const mockFile1 = { querySelector: (selector) => { if (selector === '.episode-number') return mockEpisodeEl1; return null; } }; const mockFile2 = { querySelector: (selector) => { if (selector === '.episode-number') return mockEpisodeEl2; return null; } }; const mockFileList = { querySelectorAll: () => [mockFile1, mockFile2] }; const total = manager.calculateTotalEpisodeCount(mockFileList); assert.strictEqual(total, 5); // 3 + 2 }); test('EpisodeManager - should get last episode end', () => { const AppState = require('./utils/renderer/AppState'); const state = new AppState(); // Test the property exists assert.strictEqual(typeof state.isUpdatingEpisodeNumbers, 'boolean'); }); // Test TagManager business logic test('TagManager - should have tag colors', () => { const TagManager = require('./utils/renderer/TagManager'); const manager = new TagManager(); assert.strictEqual(manager.tagColors.extra, '#28a745'); assert.strictEqual(manager.tagColors['behind-the-scenes'], '#17a2b8'); assert.strictEqual(manager.tagColors.delete, '#dc3545'); }); test('TagManager - should identify tag types', () => { const TagManager = require('./utils/renderer/TagManager'); const manager = new TagManager(); assert.ok(manager.tagColors['extra'], 'Should have extra tag color'); assert.ok(manager.tagColors['behind-the-scenes'], 'Should have behind-the-scenes tag color'); assert.ok(manager.tagColors['delete'], 'Should have delete tag color'); }); // Test FileManager business logic test('FileManager - should have all required methods', () => { const FileManager = require('./utils/renderer/FileManager'); const manager = new FileManager(); assert.strictEqual(typeof manager.selectDirectory, 'function'); assert.strictEqual(typeof manager.scanDirectory, 'function'); assert.strictEqual(typeof manager.renameFile, 'function'); assert.strictEqual(typeof manager.beginMapping, 'function'); assert.strictEqual(typeof manager.logAuditEvent, 'function'); assert.strictEqual(typeof manager.moveFileToFolder, 'function'); assert.strictEqual(typeof manager.logFileInfo, 'function'); }); test('FileManager - should collect file data with episode ranges', () => { const FileManager = require('./utils/renderer/FileManager'); const manager = new FileManager(); // Test the method exists assert.strictEqual(typeof manager.collectFileData, 'function'); }); // Test SearchManager business logic test('SearchManager - should initialize with default values', () => { const SearchManager = require('./utils/renderer/SearchManager'); // Create mock elements const mockInput = { value: '' }; const mockResults = { innerHTML: '' }; const manager = new SearchManager(mockInput, mockResults); assert.strictEqual(manager.currentShow, null); }); test('SearchManager - should clear search results', () => { const SearchManager = require('./utils/renderer/SearchManager'); const mockInput = { value: '' }; const mockResults = { innerHTML: '' }; const manager = new SearchManager(mockInput, mockResults); assert.strictEqual(typeof manager.clearSearchResults, 'function'); }); // Test ProgressManager business logic test('ProgressManager - should show progress', () => { const ProgressManager = require('./utils/renderer/ProgressManager'); const mockContainer = { style: { display: '' } }; const mockText = { textContent: '' }; const mockCount = { textContent: '' }; const manager = new ProgressManager(mockContainer, mockText, mockCount); assert.strictEqual(typeof manager.showProgress, 'function'); }); test('ProgressManager - should hide progress', () => { const ProgressManager = require('./utils/renderer/ProgressManager'); const mockContainer = { style: { display: '' } }; const mockText = { textContent: '' }; const mockCount = { textContent: '' }; const manager = new ProgressManager(mockContainer, mockText, mockCount); assert.strictEqual(typeof manager.hideProgress, 'function'); }); // Test UIManager business logic test('UIManager - should initialize all managers', () => { const UIManager = require('./utils/renderer/UIManager'); // Verify UIManager exists and is a class assert.strictEqual(typeof UIManager, 'function'); assert.strictEqual(UIManager.name, 'UIManager'); }); // Skip UIManager constructor test in Node.js environment (requires DOM) test('UIManager - should have all required methods', () => { // Mock Electron ipcRenderer const mockIpcRenderer = { on: () => {}, invoke: () => ({ success: true }) }; // Mock window object const mockWindow = { addEventListener: () => {} }; // Mock document with required elements const mockDocument = { getElementById: (id) => { // Return mock elements for required IDs const mockElement = { addEventListener: () => {}, style: {}, textContent: '', innerHTML: '', querySelector: () => null, querySelectorAll: () => [], classList: { add: () => {}, remove: () => {} }, dataset: {}, hasAttribute: () => false, setAttribute: () => {}, removeAttribute: () => {} }; return mockElement; }, querySelectorAll: (selector) => [], addEventListener: () => {}, body: { appendChild: () => {} } }; // Store original require cache entries const originalRequireCache = { ...require.cache }; // Create mock electron module const mockElectronModule = { ipcRenderer: mockIpcRenderer }; // Create mock window module (empty, just for completeness) const mockWindowModule = {}; // Temporarily replace require cache for electron and window const electronRequirePath = require.resolve('electron'); require.cache[electronRequirePath] = { exports: mockElectronModule }; // Temporarily replace document and window globals const originalDocument = global.document; const originalWindow = global.window; global.document = mockDocument; global.window = mockWindow; try { // Clear the UIManager module cache to force re-require with mocked dependencies delete require.cache[require.resolve('./utils/renderer/UIManager')]; const UIManager = require('./utils/renderer/UIManager'); const uiManager = new UIManager(); // Check that key methods exist assert.strictEqual(typeof uiManager.selectDirectory, 'function'); assert.strictEqual(typeof uiManager.scanDirectory, 'function'); assert.strictEqual(typeof uiManager.searchShows, 'function'); assert.strictEqual(typeof uiManager.beginMapping, 'function'); } finally { // Restore original require cache require.cache = originalRequireCache; // Restore original globals global.document = originalDocument; global.window = originalWindow; } }); console.log('\n✅ All renderer business logic tests passed!');