microsoft/teams.net

Public

mirrored fromhttps://github.com/microsoft/teams.netAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
411466c009b3ae7aeeb169d3a8f51ca09c90eca2

Branches

Tags

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

Clone

HTTPS

Download ZIP

Tests/Microsoft.Teams.Apps.Tests/AppTests.cs

303lines · modecode

1using Microsoft.Teams.Api;
2using Microsoft.Teams.Api.Activities;
3using Microsoft.Teams.Api.Auth;
4using Microsoft.Teams.Api.Clients;
5using Microsoft.Teams.Apps.Plugins;
6using Microsoft.Teams.Common.Http;
7
8using Moq;
9
10namespace Microsoft.Teams.Apps.Tests;
11
12public class AppTests
13{
14 private readonly string _unexpiredJwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMiwiZXhwIjoxOTE2MjM5MDIyfQ.ZTe6TPjyWE8aMo-RAXX6aO1K5VkpMwyxofRQcndwYjQ";
15 private readonly string _expiredJwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMiwiZXhwIjoxNTE2MjM5MDIzfQ.6dB5kVQtR71r1JDYQqe5Aa1MQoEhCdK4b6ryseopAR0";
16 private readonly string _serviceUrl = "https://test.net/";
17
18 [Fact]
19 public async Task Test_App_Start_GetBotToken_Success()
20 {
21 // arrange
22 var credentials = new Mock<IHttpCredentials>();
23 var options = new AppOptions()
24 {
25 Credentials = credentials.Object,
26 };
27 var app = new App(options);
28 var api = new Mock<ApiClient>(_serviceUrl, CancellationToken.None) { CallBase = true };
29 api.Setup(a => a.Bots.Token.GetAsync(It.IsAny<IHttpCredentials>(), It.IsAny<IHttpClient>(), It.IsAny<CancellationToken>()))
30 .ReturnsAsync(new TokenResponse() { AccessToken = _unexpiredJwt, TokenType = "bot" });
31 app.Api = api.Object;
32
33 // act
34 await app.Start();
35
36 // assert
37 api.Verify(api => api.Bots.Token.GetAsync(It.IsAny<IHttpCredentials>(), It.IsAny<IHttpClient>(), It.IsAny<CancellationToken>()), Times.Once);
38 Assert.True(app.Token!.ToString() == _unexpiredJwt);
39 }
40
41 [Fact]
42 public async Task Test_App_Start_GetBotToken_Failure()
43 {
44 // arrange
45 var logger = new Mock<Common.Logging.ILogger>();
46 var exception = new Exception("failed to get token");
47 logger.Setup(logger => logger.Error(It.IsAny<string?>(), It.IsAny<Exception>()));
48 var credentials = new Mock<IHttpCredentials>();
49 var options = new AppOptions()
50 {
51 Credentials = credentials.Object,
52 Logger = logger.Object,
53 };
54 var app = new App(options);
55 var api = new Mock<ApiClient>(_serviceUrl, CancellationToken.None) { CallBase = true };
56 api.Setup(a => a.Bots.Token.GetAsync(It.IsAny<IHttpCredentials>(), It.IsAny<IHttpClient>(), It.IsAny<CancellationToken>()))
57 .ThrowsAsync(exception);
58 app.Api = api.Object;
59
60 // act
61 await app.Start();
62
63 // assert
64 logger.Verify(logger => logger.Error("Failed to get bot token on app startup.", exception), Times.Once);
65 Assert.Null(app.Token);
66 }
67
68 [Fact]
69 public async Task Test_App_Start_DoesNot_GetBotToken_WhenNoCredentials()
70 {
71 // arrange
72 var options = new AppOptions()
73 {
74 Credentials = null,
75 };
76 var app = new App(options);
77 var api = new Mock<ApiClient>(_serviceUrl, CancellationToken.None) { CallBase = true };
78 api.Setup(a => a.Bots.Token.GetAsync(It.IsAny<IHttpCredentials>(), It.IsAny<IHttpClient>(), It.IsAny<CancellationToken>()))
79 .ReturnsAsync(new TokenResponse() { AccessToken = _unexpiredJwt, TokenType = "bot" });
80 app.Api = api.Object;
81
82 // act
83 await app.Start();
84
85 // assert
86 api.Verify(api => api.Bots.Token.GetAsync(It.IsAny<IHttpCredentials>(), It.IsAny<IHttpClient>(), It.IsAny<CancellationToken>()), Times.Never);
87 Assert.Null(app.Token);
88 }
89
90 [Fact]
91 public void Test_App_Client_TokenFactory_GetsToken_IfNotExists()
92 {
93 // arrange
94 var client = new Mock<Common.Http.HttpClient>() { CallBase = true };
95 var credentials = new Mock<IHttpCredentials>();
96 var options = new AppOptions()
97 {
98 Client = client.Object,
99 Credentials = credentials.Object,
100 };
101 var app = new App(options);
102 var api = new Mock<ApiClient>(_serviceUrl, CancellationToken.None) { CallBase = true };
103 api.Setup(a => a.Bots.Token.GetAsync(It.IsAny<IHttpCredentials>(), It.IsAny<IHttpClient>(), It.IsAny<CancellationToken>()))
104 .ReturnsAsync(new TokenResponse() { AccessToken = _unexpiredJwt, TokenType = "bot" });
105 app.Api = api.Object;
106
107 // act
108 Assert.NotNull(client.Object.Options.TokenFactory);
109 client.Object.Options.TokenFactory();
110
111 // assert
112 api.Verify(api => api.Bots.Token.GetAsync(It.IsAny<IHttpCredentials>(), It.IsAny<IHttpClient>(), It.IsAny<CancellationToken>()), Times.Once);
113 Assert.True(app.Token!.ToString() == _unexpiredJwt);
114 }
115
116 [Fact]
117 public void Test_App_Client_TokenFactory_GetsToken_IfExpired()
118 {
119 // arrange
120 var client = new Mock<Common.Http.HttpClient>() { CallBase = true };
121 var credentials = new Mock<IHttpCredentials>();
122 var options = new AppOptions()
123 {
124 Client = client.Object,
125 Credentials = credentials.Object,
126 };
127 var app = new App(options);
128 app.Token = new JsonWebToken(_expiredJwt);
129 credentials.Setup(c => c.Resolve(It.IsAny<IHttpClient>(), It.IsAny<string[]>(), It.IsAny<CancellationToken>()))
130 .ReturnsAsync(new TokenResponse() { AccessToken = _unexpiredJwt, TokenType = "bot" });
131
132 // act
133 Assert.NotNull(client.Object.Options.TokenFactory);
134 client.Object.Options.TokenFactory();
135
136 // assert
137 credentials.Verify(c => c.Resolve(It.IsAny<IHttpClient>(), It.IsAny<string[]>(), It.IsAny<CancellationToken>()), Times.Once);
138 Assert.True(app.Token!.ToString() == _unexpiredJwt);
139 }
140
141 [Fact]
142 public void Test_App_Client_TokenFactory_DoesNotGetToken_IfValid()
143 {
144 // arrange
145 var client = new Mock<Common.Http.HttpClient>() { CallBase = true };
146 var credentials = new Mock<IHttpCredentials>();
147 var options = new AppOptions()
148 {
149 Client = client.Object,
150 Credentials = credentials.Object,
151 };
152 var app = new App(options);
153 app.Token = new JsonWebToken(_unexpiredJwt);
154 credentials.Setup(c => c.Resolve(It.IsAny<IHttpClient>(), It.IsAny<string[]>(), It.IsAny<CancellationToken>()))
155 .ReturnsAsync(new TokenResponse() { AccessToken = _unexpiredJwt, TokenType = "bot" });
156 var api = new Mock<ApiClient>(_serviceUrl, CancellationToken.None) { CallBase = true };
157 api.Setup(a => a.Bots.Token.GetAsync(It.IsAny<IHttpCredentials>(), It.IsAny<IHttpClient>(), It.IsAny<CancellationToken>()))
158 .ReturnsAsync(new TokenResponse() { AccessToken = _unexpiredJwt, TokenType = "bot" });
159 app.Api = api.Object;
160
161 // act
162 Assert.NotNull(client.Object.Options.TokenFactory);
163 client.Object.Options.TokenFactory();
164
165 // assert
166 credentials.Verify(c => c.Resolve(It.IsAny<IHttpClient>(), It.IsAny<string[]>(), It.IsAny<CancellationToken>()), Times.Never);
167 api.Verify(api => api.Bots.Token.GetAsync(It.IsAny<IHttpCredentials>(), It.IsAny<IHttpClient>(), It.IsAny<CancellationToken>()), Times.Never);
168 }
169
170 [Fact]
171 public void Test_App_Client_TokenFactory_DoesNotGetToken_IfNoCredentials()
172 {
173 // arrange
174 var client = new Mock<Common.Http.HttpClient>() { CallBase = true };
175 var options = new AppOptions()
176 {
177 Client = client.Object,
178 Credentials = null,
179 };
180 var app = new App(options);
181 var api = new Mock<ApiClient>(_serviceUrl, CancellationToken.None) { CallBase = true };
182 api.Setup(a => a.Bots.Token.GetAsync(It.IsAny<IHttpCredentials>(), It.IsAny<IHttpClient>(), It.IsAny<CancellationToken>()))
183 .ReturnsAsync(new TokenResponse() { AccessToken = _unexpiredJwt, TokenType = "bot" });
184 app.Api = api.Object;
185
186 // act
187 Assert.NotNull(client.Object.Options.TokenFactory);
188 client.Object.Options.TokenFactory();
189
190 // assert
191 api.Verify(api => api.Bots.Token.GetAsync(It.IsAny<IHttpCredentials>(), It.IsAny<IHttpClient>(), It.IsAny<CancellationToken>()), Times.Never);
192 Assert.Null(app.Token);
193 }
194
195 [Fact]
196 public void Test_App_Client_CustomTokenFactory()
197 {
198 // arrange
199 var client = new Mock<Common.Http.HttpClient>() { CallBase = true };
200 var tokenFactoryInvoked = false;
201 IHttpClientOptions.HttpTokenFactory tokenFactory = () =>
202 {
203 tokenFactoryInvoked = true;
204 return null;
205 };
206 client.Object.Options.TokenFactory = tokenFactory;
207 var options = new AppOptions()
208 {
209 Client = client.Object,
210 Credentials = null,
211 };
212 var app = new App(options);
213
214 // act
215 client.Object.Options.TokenFactory();
216
217 // assert
218 Assert.True(tokenFactoryInvoked);
219 }
220
221 [Fact]
222 public async Task Test_App_Process_Should_Call_Middleware()
223 {
224 // arrange
225 var client = new Mock<Common.Http.HttpClient>();
226 var app = new App();
227 var sender = new Mock<ISenderPlugin>();
228 sender.Setup(s => s.CreateStream(It.IsAny<ConversationReference>(), It.IsAny<CancellationToken>())).Returns(new Mock<IStreamer>().Object);
229 var token = new Mock<IToken>();
230 var activity = new MessageActivity()
231 {
232 From = new() { Id = "testId" }
233 };
234
235 // act
236 var middlewareCalled = false;
237 app.Use(async (context) =>
238 {
239 middlewareCalled = true;
240 await context.Next();
241 });
242 await app.Process(sender.Object, token.Object, activity);
243
244 // assert
245 Assert.True(middlewareCalled);
246 }
247
248 [Fact]
249 public async Task Test_App_Process_Should_Call_Middlewares_In_Order()
250 {
251 // arrange
252 var client = new Mock<Common.Http.HttpClient>();
253 var app = new App();
254 var sender = new Mock<ISenderPlugin>();
255 sender.Setup(s => s.CreateStream(It.IsAny<ConversationReference>(), It.IsAny<CancellationToken>())).Returns(new Mock<IStreamer>().Object);
256 var token = new Mock<IToken>();
257 var activity = new MessageActivity()
258 {
259 From = new() { Id = "testId" }
260 };
261
262 // act
263 var firstMiddlewareCalled = false;
264 var secondMiddlewareCalled = false;
265 var middlewaresCalledInOrder = false;
266 app.Use(async (context) =>
267 {
268 firstMiddlewareCalled = true;
269 var middleware = await context.Next();
270 if ((string?)middleware == "middleware2" && secondMiddlewareCalled)
271 {
272 middlewaresCalledInOrder = true;
273 }
274
275 return null;
276 });
277 app.Use((context) =>
278 {
279 secondMiddlewareCalled = true;
280 return Task.FromResult((object?)"middleware2");
281 });
282 await app.Process(sender.Object, token.Object, activity);
283
284 // assert
285 Assert.True(middlewaresCalledInOrder);
286 Assert.True(secondMiddlewareCalled);
287 Assert.True(firstMiddlewareCalled);
288 }
289
290 [Fact]
291 public void Test_App_Send_TargetedMessage_WithRecipient_PassesValidation()
292 {
293 // arrange
294 var targetedMessage = new MessageActivity("Hello")
295 .WithRecipient(new Account() { Id = "user123", Name = "Test User", Role = Role.User }, true);
296
297 // assert
298 Assert.True(targetedMessage.Recipient.IsTargeted);
299 Assert.NotNull(targetedMessage.Recipient);
300 Assert.Equal("user123", targetedMessage.Recipient.Id);
301 }
302
303}