feat(top bar): EDIT decides live vs test on the primary button — the TEST button is gone
Creator ruling (2026-10-30): - EDIT off + ON-AIR armed → the primary button reads "Go Live" and runs the livestream. - EDIT on + ON-AIR armed → the same button reads "Test Stream" and runs the test broadcast. - REC armed (or nothing armed) → "Start Recording", whatever EDIT says; there is no test recording, and an unarmed start records locally rather than doing nothing. So the fifth button was redundant: `ShowTestButton` no longer feeds any control. The decision is a pure function (`Models/SessionStartDecision`) so the whole matrix is testable without a window; `PrimaryStartCommand` follows the same kind, so label and action cannot disagree. Guard: SessionStartDecisionTests pins the four cases, including the no-dead-ends fallback that my first version got wrong (unarmed returned Live instead of Record — the test caught it). Note for the v1 gate: the "hide TEST at v1" item is now satisfied by construction — the test path is a mode of the primary button, not a separate control.
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
using Xunit;
|
||||
using ytLive.Models;
|
||||
|
||||
namespace ytLive.Tests;
|
||||
|
||||
/// <summary>Creator ruling (2026-10-30): the top bar's primary button is context-sensitive and the
|
||||
/// separate TEST button is gone.
|
||||
///
|
||||
/// <para>EDIT off + ON-AIR → the livestream message. EDIT on + ON-AIR → the test-livestream
|
||||
/// message. REC always records, because there is no test recording. The matrix is pure, so it is
|
||||
/// cheaper to pin it here than to drive a window.</para></summary>
|
||||
public class SessionStartDecisionTests
|
||||
{
|
||||
[Fact]
|
||||
public void Edit_decides_whether_the_on_air_start_is_live_or_a_test()
|
||||
{
|
||||
// ON-AIR armed: EDIT decides.
|
||||
Assert.Equal(SessionStartKind.Live, SessionStartDecision.For(recordArmed: false, onAirArmed: true, editing: false));
|
||||
Assert.Equal("Go Live", SessionStartDecision.LabelFor(SessionStartKind.Live));
|
||||
|
||||
Assert.Equal(SessionStartKind.Test, SessionStartDecision.For(recordArmed: false, onAirArmed: true, editing: true));
|
||||
Assert.Equal("Test Stream", SessionStartDecision.LabelFor(SessionStartKind.Test));
|
||||
|
||||
// REC armed: always a recording, whatever EDIT says (no test recording exists).
|
||||
Assert.Equal(SessionStartKind.Record, SessionStartDecision.For(true, false, false));
|
||||
Assert.Equal(SessionStartKind.Record, SessionStartDecision.For(true, false, true));
|
||||
Assert.Equal("Start Recording", SessionStartDecision.LabelFor(SessionStartKind.Record));
|
||||
|
||||
// Unarmed start records locally (the no-dead-ends rule).
|
||||
Assert.Equal(SessionStartKind.Record, SessionStartDecision.For(false, false, false));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user