using Xunit; using ytLive.Models; using ytLive.Services; namespace ytLive.Tests; /// /// Report-by-exception (TASK 5 item 3): the banner decision is pure so the /// severity/threshold rules are pinned without any HTTP or UI. /// public class StreamHealthReporterTests { [Fact] public void Banner_Is_Null_For_Empty_Or_Info_Only_Issues() { Assert.Null(StreamHealthReporter.BannerFor([]).Text); var report = StreamHealthReporter.BannerFor(new[] { new StreamConfigurationIssue { Severity = StreamIssueSeverity.Info, Type = "lowLatency" }, }); Assert.Null(report.Text); } [Fact] public void Warning_Yields_Text_Without_Error_Color() { var report = StreamHealthReporter.BannerFor(new[] { new StreamConfigurationIssue { Severity = StreamIssueSeverity.Warning, Type = "reconnect" }, }); Assert.Equal("reconnect", report.Text); Assert.False(report.IsError); } [Fact] public void Error_Issue_Yields_Text_And_Error_Color_Even_With_Warnings() { var report = StreamHealthReporter.BannerFor(new[] { new StreamConfigurationIssue { Severity = StreamIssueSeverity.Warning, Type = "reconnect" }, new StreamConfigurationIssue { Severity = StreamIssueSeverity.Error, Type = "bitrateHigh" }, }); Assert.Equal("reconnect, bitrateHigh", report.Text); Assert.True(report.IsError); } [Fact] public void Blank_Issue_Types_Are_Dropped_From_The_Banner() { var report = StreamHealthReporter.BannerFor(new[] { new StreamConfigurationIssue { Severity = StreamIssueSeverity.Error, Type = null }, new StreamConfigurationIssue { Severity = StreamIssueSeverity.Error, Type = " " }, new StreamConfigurationIssue { Severity = StreamIssueSeverity.Error, Type = "bitrateLow" }, }); Assert.Equal("bitrateLow", report.Text); Assert.True(report.IsError); } }