Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Implemented a rest client that can serialize payloads using an ISeria…

…lizer before sending the request to the HTTP client. Then turn around and deserialize the content using ISerializer to a type we provide from the response.
  • Loading branch information...
commit cdf8c9da3ed731d9f99d8b4bf28419d2c9c9772b 1 parent 26259bd
@dragan dragan authored
View
16 src/SineSignal.Ottoman.Specs/CouchProxySpecs.cs
@@ -67,15 +67,15 @@ public void Should_return_deserialized_object()
Assert.That(resultStub.Status, Is.EqualTo("completed"));
}
}
-
- public class ResultStub
- {
- public string Status { get; private set; }
+ }
+
+ public class ResultStub
+ {
+ public string Status { get; private set; }
- public ResultStub()
- {
- Status = "completed";
- }
+ public ResultStub()
+ {
+ Status = "completed";
}
}
}
View
106 src/SineSignal.Ottoman.Specs/Http/RestClientSpecs.cs
@@ -0,0 +1,106 @@
+using System;
+using System.Net;
+
+using NSubstitute;
+using NUnit.Framework;
+using SineSignal.Ottoman.Specs.Framework;
+
+using SineSignal.Ottoman.Http;
+using SineSignal.Ottoman.Serialization;
+
+namespace SineSignal.Ottoman.Specs.Http
+{
+ public class RestClientSpecs
+ {
+ public class When_processing_a_post_request : ConcernFor<RestClient>
+ {
+ private Uri baseUri;
+ private IHttpClient httpClient;
+ private RestRequest restRequest;
+ private Employee payload;
+ private RestResponse<ResultStub> restResponse;
+ private ISerializer serializer;
+ private string requestContent;
+ private string responseContent;
+ private ResultStub contentDeserialized;
+ private string jsonContentType;
+
+ protected override void Given()
+ {
+ baseUri = new Uri("http://127.0.0.1:5984");
+ payload = new Employee { Name = "Bob", Login = "boblogin" };
+ restRequest = new RestRequest { Path = "some/path", Method = HttpMethod.Post, Payload = payload };
+ requestContent = "{\"Id\":\"" + Guid.Empty + "\",\"Name\":\"\",\"Login\":\"\"}";
+ responseContent = "{\"status\":\"completed\"}";
+ jsonContentType = "application/json";
+
+ serializer = Fake<ISerializer>();
+ serializer.Serialize(Arg.Any<object>()).Returns(requestContent);
+ contentDeserialized = new ResultStub();
+ serializer.Deserialize<ResultStub>(Arg.Any<string>()).Returns(contentDeserialized);
+
+ httpClient = Fake<IHttpClient>();
+ httpClient.Send(Arg.Any<HttpRequest>()).Returns(new HttpResponse {
+ ContentType = jsonContentType,
+ ContentLength = responseContent.Length,
+ Content = responseContent,
+ StatusCode = HttpStatusCode.Created,
+ StatusDescription = HttpStatusCode.Created.ToString()
+ });
+ }
+
+ public override RestClient CreateSystemUnderTest()
+ {
+ return new RestClient(baseUri, httpClient, serializer);
+ }
+
+ protected override void When()
+ {
+ restResponse = Sut.Process<ResultStub>(restRequest);
+ }
+
+ [Test]
+ public void Should_call_serialize_on_serializer_with_the_payload()
+ {
+ serializer.Received().Serialize(Arg.Is<Employee>(e => {
+ return e.Id == Guid.Empty &&
+ e.Name == "Bob" &&
+ e.Login == "boblogin";
+ }));
+ }
+
+ [Test]
+ public void Should_call_send_on_http_client_with_generated_http_request()
+ {
+ httpClient.Received().Send(Arg.Is<HttpRequest>(h => {
+ return h.Url == new Uri(baseUri.ToString() + restRequest.Path) &&
+ h.Accept == jsonContentType &&
+ h.Method == restRequest.Method &&
+ h.ContentType == jsonContentType &&
+ h.Content == requestContent &&
+ h.ContentLength == requestContent.Length;
+ }));
+ }
+
+ [Test]
+ public void Should_call_deserialize_on_serializer_with_content_of_response()
+ {
+ serializer.Received().Deserialize<ResultStub>(Arg.Is<string>(s => {
+ return s == responseContent;
+ }));
+ }
+
+ [Test]
+ public void Should_return_rest_response_generated_from_http_response()
+ {
+ Assert.That(restResponse.RestRequest, Is.EqualTo(restRequest));
+ Assert.That(restResponse.ContentType, Is.EqualTo(jsonContentType));
+ Assert.That(restResponse.Content, Is.EqualTo(responseContent));
+ Assert.That(restResponse.ContentLength, Is.EqualTo(responseContent.Length));
+ Assert.That(restResponse.StatusCode, Is.EqualTo(HttpStatusCode.Created));
+ Assert.That(restResponse.StatusDescription, Is.EqualTo(HttpStatusCode.Created.ToString()));
+ Assert.That(restResponse.ContentDeserialized, Is.EqualTo(contentDeserialized));
+ }
+ }
+ }
+}
View
2  src/SineSignal.Ottoman.Specs/SineSignal.Ottoman.Specs.csproj
@@ -38,6 +38,7 @@
<Compile Include="CouchDocumentSessionSpecs.cs" />
<Compile Include="CouchProxySpecs.cs" />
<Compile Include="CouchDocumentSpecs.cs" />
+ <Compile Include="Http\RestClientSpecs.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SineSignal.Ottoman\SineSignal.Ottoman.csproj">
@@ -61,5 +62,6 @@
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
<Folder Include="Framework\" />
+ <Folder Include="Http\" />
</ItemGroup>
</Project>
View
1  src/SineSignal.Ottoman/Http/HttpClient.cs
@@ -17,6 +17,7 @@ public HttpResponse Send(HttpRequest httpRequest)
private static HttpWebRequest InitializeHttpWebRequest(HttpRequest httpRequest)
{
HttpWebRequest httpWebRequest = WebRequest.Create(httpRequest.Url) as HttpWebRequest;
+ httpWebRequest.Accept = httpRequest.Accept;
httpWebRequest.UserAgent = USER_AGENT;
httpWebRequest.Method = httpRequest.Method;
httpWebRequest.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip | DecompressionMethods.None;
View
1  src/SineSignal.Ottoman/Http/HttpRequest.cs
@@ -8,6 +8,7 @@ public sealed class HttpRequest
{
public Uri Url { get; set; }
public IList<HttpHeader> Headers { get; private set; }
+ public string Accept { get; set; }
public string Method { get; set; }
public string ContentType { get; set; }
public string Content { get; set; }
View
57 src/SineSignal.Ottoman/Http/RestClient.cs
@@ -0,0 +1,57 @@
+using System;
+
+using SineSignal.Ottoman.Serialization;
+
+namespace SineSignal.Ottoman.Http
+{
+ public class RestClient : IRestClient
+ {
+ private UriBuilder _requestUri;
+
+ public Uri BaseUri { get; private set; }
+ private IHttpClient HttpClient { get; set; }
+ private ISerializer Serializer { get; set; }
+
+ public RestClient(Uri baseUri, IHttpClient httpClient, ISerializer serializer)
+ {
+ _requestUri = new UriBuilder(baseUri);
+ BaseUri = baseUri;
+ HttpClient = httpClient;
+ Serializer = serializer;
+ }
+
+ public RestResponse<T> Process<T>(RestRequest restRequest)
+ {
+ HttpRequest httpRequest = ConverToHttpRequestFrom(restRequest);
+ HttpResponse httpResponse = HttpClient.Send(httpRequest);
+
+ return ConvertToRestResponseFrom<T>(httpResponse, restRequest);
+ }
+
+ private HttpRequest ConverToHttpRequestFrom(RestRequest restRequest)
+ {
+ _requestUri.Path = restRequest.Path;
+
+ return new HttpRequest {
+ Url = _requestUri.Uri,
+ Accept = "application/json",
+ Method = restRequest.Method,
+ ContentType = "application/json",
+ Content = Serializer.Serialize(restRequest.Payload)
+ };
+ }
+
+ private RestResponse<T> ConvertToRestResponseFrom<T>(HttpResponse httpResponse, RestRequest restRequest)
+ {
+ return new RestResponse<T> {
+ RestRequest = restRequest,
+ ContentType = httpResponse.ContentType,
+ ContentLength = httpResponse.ContentLength,
+ Content = httpResponse.Content,
+ StatusCode = httpResponse.StatusCode,
+ StatusDescription = httpResponse.StatusDescription,
+ ContentDeserialized = Serializer.Deserialize<T>(httpResponse.Content)
+ };
+ }
+ }
+}
View
4 src/SineSignal.Ottoman/Http/RestResponse.cs
@@ -1,3 +1,5 @@
+using System.Net;
+
namespace SineSignal.Ottoman.Http
{
public class RestResponse<T>
@@ -6,7 +8,7 @@ public class RestResponse<T>
public string ContentType { get; set; }
public long ContentLength { get; set; }
public string Content { get; set; }
- public System.Net.HttpStatusCode StatusCode { get; set; }
+ public HttpStatusCode StatusCode { get; set; }
public string StatusDescription { get; set; }
public T ContentDeserialized { get; set; }
}
View
8 src/SineSignal.Ottoman/Serialization/ISerializer.cs
@@ -0,0 +1,8 @@
+namespace SineSignal.Ottoman.Serialization
+{
+ public interface ISerializer
+ {
+ string Serialize(object objectToSerialize);
+ T Deserialize<T>(string content);
+ }
+}
View
3  src/SineSignal.Ottoman/SineSignal.Ottoman.csproj
@@ -50,6 +50,8 @@
<Compile Include="Http\RestResponse.cs" />
<Compile Include="Http\IRestClient.cs" />
<Compile Include="CouchProxy.cs" />
+ <Compile Include="Http\RestClient.cs" />
+ <Compile Include="Serialization\ISerializer.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
@@ -61,5 +63,6 @@
<Folder Include="Exceptions\" />
<Folder Include="Http\" />
<Folder Include="Commands\" />
+ <Folder Include="Serialization\" />
</ItemGroup>
</Project>
Please sign in to comment.
Something went wrong with that request. Please try again.