using Xunit; using ytLive.Models; namespace ytLive.Tests; /// Which session an armed output starts, and where a press routes. /// /// Superseded 2026-11-12: the ON-AIR start no longer infers Test from EDIT. The output stage /// offers "Private Test Stream" and "Review & Go Live" as separate buttons, so ON-AIR always means the /// real livestream here. REC always records, because there is no test recording. public class SessionStartDecisionTests { [Fact] public void The_armed_output_decides_the_session_kind_and_test_is_never_inferred() { // ON-AIR armed: the real livestream, never a test. Assert.Equal(SessionStartKind.Live, SessionStartDecision.For(recordArmed: false, onAirArmed: true)); Assert.Equal("Go Live", SessionStartDecision.LabelFor(SessionStartKind.Live)); // REC armed: always a recording (no test recording exists). Assert.Equal(SessionStartKind.Record, SessionStartDecision.For(true, false)); Assert.Equal("Start Recording", SessionStartDecision.LabelFor(SessionStartKind.Record)); // Signed out: an ON-AIR press (live OR test) routes to the sign-in flow, never a dead // button. Recording never needs an account. Assert.Equal(SessionStartDecision.Route.SignIn, SessionStartDecision.RouteFor(SessionStartKind.Live, connected: false)); Assert.Equal(SessionStartDecision.Route.SignIn, SessionStartDecision.RouteFor(SessionStartKind.Test, connected: false)); Assert.Equal(SessionStartDecision.Route.Live, SessionStartDecision.RouteFor(SessionStartKind.Live, connected: true)); Assert.Equal(SessionStartDecision.Route.Test, SessionStartDecision.RouteFor(SessionStartKind.Test, connected: true)); Assert.Equal(SessionStartDecision.Route.Record, SessionStartDecision.RouteFor(SessionStartKind.Record, connected: false)); // Unarmed start records locally (the no-dead-ends rule). Assert.Equal(SessionStartKind.Record, SessionStartDecision.For(false, false)); } }