From 519352a54a5b8a741c69ff8b4d41f38a785b5f00 Mon Sep 17 00:00:00 2001 From: James Skimming Date: Wed, 26 Aug 2015 11:33:39 +0100 Subject: [PATCH 1/3] Added error tests to get all zones --- src/CloudFlare.NET/CloudFlare.NET.csproj | 1 + src/CloudFlare.NET/CloudFlareException.cs | 62 +++++++++++++++++++ src/CloudFlare.NET/HttpClientExtensions.cs | 14 ++--- .../CloudFlare.NET.Tests/FixtureContext.cs | 13 ++++ .../HttpHandlers/TestHttpHandler.cs | 12 ++-- .../LikenessExtensions.cs | 16 +++++ .../RequestBehaviorTemplates.cs | 18 +++++- .../CloudFlare.NET.Tests/ZoneClientSpec.cs | 22 +++++++ 8 files changed, 142 insertions(+), 16 deletions(-) create mode 100644 src/CloudFlare.NET/CloudFlareException.cs diff --git a/src/CloudFlare.NET/CloudFlare.NET.csproj b/src/CloudFlare.NET/CloudFlare.NET.csproj index fe89f69..ba8dfaf 100644 --- a/src/CloudFlare.NET/CloudFlare.NET.csproj +++ b/src/CloudFlare.NET/CloudFlare.NET.csproj @@ -67,6 +67,7 @@ + diff --git a/src/CloudFlare.NET/CloudFlareException.cs b/src/CloudFlare.NET/CloudFlareException.cs new file mode 100644 index 0000000..e0c669e --- /dev/null +++ b/src/CloudFlare.NET/CloudFlareException.cs @@ -0,0 +1,62 @@ +namespace CloudFlare.NET +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Net.Http; + + /// + /// Contains the erred to a request. + /// + public class CloudFlareException : Exception + { + /// + /// Initializes a new instance of the class. + /// + public CloudFlareException( + CloudFlareResponseBase response, + HttpResponseMessage httpResponse = null, + Exception innerException = null) + : base(GetMessage(response, httpResponse), innerException) + { + Response = response; + SetupData(response); + } + + /// + /// Gets the error information of the response. + /// + public CloudFlareResponseBase Response { get; } + + private static string GetMessage(CloudFlareResponseBase response, HttpResponseMessage httpResponse = null) + { + if (response == null) + throw new ArgumentNullException(nameof(response)); + + string message = response.Errors.FirstOrDefault()?.Message ?? "Unknown error."; + string requestMethod = httpResponse?.RequestMessage?.Method?.ToString() ?? "Unknown HTTP Method"; + string requestUri = httpResponse?.RequestMessage?.RequestUri?.AbsoluteUri ?? "Unknown Uri"; + + return $"{message}: {requestMethod} {requestUri}"; + } + + private void SetupData(CloudFlareResponseBase response) + { + if (response == null) + throw new ArgumentNullException(nameof(response)); + + int index = 1; + foreach (CloudFlareError error in response.Errors) + { + Data[$"ErrorCode{index}"] = error.Code; + Data[$"ErrorMessage{index}"] = error.Message; + } + + index = 1; + foreach (string message in response.Messages) + { + Data[$"Message{index}"] = message; + } + } + } +} diff --git a/src/CloudFlare.NET/HttpClientExtensions.cs b/src/CloudFlare.NET/HttpClientExtensions.cs index c87ed9d..0fcaebd 100644 --- a/src/CloudFlare.NET/HttpClientExtensions.cs +++ b/src/CloudFlare.NET/HttpClientExtensions.cs @@ -19,7 +19,7 @@ public static class HttpClientExtensions public static Uri ZonesUri { get; } = new Uri(CloudFlareConstants.BaseUri, "zones"); /// - /// Gets the of a CloudFlare API . + /// Gets the of a CloudFlare API . /// /// The type of the . public static async Task> GetResultAsync( @@ -38,13 +38,13 @@ public static async Task> GetResultAsync( .ConfigureAwait(false); } - var errorResult = await response - .Content - .ReadAsAsync(cancellationToken) - .ConfigureAwait(false); + CloudFlareResponseBase errorResponse = + await response + .Content + .ReadAsAsync(cancellationToken) + .ConfigureAwait(false); - // TODO: Do some nice error handling. - throw new Exception("It's Not so good and stuff."); + throw new CloudFlareException(errorResponse, response); } /// diff --git a/src/Tests/CloudFlare.NET.Tests/FixtureContext.cs b/src/Tests/CloudFlare.NET.Tests/FixtureContext.cs index d58ff9c..3469922 100644 --- a/src/Tests/CloudFlare.NET.Tests/FixtureContext.cs +++ b/src/Tests/CloudFlare.NET.Tests/FixtureContext.cs @@ -3,6 +3,7 @@ namespace CloudFlare.NET using System; using System.Collections.Generic; using System.Linq; + using System.Net; using System.Net.Http; using CloudFlare.NET.HttpHandlers; using Machine.Specifications; @@ -31,4 +32,16 @@ public abstract class RequestContext : FixtureContext _auth = _fixture.Create(); }; } + + public abstract class ErredRequestContext : RequestContext + { + protected static CloudFlareResponseBase _erredResponse; + protected static Exception _exception; + + Establish context = () => + { + _erredResponse = _fixture.Create(); + _handler.SetResponseContent(_erredResponse, (HttpStatusCode)new Random().Next(400, 600)); + }; + } } diff --git a/src/Tests/CloudFlare.NET.Tests/HttpHandlers/TestHttpHandler.cs b/src/Tests/CloudFlare.NET.Tests/HttpHandlers/TestHttpHandler.cs index 1c82a78..d28e110 100644 --- a/src/Tests/CloudFlare.NET.Tests/HttpHandlers/TestHttpHandler.cs +++ b/src/Tests/CloudFlare.NET.Tests/HttpHandlers/TestHttpHandler.cs @@ -56,19 +56,19 @@ public HttpResponseMessage Response public Func> OnSendingRequest { get; set; } - public void SetResponseContent(object content) + public void SetResponseContent(object content, HttpStatusCode code = HttpStatusCode.OK) { - SetResponseContent(JObject.FromObject(content).ToString(Formatting.None)); + SetResponseContent(JObject.FromObject(content).ToString(Formatting.None), code); } - public void SetResponseContent(string content) + public void SetResponseContent(string content, HttpStatusCode code = HttpStatusCode.OK) { - Response = CreateResponse(content); + Response = CreateResponse(content, code); } - public void AddResponseContent(string content) + public void AddResponseContent(string content, HttpStatusCode code = HttpStatusCode.OK) { - Responses.Add(CreateResponse(content)); + Responses.Add(CreateResponse(content, code)); } protected async override Task SendAsync( diff --git a/src/Tests/CloudFlare.NET.Tests/LikenessExtensions.cs b/src/Tests/CloudFlare.NET.Tests/LikenessExtensions.cs index f43d1ad..044f6d9 100644 --- a/src/Tests/CloudFlare.NET.Tests/LikenessExtensions.cs +++ b/src/Tests/CloudFlare.NET.Tests/LikenessExtensions.cs @@ -18,6 +18,22 @@ public static Likeness AsLikeness(this T actual) return actual.AsSource().OfLikeness(); } + public static Likeness AsLikeness(this CloudFlareResponseBase actual) + { + if (actual == null) + throw new ArgumentNullException(nameof(actual)); + + return actual + .AsSource() + .OfLikeness() + .With(r => r.Errors) + .EqualsWhen((a, e) => a.Errors.SequenceEqual(e.Errors)) + .With(r => r.Messages) + .EqualsWhen((a, e) => a.Messages.SequenceEqual(e.Messages)) + .With(r => r.ResultInfo) + .EqualsWhen((a, e) => a.ResultInfo.AsLikeness().Equals(e.ResultInfo)); + } + public static Likeness AsLikeness(this Zone actual) { if (actual == null) diff --git a/src/Tests/CloudFlare.NET.Tests/RequestBehaviorTemplates.cs b/src/Tests/CloudFlare.NET.Tests/RequestBehaviorTemplates.cs index 5254600..97a0453 100644 --- a/src/Tests/CloudFlare.NET.Tests/RequestBehaviorTemplates.cs +++ b/src/Tests/CloudFlare.NET.Tests/RequestBehaviorTemplates.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; using System.Linq; - using System.Threading.Tasks; using CloudFlare.NET.HttpHandlers; using Machine.Specifications; @@ -14,10 +13,23 @@ public class AuthenticatedRequestBehaviour protected static TestHttpHandler _handler; protected static CloudFlareAuth _auth; - It It_should_provide_the_email_authentication_header = () => + It should_provide_the_email_authentication_header = () => _handler.Request.Headers.GetValues("X-Auth-Email").Single().ShouldEqual(_auth.Email); - It It_should_provide_the_key_authentication_header = () => + It should_provide_the_key_authentication_header = () => _handler.Request.Headers.GetValues("X-Auth-Key").Single().ShouldEqual(_auth.Key); } + + /// + [Behaviors] + public class ErredRequestBehaviour + { + protected static CloudFlareResponseBase _erredResponse; + protected static Exception _exception; + + It should_throw_a_CloudFlareException = () => _exception.ShouldBeOfExactType(); + + It should_contain_the_erred_response_in_the_exception = + () => ((CloudFlareException)_exception).Response.AsLikeness().ShouldEqual(_erredResponse); + } } diff --git a/src/Tests/CloudFlare.NET.Tests/ZoneClientSpec.cs b/src/Tests/CloudFlare.NET.Tests/ZoneClientSpec.cs index 98a0005..a880198 100644 --- a/src/Tests/CloudFlare.NET.Tests/ZoneClientSpec.cs +++ b/src/Tests/CloudFlare.NET.Tests/ZoneClientSpec.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Linq; + using System.Net; using System.Net.Http; using Machine.Specifications; using Ploeh.AutoFixture; @@ -34,6 +35,27 @@ public class When_getting_all_zones : RequestContext _actual.Select(z => z.AsLikeness().CreateProxy()).SequenceEqual(_expected).ShouldBeTrue(); } + [Subject(typeof(CloudFlareClient))] + public class When_getting_all_zones_and_an_error_occurs : ErredRequestContext + { + static Uri _expectedRequestUri; + + Establish context = () => + { + _expectedRequestUri = new Uri(CloudFlareConstants.BaseUri, "zones"); + }; + + Because of = () => _exception = Catch.Exception(() => _sut.GetZonesAsync(_auth).Await()); + + Behaves_like authenticated_request_behaviour; + + Behaves_like erred_request_behaviour; + + It should_make_a_GET_request = () => _handler.Request.Method.ShouldEqual(HttpMethod.Get); + + It should_request_the_zones_endpoint = () => _handler.Request.RequestUri.ShouldEqual(_expectedRequestUri); + } + [Subject(typeof(CloudFlareClient))] public class When_getting_a_zone : RequestContext { From bdbac15319565f59d49e558655aec53e8f2992c3 Mon Sep 17 00:00:00 2001 From: James Skimming Date: Wed, 26 Aug 2015 11:38:24 +0100 Subject: [PATCH 2/3] Added error test for get zone --- .../CloudFlare.NET.Tests/ZoneClientSpec.cs | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/Tests/CloudFlare.NET.Tests/ZoneClientSpec.cs b/src/Tests/CloudFlare.NET.Tests/ZoneClientSpec.cs index a880198..2a77cc4 100644 --- a/src/Tests/CloudFlare.NET.Tests/ZoneClientSpec.cs +++ b/src/Tests/CloudFlare.NET.Tests/ZoneClientSpec.cs @@ -81,4 +81,27 @@ public class When_getting_a_zone : RequestContext It should_return_the_expected_zones = () => _actual.AsLikeness().ShouldEqual(_expected); } + + [Subject(typeof(CloudFlareClient))] + public class When_getting_a_zone_and_an_error_occurs : ErredRequestContext + { + static IdentifierTag _zoneId; + static Uri _expectedRequestUri; + + Establish context = () => + { + _zoneId = _fixture.Create(); + _expectedRequestUri = new Uri(CloudFlareConstants.BaseUri, $"zones/{_zoneId}"); + }; + + Because of = () => _exception = Catch.Exception(() => _sut.GetZoneAsync(_zoneId, _auth).Await()); + + Behaves_like authenticated_request_behaviour; + + Behaves_like erred_request_behaviour; + + It should_make_a_GET_request = () => _handler.Request.Method.ShouldEqual(HttpMethod.Get); + + It should_request_the_zone_endpoint = () => _handler.Request.RequestUri.ShouldEqual(_expectedRequestUri); + } } From 7d2cf6eaa9a2c9281c562844b19a5edadbf783af Mon Sep 17 00:00:00 2001 From: James Skimming Date: Wed, 26 Aug 2015 11:42:29 +0100 Subject: [PATCH 3/3] Added error test for get DNS records --- .../DnsRecordClientSpec.cs | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/Tests/CloudFlare.NET.Tests/DnsRecordClientSpec.cs b/src/Tests/CloudFlare.NET.Tests/DnsRecordClientSpec.cs index e5f6aff..cbda5d3 100644 --- a/src/Tests/CloudFlare.NET.Tests/DnsRecordClientSpec.cs +++ b/src/Tests/CloudFlare.NET.Tests/DnsRecordClientSpec.cs @@ -30,9 +30,32 @@ public class When_getting_dnsRecords : RequestContext It should_make_a_GET_request = () => _handler.Request.Method.ShouldEqual(HttpMethod.Get); - It should_request_the_zones_endpoint = () => _handler.Request.RequestUri.ShouldEqual(_expectedRequestUri); + It should_request_the_DNS_records_endpoint = () => _handler.Request.RequestUri.ShouldEqual(_expectedRequestUri); It should_return_the_expected_zones = () => _actual.Select(z => z.AsLikeness().CreateProxy()).SequenceEqual(_expected).ShouldBeTrue(); } + + [Subject(typeof(CloudFlareClient))] + public class When_getting_dnsRecords_and_an_error_occurs : ErredRequestContext + { + static IdentifierTag _zoneId; + static Uri _expectedRequestUri; + + Establish context = () => + { + _zoneId = _fixture.Create(); + _expectedRequestUri = new Uri(CloudFlareConstants.BaseUri, $"zones/{_zoneId}/dns_records"); + }; + + Because of = () => _exception = Catch.Exception(() => _sut.GetDnsRecordsAsync(_zoneId, _auth).Await()); + + Behaves_like authenticated_request_behaviour; + + Behaves_like erred_request_behaviour; + + It should_make_a_GET_request = () => _handler.Request.Method.ShouldEqual(HttpMethod.Get); + + It should_request_the_DNS_records_endpoint = () => _handler.Request.RequestUri.ShouldEqual(_expectedRequestUri); + } }