microsoft/teams.net

Public

mirrored fromhttps://github.com/microsoft/teams.netAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
samples/migration-bot

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

core/test/Microsoft.Teams.Bot.Core.Tests/ConversationClientTest.cs

732lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4using Microsoft.Bot.Connector;
5using Microsoft.Extensions.Configuration;
6using Microsoft.Extensions.DependencyInjection;
7using Microsoft.Extensions.Logging;
8using Microsoft.Teams.Bot.Core;
9using Microsoft.Teams.Bot.Core.Hosting;
10using Microsoft.Teams.Bot.Core.Schema;
11using Xunit.Abstractions;
12
13namespace Microsoft.Bot.Core.Tests;
14
15public class ConversationClientTest
16{
17 private readonly ServiceProvider _serviceProvider;
18 private readonly ConversationClient _conversationClient;
19 private readonly Uri _serviceUrl;
20
21 private readonly string _conversationId;
22 private readonly ConversationAccount _recipient = new ConversationAccount();
23 private AgenticIdentity? _agenticIdentity;
24
25 public ConversationClientTest(ITestOutputHelper outputHelper)
26 {
27 IConfigurationBuilder builder = new ConfigurationBuilder()
28 .SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
29 .AddEnvironmentVariables();
30
31 IConfiguration configuration = builder.Build();
32
33 ServiceCollection services = new();
34 services.AddLogging((builder) => {
35 builder.AddXUnit(outputHelper);
36 builder.AddFilter("System.Net", LogLevel.Warning);
37 builder.AddFilter("Microsoft.Identity", LogLevel.Error);
38 builder.AddFilter("Microsoft.Teams", LogLevel.Trace);
39 });
40 services.AddSingleton(configuration);
41 services.AddBotApplication<BotApplication>();
42 _serviceProvider = services.BuildServiceProvider();
43 _conversationClient = _serviceProvider.GetRequiredService<ConversationClient>();
44 _serviceUrl = new Uri(Environment.GetEnvironmentVariable("TEST_SERVICEURL") ?? "https://smba.trafficmanager.net/teams/");
45 _conversationId = Environment.GetEnvironmentVariable("TEST_CONVERSATIONID") ?? throw new InvalidOperationException("TEST_ConversationId environment variable not set");
46 string agenticAppBlueprintId = Environment.GetEnvironmentVariable("AzureAd__ClientId") ?? throw new InvalidOperationException("AzureAd__ClientId environment variable not set");
47 string? agenticAppId = Environment.GetEnvironmentVariable("TEST_AGENTIC_APPID");// ?? throw new InvalidOperationException("TEST_AGENTIC_APPID environment variable not set");
48 string? agenticUserId = Environment.GetEnvironmentVariable("TEST_AGENTIC_USERID");// ?? throw new InvalidOperationException("TEST_AGENTIC_USERID environment variable not set");
49
50 _agenticIdentity = null;
51 if (!string.IsNullOrEmpty(agenticAppId) && !string.IsNullOrEmpty(agenticUserId))
52 {
53 _recipient.Properties.Add("agenticAppBlueprintId", agenticAppBlueprintId);
54 _recipient.Properties.Add("agenticAppId", agenticAppId);
55 _recipient.Properties.Add("agenticUserId", agenticUserId);
56 _agenticIdentity = AgenticIdentity.FromProperties(_recipient.Properties);
57 }
58 }
59
60 [Fact]
61 public async Task SendActivityToChannel()
62 {
63 CoreActivity activity = new()
64 {
65 Type = ActivityType.Message,
66 Properties = { { "text", $"Message from Automated tests, running in SDK `{BotApplication.Version}` at `{DateTime.UtcNow:s}`" } },
67 ServiceUrl = _serviceUrl,
68 Conversation = new(_conversationId),
69 From = _recipient
70 };
71 SendActivityResponse? res = await _conversationClient.SendActivityAsync(activity, cancellationToken: CancellationToken.None);
72 Assert.NotNull(res);
73 Assert.NotNull(res.Id);
74 }
75
76 [Fact]
77 public async Task SendActivityToPersonalChat_FailsWithBad_ConversationId()
78 {
79 CoreActivity activity = new()
80 {
81 Type = ActivityType.Message,
82 Properties = { { "text", $"Message from Automated tests, running in SDK `{BotApplication.Version}` at `{DateTime.UtcNow:s}`" } },
83 ServiceUrl = _serviceUrl,
84 Conversation = new("a:1"),
85 From = _recipient
86 };
87
88 await Assert.ThrowsAsync<HttpRequestException>(()
89 => _conversationClient.SendActivityAsync(activity));
90 }
91
92 [Fact]
93 public async Task UpdateActivity()
94 {
95 // First send an activity to get an ID
96 CoreActivity activity = new()
97 {
98 Type = ActivityType.Message,
99 Properties = { { "text", $"Original message from Automated tests at `{DateTime.UtcNow:s}`" } },
100 ServiceUrl = _serviceUrl,
101 Conversation = new(_conversationId),
102 From = _recipient
103 };
104
105 SendActivityResponse? sendResponse = await _conversationClient.SendActivityAsync(activity, cancellationToken: CancellationToken.None);
106 Assert.NotNull(sendResponse);
107 Assert.NotNull(sendResponse.Id);
108
109 // Now update the activity
110 CoreActivity updatedActivity = new()
111 {
112 Type = ActivityType.Message,
113 Properties = { { "text", $"Updated message from Automated tests at `{DateTime.UtcNow:s}`" } },
114 ServiceUrl = _serviceUrl,
115 Conversation = new(_conversationId),
116 From = _recipient
117 };
118
119 UpdateActivityResponse updateResponse = await _conversationClient.UpdateActivityAsync(
120 activity.Conversation.Id,
121 sendResponse.Id,
122 updatedActivity,
123 cancellationToken: CancellationToken.None);
124
125 Assert.NotNull(updateResponse);
126 Assert.NotNull(updateResponse.Id);
127 }
128
129 [Fact]
130 public async Task DeleteActivity()
131 {
132 // First send an activity to get an ID
133 CoreActivity activity = new()
134 {
135 Type = ActivityType.Message,
136 Properties = { { "text", $"Message to delete from Automated tests at `{DateTime.UtcNow:s}`" } },
137 ServiceUrl = _serviceUrl,
138 Conversation = new(_conversationId),
139 From = _recipient
140 };
141
142 SendActivityResponse? sendResponse = await _conversationClient.SendActivityAsync(activity, cancellationToken: CancellationToken.None);
143 Assert.NotNull(sendResponse);
144 Assert.NotNull(sendResponse.Id);
145
146 // Add a delay for 5 seconds
147 await Task.Delay(TimeSpan.FromSeconds(5));
148
149 // Now delete the activity
150 await _conversationClient.DeleteActivityAsync(
151 activity.Conversation.Id,
152 sendResponse.Id,
153 _serviceUrl,
154 _agenticIdentity,
155 cancellationToken: CancellationToken.None);
156
157 // If no exception was thrown, the delete was successful
158 }
159
160 [Fact]
161 public async Task GetConversationMembers()
162 {
163 IList<ConversationAccount> members = await _conversationClient.GetConversationMembersAsync(
164 _conversationId,
165 _serviceUrl,
166 _agenticIdentity,
167 cancellationToken: CancellationToken.None);
168
169 Assert.NotNull(members);
170 Assert.NotEmpty(members);
171
172 // Log members
173 Console.WriteLine($"Found {members.Count} members in conversation {_conversationId}:");
174 foreach (ConversationAccount member in members)
175 {
176 Console.WriteLine($" - Id: {member.Id}, Name: {member.Name}");
177 Assert.NotNull(member);
178 Assert.NotNull(member.Id);
179 }
180 }
181
182 [Fact]
183 public async Task GetConversationMember()
184 {
185 string userId = Environment.GetEnvironmentVariable("TEST_USER_ID") ?? throw new InvalidOperationException("TEST_USER_ID environment variable not set");
186
187 ConversationAccount member = await _conversationClient.GetConversationMemberAsync<ConversationAccount>(
188 _conversationId,
189 userId,
190 _serviceUrl,
191 _agenticIdentity,
192 cancellationToken: CancellationToken.None);
193
194 Assert.NotNull(member);
195
196 // Log member
197 Console.WriteLine($"Found member in conversation {_conversationId}:");
198 Console.WriteLine($" - Id: {member.Id}, Name: {member.Name}");
199 Assert.NotNull(member);
200 Assert.NotNull(member.Id);
201 }
202
203
204 [Fact]
205 public async Task GetConversationMembersInChannel()
206 {
207 string channelId = Environment.GetEnvironmentVariable("TEST_CHANNELID") ?? throw new InvalidOperationException("TEST_CHANNELID environment variable not set");
208
209 IList<ConversationAccount> members = await _conversationClient.GetConversationMembersAsync(
210 channelId,
211 _serviceUrl,
212 _agenticIdentity,
213 cancellationToken: CancellationToken.None);
214
215 Assert.NotNull(members);
216 Assert.NotEmpty(members);
217
218 // Log members
219 Console.WriteLine($"Found {members.Count} members in channel {channelId}:");
220 foreach (ConversationAccount member in members)
221 {
222 Console.WriteLine($" - Id: {member.Id}, Name: {member.Name}");
223 Assert.NotNull(member);
224 Assert.NotNull(member.Id);
225 }
226 }
227
228 [Fact]
229 public async Task GetActivityMembers()
230 {
231 // First send an activity to get an activity ID
232 CoreActivity activity = new()
233 {
234 Type = ActivityType.Message,
235 Properties = { { "text", $"Message for GetActivityMembers test at `{DateTime.UtcNow:s}`" } },
236 ServiceUrl = _serviceUrl,
237 Conversation = new(_conversationId),
238 From = _recipient
239 };
240
241 SendActivityResponse? sendResponse = await _conversationClient.SendActivityAsync(activity, cancellationToken: CancellationToken.None);
242 Assert.NotNull(sendResponse);
243 Assert.NotNull(sendResponse.Id);
244
245 // Now get the members of this activity
246 IList<ConversationAccount> members = await _conversationClient.GetActivityMembersAsync(
247 activity.Conversation.Id,
248 sendResponse.Id,
249 _serviceUrl,
250 _agenticIdentity,
251 cancellationToken: CancellationToken.None);
252
253 Assert.NotNull(members);
254 Assert.NotEmpty(members);
255
256 // Log activity members
257 Console.WriteLine($"Found {members.Count} members for activity {sendResponse.Id}:");
258 foreach (ConversationAccount member in members)
259 {
260 Console.WriteLine($" - Id: {member.Id}, Name: {member.Name}");
261 Assert.NotNull(member);
262 Assert.NotNull(member.Id);
263 }
264 }
265
266 // TODO: This doesn't work
267 [Fact(Skip = "Method not allowed by API")]
268 public async Task GetConversations()
269 {
270 GetConversationsResponse response = await _conversationClient.GetConversationsAsync(
271 _serviceUrl,
272 cancellationToken: CancellationToken.None);
273
274 Assert.NotNull(response);
275 Assert.NotNull(response.Conversations);
276 Assert.NotEmpty(response.Conversations);
277
278 // Log conversations
279 Console.WriteLine($"Found {response.Conversations.Count} conversations:");
280 foreach (ConversationMembers conversation in response.Conversations)
281 {
282 Console.WriteLine($" - Conversation Id: {conversation.Id}");
283 Assert.NotNull(conversation);
284 Assert.NotNull(conversation.Id);
285
286 if (conversation.Members != null && conversation.Members.Any())
287 {
288 Console.WriteLine($" Members ({conversation.Members.Count}):");
289 foreach (ConversationAccount member in conversation.Members)
290 {
291 Console.WriteLine($" - Id: {member.Id}, Name: {member.Name}");
292 }
293 }
294 }
295 }
296
297 [Fact(Skip = "CreateConversation_WithMembers is not working with agentic identity")]
298 public async Task CreateConversation_WithMembers()
299 {
300 // Create a 1-on-1 conversation with a member
301 ConversationParameters parameters = new()
302 {
303 IsGroup = false,
304 Members =
305 [
306 new()
307 {
308 Id = Environment.GetEnvironmentVariable("TEST_USER_ID") ?? throw new InvalidOperationException("TEST_USER_ID environment variable not set"),
309 }
310 ],
311 // TODO: This is required for some reason. Should it be required in the api?
312 TenantId = Environment.GetEnvironmentVariable("AzureAd__TenantId") ?? throw new InvalidOperationException("AzureAd__TenantId environment variable not set")
313 };
314
315 CreateConversationResponse response = await _conversationClient.CreateConversationAsync(
316 parameters,
317 _serviceUrl,
318 _agenticIdentity,
319 cancellationToken: CancellationToken.None);
320
321 Assert.NotNull(response);
322 Assert.NotNull(response.Id);
323
324 Console.WriteLine($"Created conversation: {response.Id}");
325 Console.WriteLine($" ActivityId: {response.ActivityId}");
326 Console.WriteLine($" ServiceUrl: {response.ServiceUrl}");
327
328 // Send a message to the newly created conversation
329 CoreActivity activity = new()
330 {
331 Type = ActivityType.Message,
332 Properties = { { "text", $"Test message to new conversation at {DateTime.UtcNow:s}" } },
333 ServiceUrl = _serviceUrl,
334 Conversation = new(response.Id)
335 };
336
337 SendActivityResponse? sendResponse = await _conversationClient.SendActivityAsync(activity, cancellationToken: CancellationToken.None);
338 Assert.NotNull(sendResponse);
339 Assert.NotNull(sendResponse.Id);
340
341 Console.WriteLine($" Sent message with activity ID: {sendResponse.Id}");
342 }
343
344 // TODO: This doesn't work
345 [Fact(Skip = "Incorrect conversation creation parameters")]
346 public async Task CreateConversation_WithGroup()
347 {
348 // Create a group conversation
349 ConversationParameters parameters = new()
350 {
351 IsGroup = true,
352 Members =
353 [
354 new()
355 {
356 Id = Environment.GetEnvironmentVariable("TEST_USER_ID") ?? throw new InvalidOperationException("TEST_USER_ID environment variable not set"),
357 },
358 new()
359 {
360 Id = Environment.GetEnvironmentVariable("TEST_USER_ID_2") ?? throw new InvalidOperationException("TEST_USER_ID_2 environment variable not set"),
361 }
362 ],
363 TenantId = Environment.GetEnvironmentVariable("TENANT_ID") ?? throw new InvalidOperationException("TENANT_ID environment variable not set")
364 };
365
366 CreateConversationResponse response = await _conversationClient.CreateConversationAsync(
367 parameters,
368 _serviceUrl,
369 cancellationToken: CancellationToken.None);
370
371 Assert.NotNull(response);
372 Assert.NotNull(response.Id);
373
374 Console.WriteLine($"Created group conversation: {response.Id}");
375
376 // Send a message to the newly created group conversation
377 CoreActivity activity = new()
378 {
379 Type = ActivityType.Message,
380 Properties = { { "text", $"Test message to new group conversation at {DateTime.UtcNow:s}" } },
381 ServiceUrl = _serviceUrl,
382 Conversation = new(response.Id)
383 };
384
385 SendActivityResponse? sendResponse = await _conversationClient.SendActivityAsync(activity, cancellationToken: CancellationToken.None);
386 Assert.NotNull(sendResponse);
387 Assert.NotNull(sendResponse.Id);
388
389 Console.WriteLine($" Sent message with activity ID: {sendResponse.Id}");
390 }
391
392 // TODO: This doesn't work
393 [Fact(Skip = "Incorrect conversation creation parameters")]
394 public async Task CreateConversation_WithTopicName()
395 {
396 // Create a conversation with a topic name
397 ConversationParameters parameters = new()
398 {
399 IsGroup = true,
400 TopicName = $"Test Conversation - {DateTime.UtcNow:s}",
401 Members =
402 [
403 new()
404 {
405 Id = Environment.GetEnvironmentVariable("TEST_USER_ID") ?? throw new InvalidOperationException("TEST_USER_ID environment variable not set"),
406 }
407 ],
408 TenantId = Environment.GetEnvironmentVariable("TENANT_ID") ?? throw new InvalidOperationException("TENANT_ID environment variable not set")
409 };
410
411 CreateConversationResponse response = await _conversationClient.CreateConversationAsync(
412 parameters,
413 _serviceUrl,
414 cancellationToken: CancellationToken.None);
415
416 Assert.NotNull(response);
417 Assert.NotNull(response.Id);
418
419 Console.WriteLine($"Created conversation with topic '{parameters.TopicName}': {response.Id}");
420
421 // Send a message to the newly created conversation
422 CoreActivity activity = new()
423 {
424 Type = ActivityType.Message,
425 Properties = { { "text", $"Test message to conversation with topic name at {DateTime.UtcNow:s}" } },
426 ServiceUrl = _serviceUrl,
427 Conversation = new(response.Id)
428 };
429
430 SendActivityResponse? sendResponse = await _conversationClient.SendActivityAsync(activity, cancellationToken: CancellationToken.None);
431 Assert.NotNull(sendResponse);
432 Assert.NotNull(sendResponse.Id);
433
434 Console.WriteLine($" Sent message with activity ID: {sendResponse.Id}");
435 }
436
437 // TODO: This doesn't fail, but doesn't actually create the initial activity
438 [Fact(Skip = "CreateConversation_WithInitialActivity is not working with agentic identity")]
439 public async Task CreateConversation_WithInitialActivity()
440 {
441 // Create a conversation with an initial message
442 ConversationParameters parameters = new()
443 {
444 IsGroup = false,
445 Members =
446 [
447 new()
448 {
449 Id = Environment.GetEnvironmentVariable("TEST_USER_ID") ?? throw new InvalidOperationException("TEST_USER_ID environment variable not set"),
450 }
451 ],
452 Activity = new CoreActivity
453 {
454 Type = ActivityType.Message,
455 Properties = { { "text", $"Initial message sent at {DateTime.UtcNow:s}" } },
456 },
457 TenantId = Environment.GetEnvironmentVariable("AzureAd__TenantId") ?? throw new InvalidOperationException("AzureAd__TenantId environment variable not set")
458 };
459
460 CreateConversationResponse response = await _conversationClient.CreateConversationAsync(
461 parameters,
462 _serviceUrl,
463 _agenticIdentity,
464 cancellationToken: CancellationToken.None);
465
466 Assert.NotNull(response);
467 Assert.NotNull(response.Id);
468 // Assert.NotNull(response.ActivityId); // Should have an activity ID since we sent an initial message
469
470 Console.WriteLine($"Created conversation with initial activity: {response.Id}");
471 Console.WriteLine($" Initial activity ID: {response.ActivityId}");
472 }
473
474 [Fact(Skip = "CreateConversation_WithChannelData is not working with agentic identity")]
475 public async Task CreateConversation_WithChannelData()
476 {
477 // Create a conversation with channel-specific data
478 ConversationParameters parameters = new()
479 {
480 IsGroup = false,
481 Members =
482 [
483 new()
484 {
485 Id = Environment.GetEnvironmentVariable("TEST_USER_ID") ?? throw new InvalidOperationException("TEST_USER_ID environment variable not set"),
486 }
487 ],
488 ChannelData = new
489 {
490 teamsChannelId = Environment.GetEnvironmentVariable("TEST_CHANNELID")
491 },
492 TenantId = Environment.GetEnvironmentVariable("AzureAd__TenantId") ?? throw new InvalidOperationException("AzureAd__TenantId environment variable not set")
493 };
494
495 CreateConversationResponse response = await _conversationClient.CreateConversationAsync(
496 parameters,
497 _serviceUrl,
498 _agenticIdentity,
499 cancellationToken: CancellationToken.None);
500
501 Assert.NotNull(response);
502 Assert.NotNull(response.Id);
503
504 Console.WriteLine($"Created conversation with channel data: {response.Id}");
505 }
506
507 [Fact]
508 public async Task GetConversationPagedMembers()
509 {
510 PagedMembersResult result = await _conversationClient.GetConversationPagedMembersAsync(
511 _conversationId,
512 _serviceUrl,
513 5,
514 null,
515 _agenticIdentity,
516 cancellationToken: CancellationToken.None);
517
518 Assert.NotNull(result);
519 Assert.NotNull(result.Members);
520 Assert.NotEmpty(result.Members);
521
522 Console.WriteLine($"Found {result.Members.Count} members in page:");
523 foreach (ConversationAccount member in result.Members)
524 {
525 Console.WriteLine($" - Id: {member.Id}, Name: {member.Name}");
526 Assert.NotNull(member);
527 Assert.NotNull(member.Id);
528 }
529
530 if (!string.IsNullOrWhiteSpace(result.ContinuationToken))
531 {
532 Console.WriteLine($"Continuation token: {result.ContinuationToken}");
533 }
534 }
535
536 [Fact]
537 public async Task AddRemoveReactionsToChat_Default()
538 {
539 CoreActivity activity = new()
540 {
541 Type = ActivityType.Message,
542 Properties = { { "text", $"I'm going to add and remove reactions from this message." } },
543 ServiceUrl = _serviceUrl,
544 Conversation = new(_conversationId),
545 From = _recipient
546 };
547 SendActivityResponse? res = await _conversationClient.SendActivityAsync(activity, cancellationToken: CancellationToken.None);
548 Assert.NotNull(res);
549 Assert.NotNull(res.Id);
550
551 await _conversationClient.AddReactionAsync(_conversationId, res.Id, "laugh", _serviceUrl, _agenticIdentity);
552 await Task.Delay(500);
553 await _conversationClient.AddReactionAsync(_conversationId, res.Id, "sad", _serviceUrl, _agenticIdentity);
554 await Task.Delay(500);
555 await _conversationClient.AddReactionAsync(_conversationId, res.Id, "yes-tone4", _serviceUrl, _agenticIdentity);
556
557 await Task.Delay(500);
558 await _conversationClient.DeleteReactionAsync(_conversationId, res.Id, "yes-tone4", _serviceUrl, _agenticIdentity);
559 await Task.Delay(500);
560 await _conversationClient.DeleteReactionAsync(_conversationId, res.Id, "sad", _serviceUrl, _agenticIdentity);
561 }
562
563 [Fact(Skip = "PageSize parameter not respected by API")]
564 public async Task GetConversationPagedMembers_WithPageSize()
565 {
566 PagedMembersResult result = await _conversationClient.GetConversationPagedMembersAsync(
567 _conversationId,
568 _serviceUrl,
569 pageSize: 1,
570 agenticIdentity: _agenticIdentity,
571 cancellationToken: CancellationToken.None);
572
573 Assert.NotNull(result);
574 Assert.NotNull(result.Members);
575 Assert.NotEmpty(result.Members);
576 Assert.Single(result.Members);
577
578 Console.WriteLine($"Found {result.Members.Count} members with pageSize=1:");
579 foreach (ConversationAccount member in result.Members)
580 {
581 Console.WriteLine($" - Id: {member.Id}, Name: {member.Name}");
582 }
583
584 // If there's a continuation token, get the next page
585 if (!string.IsNullOrWhiteSpace(result.ContinuationToken))
586 {
587 Console.WriteLine($"Getting next page with continuation token...");
588
589 PagedMembersResult nextPage = await _conversationClient.GetConversationPagedMembersAsync(
590 _conversationId,
591 _serviceUrl,
592 pageSize: 1,
593 continuationToken: result.ContinuationToken,
594 cancellationToken: CancellationToken.None);
595
596 Assert.NotNull(nextPage);
597 Assert.NotNull(nextPage.Members);
598
599 Console.WriteLine($"Found {nextPage.Members.Count} members in next page:");
600 foreach (ConversationAccount member in nextPage.Members)
601 {
602 Console.WriteLine($" - Id: {member.Id}, Name: {member.Name}");
603 }
604 }
605 }
606
607 [Fact(Skip = "Method not allowed by API")]
608 public async Task DeleteConversationMember()
609 {
610 // Get members before deletion
611 IList<ConversationAccount> membersBefore = await _conversationClient.GetConversationMembersAsync(
612 _conversationId,
613 _serviceUrl,
614 cancellationToken: CancellationToken.None);
615
616 Assert.NotNull(membersBefore);
617 Assert.NotEmpty(membersBefore);
618
619 Console.WriteLine($"Members before deletion: {membersBefore.Count}");
620 foreach (ConversationAccount member in membersBefore)
621 {
622 Console.WriteLine($" - Id: {member.Id}, Name: {member.Name}");
623 }
624
625 // Delete the test user
626 string memberToDelete = Environment.GetEnvironmentVariable("TEST_USER_ID") ?? throw new InvalidOperationException("TEST_USER_ID environment variable not set");
627
628 // Verify the member is in the conversation before attempting to delete
629 Assert.Contains(membersBefore, m => m.Id == memberToDelete);
630
631 await _conversationClient.DeleteConversationMemberAsync(
632 _conversationId,
633 memberToDelete,
634 _serviceUrl,
635 cancellationToken: CancellationToken.None);
636
637 Console.WriteLine($"Deleted member: {memberToDelete}");
638
639 // Get members after deletion
640 IList<ConversationAccount> membersAfter = await _conversationClient.GetConversationMembersAsync(
641 _conversationId,
642 _serviceUrl,
643 cancellationToken: CancellationToken.None);
644
645 Assert.NotNull(membersAfter);
646
647 Console.WriteLine($"Members after deletion: {membersAfter.Count}");
648 foreach (ConversationAccount member in membersAfter)
649 {
650 Console.WriteLine($" - Id: {member.Id}, Name: {member.Name}");
651 }
652
653 // Verify the member was deleted
654 Assert.DoesNotContain(membersAfter, m => m.Id == memberToDelete);
655 }
656
657 [Fact(Skip = "Unknown activity type error")]
658 public async Task SendConversationHistory()
659 {
660 // Create a transcript with historic activities
661 Transcript transcript = new()
662 {
663 Activities =
664 [
665 new()
666 {
667 Type = ActivityType.Message,
668 Id = Guid.NewGuid().ToString(),
669 Properties = { { "text", "Historic message 1" } },
670 ServiceUrl = _serviceUrl,
671 Conversation = new(_conversationId)
672 },
673 new()
674 {
675 Type = ActivityType.Message,
676 Id = Guid.NewGuid().ToString(),
677 Properties = { { "text", "Historic message 2" } },
678 ServiceUrl = _serviceUrl,
679 Conversation = new(_conversationId)
680 },
681 new()
682 {
683 Type = ActivityType.Message,
684 Id = Guid.NewGuid().ToString(),
685 Properties = { { "text", "Historic message 3" } },
686 ServiceUrl = _serviceUrl,
687 Conversation = new(_conversationId)
688 }
689 ]
690 };
691
692 SendConversationHistoryResponse response = await _conversationClient.SendConversationHistoryAsync(
693 _conversationId,
694 transcript,
695 _serviceUrl,
696 cancellationToken: CancellationToken.None);
697
698 Assert.NotNull(response);
699
700 Console.WriteLine($"Sent conversation history with {transcript.Activities?.Count} activities");
701 Console.WriteLine($"Response ID: {response.Id}");
702 }
703
704 [Fact(Skip = "Attachment upload endpoint not found")]
705 public async Task UploadAttachment()
706 {
707 // Create a simple text file as an attachment
708 string fileContent = "This is a test attachment file created at " + DateTime.UtcNow.ToString("s");
709 byte[] fileBytes = System.Text.Encoding.UTF8.GetBytes(fileContent);
710
711 AttachmentData attachmentData = new()
712 {
713 Type = "text/plain",
714 Name = "test-attachment.txt",
715 OriginalBase64 = fileBytes
716 };
717
718 UploadAttachmentResponse response = await _conversationClient.UploadAttachmentAsync(
719 _conversationId,
720 attachmentData,
721 _serviceUrl,
722 cancellationToken: CancellationToken.None);
723
724 Assert.NotNull(response);
725 Assert.NotNull(response.Id);
726
727 Console.WriteLine($"Uploaded attachment: {attachmentData.Name}");
728 Console.WriteLine($" Attachment ID: {response.Id}");
729 Console.WriteLine($" Content-Type: {attachmentData.Type}");
730 Console.WriteLine($" Size: {fileBytes.Length} bytes");
731 }
732}
733