Skip to content

Commit 72b1087

Browse files
Copilotstephentoub
andcommitted
Add serialization and edge case tests for Reason property
Co-authored-by: stephentoub <[email protected]>
1 parent b35185b commit 72b1087

File tree

2 files changed

+69
-3
lines changed

2 files changed

+69
-3
lines changed

test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Contents/FunctionApprovalResponseContentTests.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,23 @@ public void Constructor_Roundtrips(string id, bool approved)
3535
Assert.Same(functionCall, content.FunctionCall);
3636
}
3737

38-
[Fact]
39-
public void Serialization_Roundtrips()
38+
[Theory]
39+
[InlineData(null)]
40+
[InlineData("Custom rejection reason")]
41+
public void Serialization_Roundtrips(string? reason)
4042
{
41-
var content = new FunctionApprovalResponseContent("request123", true, new FunctionCallContent("call123", "functionName"));
43+
var content = new FunctionApprovalResponseContent("request123", true, new FunctionCallContent("call123", "functionName"))
44+
{
45+
Reason = reason
46+
};
4247

4348
var json = JsonSerializer.Serialize(content, AIJsonUtilities.DefaultOptions);
4449
var deserializedContent = JsonSerializer.Deserialize<FunctionApprovalResponseContent>(json, AIJsonUtilities.DefaultOptions);
4550

4651
Assert.NotNull(deserializedContent);
4752
Assert.Equal(content.Id, deserializedContent.Id);
4853
Assert.Equal(content.Approved, deserializedContent.Approved);
54+
Assert.Equal(content.Reason, deserializedContent.Reason);
4955
Assert.NotNull(deserializedContent.FunctionCall);
5056
Assert.Equal(content.FunctionCall.CallId, deserializedContent.FunctionCall.CallId);
5157
Assert.Equal(content.FunctionCall.Name, deserializedContent.FunctionCall.Name);

test/Libraries/Microsoft.Extensions.AI.Tests/ChatCompletion/FunctionInvokingChatClientApprovalsTests.cs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,66 @@ public async Task MixedApprovalResponsesWithCustomAndDefaultReasonsAsync()
524524
await InvokeAndAssertStreamingAsync(options, input, downstreamClientOutput, streamingOutput, expectedDownstreamClientInput);
525525
}
526526

527+
[Theory]
528+
[InlineData(null)]
529+
[InlineData("")]
530+
[InlineData(" ")]
531+
public async Task RejectedApprovalResponsesWithEmptyOrWhitespaceReasonUsesDefaultMessageAsync(string? reason)
532+
{
533+
var options = new ChatOptions
534+
{
535+
Tools =
536+
[
537+
new ApprovalRequiredAIFunction(AIFunctionFactory.Create(() => "Result 1", "Func1")),
538+
]
539+
};
540+
541+
List<ChatMessage> input =
542+
[
543+
new ChatMessage(ChatRole.User, "hello"),
544+
new ChatMessage(ChatRole.Assistant,
545+
[
546+
new FunctionApprovalRequestContent("callId1", new FunctionCallContent("callId1", "Func1")),
547+
]) { MessageId = "resp1" },
548+
new ChatMessage(ChatRole.User,
549+
[
550+
new FunctionApprovalResponseContent("callId1", false, new FunctionCallContent("callId1", "Func1"))
551+
{
552+
Reason = reason
553+
},
554+
]),
555+
];
556+
557+
List<ChatMessage> expectedDownstreamClientInput =
558+
[
559+
new ChatMessage(ChatRole.User, "hello"),
560+
new ChatMessage(ChatRole.Assistant, [new FunctionCallContent("callId1", "Func1")]),
561+
new ChatMessage(ChatRole.Tool,
562+
[
563+
new FunctionResultContent("callId1", result: "Tool call invocation rejected.")
564+
]),
565+
];
566+
567+
List<ChatMessage> downstreamClientOutput =
568+
[
569+
new ChatMessage(ChatRole.Assistant, "world"),
570+
];
571+
572+
List<ChatMessage> output =
573+
[
574+
new ChatMessage(ChatRole.Assistant, [new FunctionCallContent("callId1", "Func1")]),
575+
new ChatMessage(ChatRole.Tool,
576+
[
577+
new FunctionResultContent("callId1", result: "Tool call invocation rejected.")
578+
]),
579+
new ChatMessage(ChatRole.Assistant, "world"),
580+
];
581+
582+
await InvokeAndAssertAsync(options, input, downstreamClientOutput, output, expectedDownstreamClientInput);
583+
584+
await InvokeAndAssertStreamingAsync(options, input, downstreamClientOutput, output, expectedDownstreamClientInput);
585+
}
586+
527587
[Fact]
528588
public async Task ApprovedInputsAreExecutedAndFunctionResultsAreConvertedAsync()
529589
{

0 commit comments

Comments
 (0)