Skip to content

Commit b948742

Browse files
authored
Merge pull request #580 from Chris0Jeky/test/577-intent-classifier-tests
Add LlmIntentClassifier and chat-to-proposal integration tests
2 parents ecc7ef7 + ca74a65 commit b948742

2 files changed

Lines changed: 81 additions & 0 deletions

File tree

backend/src/Taskdeck.Application/Services/LlmIntentClassifier.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ public static class LlmIntentClassifier
44
{
55
public static (bool IsActionable, string? ActionIntent) Classify(string message)
66
{
7+
if (string.IsNullOrWhiteSpace(message))
8+
return (false, null);
9+
710
var lower = message.ToLowerInvariant();
811

912
// Card creation — explicit commands and natural language

backend/tests/Taskdeck.Application.Tests/Services/LlmIntentClassifierTests.cs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,84 @@ public void Classify_NonActionable_ShouldReturnFalse(string message)
142142

143143
#endregion
144144

145+
#region Edge Cases — Input Extremes
146+
147+
[Fact]
148+
public void Classify_NullInput_ReturnsNotActionable()
149+
{
150+
var (isActionable, actionIntent) = LlmIntentClassifier.Classify(null!);
151+
152+
isActionable.Should().BeFalse();
153+
actionIntent.Should().BeNull();
154+
}
155+
156+
[Fact]
157+
public void Classify_VeryLongString_ReturnsNotActionable()
158+
{
159+
var longMessage = new string('x', 50_000);
160+
161+
var (isActionable, actionIntent) = LlmIntentClassifier.Classify(longMessage);
162+
163+
isActionable.Should().BeFalse();
164+
actionIntent.Should().BeNull();
165+
}
166+
167+
[Fact]
168+
public void Classify_VeryLongStringContainingPattern_StillMatches()
169+
{
170+
var longMessage = new string('x', 25_000) + " create card for testing " + new string('x', 25_000);
171+
172+
var (isActionable, actionIntent) = LlmIntentClassifier.Classify(longMessage);
173+
174+
isActionable.Should().BeTrue();
175+
actionIntent.Should().Be("card.create");
176+
}
177+
178+
[Theory]
179+
[InlineData(" ")]
180+
[InlineData("\t\t")]
181+
[InlineData("\n\n\n")]
182+
public void Classify_WhitespaceOnly_ReturnsNotActionable(string message)
183+
{
184+
var (isActionable, actionIntent) = LlmIntentClassifier.Classify(message);
185+
186+
isActionable.Should().BeFalse();
187+
actionIntent.Should().BeNull();
188+
}
189+
190+
[Theory]
191+
[InlineData("Hello! @#$%^&*() special chars")]
192+
[InlineData("Unicode: \u00e9\u00e8\u00ea\u00eb\u00fc\u00f6\u00e4")]
193+
[InlineData("<script>alert('xss')</script>")]
194+
[InlineData("SELECT * FROM cards; DROP TABLE boards;")]
195+
public void Classify_SpecialCharacters_WithoutPattern_ReturnsNotActionable(string message)
196+
{
197+
var (isActionable, actionIntent) = LlmIntentClassifier.Classify(message);
198+
199+
isActionable.Should().BeFalse();
200+
actionIntent.Should().BeNull();
201+
}
202+
203+
[Fact]
204+
public void Classify_PatternWithSpecialCharsSurrounding_StillMatches()
205+
{
206+
var (isActionable, actionIntent) = LlmIntentClassifier.Classify("!!! create card !!! @#$ testing");
207+
208+
isActionable.Should().BeTrue();
209+
actionIntent.Should().Be("card.create");
210+
}
211+
212+
[Fact]
213+
public void Classify_PatternWithNewlines_StillMatches()
214+
{
215+
var (isActionable, actionIntent) = LlmIntentClassifier.Classify("line 1\ncreate card for testing\nline 3");
216+
217+
isActionable.Should().BeTrue();
218+
actionIntent.Should().Be("card.create");
219+
}
220+
221+
#endregion
222+
145223
#region Known Gaps — Natural Language Misses (Documents #570/#571)
146224

147225
/// <summary>

0 commit comments

Comments
 (0)