using HSchool.Content; using HSchool.Protocol; using HSchool.Server.Game; namespace HSchool.Server.Tests; public class NoticeBoardTests { [Fact] public void PausingPost_IsSticky_InfoIsNot() { var board = new NoticeBoard(maxSticky: 8); Assert.True(board.TryPost(Info(), personKey: "", kind: "", out var info)); Assert.False(info.Pause); Assert.False(board.HasPausing); Assert.Empty(board.Sticky); Assert.True(board.TryPost(Pausing(), personKey: "", kind: "", out var warning)); Assert.True(warning.Pause); Assert.True(board.HasPausing); Assert.Equal("GenerationFailed", Assert.Single(board.Sticky).DefName); Assert.DoesNotContain(board.ToSave(), row => row.DefName == "DayStarted"); } [Fact] public void NinthSticky_IsNotPosted() { var board = new NoticeBoard(maxSticky: 8); for (var i = 0; i < 8; i++) { Assert.True(board.TryPost(Pausing(), personKey: "", kind: "", out _)); } Assert.False(board.TryPost(Pausing(), personKey: "", kind: "", out var ninth)); Assert.Equal(default, ninth); Assert.Equal(8, board.Sticky.Count); } [Fact] public void Dismiss_RemovesSticky_DoesNotClearTheBoardUntilTheLast() { var board = new NoticeBoard(maxSticky: 8); Assert.True(board.TryPost(Pausing(), personKey: "", kind: "", out var first)); Assert.True(board.TryPost(Pausing(), personKey: "", kind: "", out var second)); Assert.True(board.TryDismiss(first.Id)); Assert.True(board.HasPausing); Assert.Equal(second.Id, Assert.Single(board.Sticky).Id); Assert.True(board.TryDismiss(second.Id)); Assert.False(board.HasPausing); Assert.False(board.TryDismiss(second.Id)); } [Fact] public void Load_RestoresSticky_SkipsInfoRows() { var saved = new StickyNoticeSave[] { new() { Id = 3, DefName = "DayStarted", Severity = NoticeSeverity.Info, Pause = false, TtlMs = 8000 }, new() { Id = 4, DefName = "GenerationFailed", Severity = NoticeSeverity.Error, Pause = true, TtlMs = 0 }, }; var board = new NoticeBoard(maxSticky: 8, saved); Assert.True(board.HasPausing); var sticky = Assert.Single(board.Sticky); Assert.Equal(4u, sticky.Id); Assert.Equal("GenerationFailed", sticky.DefName); Assert.Equal(NoticeSeverity.Error, sticky.Severity); } [Fact] public void GenerateImage_WithoutPerson_StillPosts_WirePersonIdIsZero() { var board = new NoticeBoard(maxSticky: 8); Assert.True(board.TryPost(Pausing(), personKey: "", kind: "full", out var message)); Assert.Equal(0u, message.PersonId); Assert.Equal(EventActions.GenerateImage, message.Action); Assert.Equal("", Assert.Single(board.Sticky).PersonKey); } [Fact] public void GenerateImage_WithPerson_StoresKeyAndKind() { var board = new NoticeBoard(maxSticky: 8); Assert.True(board.TryPost(Pausing(), personKey: "a0.p0", kind: "avatar", out var message)); Assert.Equal(1u, message.PersonId); Assert.Equal(EventActions.GenerateImage, message.Action); var sticky = Assert.Single(board.Sticky); Assert.Equal("a0.p0", sticky.PersonKey); Assert.Equal("avatar", sticky.Kind); } [Fact] public void DirectorSummonedInfo_IsNotStickyInSave() { var board = new NoticeBoard(maxSticky: 8); Assert.True(board.TryPost(DirectorSummoned(), personKey: "a0.p0", kind: "", out var info)); Assert.Equal("DirectorSummoned", info.DefName); Assert.False(info.Pause); Assert.Empty(board.Sticky); Assert.DoesNotContain(board.ToSave(), row => row.DefName == "DirectorSummoned"); } private static EventDef Info() => new() { DefName = "DayStarted", Severity = EventSeverities.Info, Pause = false, TtlMs = 8000, Trigger = EventTriggers.DayStart, Action = EventActions.None, }; private static EventDef DirectorSummoned() => new() { DefName = "DirectorSummoned", Severity = EventSeverities.Info, Pause = false, TtlMs = 8000, Trigger = EventTriggers.DirectorSummon, Action = EventActions.None, }; private static EventDef Pausing() => new() { DefName = "GenerationFailed", Severity = EventSeverities.Error, Pause = true, TtlMs = 0, Trigger = EventTriggers.GenerationFailed, Action = EventActions.GenerateImage, }; }