Permalink
Browse files

We can now connect to CouchDB given an address of a running instance.

  • Loading branch information...
dragan committed Aug 21, 2010
1 parent ebf9e6c commit cb28cc4bd19b60d69bf76d0ae92f929d3f76495d
@@ -0,0 +1,10 @@
+Feature: Developer connects to a server
+ In order to use CouchDB for my data persistence layer
+ As a developer
+ I want to connect to a server
+
+Scenario: Connect to server
+ Given I have a CouchDB instance running at http://127.0.0.1:5984
+ When I call ConnectTo on CouchClient
+ Then the result should be an instance of CouchClient
+ And ServerVersion should not be null or empty

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
@@ -43,6 +43,10 @@
</ItemGroup>
<ItemGroup>
<Compile Include="AssemblyInfo.cs" />
+ <Compile Include="Developer_connects_to_server.feature.cs">
+ <DependentUpon>Developer_connects_to_server.feature</DependentUpon>
+ </Compile>
+ <Compile Include="StepDefinitions\DeveloperConnectsToServerSteps.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
@@ -51,4 +55,13 @@
<Name>SineSignal.Ottoman</Name>
</ProjectReference>
</ItemGroup>
+ <ItemGroup>
+ <None Include="Developer_connects_to_server.feature">
+ <Generator>SpecFlowSingleFileGenerator</Generator>
+ <LastGenOutput>Developer_connects_to_server.feature.cs</LastGenOutput>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <Folder Include="StepDefinitions\" />
+ </ItemGroup>
</Project>
@@ -0,0 +1,41 @@
+using System;
+
+using NUnit.Framework;
+using NUnit.Framework.SyntaxHelpers;
+using TechTalk.SpecFlow;
+
+using SineSignal.Ottoman;
+
+namespace SineSignal.Ottoman.AcceptanceSpecs
+{
+ [Binding]
+ public class DeveloperConnectsToServerSteps
+ {
+ private string address;
+ private CouchClient couchClient;
+
+ [Given("I have a CouchDB instance running at http://127.0.0.1:5984")]
+ public void GivenIHaveACouchDBInstanceRunningAtHttp127_0_0_15984()
+ {
+ address = "http://127.0.0.1:5984";
+ }
+
+ [When("I call ConnectTo on CouchClient")]
+ public void WhenICallConnectToOnCouchClient()
+ {
+ couchClient = CouchClient.ConnectTo(address);
+ }
+
+ [Then("the result should be an instance of CouchClient")]
+ public void ThenTheResultShouldBeAnInstanceOfCouchClient()
+ {
+ Assert.That(couchClient, Is.Not.Null);
+ }
+
+ [Then("ServerVersion should not be null or empty")]
+ public void ThenServerVersionShouldNotBeNullOrEmpty()
+ {
+ Assert.That(String.IsNullOrEmpty(couchClient.ServerVersion), Is.False);
+ }
+ }
+}
@@ -103,5 +103,92 @@ public void Should_return_rest_response_generated_from_http_response()
Assert.That(restResponse.ContentDeserialized, Is.EqualTo(contentDeserialized));
}
}
+
+ public class When_processing_a_get_request : ConcernFor<RestClient>
+ {
+ private Uri baseUri;
+ private IHttpClient httpClient;
+ private RestRequest restRequest;
+ private RestResponse<ResultStub> restResponse;
+ private ISerializer serializer;
+ private string requestContent;
+ private string requestContentType;
+ private string responseContent;
+ private ResultStub contentDeserialized;
+ private string responseContentType;
+
+ protected override void Given()
+ {
+ baseUri = new Uri("http://127.0.0.1:5984");
+ restRequest = new RestRequest { Path = "some/path", Method = HttpMethod.Get, Payload = null };
+ requestContent = "";
+ requestContentType = "";
+ responseContent = "{\"status\":\"completed\"}";
+ responseContentType = "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 = responseContentType,
+ 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_not_call_serialize_on_serializer_with_the_payload()
+ {
+ serializer.DidNotReceive().Serialize(null);
+ }
+
+ [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 == responseContentType &&
+ h.Method == restRequest.Method &&
+ h.ContentType == requestContentType &&
+ 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(responseContentType));
+ 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));
+ }
+ }
}
}
@@ -0,0 +1,30 @@
+using System;
+
+using SineSignal.Ottoman.Http;
+using SineSignal.Ottoman.Serialization;
+
+namespace SineSignal.Ottoman.Commands
+{
+ public class ConnectToServerCommand : ICouchCommand
+ {
+ public string Route { get; private set; }
+ public string Operation { get; private set; }
+ public object Message { get; private set; }
+
+ public ConnectToServerCommand()
+ {
+ Route = "/";
+ Operation = HttpMethod.Get;
+ Message = null;
+ }
+ }
+
+ public class ConnectToServerResult
+ {
+ [JsonMember("couchdb")]
+ public string Message { get; set; }
+
+ [JsonMember("version")]
+ public string Version { get; set; }
+ }
+}
@@ -0,0 +1,28 @@
+using System;
+
+using SineSignal.Ottoman.Commands;
+
+namespace SineSignal.Ottoman
+{
+ public class CouchClient
+ {
+ public string ServerVersion { get; private set; }
+
+ private ICouchProxy CouchProxy { get; set; }
+
+ private CouchClient(ICouchProxy couchProxy, string serverVersion)
+ {
+ CouchProxy = couchProxy;
+ ServerVersion = serverVersion;
+ }
+
+ public static CouchClient ConnectTo(string address)
+ {
+ ICouchProxy couchProxy = new CouchProxy(new Uri(address));
+ ICouchCommand couchCommand = new ConnectToServerCommand();
+ ConnectToServerResult couchResult = couchProxy.Execute<ConnectToServerResult>(couchCommand);
+
+ return new CouchClient(couchProxy, couchResult.Version);
+ }
+ }
+}
@@ -1,3 +1,5 @@
+using System;
+
using SineSignal.Ottoman.Commands;
using SineSignal.Ottoman.Http;
@@ -7,6 +9,10 @@ public class CouchProxy : ICouchProxy
{
public IRestClient RestClient { get; private set; }
+ public CouchProxy(Uri serverLocation) : this(new RestClient(serverLocation))
+ {
+ }
+
public CouchProxy(IRestClient restClient)
{
RestClient = restClient;
@@ -12,6 +12,10 @@ public class RestClient : IRestClient
private IHttpClient HttpClient { get; set; }
private ISerializer Serializer { get; set; }
+ public RestClient(Uri baseUri) : this(baseUri, new HttpClient(), new JsonSerializer())
+ {
+ }
+
public RestClient(Uri baseUri, IHttpClient httpClient, ISerializer serializer)
{
_requestUri = new UriBuilder(baseUri);
@@ -32,12 +36,25 @@ private HttpRequest ConverToHttpRequestFrom(RestRequest restRequest)
{
_requestUri.Path = restRequest.Path;
+ string content = String.Empty;
+ string contentType = String.Empty;
+
+ if (restRequest.Method == HttpMethod.Put ||
+ restRequest.Method == HttpMethod.Post)
+ {
+ if (restRequest.Payload != null)
+ {
+ contentType = "application/json";
+ content = Serializer.Serialize(restRequest.Payload);
+ }
+ }
+
return new HttpRequest {
Url = _requestUri.Uri,
Accept = "application/json",
Method = restRequest.Method,
- ContentType = "application/json",
- Content = Serializer.Serialize(restRequest.Payload)
+ ContentType = contentType,
+ Content = content
};
}
@@ -60,6 +60,8 @@
<Compile Include="Serialization\JsonConvert.cs" />
<Compile Include="Serialization\JsonSerializer.cs" />
<Compile Include="Serialization\JsonMemberAttribute.cs" />
+ <Compile Include="CouchClient.cs" />
+ <Compile Include="Commands\ConnectToServerCommand.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="System" />

0 comments on commit cb28cc4

Please sign in to comment.