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

Tests/Microsoft.Teams.Api.Tests/Activities/Message/MessageActivityTests.cs

559lines · modecode

1using System.Text;
2using System.Text.Json;
3using System.Text.Json.Serialization;
4
5using Microsoft.Teams.Api.Activities;
6
7namespace Microsoft.Teams.Api.Tests.Activities;
8
9public class MessageActivityTests
10{
11 [Fact]
12 public void JsonSerialize()
13 {
14 var activity = new MessageActivity("testing123")
15 {
16 Id = "1",
17 From = new()
18 {
19 Id = "1",
20 Name = "test",
21 Role = Role.User
22 },
23 Conversation = new()
24 {
25 Id = "1",
26 Type = ConversationType.Personal
27 },
28 Recipient = new()
29 {
30 Id = "2",
31 Name = "test-bot",
32 Role = Role.Bot
33 }
34 };
35
36 var json = JsonSerializer.Serialize(activity, new JsonSerializerOptions()
37 {
38 WriteIndented = true,
39 IndentSize = 4,
40 DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull
41 });
42
43 Assert.Equal(File.ReadAllText(
44 @"../../../Json/Activity/Message/MessageActivity.json"
45 ), json);
46 }
47
48 [Fact]
49 public void JsonSerialize_Derived()
50 {
51 MessageActivity activity = new MessageActivity("testing123")
52 {
53 Id = "1",
54 From = new()
55 {
56 Id = "1",
57 Name = "test",
58 Role = Role.User
59 },
60 Conversation = new()
61 {
62 Id = "1",
63 Type = ConversationType.Personal
64 },
65 Recipient = new()
66 {
67 Id = "2",
68 Name = "test-bot",
69 Role = Role.Bot
70 }
71 };
72
73 var json = JsonSerializer.Serialize(activity, new JsonSerializerOptions()
74 {
75 WriteIndented = true,
76 IndentSize = 4,
77 DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull
78 });
79
80 Assert.Equal(File.ReadAllText(
81 @"../../../Json/Activity/Message/MessageActivity.json"
82 ), json);
83 }
84
85 [Fact]
86 public void JsonSerialize_Derived_Interface()
87 {
88 Activity activity = new MessageActivity("testing123")
89 {
90 Id = "1",
91 From = new()
92 {
93 Id = "1",
94 Name = "test",
95 Role = Role.User
96 },
97 Conversation = new()
98 {
99 Id = "1",
100 Type = ConversationType.Personal
101 },
102 Recipient = new()
103 {
104 Id = "2",
105 Name = "test-bot",
106 Role = Role.Bot
107 }
108 };
109
110 var json = JsonSerializer.Serialize(activity, new JsonSerializerOptions()
111 {
112 WriteIndented = true,
113 IndentSize = 4,
114 DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull
115 });
116
117 Assert.Equal(File.ReadAllText(
118 @"../../../Json/Activity/Message/MessageActivity.json"
119 ), json);
120 }
121
122 [Fact]
123 public void JsonSerialize_Mention()
124 {
125 Account bot = new()
126 {
127 Id = "2",
128 Name = "test-bot",
129 Role = Role.Bot
130 };
131
132 Activity activity = new MessageActivity("testing123")
133 {
134 Id = "1",
135 From = new()
136 {
137 Id = "1",
138 Name = "test",
139 Role = Role.User
140 },
141 Conversation = new()
142 {
143 Id = "1",
144 Type = ConversationType.Personal
145 },
146 Recipient = bot
147 }.AddMention(bot);
148
149 var json = JsonSerializer.Serialize(activity, new JsonSerializerOptions()
150 {
151 WriteIndented = true,
152 IndentSize = 4,
153 DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull,
154 Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
155 });
156
157 var text = File.ReadAllText(
158 @"../../../Json/Activity/Message/MessageActivity_Mention.json",
159 Encoding.UTF8
160 );
161
162 Assert.Equal(text, json);
163 }
164
165 [Fact]
166 public void JsonDeserialize()
167 {
168 var json = File.ReadAllText(@"../../../Json/Activity/Message/MessageActivity.json");
169 var activity = JsonSerializer.Deserialize<MessageActivity>(json);
170 var expected = new MessageActivity("testing123")
171 {
172 Id = "1",
173 From = new()
174 {
175 Id = "1",
176 Name = "test",
177 Role = Role.User
178 },
179 Conversation = new()
180 {
181 Id = "1",
182 Type = ConversationType.Personal
183 },
184 Recipient = new()
185 {
186 Id = "2",
187 Name = "test-bot",
188 Role = Role.Bot
189 }
190 };
191
192 Assert.Equivalent(expected, activity);
193 }
194
195 [Fact]
196 public void JsonDeserialize_Derived()
197 {
198 var json = File.ReadAllText(@"../../../Json/Activity/Message/MessageActivity.json");
199 var activity = JsonSerializer.Deserialize<Activity>(json);
200 var expected = new MessageActivity("testing123")
201 {
202 Id = "1",
203 From = new()
204 {
205 Id = "1",
206 Name = "test",
207 Role = Role.User
208 },
209 Conversation = new()
210 {
211 Id = "1",
212 Type = ConversationType.Personal
213 },
214 Recipient = new()
215 {
216 Id = "2",
217 Name = "test-bot",
218 Role = Role.Bot
219 }
220 };
221
222 Assert.Equivalent(expected, activity);
223 }
224
225 [Fact]
226 public void JsonSerialize_WebChat_AllowsEmptyConversationType()
227 {
228 MessageActivity activity = new MessageActivity()
229 {
230 Id = "1",
231 ChannelId = new ChannelId("webchat"),
232 From = new Account()
233 {
234 Id = "1",
235 Name = "test",
236 Role = Role.User
237 },
238 Conversation = new Api.Conversation()
239 {
240 Id = "1"
241 },
242 Recipient = new Account
243 {
244 Id = "2",
245 Name = "test-bot",
246 Role = Role.Bot
247 }
248 };
249 string json = JsonSerializer.Serialize(activity, new JsonSerializerOptions { WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull });
250 string expected = File.ReadAllText(@"../../../Json/Activity/Message/MessageActivity_webChat.json");
251 Assert.Equal(expected, json);
252 }
253
254 [Fact]
255 public void JsonDeserialize_WebChat_AllowsEmptyConversationType()
256 {
257 var json = File.ReadAllText(@"../../../Json/Activity/Message/MessageActivity_webChat.json");
258 var activity = JsonSerializer.Deserialize<MessageActivity>(json);
259 Assert.NotNull(activity);
260 Assert.Equal("1", activity.Id);
261 Assert.Equal("webchat", activity.ChannelId);
262 Assert.NotNull(activity.From);
263 Assert.Equal("1", activity.From.Id);
264 Assert.Equal("test", activity.From.Name);
265 Assert.NotNull(activity.From.Role);
266 Assert.Equal(Role.User, activity.From.Role.Value);
267 Assert.NotNull(activity.Conversation);
268 Assert.Equal("1", activity.Conversation.Id);
269 Assert.Null(activity.Conversation.Type);
270 Assert.NotNull(activity.Recipient);
271 Assert.Equal("2", activity.Recipient.Id);
272 Assert.Equal("test-bot", activity.Recipient.Name);
273 Assert.NotNull(activity.Recipient.Role);
274 Assert.Equal(Role.Bot, activity.Recipient.Role.Value);
275 }
276
277 [Fact]
278 public void MultipleAddAIGenerated_DoesNotCreateDuplicateMessageEntities()
279 {
280 var activity = new MessageActivity("test");
281
282 activity.AddAIGenerated();
283 activity.AddAIGenerated();
284 activity.AddAIGenerated();
285
286 var messageEntities = activity.Entities?.Where(e =>
287 e.Type == "https://schema.org/Message" && e.OType == "Message"
288 ).ToList();
289
290 Assert.NotNull(messageEntities);
291 Assert.Single(messageEntities);
292 }
293
294 [Fact]
295 public void MultipleAddCitation_DoesNotCreateDuplicateMessageEntities()
296 {
297 var activity = new MessageActivity("test");
298
299 var appearance1 = new Microsoft.Teams.Api.Entities.CitationAppearance
300 {
301 Name = "Doc 1",
302 Abstract = "Abstract 1"
303 };
304
305 var appearance2 = new Microsoft.Teams.Api.Entities.CitationAppearance
306 {
307 Name = "Doc 2",
308 Abstract = "Abstract 2"
309 };
310
311 var appearance3 = new Microsoft.Teams.Api.Entities.CitationAppearance
312 {
313 Name = "Doc 3",
314 Abstract = "Abstract 3"
315 };
316
317 activity.AddCitation(1, appearance1);
318 activity.AddCitation(2, appearance2);
319 activity.AddCitation(3, appearance3);
320
321 var messageEntities = activity.Entities?.Where(e =>
322 e.Type == "https://schema.org/Message" && e.OType == "Message"
323 ).ToList();
324
325 Assert.NotNull(messageEntities);
326 Assert.Single(messageEntities);
327
328 // Verify all citations are in the single message entity
329 var citationEntity = messageEntities[0] as Microsoft.Teams.Api.Entities.CitationEntity;
330 Assert.NotNull(citationEntity);
331 Assert.NotNull(citationEntity.Citation);
332 Assert.Equal(3, citationEntity.Citation.Count);
333 }
334
335 [Fact]
336 public void MixedAddAIGeneratedAndAddCitation_DoesNotCreateDuplicateMessageEntities()
337 {
338 var activity = new MessageActivity("test");
339
340 activity.AddAIGenerated();
341
342 var appearance = new Microsoft.Teams.Api.Entities.CitationAppearance
343 {
344 Name = "Doc 1",
345 Abstract = "Abstract 1"
346 };
347
348 activity.AddCitation(1, appearance);
349 activity.AddAIGenerated();
350
351 var messageEntities = activity.Entities?.Where(e =>
352 e.Type == "https://schema.org/Message" && e.OType == "Message"
353 ).ToList();
354
355 Assert.NotNull(messageEntities);
356 Assert.Single(messageEntities);
357
358 // Verify it has both AI generated flag and citation
359 var entity = messageEntities[0] as Microsoft.Teams.Api.Entities.IMessageEntity;
360 Assert.NotNull(entity?.AdditionalType);
361 Assert.Contains("AIGeneratedContent", entity.AdditionalType);
362
363 var citationEntity = messageEntities[0] as Microsoft.Teams.Api.Entities.CitationEntity;
364 Assert.NotNull(citationEntity);
365 Assert.NotNull(citationEntity.Citation);
366 Assert.Single(citationEntity.Citation);
367 }
368
369 [Fact]
370 public void AddMention_WithAddTextFalse_DoesNotAddTextToActivity()
371 {
372 Account bot = new()
373 {
374 Id = "2",
375 Name = "test-bot",
376 Role = Role.Bot
377 };
378
379 var activity = new MessageActivity("testing123")
380 {
381 Id = "1",
382 From = new()
383 {
384 Id = "1",
385 Name = "test",
386 Role = Role.User
387 },
388 Conversation = new()
389 {
390 Id = "1",
391 Type = ConversationType.Personal
392 },
393 Recipient = bot
394 }.AddMention(bot, addText: false);
395
396 // Text should remain unchanged
397 Assert.Equal("testing123", activity.Text);
398
399 // But mention entity should still be added
400 var mention = activity.GetAccountMention("2");
401 Assert.NotNull(mention);
402 Assert.Equal("<at>test-bot</at>", mention.Text);
403 }
404
405 [Fact]
406 public void AddMention_WithCustomText_UsesCustomText()
407 {
408 Account bot = new()
409 {
410 Id = "2",
411 Name = "test-bot",
412 Role = Role.Bot
413 };
414
415 var activity = new MessageActivity("Hello ")
416 {
417 Id = "1",
418 From = new()
419 {
420 Id = "1",
421 Name = "test",
422 Role = Role.User
423 },
424 Conversation = new()
425 {
426 Id = "1",
427 Type = ConversationType.Personal
428 },
429 Recipient = bot
430 }.AddMention(bot, text: "Custom Name");
431
432 // Text should include custom mention text at the beginning
433 Assert.Equal("<at>Custom Name</at> Hello ", activity.Text);
434
435 // Mention entity should use custom text
436 var mention = activity.GetAccountMention("2");
437 Assert.NotNull(mention);
438 Assert.Equal("<at>Custom Name</at>", mention.Text);
439 }
440
441 [Fact]
442 public void AddMention_WithCustomTextAndAddTextFalse_DoesNotAddText()
443 {
444 Account bot = new()
445 {
446 Id = "2",
447 Name = "test-bot",
448 Role = Role.Bot
449 };
450
451 var activity = new MessageActivity("Hello")
452 {
453 Id = "1",
454 From = new()
455 {
456 Id = "1",
457 Name = "test",
458 Role = Role.User
459 },
460 Conversation = new()
461 {
462 Id = "1",
463 Type = ConversationType.Personal
464 },
465 Recipient = bot
466 }.AddMention(bot, text: "Custom Name", addText: false);
467
468 // Text should remain unchanged
469 Assert.Equal("Hello", activity.Text);
470
471 // But mention entity should use custom text
472 var mention = activity.GetAccountMention("2");
473 Assert.NotNull(mention);
474 Assert.Equal("<at>Custom Name</at>", mention.Text);
475 }
476
477 [Fact]
478 public void WithRecipient_DefaultsToNotTargeted()
479 {
480 var activity = new MessageActivity("hello").WithRecipient(new Account() { Id = "1" });
481
482 Assert.Null(activity.Recipient.IsTargeted);
483 Assert.NotNull(activity.Recipient);
484 }
485
486 [Fact]
487 public void WithRecipient_Bool_SetsIsTargeted()
488 {
489 var activity = new MessageActivity("hello").WithRecipient(new Account() { Id = "1" }, true);
490
491 Assert.True(activity.Recipient.IsTargeted);
492 Assert.NotNull(activity.Recipient);
493 }
494
495 [Fact]
496 public void WithRecipient_SetsIsTargetedAndRecipient()
497 {
498 var activity = new MessageActivity("hello").WithRecipient(new Account() { Id = "user-123", Name = "user", Role = Role.User }, true);
499
500 Assert.True(activity.Recipient.IsTargeted);
501 Assert.NotNull(activity.Recipient);
502 Assert.Equal("user-123", activity.Recipient.Id);
503 Assert.Equal("user", activity.Recipient.Name);
504 Assert.Equal(Role.User, activity.Recipient.Role);
505 }
506
507 [Fact]
508 public void WithRecipient_MaintainsFluentChaining()
509 {
510 // This test ensures that WithRecipient(account) returns MessageActivity, not Activity
511 // If it returned Activity, the call to AddText would not compile
512 var activity = new MessageActivity("hello")
513 .WithRecipient(new Account() { Id = "user-123" })
514 .AddText(" world");
515
516 Assert.Equal("hello world", activity.Text);
517 Assert.NotNull(activity.Recipient);
518 Assert.Equal("user-123", activity.Recipient.Id);
519 Assert.Null(activity.Recipient.IsTargeted);
520 }
521
522 [Fact]
523 public void JsonSerialize_WithIsTargeted()
524 {
525 var activity = new MessageActivity("targeted message").WithRecipient(new Account() { Id = "user-123" }, true);
526 activity.Id = "1";
527 activity.From = new() { Id = "1", Name = "test", Role = Role.User };
528 activity.Conversation = new() { Id = "1", Type = ConversationType.Personal };
529
530 var json = JsonSerializer.Serialize(activity, new JsonSerializerOptions()
531 {
532 WriteIndented = true,
533 IndentSize = 4,
534 DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull
535 });
536
537 // IsTargeted is serialized in the recipient object
538 Assert.Contains("\"isTargeted\": true", json);
539 Assert.Contains("\"text\": \"targeted message\"", json);
540 // Verify the property is still set on the object
541 Assert.True(activity.Recipient.IsTargeted);
542 }
543
544 [Fact]
545 public void Validate_FluentAPI()
546 {
547 var msg = new MessageActivity("Hello")
548 .WithDeliveryMode(DeliveryMode.Notification)
549 .WithRecipient(new Account() { Id = "user-123", Name = "Test User", Role = Role.User }, true)
550 .WithImportance(Importance.High);
551
552 Assert.Equal("Hello", msg.Text);
553 Assert.True(msg.Recipient.IsTargeted);
554 Assert.NotNull(msg.Recipient);
555 Assert.Equal("user-123", msg.Recipient.Id);
556 Assert.Equal("Test User", msg.Recipient.Name);
557 Assert.Equal(Role.User, msg.Recipient.Role);
558 }
559}