Skip to content

Commit fe27f06

Browse files
author
Johan Broberg
committed
Update with CancellationToken
1 parent bffca5e commit fe27f06

File tree

4 files changed

+192
-29
lines changed

4 files changed

+192
-29
lines changed

src/Tests/Microsoft.Agents.A365.Tooling.Extensions.AgentFramework.Tests/Services/McpToolRegistrationServiceTests/SendChatHistoryAsync_ChatMessageStore_Tests.cs

Lines changed: 73 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ public async Task WithEmptyStore_ReturnsSuccessWithoutCallingService()
9999
s => s.SendChatHistoryAsync(
100100
It.IsAny<ITurnContext>(),
101101
It.IsAny<ChatHistoryMessage[]>(),
102-
It.IsAny<ToolOptions>()),
102+
It.IsAny<ToolOptions>(),
103+
It.IsAny<CancellationToken>()),
103104
Times.Never);
104105
}
105106

@@ -124,7 +125,8 @@ public async Task WithEmptyStoreAndToolOptions_ReturnsSuccessWithoutCallingServi
124125
s => s.SendChatHistoryAsync(
125126
It.IsAny<ITurnContext>(),
126127
It.IsAny<ChatHistoryMessage[]>(),
127-
It.IsAny<ToolOptions>()),
128+
It.IsAny<ToolOptions>(),
129+
It.IsAny<CancellationToken>()),
128130
Times.Never);
129131
}
130132

@@ -137,7 +139,8 @@ public async Task WithValidStore_RetrievesAndSendsMessages()
137139
.Setup(s => s.SendChatHistoryAsync(
138140
It.IsAny<ITurnContext>(),
139141
It.IsAny<ChatHistoryMessage[]>(),
140-
It.IsAny<ToolOptions>()))
142+
It.IsAny<ToolOptions>(),
143+
It.IsAny<CancellationToken>()))
141144
.ReturnsAsync(expectedResult);
142145

143146
var service = CreateService();
@@ -167,7 +170,8 @@ public async Task WithValidStore_RetrievesAndSendsMessages()
167170
messages[0].Id == "msg-1" &&
168171
messages[1].Id == "msg-2"),
169172
It.Is<ToolOptions>(opts =>
170-
opts.UserAgentConfiguration == Agent365AgentFrameworkSdkUserAgentConfiguration.Instance)),
173+
opts.UserAgentConfiguration == Agent365AgentFrameworkSdkUserAgentConfiguration.Instance),
174+
It.IsAny<CancellationToken>()),
171175
Times.Once);
172176
}
173177

@@ -180,7 +184,8 @@ public async Task WithValidStoreAndToolOptions_RetrievesAndSendsMessages()
180184
.Setup(s => s.SendChatHistoryAsync(
181185
It.IsAny<ITurnContext>(),
182186
It.IsAny<ChatHistoryMessage[]>(),
183-
It.IsAny<ToolOptions>()))
187+
It.IsAny<ToolOptions>(),
188+
It.IsAny<CancellationToken>()))
184189
.ReturnsAsync(expectedResult);
185190

186191
var service = CreateService();
@@ -238,7 +243,8 @@ public async Task WithCustomToolOptions_PassesOptionsToService()
238243
.Setup(s => s.SendChatHistoryAsync(
239244
It.IsAny<ITurnContext>(),
240245
It.IsAny<ChatHistoryMessage[]>(),
241-
It.IsAny<ToolOptions>()))
246+
It.IsAny<ToolOptions>(),
247+
It.IsAny<CancellationToken>()))
242248
.ReturnsAsync(expectedResult);
243249

