using System.IO; using System.Linq; using Paca.Browser.Tabs; using Xunit; namespace Paca.Tests.Browser; public class ChromeTabGroupAdvancedTests { [Fact] public void ChromeTabGroupPalette_Contains_Nine_Official_Colors() { var colors = ChromeTabGroupPalette.Presets; Assert.Equal(9, colors.Count); Assert.Contains(colors, c => c.Name == "Blue" && c.Hex == "#1A73E8"); Assert.Contains(colors, c => c.Name == "Red" && c.Hex == "#D93025"); Assert.Contains(colors, c => c.Name == "Yellow" && c.Hex == "#F9AB00"); Assert.Contains(colors, c => c.Name == "Green" && c.Hex == "#188038"); Assert.Contains(colors, c => c.Name == "Pink" && c.Hex == "#E52592"); Assert.Contains(colors, c => c.Name == "Purple" && c.Hex == "#A142F4"); Assert.Contains(colors, c => c.Name == "Cyan" && c.Hex == "#007B83"); Assert.Contains(colors, c => c.Name == "Orange" && c.Hex == "#E37400"); Assert.Contains(colors, c => c.Name == "Grey" && c.Hex == "#5F6368"); Assert.Equal("#1A73E8", ChromeTabGroupPalette.Normalize("blue")); Assert.Equal("#D93025", ChromeTabGroupPalette.Normalize("#d93025")); Assert.Equal("#5F6368", ChromeTabGroupPalette.Normalize("invalid-color")); } [Fact] public void MoveGroup_Moves_Entire_Group_Of_Tabs_Atomically() { var mgr = new TabManager(() => new TabItem()); var t0 = mgr.NewTab("https://a.com"); var t1 = mgr.NewTab("https://b.com"); var t2 = mgr.NewTab("https://c.com"); var t3 = mgr.NewTab("https://d.com"); var t4 = mgr.NewTab("https://e.com"); mgr.SetGroup(t1, "Group1", "#1A73E8"); mgr.SetGroup(t2, "Group1", "#1A73E8"); // Initial order: t0, t1, t2, t3, t4 Assert.Equal(new[] { t0, t1, t2, t3, t4 }, mgr.Tabs); // Move Group1 to start at index 2 (after t3) bool moved = mgr.MoveGroup("Group1", 2); Assert.True(moved); // New order should have t1, t2 together starting at index 2: t0, t3, t1, t2, t4 Assert.Equal(new[] { t0, t3, t1, t2, t4 }, mgr.Tabs); } [Fact] public void Activating_Tab_In_Collapsed_Group_Expands_Group_Automatically() { var mgr = new TabManager(() => new TabItem()); var t0 = mgr.NewTab("https://home.com"); var t1 = mgr.NewTab("https://work1.com"); var t2 = mgr.NewTab("https://work2.com"); mgr.SetGroup(t1, "Work", "#1A73E8"); mgr.SetGroup(t2, "Work", "#1A73E8"); mgr.ToggleGroupCollapsed("Work"); Assert.True(t1.IsGroupCollapsed); Assert.True(t2.IsGroupCollapsed); // Activating a collapsed tab expands its entire group mgr.Activate(t1); Assert.Same(t1, mgr.ActiveTab); Assert.False(t1.IsGroupCollapsed); Assert.False(t2.IsGroupCollapsed); } [Fact] public void TabSessionStore_Preserves_Tab_Groups_And_Collapsed_State() { var tmp = Path.Combine(Path.GetTempPath(), $"paca_session_{System.Guid.NewGuid():N}.json"); try { var mgr1 = new TabManager(() => new TabItem()); var t0 = mgr1.NewTab("https://home.com"); var t1 = mgr1.NewTab("https://work1.com"); var t2 = mgr1.NewTab("https://work2.com"); mgr1.SetGroup(t1, "Work", "#1A73E8"); mgr1.SetGroup(t2, "Work", "#1A73E8"); mgr1.ToggleGroupCollapsed("Work"); mgr1.Activate(t0); // Keep active tab outside collapsed group so it stays collapsed on restore var snap = mgr1.CaptureSession(); TabSessionStore.Save(tmp, snap); var loadedSnap = TabSessionStore.Load(tmp); Assert.NotNull(loadedSnap); var mgr2 = new TabManager(() => new TabItem()); mgr2.RestoreSession(loadedSnap); Assert.Equal(3, mgr2.Tabs.Count); Assert.Null(mgr2.Tabs[0].GroupName); Assert.Equal("Work", mgr2.Tabs[1].GroupName); Assert.Equal("#1A73E8", mgr2.Tabs[1].GroupColor); Assert.True(mgr2.Tabs[1].IsGroupCollapsed); Assert.Equal("Work", mgr2.Tabs[2].GroupName); Assert.Equal("#1A73E8", mgr2.Tabs[2].GroupColor); Assert.True(mgr2.Tabs[2].IsGroupCollapsed); } finally { if (File.Exists(tmp)) File.Delete(tmp); } } }