'use strict'; const test = require('node:test'); const assert = require('node:assert/strict'); const { buildEvents, compareEvents, isEligible } = require('../src/events'); const timezone = 'Europe/Brussels'; function stream(id, name) { return { stream_id: id, name }; } function build(streams, overrides = {}) { return buildEvents(streams, { searchTerm: 'Jupiler Pro League', language: 'nl', timezone, eventDurationMs: 150 * 60 * 1000, urlBuilder: (id) => [`http://upstream/live/u/p/${id}.ts`], ...overrides, }); } test('filters by search term and language, dedupes the same match', () => { const { events } = build([ stream( 1, 'DAZN 01 [Standard de Liège - SK Beveren | Jupiler Pro League (nl) (2026-11-06 19:25:00)]' ), stream( 2, 'DAZN 02 [Standard de Liège - SK Beveren | Jupiler Pro League (nl) (2026-11-06 19:25:00)]' ), stream( 3, 'DAZN 03 [Standard de Liège - SK Beveren | Jupiler Pro League (fr) (2026-11-06 19:25:00)]' ), stream(4, 'DAZN 04 [Anderlecht - Genk | Jupiler Pro League (2026-11-06 19:25:00)]'), stream(5, 'DAZN 05 [Other League (nl) (2026-11-06 19:25:00)]'), ]); assert.equal(events.size, 2); const [first, second] = [...events.values()]; assert.equal(first.title, 'Standard de Liège - SK Beveren'); assert.deepEqual(first.sources.map((source) => source.streamId), ['1', '2']); assert.equal(first.language, 'nl'); assert.equal(second.sources[0].streamId, '4'); }); test('reports unparseable matching names as warnings', () => { const { events, warnings } = build([stream(1, 'DAZN 01 | Jupiler Pro League zonder tijd')]); assert.equal(events.size, 0); assert.equal(warnings.length, 1); assert.equal(warnings[0].reason, 'unparseable_name'); }); test('an event is eligible inside the start grace and before its end', () => { const event = { startAt: new Date('2026-11-06T18:25:00.000Z'), endAt: new Date('2026-11-06T20:55:00.000Z'), }; const options = { startGraceMs: 10 * 60 * 1000 }; assert.equal(isEligible(event, Date.parse('2026-11-06T18:16:00.000Z'), options), true); assert.equal(isEligible(event, Date.parse('2026-11-06T18:14:00.000Z'), options), false); assert.equal(isEligible(event, Date.parse('2026-11-06T20:54:00.000Z'), options), true); assert.equal(isEligible(event, Date.parse('2026-11-06T20:56:00.000Z'), options), false); }); test('sorting is by start time and then arrival order', () => { const a = { key: 'a', startAt: new Date('2026-11-06T19:00:00Z'), firstSeenSeq: 2, }; const b = { key: 'b', startAt: new Date('2026-11-06T19:00:00Z'), firstSeenSeq: 1, }; const c = { key: 'c', startAt: new Date('2026-11-06T18:00:00Z'), firstSeenSeq: 3, }; assert.deepEqual([a, b, c].sort(compareEvents).map((event) => event.key), ['c', 'b', 'a']); });