244250
var service = CreateService();
@@ -273,7 +279,67 @@ public async Task WithCustomToolOptions_PassesOptionsToService()
273279
s => s.SendChatHistoryAsync(
274280
turnContextMock.Object,
275281
It.IsAny<ChatHistoryMessage[]>(),
276-
customToolOptions),
282+
customToolOptions,
283+
It.IsAny<CancellationToken>()),
277284
Times.Once);
278285
}
286+
287+
[Fact]
288+
public async Task WithCancelledToken_ThrowsOperationCanceledException()
289+
{
290+
// Arrange
291+
var service = CreateService();
292+
var store = new TestChatMessageStore(new List<ChatMessage>
293+
{
294+
new ChatMessage(ChatRole.User, "Test") { MessageId = "msg-1", CreatedAt = DateTimeOffset.UtcNow }
295+
});
296+
var turnContextMock = new Mock<ITurnContext>();
297+
var cts = new CancellationTokenSource();
298+
cts.Cancel();
299+
300+
// Act
301+
Func<Task> act = async () => await service.SendChatHistoryAsync(store, turnContextMock.Object, cts.Token);
302+
303+
// Assert
304+
await act.Should().ThrowAsync<OperationCanceledException>();
305+
306+
// Verify underlying service was NOT called
307+
McpServerConfigurationServiceMock.Verify(
308+
s => s.SendChatHistoryAsync(
309+
It.IsAny<ITurnContext>(),
310+
It.IsAny<ChatHistoryMessage[]>(),
311+
It.IsAny<ToolOptions>(),
312+
It.IsAny<CancellationToken>()),
313+
Times.Never);
314+
}
315+
316+
[Fact]
317+
public async Task WithCancelledTokenAndToolOptions_ThrowsOperationCanceledException()
318+
{
319+
// Arrange
320+
var service = CreateService();
321+
var store = new TestChatMessageStore(new List<ChatMessage>
322+
{
323+
new ChatMessage(ChatRole.User, "Test") { MessageId = "msg-1", CreatedAt = DateTimeOffset.UtcNow }
324+
});
325+
var turnContextMock = new Mock<ITurnContext>();
326+
var toolOptions = new ToolOptions();
327+
var cts = new CancellationTokenSource();
328+
cts.Cancel();
329+
330+
// Act
331+
Func<Task> act = async () => await service.SendChatHistoryAsync(store, turnContextMock.Object, toolOptions, cts.Token);
332+
333+
// Assert
334+
await act.Should().ThrowAsync<OperationCanceledException>();
335+
336+
// Verify underlying service was NOT called
337+
McpServerConfigurationServiceMock.Verify(
338+
s => s.SendChatHistoryAsync(
339+
It.IsAny<ITurnContext>(),
340+
It.IsAny<ChatHistoryMessage[]>(),
341+
It.IsAny<ToolOptions>(),
342+
It.IsAny<CancellationToken>()),
343+
Times.Never);
344+
}
279345
}

src/Tests/Microsoft.Agents.A365.Tooling.Extensions.AgentFramework.Tests/Services/McpToolRegistrationServiceTests/SendChatHistoryAsync_IEnumerable_Tests.cs

Lines changed: 53 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ public async Task WithEmptyChatMessages_ReturnsSuccessWithoutCallingService()
7878
s => s.SendChatHistoryAsync(
7979
It.IsAny<ITurnContext>(),
8080
It.IsAny<ChatHistoryMessage[]>(),
81-
It.IsAny<ToolOptions>()),
81+
It.IsAny<ToolOptions>(),
82+
It.IsAny<CancellationToken>()),
8283
Times.Never);
8384
}
8485

@@ -91,7 +92,8 @@ public async Task WithValidChatMessages_CallsServiceWithConvertedMessages()
9192
.Setup(s => s.SendChatHistoryAsync(
9293
It.IsAny<ITurnContext>(),
9394
It.IsAny<ChatHistoryMessage[]>(),
94-
It.IsAny<ToolOptions>()))
95+
It.IsAny<ToolOptions>(),
96+
It.IsAny<CancellationToken>()))
9597
.ReturnsAsync(expectedResult);
9698

9799
var service = CreateService();
@@ -137,7 +139,8 @@ public async Task WithValidChatMessages_CallsServiceWithConvertedMessages()
137139
messages[1].Content == "I'm doing well, thank you!" &&
138140
messages[1].Timestamp == timestamp2),
139141
It.Is<ToolOptions>(opts =>
140-
opts.UserAgentConfiguration == Agent365AgentFrameworkSdkUserAgentConfiguration.Instance)),
142+
opts.UserAgentConfiguration == Agent365AgentFrameworkSdkUserAgentConfiguration.Instance),
143+
It.IsAny<CancellationToken>()),
141144
Times.Once);
142145
}
143146

@@ -150,7 +153,8 @@ public async Task WithValidChatMessages_PreservesMessageOrder()
150153
.Setup(s => s.SendChatHistoryAsync(
151154
It.IsAny<ITurnContext>(),
152155
It.IsAny<ChatHistoryMessage[]>(),
153-
It.IsAny<ToolOptions>()))
156+
It.IsAny<ToolOptions>(),
157+
It.IsAny<CancellationToken>()))
154158
.ReturnsAsync(expectedResult);
155159

