namespace ItWorx.KnowledgeHub.Domain.Tests; using ItWorx.KnowledgeHub.Domain.Knowledge; public sealed class PageCreationSessionTests { private static readonly DateTimeOffset Now = new(2026, 8, 3, 12, 0, 0, TimeSpan.Zero); [Fact] public void Open_starts_in_the_Open_status_with_an_expiry_derived_from_the_lifespan() { var session = PageCreationSession.Open(Guid.NewGuid(), null, Guid.NewGuid(), Now, TimeSpan.FromHours(24)); Assert.True(session.IsOpen); Assert.Equal(PageCreationSessionStatus.Open, session.Status); Assert.Equal(Now.AddHours(24), session.ExpiresAt); Assert.Null(session.CommittedPageId); Assert.Null(session.ClosedAt); Assert.False(session.IsExpired(Now)); Assert.True(session.IsExpired(Now.AddHours(25))); } [Fact] public void MarkCommitted_transitions_to_Committed_and_records_the_page_id() { var session = PageCreationSession.Open(Guid.NewGuid(), null, Guid.NewGuid(), Now, TimeSpan.FromHours(24)); var pageId = Guid.NewGuid(); session.MarkCommitted(pageId, Now.AddMinutes(5)); Assert.False(session.IsOpen); Assert.Equal(PageCreationSessionStatus.Committed, session.Status); Assert.Equal(pageId, session.CommittedPageId); Assert.Equal(Now.AddMinutes(5), session.ClosedAt); } [Fact] public void MarkCommitted_a_second_time_throws_never_silently_double_commits() { var session = PageCreationSession.Open(Guid.NewGuid(), null, Guid.NewGuid(), Now, TimeSpan.FromHours(24)); session.MarkCommitted(Guid.NewGuid(), Now); Assert.Throws(() => session.MarkCommitted(Guid.NewGuid(), Now)); } [Fact] public void MarkDiscarded_transitions_to_Discarded() { var session = PageCreationSession.Open(Guid.NewGuid(), null, Guid.NewGuid(), Now, TimeSpan.FromHours(24)); session.MarkDiscarded(Now.AddMinutes(1)); Assert.Equal(PageCreationSessionStatus.Discarded, session.Status); Assert.Equal(Now.AddMinutes(1), session.ClosedAt); } [Fact] public void MarkDiscarded_is_idempotent_when_already_discarded() { var session = PageCreationSession.Open(Guid.NewGuid(), null, Guid.NewGuid(), Now, TimeSpan.FromHours(24)); session.MarkDiscarded(Now); var exception = Record.Exception(() => session.MarkDiscarded(Now.AddMinutes(1))); Assert.Null(exception); Assert.Equal(PageCreationSessionStatus.Discarded, session.Status); } [Fact] public void MarkDiscarded_after_MarkCommitted_throws_a_committed_page_can_never_be_discarded() { var session = PageCreationSession.Open(Guid.NewGuid(), null, Guid.NewGuid(), Now, TimeSpan.FromHours(24)); session.MarkCommitted(Guid.NewGuid(), Now); Assert.Throws(() => session.MarkDiscarded(Now)); } }