microsoft/teams.net

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
devtools-port-no-auth

Branches

Tags

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

Clone

HTTPS

Download ZIP

Tests/Microsoft.Teams.Common.Tests/Http/HttpClientTests.cs

396lines · modecode

1using System.Net;
2using System.Net.Http.Json;
3using System.Text;
4using System.Text.Json;
5
6using Microsoft.Teams.Api.SignIn;
7using Microsoft.Teams.Cards;
8using Microsoft.Teams.Common.Http;
9
10using Moq;
11using Moq.Protected;
12
13namespace Microsoft.Teams.Common.Tests.Http;
14
15public class HttpClientTests
16{
17 [Fact]
18 public async Task HttpClient_ShouldReturnExpectedResponse_WhenMocked()
19 {
20 // Arrange
21 var mockMessageHandler = new Mock<HttpMessageHandler>();
22 mockMessageHandler.Protected()
23 .Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
24 .ReturnsAsync(new HttpResponseMessage
25 {
26 StatusCode = HttpStatusCode.OK,
27 Content = new StringContent("Mocked response")
28 });
29
30 var httpClient = new Common.Http.HttpClient(new System.Net.Http.HttpClient(mockMessageHandler.Object));
31 HttpRequest request = HttpRequest.Get("https://www.microsoft.com");
32
33 // Act
34 var response = await httpClient.SendAsync(request);
35
36 // Assert
37 Assert.Equal(HttpStatusCode.OK, response.StatusCode);
38 Assert.Equal("Mocked response", response.Body);
39 }
40
41 [Fact]
42 public async Task HttpClient_ShouldReturnExpectedResponseWithHeaders()
43 {
44 // Arrange
45 var responseMessage = new HttpResponseMessage();
46 responseMessage.Headers.Add("Custom-Header", "HeaderValue");
47 var mockMessageHandler = new Mock<HttpMessageHandler>();
48 mockMessageHandler.Protected()
49 .Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
50 .ReturnsAsync(new HttpResponseMessage
51 {
52 StatusCode = HttpStatusCode.OK,
53 Content = new StringContent("Mocked response"),
54 });
55
56 var httpClient = new Common.Http.HttpClient(new System.Net.Http.HttpClient(mockMessageHandler.Object));
57 HttpRequest request = HttpRequest.Get("https://www.microsoft.com");
58
59 // Act
60 var response = await httpClient.SendAsync(request);
61
62 // Assert
63 Assert.Equal(HttpStatusCode.OK, response.StatusCode);
64 Assert.Equal("Mocked response", response.Body);
65 }
66
67 [Fact]
68 public async Task HttpClient_ShouldReturnExpectedResponse_ResponseObject()
69 {
70 // Arrange
71 var urlResponse = new UrlResponse()
72 {
73 SignInLink = "valid signin dataa",
74 TokenExchangeResource = new Api.TokenExchange.Resource()
75 {
76 Id = "id",
77 ProviderId = "providerId",
78 Uri = "uri",
79 },
80 TokenPostResource = new Api.Token.PostResource()
81 {
82 SasUrl = "valid sas url",
83 }
84 };
85 var urlResponseJson = JsonSerializer.Serialize(urlResponse, new JsonSerializerOptions()
86 {
87 WriteIndented = true,
88 IndentSize = 2,
89 DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull
90 });
91 var mockMessageHandler = new Mock<HttpMessageHandler>();
92 mockMessageHandler.Protected()
93 .Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
94 .ReturnsAsync(new HttpResponseMessage
95 {
96 StatusCode = HttpStatusCode.OK,
97 Content = new StringContent(urlResponseJson, Encoding.UTF8, "application/json"),
98 });
99
100 var httpClient = new Common.Http.HttpClient(new System.Net.Http.HttpClient(mockMessageHandler.Object));
101 HttpRequest request = HttpRequest.Get("https://www.microsoft.com");
102
103 // Act
104 var response = await httpClient.SendAsync<UrlResponse>(request);
105
106 // Assert
107 Assert.Equal(HttpStatusCode.OK, response.StatusCode);
108 Assert.Equal(urlResponse.ToString(), response.Body.ToString());
109 }
110
111 [Fact]
112 public void HttpClient_ShouldDisposeClient()
113 {
114 // Arrange
115 var httpClient = new Common.Http.HttpClient();
116 // Act
117 httpClient.Dispose();
118 // Assert
119 Assert.True(true); // No exception should be thrown
120 Assert.NotNull(httpClient.Options);
121 }
122
123
124
125 public class MockHttpClient : Common.Http.HttpClient
126 {
127 public HttpRequestMessage ValidateCreateRequest(HttpRequest request)
128 {
129 var httpRequestMessage = CreateRequest(request);
130 return httpRequestMessage;
131 }
132
133 public async Task<IHttpResponse<string>> ValidateCreateResponse(HttpResponseMessage response, CancellationToken cancellationToken = default)
134 {
135 return await CreateResponse(response, cancellationToken);
136 }
137 }
138
139 [Fact]
140 public void HttpClient_ShouldSetRequestHeaders_CustomHeader()
141 {
142 // Arrange
143 var customRequestHeader = new List<string> { "HeaderValue", "someOther value" };
144 HttpRequest request = HttpRequest.Get("https://www.microsoft.com");
145 request.AddHeader("Custom-Header", customRequestHeader);
146
147 var mockHttpclient = new MockHttpClient();
148
149 // Act
150 var httpRequestMessage = mockHttpclient.ValidateCreateRequest(request);
151
152 // Assert
153 Assert.Equal("GET", httpRequestMessage.Method.Method);
154 var httpRequestHeaders = httpRequestMessage.Headers.GetValues("Custom-Header").ToList();
155 Assert.Equal("HeaderValue", httpRequestHeaders[0]);
156 Assert.Equal("someOther value", httpRequestHeaders[1]);
157 }
158
159 [Fact]
160 public void HttpClient_ShouldSetRequestHeaders_BodyAsDictionary()
161 {
162 // Arrange
163 var customRequestHeader = new List<string> { "HeaderValue", "someOther value" };
164 HttpRequest request = HttpRequest.Post("https://www.microsoft.com");
165 request.AddHeader("Custom-Header", customRequestHeader);
166 request.Body = new Dictionary<string, string>()
167 {
168 { "grant_type", "client_credentials" },
169 { "client_id", "ClientId" },
170 { "client_secret", "ClientSecret" },
171 { "scope", "scope" }
172 };
173
174 var mockHttpclient = new MockHttpClient();
175
176 // Act
177 var httpRequestMessage = mockHttpclient.ValidateCreateRequest(request);
178
179 // Assert
180 Assert.Equal("POST", httpRequestMessage.Method.Method);
181 var httpRequestHeaders = httpRequestMessage.Headers.GetValues("Custom-Header").ToList();
182 Assert.Equal("HeaderValue", httpRequestHeaders[0]);
183 Assert.Equal("someOther value", httpRequestHeaders[1]);
184
185 var contentTypeHeader = httpRequestMessage.Content?.Headers.GetValues("Content-Type").ToList();
186 Assert.Single(contentTypeHeader!);
187 Assert.Equal("application/x-www-form-urlencoded", httpRequestMessage.Content?.Headers.ContentType?.MediaType);
188 Assert.Equal("application/x-www-form-urlencoded", contentTypeHeader![0]);
189
190 // TODO : Check the content of the request body
191 //var requestBody = httpRequestMessage.Content?.ToString();
192 //Assert.Contains("grant_type=client_credentials", requestBody);
193
194 }
195
196 [Fact]
197 public void HttpClient_ShouldSetRequestHeaders_BodyAsString()
198 {
199 // Arrange
200 var customRequestHeader = new List<string> { "HeaderValue", "someOther value" };
201 HttpRequest request = HttpRequest.Post("https://www.microsoft.com");
202 request.AddHeader("Custom-Header", customRequestHeader);
203 request.AddHeader("Content-Type", "application/json");
204 request.Body = "post data";
205
206 var mockHttpclient = new MockHttpClient();
207
208 // Act
209 var httpRequestMessage = mockHttpclient.ValidateCreateRequest(request);
210
211 // Assert
212 Assert.Equal("POST", httpRequestMessage.Method.Method);
213 var httpRequestHeaders = httpRequestMessage.Headers.GetValues("Custom-Header").ToList();
214 Assert.Equal("HeaderValue", httpRequestHeaders[0]);
215 Assert.Equal("someOther value", httpRequestHeaders[1]);
216
217 var contentTypeHeader = httpRequestMessage.Content?.Headers.GetValues("Content-Type").ToList();
218 Assert.Single(contentTypeHeader!);
219 Assert.Equal("application/json", httpRequestMessage.Content?.Headers.ContentType?.MediaType);
220 Assert.Equal("application/json", contentTypeHeader![0]);
221
222 // TODO : Check the content of the request body
223 }
224
225 [Fact]
226 public async Task HttpClient_ShouldSetRequestHeaders_BodyAsJsonObject()
227 {
228 // Arrange
229 var tokenData = new Api.Tabs.Request()
230 {
231 Context = new Api.Tabs.Context()
232 {
233 Theme = "default",
234 },
235 State = "state",
236 TabContext = new Api.Tabs.EntityContext()
237 {
238 TabEntityId = "tabEntityId",
239 }
240 };
241
242 var customRequestHeader = new List<string> { "HeaderValue", "someOther value" };
243 HttpRequest request = HttpRequest.Post("https://www.microsoft.com");
244 request.AddHeader("Custom-Header", customRequestHeader);
245 request.AddHeader("Content-data", "valid");
246 request.Body = tokenData;
247
248 var mockHttpclient = new MockHttpClient();
249
250 // Act
251 var httpRequestMessage = mockHttpclient.ValidateCreateRequest(request);
252
253 // Assert
254 Assert.Equal("POST", httpRequestMessage.Method.Method);
255 var httpRequestHeaders = httpRequestMessage.Headers.GetValues("Custom-Header").ToList();
256 Assert.Equal("HeaderValue", httpRequestHeaders[0]);
257 Assert.Equal("someOther value", httpRequestHeaders[1]);
258
259 Assert.NotNull(httpRequestMessage.Content);
260 var contentTypeHeader = httpRequestMessage.Content.Headers.GetValues("Content-Type").ToList();
261 Assert.NotNull(contentTypeHeader);
262 Assert.Single(contentTypeHeader!);
263 Assert.Equal("application/json", httpRequestMessage.Content.Headers.ContentType?.MediaType);
264 Assert.Equal("application/json; charset=utf-8", contentTypeHeader[0]);
265
266 var deserializedContent = await httpRequestMessage.Content.ReadFromJsonAsync<Api.Tabs.Request>();
267 Assert.Equal(tokenData.ToString(), deserializedContent!.ToString());
268 }
269
270 [Fact]
271 public async Task HttpClient_ShouldThrowException_WhenResponseIsNotSuccess()
272 {
273 // Arrange
274 var errorResponse = new
275 {
276 error = "invalid_grant",
277 error_description = "The provided value for the client_assertion parameter is not valid."
278 };
279
280 var errorResponseJson = JsonSerializer.Serialize(errorResponse, new JsonSerializerOptions()
281 {
282 WriteIndented = false,
283 DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull,
284 PropertyNamingPolicy = JsonNamingPolicy.CamelCase
285 });
286
287 var mockMessageHandler = new Mock<HttpMessageHandler>();
288 mockMessageHandler.Protected()
289 .Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
290 .ReturnsAsync(new HttpResponseMessage
291 {
292 StatusCode = HttpStatusCode.BadRequest,
293 Content = new StringContent(errorResponseJson, Encoding.UTF8, "application/json"),
294 });
295 var httpClient = new Common.Http.HttpClient(new System.Net.Http.HttpClient(mockMessageHandler.Object));
296 HttpRequest request = HttpRequest.Get("https://www.microsoft.com");
297
298 // Act & Assert
299 var ex = await Assert.ThrowsAsync<HttpException>(async () => await httpClient.SendAsync(request));
300
301 var expectedSubmitException = "Exception of type 'Microsoft.Teams.Common.Http.HttpException' was thrown.";
302 Assert.Equal(expectedSubmitException, ex.Message);
303 Assert.Equal(HttpStatusCode.BadRequest, ex.StatusCode);
304 Assert.NotNull(ex.Body);
305 Assert.Equal($$"""
306 {
307 "headers": [],
308 "statusCode": 400,
309 "body": {
310 "error": "invalid_grant",
311 "error_description": "The provided value for the client_assertion parameter is not valid."
312 }
313 }
314 """, ex.ToString());
315 }
316
317 [Fact]
318 public async Task HttpClient_ShouldThrowException_WhenResponseIsNotSuccess_WithPlainTextContent()
319 {
320 // Arrange
321 var errorResponseContent = "Invalid request";
322 var mockMessageHandler = new Mock<HttpMessageHandler>();
323 mockMessageHandler.Protected()
324 .Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
325 .ReturnsAsync(new HttpResponseMessage
326 {
327 StatusCode = HttpStatusCode.BadRequest,
328 Content = new StringContent(errorResponseContent, Encoding.UTF8, "text/plain"),
329 });
330 var httpClient = new Common.Http.HttpClient(new System.Net.Http.HttpClient(mockMessageHandler.Object));
331 HttpRequest request = HttpRequest.Get("https://www.microsoft.com");
332
333 // Act & Assert
334 var ex = await Assert.ThrowsAsync<HttpException>(async () => await httpClient.SendAsync(request));
335
336 var expectedSubmitException = "Exception of type 'Microsoft.Teams.Common.Http.HttpException' was thrown.";
337 Assert.Equal(expectedSubmitException, ex.Message);
338 Assert.Equal(HttpStatusCode.BadRequest, ex.StatusCode);
339 Assert.NotNull(ex.Body);
340 Assert.Equal($$"""
341 {
342 "headers": [],
343 "statusCode": 400,
344 "body": "Invalid request"
345 }
346 """, ex.ToString());
347 }
348
349 [Fact]
350 public async Task HttpClient_ShouldThrowException_WhenResponseObjectIsNotSuccess()
351 {
352 var errorResponse = new
353 {
354 error = "invalid_grant",
355 error_description = "The provided value for the client_assertion parameter is not valid."
356 };
357
358 var errorResponseJson = JsonSerializer.Serialize(errorResponse, new JsonSerializerOptions()
359 {
360 WriteIndented = false,
361 DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull,
362 PropertyNamingPolicy = JsonNamingPolicy.CamelCase
363 });
364
365 var mockMessageHandler = new Mock<HttpMessageHandler>();
366 mockMessageHandler.Protected()
367 .Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
368 .ReturnsAsync(new HttpResponseMessage()
369 {
370 StatusCode = HttpStatusCode.BadRequest,
371 Content = new StringContent(errorResponseJson, Encoding.UTF8, "application/json"),
372 });
373
374 var httpClient = new Common.Http.HttpClient(new System.Net.Http.HttpClient(mockMessageHandler.Object));
375 HttpRequest request = HttpRequest.Get("https://www.microsoft.com");
376
377
378 // Act & Assert
379 var ex = await Assert.ThrowsAsync<HttpException>(async () => await httpClient.SendAsync<UrlResponse>(request));
380
381 var expectedSubmitException = "Exception of type 'Microsoft.Teams.Common.Http.HttpException' was thrown.";
382 Assert.Equal(expectedSubmitException, ex.Message);
383 Assert.Equal(HttpStatusCode.BadRequest, ex.StatusCode);
384 Assert.NotNull(ex.Body);
385 Assert.Equal($$"""
386 {
387 "headers": [],
388 "statusCode": 400,
389 "body": {
390 "error": "invalid_grant",
391 "error_description": "The provided value for the client_assertion parameter is not valid."
392 }
393 }
394 """, ex.ToString());
395 }
396}