microsoft/teams.net

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
feature/user-agent-header

Branches

Tags

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

Clone

HTTPS

Download ZIP

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

449lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4using System.Text.Json.Nodes;
5using Microsoft.Teams.Bot.Core.Schema;
6using Microsoft.Teams.Bot.Apps.Schema;
7using Microsoft.Teams.Bot.Apps.Schema.Entities;
8using Microsoft.Teams.Bot.Apps.Schema.MessageActivities;
9
10namespace Microsoft.Teams.Bot.Apps.UnitTests;
11
12public class TeamsActivityTests
13{
14
15 [Fact]
16 public void DeserializeActivityWithTeamsChannelData()
17 {
18 TeamsActivity activityWithTeamsChannelData = TeamsActivity.FromJsonString(json);
19 TeamsChannelData tcd = activityWithTeamsChannelData.ChannelData!;
20 Assert.Equal("19:6848757105754c8981c67612732d9aa7@thread.tacv2", tcd.TeamsChannelId);
21 Assert.Equal("19:6848757105754c8981c67612732d9aa7@thread.tacv2", tcd.Channel!.Id);
22 // Assert.Equal("b15a9416-0ad3-4172-9210-7beb711d3f70", activity.From.AadObjectId);
23 }
24
25 [Fact]
26 public void DeserializeTeamsActivityWithTeamsChannelData()
27 {
28 TeamsActivity activity = TeamsActivity.FromJsonString(json);
29 TeamsChannelData tcd = activity.ChannelData!;
30 Assert.Equal("19:6848757105754c8981c67612732d9aa7@thread.tacv2", tcd.TeamsChannelId);
31 Assert.Equal("19:6848757105754c8981c67612732d9aa7@thread.tacv2", tcd.Channel!.Id);
32 Assert.Equal("b15a9416-0ad3-4172-9210-7beb711d3f70", activity.From.AadObjectId);
33 Assert.Equal("19:6848757105754c8981c67612732d9aa7@thread.tacv2;messageid=1759881511856", activity.Conversation.Id);
34
35 Assert.NotNull(activity.Attachments);
36 Assert.Single(activity.Attachments);
37 Assert.Equal("text/html", activity.Attachments[0].ContentType);
38
39 Assert.NotNull(activity.Entities);
40 Assert.Equal(2, activity.Entities.Count);
41
42 }
43
44 [Fact]
45 public void DownCastTeamsActivity_To_CoreActivity()
46 {
47 CoreActivity activity = CoreActivity.FromJsonString(json);
48 Assert.Equal("19:6848757105754c8981c67612732d9aa7@thread.tacv2;messageid=1759881511856", activity.Conversation!.Id);
49 TeamsActivity teamsActivity = TeamsActivity.FromActivity(activity);
50 Assert.Equal("19:6848757105754c8981c67612732d9aa7@thread.tacv2;messageid=1759881511856", teamsActivity.Conversation!.Id);
51
52 static void AssertCid(CoreActivity a)
53 {
54 Assert.Equal("19:6848757105754c8981c67612732d9aa7@thread.tacv2;messageid=1759881511856", a.Conversation!.Id);
55 }
56 AssertCid(teamsActivity);
57
58 }
59
60 [Fact]
61 public void DownCastTeamsActivity_To_CoreActivity_FromBuilder()
62 {
63
64 TeamsActivity teamsActivity = TeamsActivity
65 .CreateBuilder()
66 .WithConversation(new Conversation() { Id = "19:6848757105754c8981c67612732d9aa7@thread.tacv2;messageid=1759881511856" })
67 .Build();
68
69 static void AssertCid(CoreActivity a)
70 {
71 Assert.Equal("19:6848757105754c8981c67612732d9aa7@thread.tacv2;messageid=1759881511856", a.Conversation!.Id);
72 }
73 AssertCid(teamsActivity);
74 }
75
76 [Fact]
77 public void DownCastTeamsActivity_To_CoreActivity_FromJsonString()
78 {
79
80 TeamsActivity teamsActivity = TeamsActivity.FromJsonString(json);
81 Assert.Equal("19:6848757105754c8981c67612732d9aa7@thread.tacv2;messageid=1759881511856", teamsActivity.Conversation!.Id);
82
83 static void AssertCid(CoreActivity a)
84 {
85 Assert.Equal("19:6848757105754c8981c67612732d9aa7@thread.tacv2;messageid=1759881511856", a.Conversation!.Id);
86 }
87 AssertCid(teamsActivity);
88
89 }
90
91 [Fact]
92 public void DownCastTeamsActivity_To_CoreActivity_WithoutRebase()
93 {
94 TeamsActivity teamsActivity = new TeamsActivity() {
95 Conversation = new TeamsConversation()
96 {
97 Id = "19:6848757105754c8981c67612732d9aa7@thread.tacv2;messageid=1759881511856"
98 }
99 };
100 Assert.Equal("19:6848757105754c8981c67612732d9aa7@thread.tacv2;messageid=1759881511856", teamsActivity.Conversation!.Id);
101
102 static void AssertCid(CoreActivity a)
103 {
104 Assert.Equal("19:6848757105754c8981c67612732d9aa7@thread.tacv2;messageid=1759881511856", a.Conversation!.Id);
105 }
106 AssertCid(teamsActivity);
107
108 }
109
110
111 [Fact]
112 public void AddMentionEntity_To_TeamsActivity()
113 {
114 TeamsActivity activity = TeamsActivity.FromActivity(new CoreActivity(ActivityType.Message));
115 activity
116 .AddMention(new ConversationAccount
117 {
118 Id = "user-id-01",
119 Name = "rido"
120 }, "ridotest");
121
122
123
124 Assert.NotNull(activity.Entities);
125 Assert.Single(activity.Entities);
126 Assert.Equal("mention", activity.Entities[0].Type);
127 MentionEntity? mention = activity.Entities[0] as MentionEntity;
128 Assert.NotNull(mention);
129 Assert.Equal("user-id-01", mention.Mentioned?.Id);
130 Assert.Equal("rido", mention.Mentioned?.Name);
131 Assert.Equal("<at>ridotest</at>", mention.Text);
132
133 string jsonResult = activity.ToJson();
134 Assert.Contains("user-id-01", jsonResult);
135 }
136
137 [Fact]
138 public void AddMentionEntity_Serialize_From_CoreActivity()
139 {
140 TeamsActivity activity = TeamsActivity.FromActivity(new CoreActivity(ActivityType.Message));
141 activity.AddMention(new ConversationAccount
142 {
143 Id = "user-id-01",
144 Name = "rido"
145 }, "ridotest");
146
147
148
149 Assert.NotNull(activity.Entities);
150 Assert.Single(activity.Entities);
151 Assert.Equal("mention", activity.Entities[0].Type);
152 MentionEntity? mention = activity.Entities[0] as MentionEntity;
153 Assert.NotNull(mention);
154 Assert.Equal("user-id-01", mention.Mentioned?.Id);
155 Assert.Equal("rido", mention.Mentioned?.Name);
156 Assert.Equal("<at>ridotest</at>", mention.Text);
157
158 static void SerializeAndAssert(CoreActivity a)
159 {
160 string json = a.ToJson();
161 Assert.Contains("user-id-01", json);
162 }
163
164 SerializeAndAssert(activity);
165 }
166
167
168 [Fact]
169 public void TeamsActivityBuilder_FluentAPI()
170 {
171 TeamsActivity activity = TeamsActivity.CreateBuilder()
172 .WithType(TeamsActivityType.Message)
173 .WithText("Hello World")
174 .WithChannelId("msteams")
175 .AddMention(new ConversationAccount
176 {
177 Id = "user-123",
178 Name = "TestUser"
179 })
180 .Build();
181
182 Assert.Equal(ActivityType.Message, activity.Type);
183 Assert.Equal("<at>TestUser</at> Hello World", activity.Properties["text"]);
184 Assert.Equal("msteams", activity.ChannelId);
185 Assert.NotNull(activity.Entities);
186 Assert.Single(activity.Entities);
187
188 MentionEntity? mention = activity.Entities[0] as MentionEntity;
189 Assert.NotNull(mention);
190 Assert.Equal("user-123", mention.Mentioned?.Id);
191 Assert.Equal("TestUser", mention.Mentioned?.Name);
192 }
193
194 [Fact]
195 public void Deserialize_With_Entities()
196 {
197 TeamsActivity activity = TeamsActivity.FromJsonString(json);
198 Assert.NotNull(activity.Entities);
199 Assert.Equal(2, activity.Entities.Count);
200
201 List<Entity> mentions = activity.Entities.Where(e => e is MentionEntity).ToList();
202 Assert.Single(mentions);
203 MentionEntity? m1 = mentions[0] as MentionEntity;
204 Assert.NotNull(m1);
205 Assert.NotNull(m1.Mentioned);
206 Assert.Equal("28:0b6fe6d1-fece-44f7-9a48-56465e2d5ab8", m1.Mentioned.Id);
207 Assert.Equal("ridotest", m1.Mentioned.Name);
208 Assert.Equal("<at>ridotest</at>", m1.Text);
209
210 List<Entity> clientInfos = [.. activity.Entities.Where(e => e is ClientInfoEntity)];
211 Assert.Single(clientInfos);
212 ClientInfoEntity? c1 = clientInfos[0] as ClientInfoEntity;
213 Assert.NotNull(c1);
214 Assert.Equal("en-US", c1.Locale);
215 Assert.Equal("US", c1.Country);
216 Assert.Equal("Web", c1.Platform);
217 Assert.Equal("America/Los_Angeles", c1.Timezone);
218
219 }
220
221
222 [Fact]
223 public void Deserialize_With_Entities_Extensions()
224 {
225 TeamsActivity activity = TeamsActivity.FromJsonString(json);
226 Assert.NotNull(activity.Entities);
227 Assert.Equal(2, activity.Entities.Count);
228
229 var mentions = activity.GetMentions();
230 Assert.Single(mentions);
231 MentionEntity? m1 = mentions.FirstOrDefault();
232 Assert.NotNull(m1);
233 Assert.NotNull(m1.Mentioned);
234 Assert.Equal("28:0b6fe6d1-fece-44f7-9a48-56465e2d5ab8", m1.Mentioned.Id);
235 Assert.Equal("ridotest", m1.Mentioned.Name);
236 Assert.Equal("<at>ridotest</at>", m1.Text);
237
238 var clientInfo = activity.GetClientInfo();
239 Assert.NotNull(clientInfo);
240 Assert.Equal("en-US", clientInfo.Locale);
241 Assert.Equal("US", clientInfo.Country);
242 Assert.Equal("Web", clientInfo.Platform);
243 Assert.Equal("America/Los_Angeles", clientInfo.Timezone);
244 }
245
246 [Fact]
247 public void Serialize_TeamsActivity_WithEntities()
248 {
249 TeamsActivity activity = TeamsActivity.CreateBuilder()
250 .WithType(ActivityType.Message)
251 .WithText("Hello World")
252 .WithChannelId("msteams")
253 .Build();
254
255 activity.AddClientInfo("Web", "US", "America/Los_Angeles", "en-US");
256
257 string jsonResult = activity.ToJson();
258 Assert.Contains("clientInfo", jsonResult);
259 Assert.Contains("Web", jsonResult);
260 Assert.Contains("Hello World", jsonResult);
261 }
262
263 [Fact]
264 public void Deserialize_TeamsActivity_WithAttachments()
265 {
266 TeamsActivity activity = TeamsActivity.FromJsonString(json);
267 Assert.NotNull(activity.Attachments);
268 Assert.Single(activity.Attachments);
269 TeamsAttachment attachment = activity.Attachments[0] as TeamsAttachment;
270 Assert.NotNull(attachment);
271 Assert.Equal("text/html", attachment.ContentType);
272 Assert.Equal("<p><span itemtype=\"http://schema.skype.com/Mention\" itemscope=\"\" itemid=\"0\">ridotest</span>&nbsp;reply to thread</p>", attachment.Content?.ToString());
273 }
274
275 [Fact]
276 public void Deserialize_TeamsActivity_Invoke_WithValue()
277 {
278 //TeamsActivity activity = CoreActivity.FromJsonString<TeamsActivity>(jsonInvoke);
279 TeamsActivity activity = TeamsActivity.FromActivity(CoreActivity.FromJsonString(jsonInvoke));
280 Assert.NotNull(activity.Value);
281 string feedback = activity.Value?["action"]?["data"]?["feedback"]?.ToString()!;
282 Assert.Equal("test invokes", feedback);
283 }
284
285 private const string jsonInvoke = """
286 {
287 "type": "invoke",
288 "channelId": "msteams",
289 "id": "f:17b96347-e8b4-f340-10bc-eb52fc1a6ad4",
290 "serviceUrl": "https://smba.trafficmanager.net/amer/56653e9d-2158-46ee-90d7-675c39642038/",
291 "channelData": {
292 "tenant": {
293 "id": "56653e9d-2158-46ee-90d7-675c39642038"
294 },
295 "source": {
296 "name": "message"
297 },
298 "legacy": {
299 "replyToId": "1:12SWreU4430kJA9eZCb1kXDuo6A8KdDEGB6d9TkjuDYM"
300 }
301 },
302 "from": {
303 "id": "29:1uMVvhoAyfTqdMsyvHL0qlJTTfQF9MOUSI8_cQts2kdSWEZVDyJO2jz-CsNOhQcdYq1Bw4cHT0__O6XDj4AZ-Jw",
304 "name": "Rido",
305 "aadObjectId": "c5e99701-2a32-49c1-a660-4629ceeb8c61"
306 },
307 "recipient": {
308 "id": "28:aabdbd62-bc97-4afb-83ee-575594577de5",
309 "name": "ridobotlocal"
310 },
311 "conversation": {
312 "id": "a:17vxw6pGQOb3Zfh8acXT8m_PqHycYpaFgzu2mFMUfkT-h0UskMctq5ZPPc7FIQxn2bx7rBSm5yE_HeUXsCcKZBrv77RgorB3_1_pAdvMhi39ClxQgawzyQ9GBFkdiwOxT",
313 "conversationType": "personal",
314 "tenantId": "56653e9d-2158-46ee-90d7-675c39642038"
315 },
316 "entities": [
317 {
318 "locale": "en-US",
319 "country": "US",
320 "platform": "Web",
321 "timezone": "America/Los_Angeles",
322 "type": "clientInfo"
323 }
324 ],
325 "value": {
326 "action": {
327 "type": "Action.Execute",
328 "title": "Submit Feedback",
329 "data": {
330 "feedback": "test invokes"
331 }
332 },
333 "trigger": "manual"
334 },
335 "name": "adaptiveCard/action",
336 "timestamp": "2026-01-07T06:04:59.89Z",
337 "localTimestamp": "2026-01-06T22:04:59.89-08:00",
338 "replyToId": "1767765488332",
339 "locale": "en-US",
340 "localTimezone": "America/Los_Angeles"
341 }
342 """;
343
344 private const string json = """
345 {
346 "type": "message",
347 "channelId": "msteams",
348 "text": "\u003Cat\u003Eridotest\u003C/at\u003E reply to thread",
349 "id": "1759944781430",
350 "serviceUrl": "https://smba.trafficmanager.net/amer/50612dbb-0237-4969-b378-8d42590f9c00/",
351 "channelData": {
352 "teamsChannelId": "19:6848757105754c8981c67612732d9aa7@thread.tacv2",
353 "teamsTeamId": "19:66P469zibfbsGI-_a0aN_toLTZpyzS6u7CT3TsXdgPw1@thread.tacv2",
354 "channel": {
355 "id": "19:6848757105754c8981c67612732d9aa7@thread.tacv2"
356 },
357 "team": {
358 "id": "19:66P469zibfbsGI-_a0aN_toLTZpyzS6u7CT3TsXdgPw1@thread.tacv2"
359 },
360 "tenant": {
361 "id": "50612dbb-0237-4969-b378-8d42590f9c00"
362 }
363 },
364 "from": {
365 "id": "29:17bUvCasIPKfQIXHvNzcPjD86fwm6GkWc1PvCGP2-NSkNb7AyGYpjQ7Xw-XgTwaHW5JxZ4KMNDxn1kcL8fwX1Nw",
366 "name": "rido",
367 "aadObjectId": "b15a9416-0ad3-4172-9210-7beb711d3f70"
368 },
369 "recipient": {
370 "id": "28:0b6fe6d1-fece-44f7-9a48-56465e2d5ab8",
371 "name": "ridotest"
372 },
373 "conversation": {
374 "id": "19:6848757105754c8981c67612732d9aa7@thread.tacv2;messageid=1759881511856",
375 "isGroup": true,
376 "conversationType": "channel",
377 "tenantId": "50612dbb-0237-4969-b378-8d42590f9c00"
378 },
379 "entities": [
380 {
381 "mentioned": {
382 "id": "28:0b6fe6d1-fece-44f7-9a48-56465e2d5ab8",
383 "name": "ridotest"
384 },
385 "text": "\u003Cat\u003Eridotest\u003C/at\u003E",
386 "type": "mention"
387 },
388 {
389 "locale": "en-US",
390 "country": "US",
391 "platform": "Web",
392 "timezone": "America/Los_Angeles",
393 "type": "clientInfo"
394 }
395 ],
396 "textFormat": "plain",
397 "attachments": [
398 {
399 "contentType": "text/html",
400 "content": "\u003Cp\u003E\u003Cspan itemtype=\u0022http://schema.skype.com/Mention\u0022 itemscope=\u0022\u0022 itemid=\u00220\u0022\u003Eridotest\u003C/span\u003E\u0026nbsp;reply to thread\u003C/p\u003E"
401 }
402 ],
403 "timestamp": "2025-10-08T17:33:01.4953744Z",
404 "localTimestamp": "2025-10-08T10:33:01.4953744-07:00",
405 "locale": "en-US",
406 "localTimezone": "America/Los_Angeles"
407 }
408 """;
409
410 [Fact]
411 public void FromJsonString_ReturnsDerivedType_WhenRegistered()
412 {
413 string json = """{"type": "message", "text": "Hello World"}""";
414 TeamsActivity activity = TeamsActivity.FromJsonString(json);
415
416 Assert.IsType<MessageActivity>(activity);
417 MessageActivity messageActivity = (MessageActivity)activity;
418 Assert.Equal("Hello World", messageActivity.Text);
419 }
420
421 [Fact]
422 public void FromJsonString_ReturnsBaseType_WhenNotRegistered()
423 {
424 string json = """{"type": "unknownType"}""";
425 TeamsActivity activity = TeamsActivity.FromJsonString(json);
426
427 Assert.Equal(typeof(TeamsActivity), activity.GetType());
428 Assert.Equal("unknownType", activity.Type);
429 }
430
431 [Fact]
432 public void FromActivity_ReturnsDerivedType_WhenRegistered()
433 {
434 CoreActivity coreActivity = new CoreActivity(ActivityType.Message);
435 TeamsActivity activity = TeamsActivity.FromActivity(coreActivity);
436
437 Assert.IsType<MessageActivity>(activity);
438 }
439
440 [Fact]
441 public void FromActivity_ReturnsBaseType_WhenNotRegistered()
442 {
443 CoreActivity coreActivity = new CoreActivity("unknownType");
444 TeamsActivity activity = TeamsActivity.FromActivity(coreActivity);
445
446 Assert.Equal(typeof(TeamsActivity), activity.GetType());
447 Assert.Equal("unknownType", activity.Type);
448 }
449}
450