using System.Linq; using AcDream.App.UI; using AcDream.UI.Abstractions; namespace AcDream.App.Tests.UI; public class UiChannelMenuTests { // PopupH = Rows(7) * ItemH(17) = 119; popup opens upward so top = -119. // Item idx -> col = idx/7, row = idx%7; row band y in [top+row*17, top+(row+1)*17). // Right column needs lx >= ColW(191). [Fact] public void Items_HasExpected14Entries() { Assert.Equal(14, UiChannelMenu.Items.Length); } [Fact] public void Items_FirstEntry_IsSquelch_Special() { Assert.Equal("Squelch (ignore)", UiChannelMenu.Items[0].Label); Assert.Null(UiChannelMenu.Items[0].Channel); } [Fact] public void Items_LastEntry_IsOlthoi() { var last = UiChannelMenu.Items[^1]; Assert.Equal("Tell to Olthoi Chat", last.Label); Assert.Equal(ChatChannelKind.Olthoi, last.Channel); } [Fact] public void Items_ContainAll12ChannelKinds() { var kinds = new HashSet( UiChannelMenu.Items.Where(i => i.Channel is not null).Select(i => i.Channel!.Value)); foreach (var k in new[] { ChatChannelKind.Say, ChatChannelKind.General, ChatChannelKind.Trade, ChatChannelKind.Lfg, ChatChannelKind.Fellowship, ChatChannelKind.Allegiance, ChatChannelKind.Patron, ChatChannelKind.Vassals, ChatChannelKind.Monarch, ChatChannelKind.Roleplay, ChatChannelKind.Society, ChatChannelKind.Olthoi, }) Assert.Contains(k, kinds); } [Fact] public void DefaultSelected_IsSay() { Assert.Equal(ChatChannelKind.Say, new UiChannelMenu().Selected); } [Fact] public void Select_AvailableLeftColumnItem_FiresChannel() { var menu = new UiChannelMenu { Width = 80f, Height = 18f }; Assert.True(menu.OnEvent(new UiEvent(0, menu, UiEventType.MouseDown, 0, 10, 5))); // open ChatChannelKind? fired = null; menu.OnChannelChanged = k => fired = k; // "Chat to All" (Say) is index 2 = left col, row 2: y in [-85,-68). Say is available. Assert.True(menu.OnEvent(new UiEvent(0, menu, UiEventType.MouseDown, 0, 10, -76))); Assert.Equal(ChatChannelKind.Say, fired); Assert.Equal(ChatChannelKind.Say, menu.Selected); } [Fact] public void Select_AvailableRightColumnItem_FiresChannel() { var menu = new UiChannelMenu { Width = 80f, Height = 18f }; Assert.True(menu.OnEvent(new UiEvent(0, menu, UiEventType.MouseDown, 0, 10, 5))); // open ChatChannelKind? fired = null; menu.OnChannelChanged = k => fired = k; // "Tell to Trade Chat" (Trade) is index 11 = right col (lx>=191), row 4: y in [-51,-34). Assert.True(menu.OnEvent(new UiEvent(0, menu, UiEventType.MouseDown, 0, 200, -42))); Assert.Equal(ChatChannelKind.Trade, fired); Assert.Equal(ChatChannelKind.Trade, menu.Selected); } [Fact] public void Select_SpecialItem_DoesNotFire() { var menu = new UiChannelMenu { Width = 80f, Height = 18f }; Assert.True(menu.OnEvent(new UiEvent(0, menu, UiEventType.MouseDown, 0, 10, 5))); // open int fired = 0; menu.OnChannelChanged = _ => fired++; // "Squelch (ignore)" is index 0 = left col, row 0 (null channel): y in [-119,-102). Assert.True(menu.OnEvent(new UiEvent(0, menu, UiEventType.MouseDown, 0, 10, -110))); Assert.Equal(0, fired); } [Fact] public void Select_UnavailableChannel_DoesNotFire() { var menu = new UiChannelMenu { Width = 80f, Height = 18f }; Assert.True(menu.OnEvent(new UiEvent(0, menu, UiEventType.MouseDown, 0, 10, 5))); // open int fired = 0; menu.OnChannelChanged = _ => fired++; // "Tell to Fellows" (Fellowship) is index 3 = left col, row 3: y in [-68,-51). // Fellowship is unavailable by the default static gate, so the click is inert. Assert.True(menu.OnEvent(new UiEvent(0, menu, UiEventType.MouseDown, 0, 10, -60))); Assert.Equal(0, fired); } [Fact] public void AvailabilityProvider_Overrides_DefaultGate() { var menu = new UiChannelMenu { Width = 80f, Height = 18f, AvailabilityProvider = _ => true }; Assert.True(menu.OnEvent(new UiEvent(0, menu, UiEventType.MouseDown, 0, 10, 5))); // open ChatChannelKind? fired = null; menu.OnChannelChanged = k => fired = k; // With every channel available, "Tell to Fellows" (idx 3, row 3) now fires. Assert.True(menu.OnEvent(new UiEvent(0, menu, UiEventType.MouseDown, 0, 10, -60))); Assert.Equal(ChatChannelKind.Fellowship, fired); } }