113 lines
3.8 KiB
C#
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, " "));
|
|
}
|
|
}
|