156160
var service = CreateService();
@@ -180,7 +184,8 @@ public async Task WithValidChatMessages_PreservesMessageOrder()
180184
messages[0].Id == "1" &&
181185
messages[1].Id == "2" &&
182186
messages[2].Id == "3"),
183-
It.IsAny<ToolOptions>()),
187+
It.IsAny<ToolOptions>(),
188+
It.IsAny<CancellationToken>()),
184189
Times.Once);
185190
}
186191

@@ -192,7 +197,8 @@ public async Task WithMissingMessageId_GeneratesNewId()
192197
.Setup(s => s.SendChatHistoryAsync(
193198
It.IsAny<ITurnContext>(),
194199
It.IsAny<ChatHistoryMessage[]>(),
195-
It.IsAny<ToolOptions>()))
200+
It.IsAny<ToolOptions>(),
201+
It.IsAny<CancellationToken>()))
196202
.ReturnsAsync(OperationResult.Success);
197203

198204
var service = CreateService();
@@ -223,7 +229,8 @@ public async Task WithMissingMessageId_GeneratesNewId()
223229
messages.Length == 1 &&
224230
!string.IsNullOrEmpty(messages[0].Id) &&
225231
IsValidGuid(messages[0].Id)),
226-
It.IsAny<ToolOptions>()),
232+
It.IsAny<ToolOptions>(),
233+
It.IsAny<CancellationToken>()),
227234
Times.Once);
228235
}
229236

@@ -237,7 +244,8 @@ public async Task WithMissingTimestamp_UsesCurrentTime()
237244
.Setup(s => s.SendChatHistoryAsync(
238245
It.IsAny<ITurnContext>(),
239246
It.IsAny<ChatHistoryMessage[]>(),
240-
It.IsAny<ToolOptions>()))
247+
It.IsAny<ToolOptions>(),
248+
It.IsAny<CancellationToken>()))
241249
.ReturnsAsync(OperationResult.Success);
242250

243251
var service = CreateService();
@@ -270,7 +278,8 @@ public async Task WithMissingTimestamp_UsesCurrentTime()
270278
messages.Length == 1 &&
271279
messages[0].Timestamp >= beforeCall &&
272280
messages[0].Timestamp <= afterCall),
273-
It.IsAny<ToolOptions>()),
281+
It.IsAny<ToolOptions>(),
282+
It.IsAny<CancellationToken>()),
274283
Times.Once);
275284
}
276285

@@ -283,7 +292,8 @@ public async Task WhenServiceThrowsException_ReturnsFailedResult()
283292
.Setup(s => s.SendChatHistoryAsync(
284293
It.IsAny<ITurnContext>(),
285294
It.IsAny<ChatHistoryMessage[]>(),
286-
It.IsAny<ToolOptions>()))
295+
It.IsAny<ToolOptions>(),
296+
It.IsAny<CancellationToken>()))
287297
.ThrowsAsync(expectedException);
288298

289299
var service = CreateService();
@@ -320,4 +330,37 @@ public async Task WhenServiceThrowsException_ReturnsFailedResult()
320330
It.IsAny<Func<It.IsAnyType, Exception?, string>>()),
321331
Times.Once);
322332
}
333+
334+
[Fact]
335+
public async Task WithCancelledToken_ThrowsOperationCanceledException()
336+
{
337+
// Arrange
338+
var service = CreateService();
339+
var chatMessages = new List<ChatMessage>
340+
{
341+
new ChatMessage(ChatRole.User, "Test")
342+
{
343+
MessageId = "msg-1",
344+
CreatedAt = DateTimeOffset.UtcNow
345+
}
346+
};
347+
var turnContextMock = new Mock<ITurnContext>();
348+
var cts = new CancellationTokenSource();
349+
cts.Cancel();
350+
351+
// Act
352+
Func<Task> act = async () => await service.SendChatHistoryAsync(chatMessages, turnContextMock.Object, cts.Token);
353+
354+
// Assert
355+
await act.Should().ThrowAsync<OperationCanceledException>();
356+
357+
// Verify underlying service was NOT called
358+
McpServerConfigurationServiceMock.Verify(
359+
s => s.SendChatHistoryAsync(
360+
It.IsAny<ITurnContext>(),
361+
It.IsAny<ChatHistoryMessage[]>(),
362+
It.IsAny<ToolOptions>(),
363+
It.IsAny<CancellationToken>()),
364+
Times.Never);
365+
}
323366
}

0 commit comments

Comments
 (0)