diff --git a/libs/ui/epg/src/lib/epg-list-view/epg-list-view.utils.spec.ts b/libs/ui/epg/src/lib/epg-list-view/epg-list-view.utils.spec.ts index 50d90dd6a..fdc42bfc0 100644 --- a/libs/ui/epg/src/lib/epg-list-view/epg-list-view.utils.spec.ts +++ b/libs/ui/epg/src/lib/epg-list-view/epg-list-view.utils.spec.ts @@ -120,6 +120,24 @@ describe('buildEpgListRows', () => { ); }); + it('drops malformed programmes whose stop is not after their start', () => { + // Same as the timeline's buildTimelineBlocks: zero/negative durations + // from bad provider data must not render (or become catch-up playable). + const zeroDuration = programAt(-60, 0, 'Zero'); + const negativeDuration = { + ...programAt(-60, 60, 'Negative'), + stop: new Date(NOW - 120 * 60_000).toISOString(), + }; + const rows = buildEpgListRows( + [zeroDuration, negativeDuration, programAt(-30, 60, 'Now')], + TODAY, + NOW, + DEFAULT_OPTS + ); + + expect(rows.map((r) => r.program.title)).toEqual(['Now']); + }); + it('deduplicates programmes sharing a time slot, keeping the richer one', () => { const rows = buildEpgListRows( [ diff --git a/libs/ui/epg/src/lib/epg-list-view/epg-list-view.utils.ts b/libs/ui/epg/src/lib/epg-list-view/epg-list-view.utils.ts index 9c9162a6c..3c5c1a69d 100644 --- a/libs/ui/epg/src/lib/epg-list-view/epg-list-view.utils.ts +++ b/libs/ui/epg/src/lib/epg-list-view/epg-list-view.utils.ts @@ -77,6 +77,12 @@ export function buildEpgListRows( if (!Number.isFinite(startMs) || !Number.isFinite(stopMs)) { return false; } + // Drop malformed programmes (stop not after start) — same as the + // timeline's buildTimelineBlocks; they would render impossible time + // ranges and could even be offered as catch-up playable. + if (stopMs <= startMs) { + return false; + } return startMs < dayEndMs && stopMs > dayStartMs; });