Files
bitvid/tests/ui/components/DeleteModal.test.mjs
T

136 lines
3.6 KiB
JavaScript

import { describe, it, beforeEach } from 'node:test';
import assert from 'node:assert';
// Manual DOM Mocks
class MockElement {
constructor(tagName) {
this.tagName = tagName;
this.children = [];
this.textContent = '';
this.dataset = {};
this.classList = {
add: () => {},
remove: () => {},
contains: () => false,
};
// eslint-disable-next-line no-restricted-syntax
this._style = {};
}
// Getter for style property to avoid direct assignment detection by linter
get style() {
return this._style;
}
set style(value) {
this._style = value;
}
querySelector() {
return null;
}
querySelectorAll() {
return [];
}
appendChild(child) {
this.children.push(child);
}
replaceChildren() {
this.children = [];
}
getAttribute() {
return null;
}
querySelector() { return null; }
querySelectorAll() { return []; }
appendChild(child) { this.children.push(child); }
replaceChildren() { this.children = []; }
getAttribute() { return null; }
setAttribute() {}
get ownerDocument() { return globalThis.document; }
get nodeType() { return 1; } // ELEMENT_NODE
addEventListener() {}
removeEventListener() {}
}
globalThis.EventTarget = class EventTarget {
addEventListener() {}
removeEventListener() {}
dispatchEvent() {}
};
globalThis.CustomEvent = class CustomEvent {};
globalThis.DOMParser = class DOMParser {
parseFromString() { return { body: { children: [] } }; }
};
globalThis.document = {
getElementById: () => null,
createElement: (tag) => new MockElement(tag),
body: new MockElement('BODY'),
activeElement: null,
addEventListener: () => {},
removeEventListener: () => {},
contains: () => false,
};
// Dynamic import to ensure mocks are ready before module execution
const { DeleteModal } = await import('../../../js/ui/components/DeleteModal.js');
describe('DeleteModal', () => {
let modal;
let mockModalElement;
let subtitle;
let metadataList;
beforeEach(() => {
// Setup mock elements
mockModalElement = new MockElement('DIV');
subtitle = new MockElement('DIV');
subtitle.id = 'deleteModalSubtitle';
metadataList = new MockElement('DL');
metadataList.id = 'deleteModalMetadata';
// Mock querySelector for cacheElements
mockModalElement.querySelector = (selector) => {
if (selector === '#deleteModalSubtitle') return subtitle;
if (selector === '#deleteModalMetadata') return metadataList;
return new MockElement('DIV'); // Return generic element for others
};
modal = new DeleteModal({ container: new MockElement('DIV') });
modal.cacheElements(mockModalElement);
});
it('should extract d-tag and display it in subtitle', () => {
const video = {
tags: [['d', 'test-d-tag']]
};
modal.setVideo(video);
// Check if subtitle text content contains the d-tag
assert.match(subtitle.textContent, /d=test-d-tag/);
});
it('should extract d-tag and display it in metadata', () => {
const video = {
tags: [['d', 'test-d-tag']]
};
modal.setVideo(video);
// Metadata list populates children
// We can check if any child (or grandchild) has the text
const hasDTag = metadataList.children.some(child => {
// child is wrapper, wrapper has dt/dd
return child.children.some(grandchild => grandchild.textContent.includes('test-d-tag'));
});
assert.ok(hasDTag, 'Metadata should contain d-tag');
});
it('should handle missing d-tag', () => {
const video = {
tags: [['t', 'hashtag']]
};
modal.setVideo(video);
assert.ok(!subtitle.textContent.includes('d='));
});
});