test(67): de-vacuify the template-stamping assertion; cover adopt-then-delete
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (pull_request) Successful in 11s
Build ErsatzTV Image / CI image pin matches docker/ci (pull_request) Successful in 9s
Build ErsatzTV Image / Docs update reminder (pull_request) Successful in 10s
Build ErsatzTV Image / decisions.md append-only (pull_request) Successful in 1m6s
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (pull_request) Successful in 13m25s
Build ErsatzTV Image / Functional E2E (curl contracts) (pull_request) Successful in 16m1s
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 20m26s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 21m19s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped

Whole-branch review found the stamping test was structurally vacuous: a bare
foreach over ChannelTemplates.Where(IsSystem) passes with zero iterations, so
the test would have stayed green if template seeding silently bailed out.
Assert the collection is non-empty first. Proven non-vacuous by a negative
control (forcing SeedChannelTemplates to bail makes exactly this test fail).

Also cover the ACTUAL production sequence -- adopt an existing hand-made row,
then delete it -- which the previous no-resurrect test did not exercise (it
covered seed-then-delete). The marker is written on the adopt path too, so
the deleted row must stay deleted.

docs: note that a deleted preset degrades to no default rather than failing,
and that the default applies to newly created channels, not retroactively.

Refs #67
This commit is contained in:
2026-07-20 21:13:47 +02:00
parent 5d0a70a20f
commit 893d4a6398
2 changed files with 42 additions and 3 deletions
@@ -99,6 +99,37 @@ public class DbInitializerChannelBugWatermarkTests
context.ChannelWatermarks.Any(w => w.Name == "Channel Bug").ShouldBeFalse();
}
// The production sequence is ADOPT (an existing hand-made row) and then, possibly, delete —
// not seed-then-delete. The marker is written on the adopt path too, so this must not resurrect.
[Test]
public async Task Initialize_Should_Not_Resurrect_An_Adopted_Preset_After_Deletion()
{
await using TvContext context = _db.CreateContext();
await context.ChannelWatermarks.AddAsync(
new ChannelWatermark
{
Name = "Channel Bug",
Mode = ChannelWatermarkMode.Permanent,
ImageSource = ChannelWatermarkImageSource.ChannelLogo,
Location = WatermarkLocation.BottomRight,
Size = WatermarkSize.Scaled,
WidthPercent = 12,
Opacity = 55
});
await context.SaveChangesAsync();
// First run adopts the existing row and records the marker.
await DbInitializer.Initialize(context, CancellationToken.None);
ChannelWatermark adopted = context.ChannelWatermarks.Single(w => w.Name == "Channel Bug");
context.ChannelWatermarks.Remove(adopted);
await context.SaveChangesAsync();
await DbInitializer.Initialize(context, CancellationToken.None);
context.ChannelWatermarks.Any(w => w.Name == "Channel Bug").ShouldBeFalse();
}
[Test]
public async Task Initialize_Should_Stamp_The_Preset_On_Freshly_Seeded_Templates()
{
@@ -107,7 +138,12 @@ public class DbInitializerChannelBugWatermarkTests
await DbInitializer.Initialize(context, CancellationToken.None);
ChannelWatermark watermark = context.ChannelWatermarks.Single(w => w.Name == "Channel Bug");
foreach (ChannelTemplate template in context.ChannelTemplates.Where(t => t.IsSystem).ToList())
List<ChannelTemplate> templates = context.ChannelTemplates.Where(t => t.IsSystem).ToList();
// Assert the collection is non-empty FIRST: a bare foreach over zero rows passes vacuously,
// so this test would stay green if template seeding silently bailed out.
templates.Count.ShouldBe(2);
foreach (ChannelTemplate template in templates)
{
template.WatermarkId.ShouldBe(watermark.Id);
}
+5 -2
View File
@@ -154,8 +154,11 @@ listing and the bug (#67). An existing `Channel Bug` row is adopted untouched, n
a `ConfigElement` marker (`watermark.channel_bug_seeded`) makes the seed run once per database, so a
deliberately deleted preset is not resurrected on the next restart.
Quick-add channel creation defaults to the preset, and the channel editor's Branding tab exposes it
as a "Use logo as on-screen bug" toggle. On a **fresh** install the seed also stamps the preset onto
Quick-add channel creation defaults to the preset (if the preset has been deleted, creation falls
back to no watermark rather than failing), and the channel editor's Branding tab exposes it as a
"Use logo as on-screen bug" toggle. The default applies to **newly created** channels — an existing
channel with no watermark does not gain one retroactively when a logo is uploaded; flip the toggle.
On a **fresh** install the seed also stamps the preset onto
the system channel templates it creates, so the library-to-lineup builder (which inherits
`WatermarkId` from the selected template) gets the default too. On an existing install the templates
are left alone, so builder-created and auto-tuned channels there inherit whatever the template