Files
llm-pii-poc/tests/PiiRedaction.Core.Tests/Detection/RegexPiiDetectorTests.cs
Bilal Nazer Ali dfc81dea28 Add PII redaction POC for secure LLM prompting.
Implements detect-redact-sanitize pipeline with regex, domain rules, and ONNX NER before the LLM boundary, plus NUnit tests and Xenovex push documentation.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 13:05:07 +05:30

93 lines
2.9 KiB
C#

using FluentAssertions;
using PiiRedaction.Core.Detection;
using PiiRedaction.Core.Models;
namespace PiiRedaction.Core.Tests.Detection;
[TestFixture]
public sealed class RegexPiiDetectorTests
{
private readonly RegexPiiDetector _detector = new();
[Test]
public void Detect_PositiveEmail_ReturnsEntity()
{
const string text = "Contact ravi.kumar@gmail.com now.";
var entities = _detector.Detect(text);
entities.Should().ContainSingle(entity =>
entity.Type == PiiEntityType.Email &&
entity.Value == "ravi.kumar@gmail.com" &&
entity.Source == PiiDetectionSource.Regex);
}
[Test]
public void Detect_PositivePhone_ReturnsTenDigitEntity()
{
var entities = _detector.Detect("Call 9876543210 today.");
entities.Should().ContainSingle(entity =>
entity.Type == PiiEntityType.Phone &&
entity.Value == "9876543210" &&
entity.Source == PiiDetectionSource.Regex);
}
[TestCase("Aadhaar 1234 5678 9012 linked.", "1234 5678 9012")]
[TestCase("Aadhaar 123456789012 linked.", "123456789012")]
public void Detect_PositiveAadhaar_ReturnsEntity(string text, string expectedValue)
{
var entities = _detector.Detect(text);
entities.Should().ContainSingle(entity =>
entity.Type == PiiEntityType.Aadhaar &&
entity.Value == expectedValue);
}
[Test]
public void Detect_PositivePan_ReturnsUppercaseEntity()
{
var entities = _detector.Detect("PAN ABCDE1234F verified.");
entities.Should().ContainSingle(entity => entity.Type == PiiEntityType.Pan);
entities[0].Value.Should().MatchRegex("^[A-Z]{5}\\d{4}[A-Z]$");
}
[Test]
public void Detect_PositiveCreditCard_ReturnsEntity()
{
var entities = _detector.Detect("Card 4111-1111-1111-1111 used.");
entities.Should().ContainSingle(entity => entity.Type == PiiEntityType.CreditCard);
}
[TestCase("not-an-email")]
[TestCase("@missing.com")]
[TestCase("pan abcde1234f")]
[TestCase("Number 987654321")]
public void Detect_NegativePatterns_ReturnsNoMatch(string text)
{
_detector.Detect(text).Should().BeEmpty();
}
[Test]
public void Detect_EmailSpan_HasCorrectIndices()
{
const string text = "Email ravi@test.com end.";
var entities = _detector.Detect(text);
var email = entities.Single(entity => entity.Type == PiiEntityType.Email);
email.StartIndex.Should().Be(6);
email.Length.Should().Be("ravi@test.com".Length);
text[email.StartIndex..email.EndIndex].Should().Be("ravi@test.com");
}
[TestCase(null)]
[TestCase("")]
[TestCase(" ")]
public void Detect_InvalidInput_ThrowsArgumentException(string? text)
{
var action = () => _detector.Detect(text!);
action.Should().Throw<ArgumentException>();
}
}