136 lines
5.1 KiB
C#
136 lines
5.1 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using Paca.Core.QuickActions;
|
|
using Xunit;
|
|
|
|
namespace Paca.Tests.App;
|
|
|
|
public class QuickActionSpotlightTwoPhase20Tests
|
|
{
|
|
private static readonly string SolutionRoot = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "..", "..", "..", "..", ".."));
|
|
|
|
[Theory]
|
|
[InlineData("https://www.youtube.com/watch?v=dQw4w9WgXcQ", ClipboardIntentType.MediaDownload)]
|
|
[InlineData("https://twitter.com/user/status/123456789", ClipboardIntentType.MediaDownload)]
|
|
[InlineData("https://example.com/live/stream.m3u8", ClipboardIntentType.MediaDownload)]
|
|
[InlineData("https://news.ycombinator.com", ClipboardIntentType.BrowseUrl)]
|
|
[InlineData("125 * 40 - 15", ClipboardIntentType.Expression)]
|
|
[InlineData("just regular plain text", ClipboardIntentType.None)]
|
|
[InlineData(null, ClipboardIntentType.None)]
|
|
public void Gate201_ClipboardDetector_AccuratelyClassifiesContent(string? text, ClipboardIntentType expected)
|
|
{
|
|
var detector = new QuickActionClipboardDetector();
|
|
var result = detector.DetectIntent(text);
|
|
|
|
Assert.Equal(expected, result.IntentType);
|
|
if (expected != ClipboardIntentType.None)
|
|
{
|
|
Assert.False(string.IsNullOrWhiteSpace(result.SuggestedActionTitle));
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void Gate202_FavoritesManager_AddRemoveAndPersistFavorites()
|
|
{
|
|
string tempJson = Path.Combine(Path.GetTempPath(), $"paca_fav_test_{Guid.NewGuid():N}.json");
|
|
try
|
|
{
|
|
var manager = new QuickActionFavoritesManager(tempJson);
|
|
|
|
Assert.False(manager.IsFavorite("browser.new_tab"));
|
|
|
|
// 1. Toggle on
|
|
bool added = manager.ToggleFavorite("browser.new_tab");
|
|
Assert.True(added);
|
|
Assert.True(manager.IsFavorite("browser.new_tab"));
|
|
Assert.Contains("browser.new_tab", manager.GetFavorites());
|
|
|
|
// 2. Reload from JSON disk
|
|
var manager2 = new QuickActionFavoritesManager(tempJson);
|
|
Assert.True(manager2.IsFavorite("browser.new_tab"));
|
|
|
|
// 3. Toggle off
|
|
bool removed = manager2.ToggleFavorite("browser.new_tab");
|
|
Assert.False(removed);
|
|
Assert.False(manager2.IsFavorite("browser.new_tab"));
|
|
Assert.DoesNotContain("browser.new_tab", manager2.GetFavorites());
|
|
}
|
|
finally
|
|
{
|
|
if (File.Exists(tempJson)) File.Delete(tempJson);
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void Gate203_UserCustomActionStore_RegistersAndInstantiatesQuickActionItem()
|
|
{
|
|
string tempJson = Path.Combine(Path.GetTempPath(), $"paca_custom_test_{Guid.NewGuid():N}.json");
|
|
try
|
|
{
|
|
var store = new UserCustomActionStore(tempJson);
|
|
var custom = new UserCustomAction(
|
|
Id: "custom.my_intranet",
|
|
Title: "사내 인트라넷 열기",
|
|
Keywords: "intranet work 사내포털",
|
|
TargetUrl: "https://intranet.company.internal",
|
|
ShortcutHint: "Ctrl+Alt+I"
|
|
);
|
|
|
|
store.AddOrUpdate(custom);
|
|
Assert.Single(store.GetAll());
|
|
|
|
// Convert to QuickActionItem
|
|
var catalog = new QuickActionCatalog();
|
|
store.InjectIntoCatalog(catalog);
|
|
|
|
var injected = catalog.FindById("custom.my_intranet");
|
|
Assert.NotNull(injected);
|
|
Assert.Equal("사내 인트라넷 열기", injected.Title);
|
|
Assert.Equal(QuickActionCategory.Ecosystem, injected.Category);
|
|
|
|
// Reload from disk
|
|
var store2 = new UserCustomActionStore(tempJson);
|
|
Assert.Single(store2.GetAll());
|
|
Assert.Equal("custom.my_intranet", store2.GetAll().First().Id);
|
|
}
|
|
finally
|
|
{
|
|
if (File.Exists(tempJson)) File.Delete(tempJson);
|
|
}
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(10, "방금 전")]
|
|
[InlineData(300, "5분 전")]
|
|
[InlineData(7200, "2시간 전")]
|
|
[InlineData(90000, "어제")]
|
|
public void Gate204_QuickActionTimeFormatter_RendersNaturalRelativeTime(int secondsAgo, string expectedKorean)
|
|
{
|
|
var now = DateTime.UtcNow;
|
|
var past = now.AddSeconds(-secondsAgo);
|
|
|
|
string formatted = QuickActionTimeFormatter.FormatRelativeTime(past, now, "ko");
|
|
Assert.Equal(expectedKorean, formatted);
|
|
}
|
|
|
|
[Fact]
|
|
public void Gate205_LauncherWindowXaml_ContainsClipboardBannerAndFavoritesSupport()
|
|
{
|
|
string xamlPath = Path.Combine(SolutionRoot, "src", "Paca.App", "QuickActionLauncherWindow.xaml");
|
|
string xaml = File.ReadAllText(xamlPath);
|
|
|
|
Assert.Contains("x:Name=\"ClipboardSuggestionBanner\"", xaml);
|
|
Assert.Contains("x:Name=\"ClipboardBannerTitle\"", xaml);
|
|
}
|
|
|
|
[Fact]
|
|
public void Gate206_LauncherWindowCs_WiresClipboardDetectionOnActivate()
|
|
{
|
|
string csPath = Path.Combine(SolutionRoot, "src", "Paca.App", "QuickActionLauncherWindow.xaml.cs");
|
|
string cs = File.ReadAllText(csPath);
|
|
|
|
Assert.Contains("CheckClipboardIntent()", cs);
|
|
Assert.Contains("QuickActionClipboardDetector", cs);
|
|
}
|
|
}
|