Skip to content

Commit ad1cd53

Browse files
authored
Merge pull request #203 from hyperaudio/197-refactor
- initial refactor - added tests
2 parents 093de68 + 34eccda commit ad1cd53

File tree

3 files changed

+520
-458
lines changed

3 files changed

+520
-458
lines changed

__TEST__/hyperaudio-lite.test.js

Lines changed: 138 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,18 @@ const { HyperaudioLite } = require("../js/hyperaudio-lite");
1111
let wordArr = [];
1212
let ht = null;
1313

14+
15+
16+
test("initialization with parameters", () => {
17+
const customHt = new HyperaudioLite("hypertranscript", "hyperplayer", true, true, true, true, true);
18+
19+
expect(customHt.minimizedMode).toBe(true);
20+
expect(customHt.autoscroll).toBe(true);
21+
expect(customHt.doubleClick).toBe(true);
22+
expect(customHt.webMonetization).toBe(true);
23+
expect(customHt.playOnClick).toBe(true);
24+
});
25+
1426
function createWordArrayResult(words) {
1527
for (let i = 0; i < words.length; ++i) {
1628
const m = parseInt(words[i].getAttribute("data-m"));
@@ -59,7 +71,8 @@ document.body.innerHTML =
5971

6072
window.HTMLMediaElement.prototype.play = () => {
6173
/* does nothing */
62-
};
74+
}
75+
6376

6477
test("instantiation - options false", () => {
6578
let minimizedMode = false;
@@ -77,6 +90,8 @@ test("instantiation - options false", () => {
7790
);
7891
});
7992

93+
94+
8095
test("createWordArray", () => {
8196
const words = document.querySelectorAll("[data-m]");
8297
const expectedResult = createWordArrayResult(words);
@@ -131,11 +146,6 @@ test("instantiation - doubleClick true", () => {
131146
);
132147
});
133148

134-
test("transcript - doubleClick on word", () => {
135-
simulateClick(document.getElementsByTagName("span")[4], "dblclick");
136-
expect(ht.player.currentTime).toStrictEqual(4.75);
137-
});
138-
139149
test("instantiation - webMonetization true", () => {
140150
let minimizedMode = false;
141151
let autoScroll = false;
@@ -152,6 +162,11 @@ test("instantiation - webMonetization true", () => {
152162
);
153163
});
154164

165+
test("transcript - doubleClick on word", () => {
166+
simulateClick(document.getElementsByTagName("span")[4], "dblclick");
167+
expect(ht.player.currentTime).toStrictEqual(4.75);
168+
});
169+
155170
// This test always passes - fix it
156171
/*test("transcript - payment pointer inserted", () => {
157172
simulateClick(document.getElementsByTagName("span")[4], "click");
@@ -177,3 +192,120 @@ test("transcript - check that active is set on paragraph", () => {
177192
simulateClick(document.getElementsByTagName("span")[4], "dblclick");
178193
expect(document.querySelector('p.active')).toBe(document.getElementsByTagName('p')[0]);
179194
});
195+
196+
test("setupTranscriptHash with no hash", () => {
197+
window.location.hash = "";
198+
ht.setupTranscriptHash();
199+
expect(ht.hashArray).toEqual([]);
200+
});
201+
202+
test("setupTranscriptHash with valid hash", () => {
203+
window.location.hash = "#hypertranscript=10,20";
204+
ht.setupTranscriptHash();
205+
expect(ht.hashArray).toEqual(["10", "20"]);
206+
});
207+
208+
test("getSelectionRange with no selection", () => {
209+
window.getSelection().removeAllRanges();
210+
expect(ht.getSelectionRange()).toBeNull();
211+
});
212+
213+
test("getSelectionRange with valid selection", () => {
214+
const firstSpan = document.querySelector('span[data-m="880"]');
215+
const lastSpan = document.querySelector('span[data-m="4750"]');
216+
const range = document.createRange();
217+
range.setStartBefore(firstSpan);
218+
range.setEndAfter(lastSpan);
219+
window.getSelection().removeAllRanges();
220+
window.getSelection().addRange(range);
221+
222+
expect(ht.getSelectionRange()).toBe("0.88,5.21");
223+
});
224+
225+
test("clearActiveClasses removes all active classes", () => {
226+
const spans = document.querySelectorAll('span');
227+
spans.forEach(span => span.classList.add('active'));
228+
229+
ht.clearActiveClasses();
230+
231+
spans.forEach(span => {
232+
expect(span.classList.contains('active')).toBe(false);
233+
});
234+
});
235+
236+
test("scrollToParagraph updates parentElementIndex", () => {
237+
ht.parentElementIndex = 0;
238+
ht.scrollToParagraph(1, 6);
239+
expect(ht.parentElementIndex).toBe(1);
240+
});
241+
242+
test("checkPaymentPointer returns correct payment pointer", () => {
243+
const p1 = document.getElementById('p1');
244+
expect(ht.checkPaymentPointer(p1)).toBe("payment-pointer");
245+
});
246+
247+
test("checkPaymentPointer returns null for element without payment pointer", () => {
248+
const p2 = document.querySelectorAll('p')[1];
249+
expect(ht.checkPaymentPointer(p2)).toBeNull();
250+
});
251+
252+
test("updateTranscriptVisualState marks words as read", () => {
253+
ht.updateTranscriptVisualState(5);
254+
const spans = document.querySelectorAll('span');
255+
expect(spans[0].classList.contains('read')).toBe(true);
256+
expect(spans[4].classList.contains('read')).toBe(true);
257+
expect(spans[5].classList.contains('unread')).toBe(true);
258+
});
259+
260+
test("setPlayHead updates currentTime and plays if playOnClick is true", () => {
261+
ht.playOnClick = true;
262+
ht.myPlayer = { setTime: jest.fn(), play: jest.fn(), paused: true };
263+
264+
const event = { target: document.querySelector('span[data-m="3950"]') };
265+
ht.setPlayHead(event);
266+
267+
expect(ht.myPlayer.setTime).toHaveBeenCalledWith(3.95);
268+
expect(ht.myPlayer.play).toHaveBeenCalled();
269+
});
270+
271+
test("preparePlayHead sets paused to false and calls checkPlayHead", () => {
272+
ht.checkPlayHead = jest.fn();
273+
ht.preparePlayHead();
274+
275+
expect(ht.myPlayer.paused).toBe(false);
276+
expect(ht.checkPlayHead).toHaveBeenCalled();
277+
});
278+
279+
test("pausePlayHead clears timer and sets paused to true", () => {
280+
jest.useFakeTimers();
281+
ht.timer = setTimeout(() => {}, 1000);
282+
ht.pausePlayHead();
283+
284+
expect(ht.myPlayer.paused).toBe(true);
285+
expect(ht.timer).toBeFalsy();
286+
jest.useRealTimers();
287+
});
288+
289+
// This test requires jest.useFakeTimers() to work properly
290+
test("checkStatus schedules next check", () => {
291+
jest.useFakeTimers();
292+
ht.myPlayer = {
293+
paused: false,
294+
getTime: jest.fn().mockResolvedValue(5)
295+
};
296+
ht.updateTranscriptVisualState = jest.fn().mockReturnValue({ currentWordIndex: 4, currentParentElementIndex: 0 });
297+
ht.scrollToParagraph = jest.fn();
298+
ht.checkPlayHead = jest.fn();
299+
300+
ht.checkStatus();
301+
302+
jest.runAllTimers();
303+
304+
expect(ht.checkPlayHead).toHaveBeenCalled();
305+
306+
jest.useRealTimers();
307+
});
308+
309+
310+
311+

0 commit comments

Comments
 (0)