releases/tests/Paca.Tests/Core/QuickActionsExtremeRedTests.cs
Yun Chan 8677853822
Some checks failed
release / test (push) Failing after 14m5s
release / windows (push) Has been cancelled
release / android (push) Has been cancelled
release / linux (push) Has been cancelled
release / macos (push) Has been cancelled
test(core/browser/platform): 26 extreme RED/GREEN TDD cycles and full regression hardening (3,235 PASS)
2026-09-18 23:32:32 +09:00

124 lines
4.5 KiB
C#

using System;
using System.Text;
using System.Threading.Tasks;
using Paca.Core.QuickActions;
using Xunit;
namespace Paca.Tests.Core;
public class QuickActionsExtremeRedTests
{
// ==========================================
// 1. QuickActionFuzzyMatcher Memory & DoS
// ==========================================
[Fact]
public void QuickActionFuzzyMatcher_LevenshteinDistance_LargeStrings_DoesNotThrowOutOfMemory()
{
// 5000 character strings would allocate ~100MB in 2D array if unbounded
string large1 = new string('A', 3000);
string large2 = new string('B', 3000);
var ex = Record.Exception(() => QuickActionFuzzyMatcher.LevenshteinDistance(large1, large2));
Assert.Null(ex);
}
[Theory]
[InlineData(null, null)]
[InlineData(null, "abc")]
[InlineData("xyz", null)]
public void QuickActionFuzzyMatcher_LevenshteinDistance_Nulls_HandledGracefully(string? s, string? t)
{
var ex = Record.Exception(() => QuickActionFuzzyMatcher.LevenshteinDistance(s, t));
Assert.Null(ex);
}
// ==========================================
// 2. QuickActionInlineEvaluator Hardening
// ==========================================
[Theory]
[InlineData("-5 + 10", "5")]
[InlineData("10 * -2", "-20")]
[InlineData("-4 * -3", "12")]
public void QuickActionInlineEvaluator_TryEvaluateMath_NegativeNumbers_CalculatesCorrectly(string expr, string expected)
{
var eval = new QuickActionInlineEvaluator();
bool success = eval.TryEvaluate(expr, out var res);
Assert.True(success, $"Expression '{expr}' should be successfully evaluated");
Assert.NotNull(res);
Assert.Equal(expected, res.Value);
}
[Theory]
[InlineData("#fff", "rgb(255, 255, 255)")]
[InlineData("#F00", "rgb(255, 0, 0)")]
[InlineData("hex 000", "rgb(0, 0, 0)")]
public void QuickActionInlineEvaluator_TryEvaluateDev_Hex3DigitShorthand_ExpandsCorrectly(string hexInput, string expectedRgb)
{
var eval = new QuickActionInlineEvaluator();
bool success = eval.TryEvaluate(hexInput, out var res);
Assert.True(success, $"Shorthand hex '{hexInput}' should be parsed");
Assert.NotNull(res);
Assert.Equal(expectedRgb, res.Value);
}
[Fact]
public void QuickActionInlineEvaluator_TryEvaluateDev_Base64WithNullBytes_DoesNotReturnRawNullChars()
{
var eval = new QuickActionInlineEvaluator();
// Base64 containing null bytes: "\0\0\0" -> "AAAA"
bool success = eval.TryEvaluate("b64d AAAA", out var res);
Assert.True(success);
Assert.NotNull(res);
Assert.DoesNotContain('\0', res.Value);
}
// ==========================================
// 3. QuickActionClipboardDetector Security & Resilience
// ==========================================
[Fact]
public void QuickActionClipboardDetector_DetectIntent_EnormousClipboard_DoesNotSpikeOrHang()
{
var detector = new QuickActionClipboardDetector();
string hugeText = new string('x', 500_000); // 500KB
var intent = detector.DetectIntent(hugeText);
Assert.NotNull(intent);
Assert.Equal(ClipboardIntentType.None, intent.IntentType);
}
[Theory]
[InlineData("youtube.com/watch?v=dQw4w9WgXcQ")]
[InlineData("www.youtube.com/watch?v=dQw4w9WgXcQ")]
[InlineData("youtu.be/dQw4w9WgXcQ")]
public void QuickActionClipboardDetector_DetectIntent_MediaUrlWithoutScheme_DetectedAsMediaDownload(string rawUrl)
{
var detector = new QuickActionClipboardDetector();
var intent = detector.DetectIntent(rawUrl);
Assert.NotNull(intent);
Assert.Equal(ClipboardIntentType.MediaDownload, intent.IntentType);
}
// ==========================================
// 4. QuickActionParameterRouter Null Context Defenses
// ==========================================
[Theory]
[InlineData("b64 hello")]
[InlineData("b64d aGVsbG8=")]
[InlineData("hash password123")]
[InlineData("note sample note")]
public async Task QuickActionParameterRouter_Handlers_NullContext_DoesNotThrowNullReferenceException(string command)
{
var router = new QuickActionParameterRouter();
bool parsed = router.TryParseCommand(command, out var action);
Assert.True(parsed);
Assert.NotNull(action);
var ex = await Record.ExceptionAsync(async () => await action!.Handler!(null!));
Assert.Null(ex);
}
}