releases/VideoDownloader.Tests/Browser/TabFeaturesTests.cs

113 lines
3.8 KiB
C#

using VideoDownloader.App.Browser.Features;
using VideoDownloader.Browser.Tabs;
namespace VideoDownloader.Tests.Browser;
// ── T2-2 탭 절전: 유휴 비활성 탭 자동 서스펜드 ──
public class TabSuspendServiceTests
{
[Fact]
public void 활성_탭은_절전하지_않는다()
{
var m = new TabManager(() => new TabItem());
var active = m.NewTab("https://a.com");
var svc = new TabSuspendService(TimeSpan.FromMinutes(10),
t => throw new InvalidOperationException("suspend should not be called"),
t => t == active);
svc.SuspendIdleTabs(m.Tabs, active, now: active.LastActivated.AddMinutes(30));
Assert.False(active.IsSuspended);
}
[Fact]
public void 유휴_비활성_탭은_절전한다()
{
var m = new TabManager(() => new TabItem());
var old = m.NewTab("https://a.com");
var active = m.NewTab("https://b.com");
var suspended = new List<TabItem>();
var svc = new TabSuspendService(TimeSpan.FromMinutes(10),
t => { suspended.Add(t); return true; },
t => t != active);
var now = old.LastActivated.AddMinutes(11);
svc.SuspendIdleTabs(m.Tabs, active, now);
Assert.Contains(old, suspended);
Assert.DoesNotContain(active, suspended);
}
[Fact]
public void 이미_절전된_탭은_중복_서스펜드_하지_않는다()
{
var m = new TabManager(() => new TabItem());
var old = m.NewTab("https://a.com");
var active = m.NewTab("https://b.com");
old.IsSuspended = true;
var calls = 0;
var svc = new TabSuspendService(TimeSpan.FromMinutes(10), t => { calls++; return true; }, t => t != active);
svc.SuspendIdleTabs(m.Tabs, active, old.LastActivated.AddHours(1));
Assert.Equal(0, calls);
}
[Fact]
public void 최근에_활성화된_탭은_절전하지_않는다()
{
var m = new TabManager(() => new TabItem());
var recent = m.NewTab("https://a.com");
var active = m.NewTab("https://b.com");
m.Activate(recent); // 방금 사용
var calls = 0;
var svc = new TabSuspendService(TimeSpan.FromMinutes(10), t => { calls++; return true; }, t => t != active);
svc.SuspendIdleTabs(m.Tabs, active, recent.LastActivated.AddMinutes(1));
Assert.Equal(0, calls);
}
}
// ── T2-8 탭 검색(Ctrl+Shift+A): 열린+닫힌 탭 필터 ──
public class TabSearchFilterTests
{
[Fact]
public void 제목과_URL_부분일치로_필터링한다()
{
var m = new TabManager(() => new TabItem());
m.NewTab("https://youtube.com/watch?v=1");
m.Tabs[0].Title = "My Favorite Video";
m.NewTab("https://news.example.com");
m.Tabs[1].Title = "News";
var hits = TabSearchFilter.Search(m.Tabs, "favorite");
Assert.Single(hits);
Assert.Equal("My Favorite Video", hits[0].Title);
hits = TabSearchFilter.Search(m.Tabs, "youtube");
Assert.Single(hits);
hits = TabSearchFilter.Search(m.Tabs, "EXAMPLE"); // 대소문자 무시
Assert.Single(hits);
}
[Fact]
public void 닫힌_탭도_검색_대상에_포함된다()
{
var m = new TabManager(() => new TabItem());
var t = m.NewTab("https://github.com/x");
m.Tabs[0].Title = "GitHub Repo";
m.CloseTab(t);
var hits = TabSearchFilter.Search(m.Tabs, m.ClosedStack, "github");
Assert.Single(hits);
Assert.Equal("GitHub Repo", hits[0].Title);
Assert.True(hits[0].IsClosed);
}
[Fact]
public void 빈_질의는_빈_결과()
{
var m = new TabManager(() => new TabItem());
m.NewTab("https://a.com");
Assert.Empty(TabSearchFilter.Search(m.Tabs, ""));
Assert.Empty(TabSearchFilter.Search(m.Tabs, " "));
}
}