Update comprehensive test suite with improved mocks

- Improved mock element implementation with proper innerHTML/textContent support
- Added getElementById mock that returns different elements based on ID
- Enhanced querySelectorAll mock for episode number queries
- Fixed isUpdatingEpisodeNumbers test to access property directly
- Tests now show 41/70 passing with improved mocks
This commit is contained in:
Jarian Cottingham 2026-02-25 08:15:55 -06:00
parent 4d7d476a44
commit f0f423c2f1

View File

@ -2,50 +2,111 @@ const { test, describe, beforeEach, afterEach } = require('node:test');
const assert = require('node:assert');
// Create a simple mock for DOM
const createMockElement = () => ({
style: {},
innerHTML: '',
textContent: '',
dataset: {},
className: '',
addEventListener: () => {},
removeEventListener: () => {},
appendChild: () => {},
insertBefore: () => {},
remove: () => {},
querySelector: () => null,
querySelectorAll: () => [],
setAttribute: () => {},
removeAttribute: () => {},
hasAttribute: () => false,
closest: () => null,
contains: () => false,
focus: () => {},
blur: () => {},
click: () => {},
dispatchEvent: () => true,
classList: { add: () => {}, remove: () => {} },
get parentElement() { return null; }
});
const createMockElement = (overrides = {}) => {
const el = {
style: {},
get innerHTML() { return this._innerHTML || ''; },
set innerHTML(val) {
this._innerHTML = val;
// Parse simple HTML to extract textContent for episode numbers
if (val.includes('episode-number')) {
const match = val.match(/>(\d+|-?\d+-\d+)<\/div>/);
this._textContent = match ? match[1] : '';
}
},
get textContent() { return this._textContent || ''; },
set textContent(val) { this._textContent = val; },
dataset: {},
className: '',
addEventListener: () => {},
removeEventListener: () => {},
appendChild: () => {},
insertBefore: () => {},
remove: () => {},
querySelector: () => null,
querySelectorAll: (selector) => {
// Simple mock implementation
if (selector === '.episode-number') {
return [{
textContent: '1',
dataset: { episodeStart: '1', episodeEnd: '1' },
style: {},
addEventListener: () => {},
removeEventListener: () => {}
}];
}
return [];
},
setAttribute: () => {},
removeAttribute: () => {},
hasAttribute: () => false,
closest: () => null,
contains: () => false,
focus: () => {},
blur: () => {},
click: () => {},
dispatchEvent: () => true,
classList: { add: () => {}, remove: () => {} },
get parentElement() { return null; }
};
return { ...el, ...overrides };
};
// Mock DOM - create different elements based on ID
const mockElements = {
'file-list': createMockElement({ innerHTML: '<div class="file-item"><div class="episode-number">1</div></div>' }),
'search-results': createMockElement(),
'show-details': createMockElement(),
'episode-list': createMockElement(),
'modal': createMockElement({ className: 'modal' }),
'progress-container': createMockElement()
};
// Mock DOM
global.document = {
getElementById: () => createMockElement(),
getElementById: (id) => mockElements[id] || createMockElement(),
querySelector: () => null,
querySelectorAll: () => [],
querySelectorAll: (selector) => {
// Return mock elements based on selector
if (selector === '.episode-number') {
return [createMockElement({ textContent: '1', dataset: { episodeStart: '1', episodeEnd: '1' } })];
}
if (selector === '.file-item') {
return [createMockElement()];
}
return [];
},
addEventListener: () => {},
removeEventListener: () => {},
createElement: () => createMockElement(),
createRange: () => ({ selectNodeContents: () => {} }),
getSelection: () => ({ addRange: () => {}, removeAllRanges: () => {} })
getSelection: () => ({
addRange: () => {},
removeAllRanges: () => {},
getRangeAt: () => ({
startContainer: { nodeValue: '1-3' },
endContainer: { nodeValue: '1-3' }
}),
toString: () => '1-3'
})
};
global.window = {
addEventListener: () => {},
dispatchEvent: () => true,
getComputedStyle: () => ({ display: 'block' })
getComputedStyle: () => ({
display: 'block',
getPropertyValue: () => '#e94560'
}),
getSelection: () => ({
toString: () => '1-3',
addRange: () => {},
removeAllRanges: () => {}
})
};
// Mock window.confirm for file move confirmation
window.confirm = () => true;
// Mock ipcRenderer with proper module handling
const mockIpcRenderer = {
invoke: async (channel, ...args) => {
@ -183,7 +244,7 @@ describe('AppState', () => {
test('should set and get updating episode numbers flag', () => {
appState.setUpdatingEpisodeNumbers(true);
assert.strictEqual(appState.isUpdatingEpisodeNumbers(), true);
assert.strictEqual(appState.isUpdatingEpisodeNumbers, true);
});
test('should reset all state', () => {