microsoft/teams.net

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
copilot/sub-pr-338

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

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