microsoft/teams.net

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
feat/msal-agentic

Branches

Tags

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

Clone

HTTPS

Download ZIP

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

372lines · modecode

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