// tests/SpamGuard.Tests/Services/EmailClassifierTests.cs namespace SpamGuard.Tests.Services; using System.Net; using System.Text.Json; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; using SpamGuard.Configuration; using SpamGuard.Models; using SpamGuard.Services; public class EmailClassifierTests { private static SpamGuardOptions DefaultOptions => new() { Claude = new ClaudeOptions { ApiKey = "test-key", Model = "claude-sonnet-4-6", MaxBodyLength = 2000 } }; private static EmailSummary SampleEmail => new( Uid: 1, From: "spammer@sketchy.com", Subject: "Buy now! Limited offer!", BodySnippet: "Click here to claim your prize...", Date: DateTimeOffset.UtcNow ); [Fact] public void BuildPrompt_ContainsSenderAndSubjectAndBody() { var classifier = new EmailClassifier( Options.Create(DefaultOptions), new NullLogger(), new HttpClient() ); var prompt = classifier.BuildPrompt(SampleEmail); Assert.Contains("spammer@sketchy.com", prompt); Assert.Contains("Buy now! Limited offer!", prompt); Assert.Contains("Click here to claim your prize...", prompt); } [Fact] public void BuildPrompt_TruncatesLongBody() { var longBody = new string('x', 5000); var email = SampleEmail with { BodySnippet = longBody }; var classifier = new EmailClassifier( Options.Create(DefaultOptions), new NullLogger(), new HttpClient() ); var prompt = classifier.BuildPrompt(email); // Body in prompt should be truncated to MaxBodyLength Assert.DoesNotContain(longBody, prompt); } [Fact] public void ParseResponse_ValidJson_ReturnsResult() { var json = """{"classification": "spam", "confidence": 0.95, "reason": "Unsolicited marketing"}"""; var result = EmailClassifier.ParseResponse(json); Assert.NotNull(result); Assert.True(result.IsSpam); Assert.Equal(0.95, result.Confidence); Assert.Equal("Unsolicited marketing", result.Reason); } [Fact] public void ParseResponse_InvalidJson_ReturnsNull() { var result = EmailClassifier.ParseResponse("not json at all"); Assert.Null(result); } [Fact] public void ParseResponse_JsonWithMarkdownFencing_ReturnsResult() { var json = """ ```json {"classification": "legitimate", "confidence": 0.85, "reason": "Normal business email"} ``` """; var result = EmailClassifier.ParseResponse(json); Assert.NotNull(result); Assert.False(result.IsSpam); } }