microsoft/teams.net

Public

mirrored from https://github.com/microsoft/teams.netAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
next/core

Branches

Tags

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

Clone

HTTPS

Download ZIP

core/test/Microsoft.Teams.Bot.Apps.UnitTests/TeamsActivityBuilderTests.cs

853lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4using Microsoft.Teams.Bot.Apps.Schema;
5using Microsoft.Teams.Bot.Apps.Schema.Entities;
6using Microsoft.Teams.Bot.Core.Schema;
7
8namespace Microsoft.Teams.Bot.Apps.UnitTests;
9
10public class TeamsActivityBuilderTests
11{
12 private readonly TeamsActivityBuilder builder;
13 private readonly TeamsActivityBuilder messageBuilder;
14 public TeamsActivityBuilderTests()
15 {
16 builder = TeamsActivity.CreateBuilder();
17 messageBuilder = TeamsActivity.CreateBuilder(new MessageActivity());
18 }
19
20 [Fact]
21 public void Constructor_DefaultConstructor_CreatesNewActivity()
22 {
23 TeamsActivity activity = TeamsActivity.CreateBuilder().Build();
24
25 Assert.NotNull(activity);
26 Assert.Null(activity.From);
27 Assert.Null(activity.Recipient);
28 Assert.Null(activity.Conversation);
29 }
30
31 [Fact]
32 public void Constructor_WithExistingActivity_UsesProvidedActivity()
33 {
34 TeamsActivity existingActivity = new()
35 {
36 Id = "test-id"
37 };
38 existingActivity.Properties["text"] = "existing text";
39
40 TeamsActivityBuilder taBuilder = TeamsActivity.CreateBuilder(existingActivity);
41 TeamsActivity activity = taBuilder.Build();
42
43 Assert.Equal("test-id", activity.Id);
44 Assert.Equal("existing text", activity.Properties["text"]);
45 }
46
47 [Fact]
48 public void Constructor_WithNullActivity_ThrowsArgumentNullException()
49 {
50 Assert.Throws<ArgumentNullException>(() => TeamsActivity.CreateBuilder(null!));
51 }
52
53 [Fact]
54 public void WithId_SetsActivityId()
55 {
56 TeamsActivity activity = builder
57 .WithId("test-activity-id")
58 .Build();
59
60 Assert.Equal("test-activity-id", activity.Id);
61 }
62
63 [Fact]
64 public void WithServiceUrl_SetsServiceUrl()
65 {
66 Uri serviceUrl = new("https://smba.trafficmanager.net/teams/");
67
68 TeamsActivity activity = builder
69 .WithServiceUrl(serviceUrl)
70 .Build();
71
72 Assert.Equal(serviceUrl, activity.ServiceUrl);
73 }
74
75 [Fact]
76 public void WithChannelId_SetsChannelId()
77 {
78 TeamsActivity activity = builder
79 .WithChannelId("msteams")
80 .Build();
81
82 Assert.Equal("msteams", activity.ChannelId);
83 }
84
85 [Fact]
86 public void WithType_SetsActivityType()
87 {
88 TeamsActivity activity = builder
89 .WithType(TeamsActivityType.Message)
90 .Build();
91
92 Assert.Equal(TeamsActivityType.Message, activity.Type);
93 }
94
95 [Fact]
96 public void WithText_SetsTextContent()
97 {
98 TeamsActivity activity = builder
99 .WithText("Hello, World!")
100 .Build();
101
102 Assert.Equal("Hello, World!", activity.Properties["text"]);
103 }
104
105 [Fact]
106 public void WithFrom_SetsSenderAccount()
107 {
108 TeamsConversationAccount? fromAccount = TeamsConversationAccount.FromConversationAccount(new ConversationAccount
109 {
110 Id = "sender-id",
111 Name = "Sender Name"
112 });
113
114 TeamsActivity activity = builder
115 .WithFrom(fromAccount)
116 .Build();
117
118 Assert.Equal("sender-id", activity.From?.Id);
119 Assert.Equal("Sender Name", activity.From?.Name);
120 }
121
122 [Fact]
123 public void WithRecipient_SetsRecipientAccount()
124 {
125 TeamsConversationAccount? recipientAccount = TeamsConversationAccount.FromConversationAccount(new ConversationAccount
126 {
127 Id = "recipient-id",
128 Name = "Recipient Name"
129 });
130 Assert.NotNull(recipientAccount);
131 TeamsActivity activity = builder
132 .WithRecipient(recipientAccount)
133 .Build();
134
135 Assert.Equal("recipient-id", activity.Recipient?.Id);
136 Assert.Equal("Recipient Name", activity.Recipient?.Name);
137 }
138
139 [Fact]
140 public void WithConversation_SetsConversationInfo()
141 {
142 Conversation baseConversation = new("conversation-id");
143
144 Assert.NotNull(baseConversation);
145 baseConversation.Properties.Add("tenantId", "tenant-123");
146 baseConversation.Properties.Add("conversationType", "channel");
147 TeamsConversation? conversation = TeamsConversation.FromConversation(baseConversation);
148
149 TeamsActivity activity = builder
150 .WithConversation(conversation)
151 .Build();
152
153 Assert.Equal("conversation-id", activity.Conversation?.Id);
154 Assert.Equal("tenant-123", activity.Conversation?.TenantId);
155 Assert.Equal("channel", activity.Conversation?.ConversationType);
156 }
157
158 [Fact]
159 public void WithChannelData_SetsChannelData()
160 {
161 TeamsChannelData channelData = new()
162 {
163 TeamsChannelId = "19:channel-id@thread.tacv2",
164 TeamsTeamId = "19:team-id@thread.tacv2"
165 };
166
167 TeamsActivity activity = builder
168 .WithChannelData(channelData)
169 .Build();
170
171 Assert.NotNull(activity.ChannelData);
172 Assert.Equal("19:channel-id@thread.tacv2", activity.ChannelData?.TeamsChannelId);
173 Assert.Equal("19:team-id@thread.tacv2", activity.ChannelData?.TeamsTeamId);
174 }
175
176 [Fact]
177 public void WithEntities_SetsEntitiesCollection()
178 {
179 EntityList entities =
180 [
181 new ClientInfoEntity
182 {
183 Locale = "en-US",
184 Platform = "Web"
185 }
186 ];
187
188 TeamsActivity activity = builder
189 .WithEntities(entities)
190 .Build();
191
192 Assert.NotNull(activity.Entities);
193 Assert.Single(activity.Entities);
194 Assert.IsType<ClientInfoEntity>(activity.Entities[0]);
195 }
196
197 [Fact]
198 public void WithAttachments_SetsAttachmentsCollection()
199 {
200 List<TeamsAttachment> attachments =
201 [
202 new() {
203 ContentType = "application/json",
204 Name = "test-attachment"
205 }
206 ];
207
208 MessageActivity activity = (MessageActivity)messageBuilder
209 .WithAttachments(attachments)
210 .Build();
211
212 Assert.NotNull(activity.Attachments);
213 Assert.Single(activity.Attachments);
214 Assert.Equal("application/json", activity.Attachments[0].ContentType);
215 Assert.Equal("test-attachment", activity.Attachments[0].Name);
216 }
217
218 [Fact]
219 public void WithAttachment_SetsSingleAttachment()
220 {
221 TeamsAttachment attachment = new()
222 {
223 ContentType = "application/json",
224 Name = "single"
225 };
226
227 MessageActivity activity = (MessageActivity)messageBuilder
228 .WithAttachment(attachment)
229 .Build();
230
231 Assert.NotNull(activity.Attachments);
232 Assert.Single(activity.Attachments);
233 Assert.Equal("single", activity.Attachments[0].Name);
234 }
235
236 [Fact]
237 public void AddEntity_AddsEntityToCollection()
238 {
239 ClientInfoEntity entity = new()
240 {
241 Locale = "en-US",
242 Country = "US"
243 };
244
245 TeamsActivity activity = builder
246 .AddEntity(entity)
247 .Build();
248
249 Assert.NotNull(activity.Entities);
250 Assert.Single(activity.Entities);
251 Assert.IsType<ClientInfoEntity>(activity.Entities[0]);
252 }
253
254 [Fact]
255 public void AddEntity_MultipleEntities_AddsAllToCollection()
256 {
257 TeamsActivity activity = builder
258 .AddEntity(new ClientInfoEntity { Locale = "en-US" })
259 .AddEntity(new ProductInfoEntity { Id = "product-123" })
260 .Build();
261
262 Assert.NotNull(activity.Entities);
263 Assert.Equal(2, activity.Entities?.Count);
264 }
265
266 [Fact]
267 public void AddAttachment_AddsAttachmentToCollection()
268 {
269 TeamsAttachment attachment = new()
270 {
271 ContentType = "text/html",
272 Name = "test.html"
273 };
274
275 MessageActivity activity = (MessageActivity)messageBuilder
276 .AddAttachment(attachment)
277 .Build();
278
279 Assert.NotNull(activity.Attachments);
280 Assert.Single(activity.Attachments);
281 Assert.Equal("text/html", activity.Attachments[0].ContentType);
282 }
283
284 [Fact]
285 public void AddAttachment_MultipleAttachments_AddsAllToCollection()
286 {
287 MessageActivity activity = (MessageActivity)messageBuilder
288 .AddAttachment(new TeamsAttachment { ContentType = "text/html" })
289 .AddAttachment(new TeamsAttachment { ContentType = "application/json" })
290 .Build();
291
292 Assert.NotNull(activity.Attachments);
293 Assert.Equal(2, activity.Attachments?.Count);
294 }
295
296 [Fact]
297 public void AddAdaptiveCardAttachment_AddsAdaptiveCard()
298 {
299 var adaptiveCard = new { type = "AdaptiveCard", version = "1.2" };
300
301 MessageActivity activity = (MessageActivity)messageBuilder
302 .AddAdaptiveCardAttachment(adaptiveCard)
303 .Build();
304
305 Assert.NotNull(activity.Attachments);
306 Assert.Single(activity.Attachments);
307 Assert.Equal("application/vnd.microsoft.card.adaptive", activity.Attachments[0].ContentType);
308 Assert.Same(adaptiveCard, activity.Attachments[0].Content);
309 }
310
311 [Fact]
312 public void WithAdaptiveCardAttachment_ConfigureActionAppliesChanges()
313 {
314 var adaptiveCard = new { type = "AdaptiveCard" };
315
316 MessageActivity activity = (MessageActivity)messageBuilder
317 .WithAdaptiveCardAttachment(adaptiveCard, b => b.WithName("feedback"))
318 .Build();
319
320 Assert.NotNull(activity.Attachments);
321 Assert.Single(activity.Attachments);
322 Assert.Equal("feedback", activity.Attachments[0].Name);
323 }
324
325 [Fact]
326 public void AddAdaptiveCardAttachment_WithNullPayload_Throws()
327 {
328 Assert.Throws<ArgumentNullException>(() => builder.AddAdaptiveCardAttachment(null!));
329 }
330
331 [Fact]
332 public void AddMention_WithNullAccount_ThrowsArgumentNullException()
333 {
334 Assert.Throws<ArgumentNullException>(() => builder.AddMention(null!));
335 }
336
337 [Fact]
338 public void AddMention_WithAccountAndDefaultText_AddsMentionAndUpdatesText()
339 {
340 ConversationAccount account = new()
341 {
342 Id = "user-123",
343 Name = "John Doe"
344 };
345
346 TeamsActivity activity = builder
347 .WithText("said hello")
348 .AddMention(account)
349 .Build();
350
351 Assert.Equal("<at>John Doe</at> said hello", activity.Properties["text"]);
352 Assert.NotNull(activity.Entities);
353 Assert.Single(activity.Entities);
354
355 MentionEntity? mention = activity.Entities[0] as MentionEntity;
356 Assert.NotNull(mention);
357 Assert.Equal("user-123", mention.Mentioned?.Id);
358 Assert.Equal("John Doe", mention.Mentioned?.Name);
359 Assert.Equal("<at>John Doe</at>", mention.Text);
360 }
361
362 [Fact]
363 public void AddMention_WithCustomText_UsesCustomText()
364 {
365 ConversationAccount account = new()
366 {
367 Id = "user-123",
368 Name = "John Doe"
369 };
370
371 TeamsActivity activity = builder
372 .WithText("replied")
373 .AddMention(account, "CustomName")
374 .Build();
375
376 Assert.Equal("<at>CustomName</at> replied", activity.Properties["text"]);
377
378 MentionEntity? mention = activity.Entities![0] as MentionEntity;
379 Assert.NotNull(mention);
380 Assert.Equal("<at>CustomName</at>", mention.Text);
381 }
382
383 [Fact]
384 public void AddMention_WithAddTextFalse_DoesNotUpdateText()
385 {
386 ConversationAccount account = new()
387 {
388 Id = "user-123",
389 Name = "John Doe"
390 };
391
392 TeamsActivity activity = builder
393 .WithText("original text")
394 .AddMention(account, addText: false)
395 .Build();
396
397 Assert.Equal("original text", activity.Properties["text"]);
398 Assert.NotNull(activity.Entities);
399 Assert.Single(activity.Entities);
400 }
401
402 [Fact]
403 public void AddMention_MultipleMentions_AddsAllMentions()
404 {
405 ConversationAccount account1 = new() { Id = "user-1", Name = "User One" };
406 ConversationAccount account2 = new() { Id = "user-2", Name = "User Two" };
407
408 TeamsActivity activity = builder
409 .WithText("message")
410 .AddMention(account1)
411 .AddMention(account2)
412 .Build();
413
414 Assert.Equal("<at>User Two</at> <at>User One</at> message", activity.Properties["text"]);
415 Assert.NotNull(activity.Entities);
416 Assert.Equal(2, activity.Entities?.Count);
417 }
418
419 [Fact]
420 public void FluentAPI_CompleteActivity_BuildsCorrectly()
421 {
422 MessageActivity activity = (MessageActivity)messageBuilder
423 .WithType(TeamsActivityType.Message)
424 .WithId("activity-123")
425 .WithChannelId("msteams")
426 .WithText("Test message")
427 .WithServiceUrl(new Uri("https://smba.trafficmanager.net/teams/"))
428 .WithFrom(TeamsConversationAccount.FromConversationAccount(new ConversationAccount
429 {
430 Id = "sender-id",
431 Name = "Sender"
432 }))
433 .WithRecipient(TeamsConversationAccount.FromConversationAccount(new ConversationAccount
434 {
435 Id = "recipient-id",
436 Name = "Recipient"
437 }))
438 .WithConversation(TeamsConversation.FromConversation(new Conversation
439 {
440 Id = "conv-id"
441 }))
442 .AddEntity(new ClientInfoEntity { Locale = "en-US" })
443 .AddAttachment(new TeamsAttachment { ContentType = "text/html" })
444 .AddMention(new ConversationAccount { Id = "user-1", Name = "User" })
445 .Build();
446
447 Assert.Equal(TeamsActivityType.Message, activity.Type);
448 Assert.Equal("activity-123", activity.Id);
449 Assert.Equal("msteams", activity.ChannelId);
450 Assert.Equal("<at>User</at> Test message", activity.Properties["text"]);
451 Assert.Equal("sender-id", activity.From?.Id);
452 Assert.Equal("recipient-id", activity.Recipient?.Id);
453 Assert.Equal("conv-id", activity.Conversation?.Id);
454 Assert.NotNull(activity.Entities);
455 Assert.Equal(2, activity.Entities?.Count); // ClientInfo + Mention
456 Assert.NotNull(activity.Attachments);
457 Assert.Single(activity.Attachments);
458 }
459
460 [Fact]
461 public void FluentAPI_MethodChaining_ReturnsBuilderInstance()
462 {
463
464 TeamsActivityBuilder result1 = builder.WithId("id");
465 TeamsActivityBuilder result2 = builder.WithText("text");
466 TeamsActivityBuilder result3 = builder.WithType(TeamsActivityType.Message);
467
468 Assert.Same(builder, result1);
469 Assert.Same(builder, result2);
470 Assert.Same(builder, result3);
471 }
472
473 [Fact]
474 public void Build_CalledMultipleTimes_ReturnsSameInstance()
475 {
476 builder
477 .WithId("test-id");
478
479 TeamsActivity activity1 = builder.Build();
480 TeamsActivity activity2 = builder.Build();
481
482 Assert.Same(activity1, activity2);
483 }
484
485 [Fact]
486 public void Builder_ModifyingExistingActivity_PreservesOriginalData()
487 {
488 TeamsActivity original = new()
489 {
490 Id = "original-id",
491 Type = TeamsActivityType.Message
492 };
493 original.Properties["text"] = "original text";
494
495 TeamsActivity modified = TeamsActivity.CreateBuilder(original)
496 .WithText("modified text")
497 .Build();
498
499 Assert.Equal("original-id", modified.Id);
500 Assert.Equal("modified text", modified.Properties["text"]);
501 Assert.Equal(TeamsActivityType.Message, modified.Type);
502 }
503
504 [Fact]
505 public void AddMention_UpdatesBaseEntityCollection()
506 {
507 ConversationAccount account = new()
508 {
509 Id = "user-123",
510 Name = "Test User"
511 };
512
513 TeamsActivity activity = builder
514 .AddMention(account)
515 .Build();
516
517 // Entities are on TeamsActivity, not CoreActivity; verify via TeamsActivity
518 Assert.NotNull(activity.Entities);
519 Assert.NotEmpty(activity.Entities);
520 }
521
522 [Fact]
523 public void WithChannelData_NullValue_SetsToNull()
524 {
525 TeamsActivity activity = builder
526 .WithChannelData(null!)
527 .Build();
528
529 Assert.Null(activity.ChannelData);
530 }
531
532 [Fact]
533 public void AddEntity_NullEntitiesCollection_InitializesCollection()
534 {
535 TeamsActivity activity = builder.Build();
536
537 Assert.Null(activity.Entities);
538
539 ClientInfoEntity entity = new() { Locale = "en-US" };
540 builder.AddEntity(entity);
541
542 TeamsActivity result = builder.Build();
543 Assert.NotNull(result.Entities);
544 Assert.Single(result.Entities);
545 }
546
547 [Fact]
548 public void AddAttachment_NullAttachmentsCollection_InitializesCollection()
549 {
550 MessageActivity activity = (MessageActivity)messageBuilder.Build();
551
552 Assert.Null(activity.Attachments);
553
554 TeamsAttachment attachment = new() { ContentType = "text/html" };
555 messageBuilder.AddAttachment(attachment);
556
557 MessageActivity result = (MessageActivity)messageBuilder.Build();
558 Assert.NotNull(result.Attachments);
559 Assert.Single(result.Attachments);
560 }
561
562 [Fact]
563 public void Builder_EmptyText_AddMention_PrependsMention()
564 {
565 ConversationAccount account = new()
566 {
567 Id = "user-123",
568 Name = "User"
569 };
570
571 TeamsActivity activity = builder
572 .AddMention(account)
573 .Build();
574
575 Assert.Equal("<at>User</at> ", activity.Properties["text"]);
576 }
577
578 [Fact]
579 public void WithConversationReference_WithNullActivity_ThrowsArgumentNullException()
580 {
581 Assert.Throws<ArgumentNullException>(() => builder.WithConversationReference(null!));
582 }
583
584 [Fact]
585 public void WithConversationReference_WithNullChannelId_ThrowsArgumentNullException()
586 {
587
588 TeamsActivity sourceActivity = new()
589 {
590 ChannelId = null!,
591 ServiceUrl = new Uri("https://test.com"),
592 Conversation = TeamsConversation.FromConversation(new Conversation()),
593 From = TeamsConversationAccount.FromConversationAccount(new ConversationAccount()),
594 Recipient = TeamsConversationAccount.FromConversationAccount(new ConversationAccount())
595 };
596
597 Assert.Throws<ArgumentNullException>(() => builder.WithConversationReference(sourceActivity));
598 }
599
600 [Fact]
601 public void WithConversationReference_WithNullServiceUrl_ThrowsArgumentNullException()
602 {
603 TeamsActivity sourceActivity = new()
604 {
605 ChannelId = "msteams",
606 ServiceUrl = null!,
607 Conversation = TeamsConversation.FromConversation(new Conversation()),
608 From = TeamsConversationAccount.FromConversationAccount(new ConversationAccount()),
609 Recipient = TeamsConversationAccount.FromConversationAccount(new ConversationAccount())
610 };
611
612 Assert.Throws<ArgumentNullException>(() => builder.WithConversationReference(sourceActivity));
613 }
614
615 [Fact]
616 public void WithConversationReference_WithEmptyConversationId_DoesNotThrow()
617 {
618 TeamsActivity sourceActivity = new()
619 {
620 ChannelId = "msteams",
621 ServiceUrl = new Uri("https://test.com"),
622 Conversation = TeamsConversation.FromConversation(new Conversation()),
623 From = TeamsConversationAccount.FromConversationAccount(new ConversationAccount { Id = "user-1" }),
624 Recipient = TeamsConversationAccount.FromConversationAccount(new ConversationAccount { Id = "bot-1" })
625 };
626
627 TeamsActivity result = builder.WithConversationReference(sourceActivity).Build();
628
629 Assert.NotNull(result.Conversation);
630 }
631
632 [Fact]
633 public void WithConversationReference_WithEmptyFromId_DoesNotThrow()
634 {
635 TeamsActivity sourceActivity = new()
636 {
637 ChannelId = "msteams",
638 ServiceUrl = new Uri("https://test.com"),
639 Conversation = TeamsConversation.FromConversation(new Conversation { Id = "conv-1" }),
640 From = TeamsConversationAccount.FromConversationAccount(new ConversationAccount()),
641 Recipient = TeamsConversationAccount.FromConversationAccount(new ConversationAccount { Id = "bot-1" })
642 };
643
644 TeamsActivity result = builder.WithConversationReference(sourceActivity).Build();
645
646 Assert.NotNull(result.From);
647 }
648
649 [Fact]
650 public void WithConversationReference_WithEmptyRecipientId_DoesNotThrow()
651 {
652 TeamsActivity sourceActivity = new()
653 {
654 ChannelId = "msteams",
655 ServiceUrl = new Uri("https://test.com"),
656 Conversation = TeamsConversation.FromConversation(new Conversation { Id = "conv-1" }),
657 From = TeamsConversationAccount.FromConversationAccount(new ConversationAccount { Id = "user-1" }),
658 Recipient = TeamsConversationAccount.FromConversationAccount(new ConversationAccount())
659 };
660
661 TeamsActivity result = builder.WithConversationReference(sourceActivity).Build();
662
663 Assert.NotNull(result.From);
664 }
665
666 [Fact]
667 public void WithFrom_WithBaseConversationAccount_ConvertsToTeamsConversationAccount()
668 {
669 ConversationAccount baseAccount = new()
670 {
671 Id = "user-123",
672 Name = "User Name"
673 };
674
675 TeamsActivity activity = builder
676 .WithFrom(baseAccount)
677 .Build();
678
679 Assert.IsType<TeamsConversationAccount>(activity.From);
680 Assert.Equal("user-123", activity.From?.Id);
681 Assert.Equal("User Name", activity.From?.Name);
682 }
683
684 [Fact]
685 public void WithRecipient_WithBaseConversationAccount_ConvertsToTeamsConversationAccount()
686 {
687 ConversationAccount baseAccount = new()
688 {
689 Id = "bot-123",
690 Name = "Bot Name"
691 };
692
693 TeamsActivity activity = builder
694 .WithRecipient(baseAccount)
695 .Build();
696
697 Assert.IsType<TeamsConversationAccount>(activity.Recipient);
698 Assert.Equal("bot-123", activity.Recipient?.Id);
699 Assert.Equal("Bot Name", activity.Recipient?.Name);
700 }
701
702 [Fact]
703 public void WithConversation_WithBaseConversation_ConvertsToTeamsConversation()
704 {
705 Conversation baseConversation = new()
706 {
707 Id = "conv-123"
708 };
709
710 TeamsActivity activity = builder
711 .WithConversation(baseConversation)
712 .Build();
713
714 Assert.IsType<TeamsConversation>(activity.Conversation);
715 Assert.Equal("conv-123", activity.Conversation?.Id);
716 }
717
718 [Fact]
719 public void WithEntities_WithNullValue_SetsToNull()
720 {
721 TeamsActivity activity = builder
722 .WithEntities([new ClientInfoEntity()])
723 .WithEntities(null!)
724 .Build();
725
726 Assert.Null(activity.Entities);
727 }
728
729 [Fact]
730 public void WithAttachments_WithNullValue_SetsToNull()
731 {
732 MessageActivity activity = (MessageActivity)messageBuilder
733 .WithAttachments([new()])
734 .WithAttachments(null!)
735 .Build();
736
737 Assert.Null(activity.Attachments);
738 }
739
740 [Fact]
741 public void AddMention_WithAccountWithNullName_UsesNullText()
742 {
743 ConversationAccount account = new()
744 {
745 Id = "user-123",
746 Name = null
747 };
748
749 TeamsActivity activity = builder
750 .WithText("message")
751 .AddMention(account)
752 .Build();
753
754 Assert.Equal("<at></at> message", activity.Properties["text"]);
755 Assert.NotNull(activity.Entities);
756 Assert.Single(activity.Entities);
757 }
758
759 [Fact]
760 public void Build_MultipleCalls_ReturnsRebasedActivity()
761 {
762 builder
763 .AddEntity(new ClientInfoEntity { Locale = "en-US" });
764
765 TeamsActivity activity1 = builder.Build();
766 Assert.NotNull(activity1.Entities);
767
768 builder.AddEntity(new ProductInfoEntity { Id = "prod-1" });
769 TeamsActivity activity2 = builder.Build();
770
771 Assert.Same(activity1, activity2);
772 Assert.NotNull(activity2.Entities);
773 Assert.Equal(2, activity2.Entities!.Count);
774 }
775
776 [Fact]
777 public void IntegrationTest_CreateComplexActivity()
778 {
779 Uri serviceUrl = new("https://smba.trafficmanager.net/amer/test/");
780 TeamsChannelData channelData = new()
781 {
782 TeamsChannelId = "19:channel@thread.tacv2",
783 TeamsTeamId = "19:team@thread.tacv2"
784 };
785
786 Conversation conv = new()
787 {
788 Id = "conv-001",
789 Properties =
790 {
791 { "tenantId", "tenant-001" },
792 { "conversationType", "channel" }
793 }
794 };
795
796 TeamsConversation? tc = TeamsConversation.FromConversation(conv);
797 Assert.NotNull(tc);
798
799 MessageActivity activity = (MessageActivity)messageBuilder
800 .WithType(TeamsActivityType.Message)
801 .WithId("msg-001")
802 .WithServiceUrl(serviceUrl)
803 .WithChannelId("msteams")
804 .WithText("Please review this document")
805 .WithFrom(TeamsConversationAccount.FromConversationAccount(new ConversationAccount
806 {
807 Id = "bot-id",
808 Name = "Bot"
809 }))
810 .WithRecipient(TeamsConversationAccount.FromConversationAccount(new ConversationAccount
811 {
812 Id = "user-id",
813 Name = "User"
814 }))
815 .WithConversation(tc)
816 .WithChannelData(channelData)
817 .AddEntity(new ClientInfoEntity
818 {
819 Locale = "en-US",
820 Country = "US",
821 Platform = "Web"
822 })
823 .AddAttachment(new TeamsAttachment
824 {
825 ContentType = "application/vnd.microsoft.card.adaptive",
826 Name = "adaptive-card.json"
827 })
828 .AddMention(new ConversationAccount
829 {
830 Id = "manager-id",
831 Name = "Manager"
832 }, "Manager")
833 .Build();
834
835 // Verify all properties
836 Assert.Equal(TeamsActivityType.Message, activity.Type);
837 Assert.Equal("msg-001", activity.Id);
838 Assert.Equal(serviceUrl, activity.ServiceUrl);
839 Assert.Equal("msteams", activity.ChannelId);
840 Assert.Equal("<at>Manager</at> Please review this document", activity.Properties["text"]);
841 Assert.Equal("bot-id", activity.From?.Id);
842 Assert.Equal("user-id", activity.Recipient?.Id);
843 Assert.Equal("conv-001", activity.Conversation?.Id);
844 Assert.Equal("tenant-001", activity.Conversation?.TenantId);
845 Assert.Equal("channel", activity.Conversation?.ConversationType);
846 Assert.NotNull(activity.ChannelData);
847 Assert.Equal("19:channel@thread.tacv2", activity.ChannelData?.TeamsChannelId);
848 Assert.NotNull(activity.Entities);
849 Assert.Equal(2, activity.Entities?.Count); // ClientInfo + Mention
850 Assert.NotNull(activity.Attachments);
851 Assert.Single(activity.Attachments);
852 }
853}
854