test: golden tests for XMLTV guide output (#28) #40

Merged
timothy merged 1 commits from test/28-xmltv-logo-goldens into main 2026-06-27 14:11:20 +02:00
Owner

Closes the XMLTV-guide half of #28 (follow-up to #11's M3U goldens). The channel-logo image test is deliberately not included — see below.

What

ChannelGuideGoldenTests drives the real GetChannelGuideHandler against a Testably fake filesystem (seeded channels.xml + per-channel fragments) and a SQLite-backed IDbContextFactory<TvContext>, then snapshots ChannelGuide.ToXml() to goldens under Iptv/Goldens/guide-*.xml. Same [CallerFilePath] + ETV_UPDATE_GOLDENS harness as the M3U goldens.

Locks the surfaces a guide regression would hit:

  • {RequestBase} host substitution — the XMLTV counterpart to the #1 regression net.
  • {AccessTokenUri} — with and without an access token.
  • etv:-tag stripping — both paired and self-closing forms.
  • hidden-channel exclusion — ShowInEpg=false channel keeps its <channel> def but drops its programme.
  • decimal fragment ordering — channels 2 and 10 prove the sort is decimal, not string.
  • external icon URL passthrough.

The volatile ?v={mtime} cache-buster is normalized; output is OS-independent (static time literals, single-line, LF, BOM stripped).

Adversarial-review fixes folded in

Removed a dead/leaking TvContext.IsSqlite static; made decimal ordering actually exercised (was vacuous with one fragment); canonicalized a trailing newline so the goldens satisfy .editorconfig; included channels.xml in the ListFiles mock to hit the skip branch; switched seeding to EnsureCreatedAsync (suite back to ~2s).

Deliberately deferred

Channel-logo image test — ChannelLogoGenerator loads its font from a global ResourcesCacheFolder path and its overlay from a hardcoded relative path, and SkiaSharp isn't byte-reproducible; a clean test needs a small DI refactor. Tracked as #39. (#28's text pre-authorized skipping it.)

Verification

Full ErsatzTV.Core.Tests: 484 passed, 0 failed (TZ=UTC).

refs #28

Closes the XMLTV-guide half of #28 (follow-up to #11's M3U goldens). The channel-logo image test is deliberately **not** included — see below. ## What `ChannelGuideGoldenTests` drives the real `GetChannelGuideHandler` against a Testably fake filesystem (seeded `channels.xml` + per-channel fragments) and a SQLite-backed `IDbContextFactory<TvContext>`, then snapshots `ChannelGuide.ToXml()` to goldens under `Iptv/Goldens/guide-*.xml`. Same `[CallerFilePath]` + `ETV_UPDATE_GOLDENS` harness as the M3U goldens. Locks the surfaces a guide regression would hit: - **`{RequestBase}` host substitution** — the XMLTV counterpart to the #1 regression net. - `{AccessTokenUri}` — with and without an access token. - **etv:-tag stripping** — both paired and self-closing forms. - **hidden-channel exclusion** — `ShowInEpg=false` channel keeps its `<channel>` def but drops its programme. - **decimal fragment ordering** — channels `2` and `10` prove the sort is decimal, not string. - external icon URL passthrough. The volatile `?v={mtime}` cache-buster is normalized; output is OS-independent (static time literals, single-line, LF, BOM stripped). ## Adversarial-review fixes folded in Removed a dead/leaking `TvContext.IsSqlite` static; made decimal ordering actually exercised (was vacuous with one fragment); canonicalized a trailing newline so the goldens satisfy `.editorconfig`; included `channels.xml` in the `ListFiles` mock to hit the skip branch; switched seeding to `EnsureCreatedAsync` (suite back to ~2s). ## Deliberately deferred Channel-logo image test — `ChannelLogoGenerator` loads its font from a global `ResourcesCacheFolder` path and its overlay from a hardcoded relative path, and SkiaSharp isn't byte-reproducible; a clean test needs a small DI refactor. Tracked as **#39**. (#28's text pre-authorized skipping it.) ## Verification Full `ErsatzTV.Core.Tests`: 484 passed, 0 failed (`TZ=UTC`). refs #28
timothy added 1 commit 2026-06-27 14:05:07 +02:00
test: golden tests for XMLTV guide output (refs #28)
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 3m47s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 4m56s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 4m2s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 5m4s
Build ErsatzTV Image / Build & push image (amd64) (push) Successful in 3m30s
38e743d3cf
Drive the real GetChannelGuideHandler against a Testably fake filesystem
(seeded channels.xml + per-channel fragments) and a SQLite-backed
IDbContextFactory with one visible + one ShowInEpg=false channel, then
snapshot ChannelGuide.ToXml(). Covers the {RequestBase}/{AccessTokenUri}
substitution (the #1 regression surface), etv:-tag stripping, hidden-channel
exclusion, and assembly — with/without access token and with a base URL.
The volatile ?v={mtime} cache-buster is normalized. Same [CallerFilePath]
Goldens + ETV_UPDATE_GOLDENS harness as the M3U goldens (#11).

Core.Tests now references ErsatzTV.Application (handler lives there).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
timothy merged commit 38e743d3cf into main 2026-06-27 14:11:20 +02:00
timothy deleted branch test/28-xmltv-logo-goldens 2026-06-27 14:11:20 +02:00
Sign in to join this conversation.