microsoft/teams.net

Public

mirrored from https://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/CompatTeamsInfoTests.cs

617lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4using Microsoft.Bot.Builder.Integration.AspNet.Core;
5using Microsoft.Bot.Schema;
6using Microsoft.Bot.Schema.Teams;
7using Microsoft.Extensions.Configuration;
8using Microsoft.Extensions.DependencyInjection;
9using Microsoft.Extensions.Logging;
10using Microsoft.Teams.Bot.Compat;
11using Xunit.Abstractions;
12
13namespace Microsoft.Bot.Core.Tests
14{
15 /// <summary>
16 /// Integration tests for CompatTeamsInfo static methods.
17 /// These tests verify that the compatibility layer correctly adapts
18 /// Bot Framework TeamsInfo API to Teams Bot Core SDK.
19 /// </summary>
20 public class CompatTeamsInfoTests
21 {
22 private readonly ITestOutputHelper _outputHelper;
23 private readonly string _serviceUrl = "https://smba.trafficmanager.net/amer/";
24 private readonly string _userId;
25 private readonly string _conversationId;
26 private readonly string _teamId;
27 private readonly string _channelId;
28 private readonly string _meetingId;
29 private readonly string _tenantId;
30 private readonly string _agenticAppBlueprintId;
31 private readonly string? _agenticAppId;
32 private readonly string? _agenticUserId;
33
34 public CompatTeamsInfoTests(ITestOutputHelper outputHelper)
35 {
36 _outputHelper = outputHelper;
37 // These tests require environment variables for live integration testing
38 _userId = Environment.GetEnvironmentVariable("TEST_USER_ID") ?? "29:test-user-id";
39 _conversationId = Environment.GetEnvironmentVariable("TEST_CONVERSATIONID") ?? "19:test-conversation-id";
40 _teamId = Environment.GetEnvironmentVariable("TEST_TEAMID") ?? "19:test-team-id";
41 _channelId = Environment.GetEnvironmentVariable("TEST_CHANNELID") ?? "19:test-channel-id";
42 _meetingId = Environment.GetEnvironmentVariable("TEST_MEETINGID") ?? "test-meeting-id";
43 _tenantId = Environment.GetEnvironmentVariable("TEST_TENANTID") ?? "test-tenant-id";
44
45 _agenticAppBlueprintId = Environment.GetEnvironmentVariable("AzureAd__ClientId") ?? throw new InvalidOperationException("AzureAd__ClientId environment variable not set");
46 _agenticAppId = Environment.GetEnvironmentVariable("TEST_AGENTIC_APPID");// ?? throw new InvalidOperationException("TEST_AGENTIC_APPID environment variable not set");
47 _agenticUserId = Environment.GetEnvironmentVariable("TEST_AGENTIC_USERID");
48 }
49
50 [Fact]
51 public async Task GetMemberAsync_WithValidUserId_ReturnsMember()
52 {
53 var adapter = InitializeCompatAdapter();
54 var conversationReference = CreateConversationReference(_conversationId);
55
56 await adapter.ContinueConversationAsync(
57 string.Empty,
58 conversationReference,
59 async (turnContext, cancellationToken) =>
60 {
61 TeamsChannelAccount member = await CompatTeamsInfo.GetMemberAsync(
62 turnContext,
63 _userId,
64 cancellationToken);
65
66 Assert.NotNull(member);
67 Assert.Equal(_userId, member.Id);
68 },
69 CancellationToken.None);
70 }
71
72 [Fact]
73 public async Task GetMembersAsync_ReturnsMembers()
74 {
75 var adapter = InitializeCompatAdapter();
76 var conversationReference = CreateConversationReference(_conversationId);
77
78 await adapter.ContinueConversationAsync(
79 string.Empty,
80 conversationReference,
81 async (turnContext, cancellationToken) =>
82 {
83#pragma warning disable CS0618 // Type or member is obsolete
84 var members = await CompatTeamsInfo.GetMembersAsync(turnContext, cancellationToken);
85#pragma warning restore CS0618 // Type or member is obsolete
86
87 Assert.NotNull(members);
88 Assert.NotEmpty(members);
89 },
90 CancellationToken.None);
91 }
92
93 [Fact]
94 public async Task GetPagedMembersAsync_ReturnsPagedResult()
95 {
96 var adapter = InitializeCompatAdapter();
97 var conversationReference = CreateConversationReference(_conversationId);
98
99 await adapter.ContinueConversationAsync(
100 string.Empty,
101 conversationReference,
102 async (turnContext, cancellationToken) =>
103 {
104 var result = await CompatTeamsInfo.GetPagedMembersAsync(
105 turnContext,
106 pageSize: 10,
107 cancellationToken: cancellationToken);
108
109 Assert.NotNull(result);
110 Assert.NotNull(result.Members);
111 Assert.True(result.Members.Count > 0);
112
113 var firstMember = result.Members[0];
114 Assert.NotNull(firstMember.Id);
115 },
116 CancellationToken.None);
117 }
118
119 [Fact]
120 public async Task GetTeamMemberAsync_WithValidUserId_ReturnsMember()
121 {
122 var adapter = InitializeCompatAdapter();
123 var conversationReference = CreateConversationReference(_conversationId);
124
125 await adapter.ContinueConversationAsync(
126 string.Empty,
127 conversationReference,
128 async (turnContext, cancellationToken) =>
129 {
130 var member = await CompatTeamsInfo.GetTeamMemberAsync(
131 turnContext,
132 _userId,
133 _teamId,
134 cancellationToken);
135
136 Assert.NotNull(member);
137 Assert.Equal(_userId, member.Id);
138 },
139 CancellationToken.None);
140 }
141
142 [Fact]
143 public async Task GetTeamMembersAsync_ReturnsTeamMembers()
144 {
145 var adapter = InitializeCompatAdapter();
146 var conversationReference = CreateConversationReference(_conversationId);
147
148 await adapter.ContinueConversationAsync(
149 string.Empty,
150 conversationReference,
151 async (turnContext, cancellationToken) =>
152 {
153#pragma warning disable CS0618 // Type or member is obsolete
154 var members = await CompatTeamsInfo.GetTeamMembersAsync(
155 turnContext,
156 _teamId,
157 cancellationToken);
158#pragma warning restore CS0618 // Type or member is obsolete
159
160 Assert.NotNull(members);
161 Assert.NotEmpty(members);
162 },
163 CancellationToken.None);
164 }
165
166 [Fact]
167 public async Task GetPagedTeamMembersAsync_ReturnsPagedResult()
168 {
169 var adapter = InitializeCompatAdapter();
170 var conversationReference = CreateConversationReference(_conversationId);
171
172 await adapter.ContinueConversationAsync(
173 string.Empty,
174 conversationReference,
175 async (turnContext, cancellationToken) =>
176 {
177 var result = await CompatTeamsInfo.GetPagedTeamMembersAsync(
178 turnContext,
179 _teamId,
180 pageSize: 5,
181 cancellationToken: cancellationToken);
182
183 Assert.NotNull(result);
184 Assert.NotNull(result.Members);
185 },
186 CancellationToken.None);
187 }
188
189 [Fact(Skip = "permissions needed")]
190 public async Task GetMeetingInfoAsync_WithMeetingId_ReturnsMeetingInfo()
191 {
192 var adapter = InitializeCompatAdapter();
193 var conversationReference = CreateConversationReference(_conversationId);
194
195 await adapter.ContinueConversationAsync(
196 string.Empty,
197 conversationReference,
198 async (turnContext, cancellationToken) =>
199 {
200 var meetingInfo = await CompatTeamsInfo.GetMeetingInfoAsync(
201 turnContext,
202 _meetingId,
203 cancellationToken);
204
205 Assert.NotNull(meetingInfo);
206 Assert.NotNull(meetingInfo.Details);
207 },
208 CancellationToken.None);
209 }
210
211 [Fact]
212 public async Task GetMeetingParticipantAsync_WithParticipantId_ReturnsParticipant()
213 {
214 var adapter = InitializeCompatAdapter();
215 var conversationReference = CreateConversationReference(_conversationId);
216
217 await adapter.ContinueConversationAsync(
218 string.Empty,
219 conversationReference,
220 async (turnContext, cancellationToken) =>
221 {
222 var participant = await CompatTeamsInfo.GetMeetingParticipantAsync(
223 turnContext,
224 _meetingId,
225 _userId,
226 _tenantId,
227 cancellationToken);
228
229 Assert.NotNull(participant);
230 Assert.NotNull(participant.User);
231 },
232 CancellationToken.None);
233 }
234
235 [Fact(Skip = "Permissions")]
236 public async Task SendMeetingNotificationAsync_SendsNotification()
237 {
238 var adapter = InitializeCompatAdapter();
239 var conversationReference = CreateConversationReference(_conversationId);
240
241 await adapter.ContinueConversationAsync(
242 string.Empty,
243 conversationReference,
244 async (turnContext, cancellationToken) =>
245 {
246 // Create a simple targeted meeting notification
247 // Note: In real scenarios, you would construct the proper notification object
248 // with surfaces and content according to the Teams schema
249 var notification = new TargetedMeetingNotification
250 {
251 Value = new TargetedMeetingNotificationValue
252 {
253 Recipients = new List<string> { _userId },
254 Surfaces = new List<Surface>
255 {
256 new MeetingStageSurface<TaskModuleContinueResponse>()
257 {
258 ContentType = ContentType.Task,
259 Content = new TaskModuleContinueResponse
260 {
261 Value = new TaskModuleTaskInfo
262 {
263 Title = "Test Notification",
264 Url = "https://www.example.com",
265 Height = 200,
266 Width = 400
267 }
268 }
269 }
270 }
271 }
272 };
273
274 var response = await CompatTeamsInfo.SendMeetingNotificationAsync(
275 turnContext,
276 notification,
277 _meetingId,
278 cancellationToken);
279
280 Assert.NotNull(response);
281 },
282 CancellationToken.None);
283 }
284
285 [Fact]
286 public async Task GetTeamDetailsAsync_WithTeamId_ReturnsTeamDetails()
287 {
288 var adapter = InitializeCompatAdapter();
289 var conversationReference = CreateConversationReference(_conversationId);
290
291 await adapter.ContinueConversationAsync(
292 string.Empty,
293 conversationReference,
294 async (turnContext, cancellationToken) =>
295 {
296 var teamDetails = await CompatTeamsInfo.GetTeamDetailsAsync(
297 turnContext,
298 _teamId,
299 cancellationToken);
300
301 Assert.NotNull(teamDetails);
302 Assert.NotNull(teamDetails.Id);
303 Assert.NotNull(teamDetails.Name);
304 },
305 CancellationToken.None);
306 }
307
308 [Fact]
309 public async Task GetTeamChannelsAsync_WithTeamId_ReturnsChannels()
310 {
311 var adapter = InitializeCompatAdapter();
312 var conversationReference = CreateConversationReference(_conversationId);
313
314 await adapter.ContinueConversationAsync(
315 string.Empty,
316 conversationReference,
317 async (turnContext, cancellationToken) =>
318 {
319 var channels = await CompatTeamsInfo.GetTeamChannelsAsync(
320 turnContext,
321 _teamId,
322 cancellationToken);
323
324 Assert.NotNull(channels);
325 Assert.NotEmpty(channels);
326
327 var firstChannel = channels[0];
328 Assert.NotNull(firstChannel.Id);
329 Assert.NotNull(firstChannel.Name);
330 },
331 CancellationToken.None);
332 }
333
334 [Fact]
335 public async Task SendMessageToListOfUsersAsync_ReturnsOperationId()
336 {
337 var adapter = InitializeCompatAdapter();
338 var conversationReference = CreateConversationReference(_conversationId);
339
340 await adapter.ContinueConversationAsync(
341 string.Empty,
342 conversationReference,
343 async (turnContext, cancellationToken) =>
344 {
345 var activity = new Activity
346 {
347 Type = ActivityTypes.Message,
348 Text = "Test message"
349 };
350 var members = new List<TeamMember>
351 {
352 new TeamMember(_channelId),
353 new TeamMember("1"),
354 new TeamMember("2"),
355 new TeamMember("4"),
356 new TeamMember("5"),
357 new TeamMember("6")
358
359 };
360
361 var operationId = await CompatTeamsInfo.SendMessageToListOfUsersAsync(
362 turnContext,
363 activity,
364 members,
365 _tenantId,
366 cancellationToken);
367
368 Assert.NotNull(operationId);
369 Assert.NotEmpty(operationId);
370 },
371 CancellationToken.None);
372 }
373
374 [Fact]
375 public async Task SendMessageToListOfChannelsAsync_ReturnsOperationId()
376 {
377 var adapter = InitializeCompatAdapter();
378 var conversationReference = CreateConversationReference(_conversationId);
379
380 await adapter.ContinueConversationAsync(
381 string.Empty,
382 conversationReference,
383 async (turnContext, cancellationToken) =>
384 {
385 var activity = new Activity
386 {
387 Type = ActivityTypes.Message,
388 Text = "Test message"
389 };
390 var channels = new List<TeamMember>
391 {
392 new TeamMember(_channelId),
393 new TeamMember("1"),
394 new TeamMember("2"),
395 new TeamMember("4"),
396 new TeamMember("5"),
397 new TeamMember("6")
398 };
399
400 var operationId = await CompatTeamsInfo.SendMessageToListOfChannelsAsync(
401 turnContext,
402 activity,
403 channels,
404 _tenantId,
405 cancellationToken);
406
407 Assert.NotNull(operationId);
408 Assert.NotEmpty(operationId);
409 },
410 CancellationToken.None);
411 }
412
413 [Fact]
414 public async Task SendMessageToAllUsersInTeamAsync_ReturnsOperationId()
415 {
416 var adapter = InitializeCompatAdapter();
417 var conversationReference = CreateConversationReference(_conversationId);
418
419 await adapter.ContinueConversationAsync(
420 string.Empty,
421 conversationReference,
422 async (turnContext, cancellationToken) =>
423 {
424 var activity = new Activity
425 {
426 Type = ActivityTypes.Message,
427 Text = "Test message to team"
428 };
429
430 var operationId = await CompatTeamsInfo.SendMessageToAllUsersInTeamAsync(
431 turnContext,
432 activity,
433 _teamId,
434 _tenantId,
435 cancellationToken);
436
437 Assert.NotNull(operationId);
438 Assert.NotEmpty(operationId);
439 },
440 CancellationToken.None);
441 }
442
443 [Fact]
444 public async Task SendMessageToAllUsersInTenantAsync_ReturnsOperationId()
445 {
446 var adapter = InitializeCompatAdapter();
447 var conversationReference = CreateConversationReference(_conversationId);
448
449 await adapter.ContinueConversationAsync(
450 string.Empty,
451 conversationReference,
452 async (turnContext, cancellationToken) =>
453 {
454 var activity = new Activity
455 {
456 Type = ActivityTypes.Message,
457 Text = "Test message to tenant"
458 };
459
460 var operationId = await CompatTeamsInfo.SendMessageToAllUsersInTenantAsync(
461 turnContext,
462 activity,
463 _tenantId,
464 cancellationToken);
465
466 Assert.NotNull(operationId);
467 Assert.NotEmpty(operationId);
468 },
469 CancellationToken.None);
470 }
471
472 [Fact(Skip = "Not implemented")]
473 public async Task SendMessageToTeamsChannelAsync_CreatesConversationAndSendsMessage()
474 {
475 var adapter = InitializeCompatAdapter();
476 var conversationReference = CreateConversationReference(_conversationId);
477
478 await adapter.ContinueConversationAsync(
479 string.Empty,
480 conversationReference,
481 async (turnContext, cancellationToken) =>
482 {
483 var activity = new Activity
484 {
485 Type = ActivityTypes.Message,
486 Text = "Test message to channel"
487 };
488 var botAppId = Environment.GetEnvironmentVariable("AzureAd__ClientId") ?? string.Empty;
489
490 var result = await CompatTeamsInfo.SendMessageToTeamsChannelAsync(
491 turnContext,
492 activity,
493 _channelId,
494 botAppId,
495 cancellationToken);
496
497 Assert.NotNull(result);
498 Assert.NotNull(result.Item1); // ConversationReference
499 Assert.NotNull(result.Item2); // ActivityId
500 },
501 CancellationToken.None);
502 }
503
504 [Fact(Skip = "Internal Server Error")]
505 public async Task GetOperationStateAsync_WithOperationId_ReturnsState()
506 {
507 var adapter = InitializeCompatAdapter();
508 var conversationReference = CreateConversationReference(_conversationId);
509 var operationId = "amer_9e0e3ba8-c562-440f-ba9d-10603ee31837";
510
511 await adapter.ContinueConversationAsync(
512 string.Empty,
513 conversationReference,
514 async (turnContext, cancellationToken) =>
515 {
516 var state = await CompatTeamsInfo.GetOperationStateAsync(
517 turnContext,
518 operationId,
519 cancellationToken);
520
521 Assert.NotNull(state);
522 Assert.NotNull(state.State);
523 },
524 CancellationToken.None);
525 }
526
527 [Fact(Skip = "Internal Server Error")]
528 public async Task GetPagedFailedEntriesAsync_WithOperationId_ReturnsFailedEntries()
529 {
530 var adapter = InitializeCompatAdapter();
531 var conversationReference = CreateConversationReference(_conversationId);
532 var operationId = "amer_9e0e3ba8-c562-440f-ba9d-10603ee31837";
533
534 await adapter.ContinueConversationAsync(
535 string.Empty,
536 conversationReference,
537 async (turnContext, cancellationToken) =>
538 {
539 var response = await CompatTeamsInfo.GetPagedFailedEntriesAsync(
540 turnContext,
541 operationId,
542 cancellationToken: cancellationToken);
543
544 Assert.NotNull(response);
545 },
546 CancellationToken.None);
547 }
548
549 [Fact(Skip = "internal error")]
550 public async Task CancelOperationAsync_WithOperationId_CancelsOperation()
551 {
552 var adapter = InitializeCompatAdapter();
553 var conversationReference = CreateConversationReference(_conversationId);
554 var operationId = "amer_9e0e3ba8-c562-440f-ba9d-10603ee31837";
555
556 await adapter.ContinueConversationAsync(
557 string.Empty,
558 conversationReference,
559 async (turnContext, cancellationToken) =>
560 {
561 await CompatTeamsInfo.CancelOperationAsync(
562 turnContext,
563 operationId,
564 cancellationToken);
565
566 // If no exception is thrown, the operation succeeded
567 Assert.True(true);
568 },
569 CancellationToken.None);
570 }
571
572 private CompatAdapter InitializeCompatAdapter()
573 {
574 IConfigurationBuilder builder = new ConfigurationBuilder()
575 .SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
576 .AddEnvironmentVariables();
577
578 IConfiguration configuration = builder.Build();
579
580 ServiceCollection services = new();
581 services.AddSingleton(configuration);
582 services.AddCompatAdapter();
583 services.AddLogging((builder) => {
584 builder.AddXUnit(_outputHelper);
585 builder.AddFilter("System.Net", LogLevel.Warning);
586 builder.AddFilter("Microsoft.Identity", LogLevel.Error);
587 builder.AddFilter("Microsoft.Teams", LogLevel.Information);
588 });
589
590 var serviceProvider = services.BuildServiceProvider();
591 CompatAdapter compatAdapter = (CompatAdapter)serviceProvider.GetRequiredService<IBotFrameworkHttpAdapter>();
592 return compatAdapter;
593 }
594
595 private ConversationReference CreateConversationReference(string conversationId)
596 {
597 return new ConversationReference
598 {
599 ChannelId = "msteams",
600 ServiceUrl = _serviceUrl,
601 Conversation = new ConversationAccount
602 {
603 Id = conversationId
604 },
605 User = new ChannelAccount()
606 {
607 Properties =
608 {
609 { "agenticAppBlueprintId", _agenticAppBlueprintId },
610 { "agenticAppId", _agenticAppId },
611 { "agenticUserId", _agenticUserId },
612 }
613 }
614 };
615 }
616 }
617}
618