Skip to content

Commit a85352f

Browse files
committed
Fixed tests
1 parent f3fa04f commit a85352f

File tree

18 files changed

+235
-204
lines changed

18 files changed

+235
-204
lines changed

src/Microsoft.Graph.Core/Requests/AuthenticationHandler.cs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,6 @@ public class AuthenticationHandler: DelegatingHandler
2323
/// </summary>
2424
public IAuthenticationProvider AuthenticationProvider { get; set; }
2525

26-
/// <summary>
27-
/// Construct a new <see cref="AuthenticationHandler"/>
28-
/// </summary>
29-
public AuthenticationHandler()
30-
{
31-
32-
}
33-
3426
/// <summary>
3527
/// Construct a new <see cref="AuthenticationHandler"/>
3628
/// <param name="authenticationProvider">An authentication provider to pass to <see cref="AuthenticationHandler"/> for authenticating requests.</param>

src/Microsoft.Graph.Core/Requests/BaseRequest.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,16 @@ public async Task<HttpResponseMessage> SendMultiPartRequestAsync(
189189
});
190190
}
191191

192+
if (this.Client.AuthenticationProvider == null)
193+
{
194+
throw new ServiceException(
195+
new Error
196+
{
197+
Code = ErrorConstants.Codes.InvalidRequest,
198+
Message = ErrorConstants.Messages.AuthenticationProviderMissing,
199+
});
200+
}
201+
192202
if (multipartContent != null)
193203
{
194204
using (var request = this.GetHttpRequestMessage())
@@ -226,6 +236,16 @@ public async Task<HttpResponseMessage> SendRequestAsync(
226236
});
227237
}
228238

239+
if (this.Client.AuthenticationProvider == null)
240+
{
241+
throw new ServiceException(
242+
new Error
243+
{
244+
Code = ErrorConstants.Codes.InvalidRequest,
245+
Message = ErrorConstants.Messages.AuthenticationProviderMissing,
246+
});
247+
}
248+
229249
using (var request = this.GetHttpRequestMessage())
230250
{
231251
if (serializableObject != null)
@@ -259,9 +279,25 @@ public HttpRequestMessage GetHttpRequestMessage()
259279
{
260280
var queryString = this.BuildQueryString();
261281
var request = new HttpRequestMessage(new HttpMethod(this.Method), string.Concat(this.RequestUrl, queryString));
282+
this.AddHeadersToRequest(request);
262283
return request;
263284
}
264285

286+
/// <summary>
287+
/// Adds all of the headers from the header collection to the request.
288+
/// </summary>
289+
/// <param name="request">The <see cref="HttpRequestMessage"/> representation of the request.</param>
290+
private void AddHeadersToRequest(HttpRequestMessage request)
291+
{
292+
if (this.Headers != null)
293+
{
294+
foreach (var header in this.Headers)
295+
{
296+
request.Headers.TryAddWithoutValidation(header.Name, header.Value);
297+
}
298+
}
299+
}
300+
265301
/// <summary>
266302
/// Gets a URL that is the request builder's request URL with the segment appended.
267303
/// </summary>

src/Microsoft.Graph.Core/Requests/HttpProvider.cs

Lines changed: 90 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public class HttpProvider : IHttpProvider
3030
/// <param name="authenticationProvider">The <see cref="IAuthenticationProvider"/> for authenticating request messages.</param>
3131
/// <param name="serializer">A serializer for serializing and deserializing JSON objects.</param>
3232
public HttpProvider(IAuthenticationProvider authenticationProvider, ISerializer serializer = null)
33-
: this((HttpMessageHandler)null, true, authenticationProvider, serializer)
33+
: this(authenticationProvider, (HttpMessageHandler)null, true, serializer)
3434
{
3535
}
3636

@@ -46,8 +46,8 @@ public HttpProvider(IAuthenticationProvider authenticationProvider, ISerializer
4646
/// an <see cref="HttpClientHandler"/> to the constructor and enabling automatic redirects this could cause issues with authentication
4747
/// over the redirect.
4848
/// </remarks>
49-
public HttpProvider(HttpClientHandler httpClientHandler, bool disposeHandler, IAuthenticationProvider authenticationProvider, ISerializer serializer = null)
50-
: this((HttpMessageHandler)httpClientHandler, disposeHandler, authenticationProvider, serializer)
49+
public HttpProvider(IAuthenticationProvider authenticationProvider, HttpClientHandler httpClientHandler, bool disposeHandler, ISerializer serializer = null)
50+
: this(authenticationProvider, (HttpMessageHandler)httpClientHandler, disposeHandler, serializer)
5151
{
5252
}
5353

@@ -58,7 +58,7 @@ public HttpProvider(HttpClientHandler httpClientHandler, bool disposeHandler, IA
5858
/// <param name="disposeHandler">Whether or not to dispose the client handler on Dispose().</param>
5959
/// <param name="authenticationProvider">The <see cref="IAuthenticationProvider"/> for authenticating request messages.</param>
6060
/// <param name="serializer">A serializer for serializing and deserializing JSON objects.</param>
61-
public HttpProvider(HttpMessageHandler httpMessageHandler, bool disposeHandler, IAuthenticationProvider authenticationProvider, ISerializer serializer)
61+
public HttpProvider(IAuthenticationProvider authenticationProvider, HttpMessageHandler httpMessageHandler, bool disposeHandler, ISerializer serializer)
6262
{
6363
this.disposeHandler = disposeHandler;
6464
this.httpMessageHandler = httpMessageHandler ?? new HttpClientHandler { AllowAutoRedirect = false };
@@ -74,35 +74,6 @@ public HttpProvider(HttpMessageHandler httpMessageHandler, bool disposeHandler,
7474
this.httpClient = GraphClientFactory.CreateClient(this.httpMessageHandler, handlers);
7575
}
7676

77-
/// <summary>
78-
/// Gets or sets the overall request timeout.
79-
/// </summary>
80-
public TimeSpan OverallTimeout
81-
{
82-
get
83-
{
84-
return this.httpClient.Timeout;
85-
}
86-
87-
set
88-
{
89-
try
90-
{
91-
this.httpClient.Timeout = value;
92-
}
93-
catch (InvalidOperationException exception)
94-
{
95-
throw new ServiceException(
96-
new Error
97-
{
98-
Code = ErrorConstants.Codes.NotAllowed,
99-
Message = ErrorConstants.Messages.OverallTimeoutCannotBeSet,
100-
},
101-
exception);
102-
}
103-
}
104-
}
105-
10677
/// <summary>
10778
/// Gets a serializer for serializing and deserializing JSON objects.
10879
/// </summary>
@@ -140,6 +111,65 @@ public async Task<HttpResponseMessage> SendAsync(
140111
HttpRequestMessage request,
141112
HttpCompletionOption completionOption,
142113
CancellationToken cancellationToken)
114+
{
115+
var response = await this.SendRequestAsync(request, completionOption, cancellationToken).ConfigureAwait(false);
116+
117+
if (!response.IsSuccessStatusCode)
118+
{
119+
using (response)
120+
{
121+
var errorResponse = await this.ConvertErrorResponseAsync(response).ConfigureAwait(false);
122+
Error error = null;
123+
124+
if (errorResponse == null || errorResponse.Error == null)
125+
{
126+
if (response != null && response.StatusCode == HttpStatusCode.NotFound)
127+
{
128+
error = new Error { Code = ErrorConstants.Codes.ItemNotFound };
129+
}
130+
else
131+
{
132+
error = new Error
133+
{
134+
Code = ErrorConstants.Codes.GeneralException,
135+
Message = ErrorConstants.Messages.UnexpectedExceptionResponse,
136+
};
137+
}
138+
}
139+
else
140+
{
141+
error = errorResponse.Error;
142+
}
143+
144+
if (string.IsNullOrEmpty(error.ThrowSite))
145+
{
146+
IEnumerable<string> throwsiteValues;
147+
148+
if (response.Headers.TryGetValues(CoreConstants.Headers.ThrowSiteHeaderName, out throwsiteValues))
149+
{
150+
error.ThrowSite = throwsiteValues.FirstOrDefault();
151+
}
152+
}
153+
154+
throw new ServiceException(error)
155+
{
156+
// Pass through the response headers to the ServiceException.
157+
ResponseHeaders = response.Headers,
158+
159+
// System.Net.HttpStatusCode does not support RFC 6585, Additional HTTP Status Codes.
160+
// Throttling status code 429 is in RFC 6586. The status code 429 will be passed through.
161+
StatusCode = response.StatusCode
162+
};
163+
}
164+
}
165+
166+
return response;
167+
}
168+
169+
internal async Task<HttpResponseMessage> SendRequestAsync(
170+
HttpRequestMessage request,
171+
HttpCompletionOption completionOption,
172+
CancellationToken cancellationToken)
143173
{
144174
try
145175
{
@@ -155,6 +185,10 @@ public async Task<HttpResponseMessage> SendAsync(
155185
},
156186
exception);
157187
}
188+
catch(ServiceException exception)
189+
{
190+
throw exception;
191+
}
158192
catch (Exception exception)
159193
{
160194
throw new ServiceException(
@@ -166,5 +200,28 @@ public async Task<HttpResponseMessage> SendAsync(
166200
exception);
167201
}
168202
}
203+
204+
/// <summary>
205+
/// Converts the <see cref="HttpRequestException"/> into an <see cref="ErrorResponse"/> object;
206+
/// </summary>
207+
/// <param name="response">The <see cref="HttpResponseMessage"/> to convert.</param>
208+
/// <returns>The <see cref="ErrorResponse"/> object.</returns>
209+
private async Task<ErrorResponse> ConvertErrorResponseAsync(HttpResponseMessage response)
210+
{
211+
try
212+
{
213+
using (var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
214+
{
215+
return this.Serializer.DeserializeObject<ErrorResponse>(responseStream);
216+
}
217+
}
218+
catch (Exception)
219+
{
220+
// If there's an exception deserializing the error response return null and throw a generic
221+
// ServiceException later.
222+
return null;
223+
}
224+
}
225+
169226
}
170227
}

src/Microsoft.Graph.Core/Requests/IHttpProvider.cs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,6 @@ public interface IHttpProvider : IDisposable
1919
/// </summary>
2020
ISerializer Serializer { get; }
2121

22-
/// <summary>
23-
/// Gets or sets the timeout interval. The default value is 100 seconds.
24-
/// </summary>
25-
TimeSpan OverallTimeout { get; set; }
26-
2722
/// <summary>
2823
/// Sends the request.
2924
/// </summary>

src/Microsoft.Graph.Core/Requests/RedirectHandler.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,15 @@ protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage
5151
// check response status code
5252
if (IsRedirect(response.StatusCode))
5353
{
54+
if (response.Headers.Location == null)
55+
{
56+
throw new ServiceException(
57+
new Error
58+
{
59+
Code = ErrorConstants.Codes.GeneralException,
60+
Message = ErrorConstants.Messages.LocationHeaderNotSetOnRedirect,
61+
});
62+
}
5463

5564
var redirectCount = 0;
5665

tests/Microsoft.Graph.Core.Test/Mocks/MockAuthenticationProvider.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Microsoft.Graph.Core.Test.Mocks
66
{
77
using System.Net.Http;
8+
using System.Net.Http.Headers;
89
using System.Threading.Tasks;
910

1011
using Moq;
@@ -18,6 +19,7 @@ public MockAuthenticationProvider()
1819

1920
this.Setup(
2021
provider => provider.AuthenticateRequestAsync(It.IsAny<HttpRequestMessage>()))
22+
.Callback<HttpRequestMessage>(r => r.Headers.Authorization = new AuthenticationHeaderValue(CoreConstants.Headers.Bearer, "Token"))
2123
.Returns(Task.FromResult(0));
2224
}
2325
}

tests/Microsoft.Graph.Core.Test/Requests/AuthenticationHandlerTests.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,12 @@ public void TearDown()
3535
}
3636

3737
[TestMethod]
38-
public void AuthHandler_DefaultConstructor()
38+
public void AuthHandler_AuthProviderConstructor()
3939
{
40-
using (AuthenticationHandler auth = new AuthenticationHandler())
40+
using (AuthenticationHandler auth = new AuthenticationHandler(mockAuthenticationProvider.Object))
4141
{
4242
Assert.IsNull(auth.InnerHandler, "Http message handler initialized");
43-
Assert.IsNull(auth.AuthenticationProvider, "Authentication provider initialized");
43+
Assert.IsNotNull(auth.AuthenticationProvider, "Authentication provider initialized");
4444
Assert.IsInstanceOfType(auth, typeof(AuthenticationHandler), "Unexpected authentication handler set");
4545
}
4646
}

0 commit comments

Comments
 (0)