Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
...
  • 15 commits
  • 27 files changed
  • 0 commit comments
  • 6 contributors
Commits on Nov 09, 2011
Chris The headers set in the EndpointInfo are now passed through to the Api
Added a default User-Agent to allow us to see when this Api Wrapper has been used

Added the ability to specify headers when sending a request.
7fb41b2
Chris Revert "The headers set in the EndpointInfo are now passed through to…
… the Api"

This reverts commit 7fb41b2.
7d875c5
Chris Added default user-agent e1ab9c9
Commits on Nov 15, 2011
@raoulmillais raoulmillais Add schema mapping for territores API and extension for ipAddress par…
…ameter
6b7de86
Commits on Nov 24, 2011
Antony Denyer added string for endpoiint info 2a356f9
Commits on Dec 16, 2011
Antony Denyer added ability to specify route parameters in endpoint info 6c8a8e9
Antony Denyer remove query params that match slug be0fc96
Commits on Feb 03, 2012
philbo change to Idictionary ba1aa68
Commits on Feb 07, 2012
Henry Oswald fixed up int test that was breaking because data came back in differe…
…nt order
a689187
Commits on Mar 03, 2012
@gregsochanik BREAKING CHANGE - IUrlResolver methods now take a string instead of a…
… Uri
c737a23
@gregsochanik Added uriencoding option to the Dictionary to QueryString extension m…
…ethod
aced966
@gregsochanik CHanged EndpointResolver so that all querystring parameter values are…
… uriencoded by default before being sent to the api - with corresponding test
4e1090e
Commits on Mar 04, 2012
@gregsochanik BREAKING CHANGE - IUrlResolver methods now take a string instead of a…
… Uri

Added uriencoding option to the Dictionary to QueryString extension method

CHanged EndpointResolver so that all querystring parameter values are uriencoded by default before being sent to the api - with corresponding test
2374369
@gregsochanik Merge branch 'trunk' of github.com:7digital/SevenDigital.Api.Wrapper …
…into trunk
113965f
@gregsochanik Merge in pull request from Featurist 261fed9
Showing with 458 additions and 175 deletions.
  1. +40 −36 src/SevenDigital.Api.Dynamic.Integration.Tests/DynamicXmlParserTests.cs
  2. +10 −7 src/SevenDigital.Api.Dynamic/DynamicXmlParser.cs
  3. +6 −0 src/SevenDigital.Api.Schema/ParameterDefinitions/Get/HasIpAddressParameter.cs
  4. +2 −0  src/SevenDigital.Api.Schema/SevenDigital.Api.Schema.csproj
  5. +17 −0 src/SevenDigital.Api.Schema/Territories/GeoIpLookup.cs
  6. +3 −0  src/SevenDigital.Api.Wrapper.ExampleUsage/SevenDigital.Api.Wrapper.ExampleUsage.csproj
  7. +1 −1  src/SevenDigital.Api.Wrapper.Integration.Tests/App.config
  8. +0 −2  src/SevenDigital.Api.Wrapper.Integration.Tests/EndpointTests/ReleaseEndpoint/ReleaseSearchTests.cs
  9. +24 −0 src/SevenDigital.Api.Wrapper.Integration.Tests/EndpointTests/TerritoriesEndpoint/TerritoriesEndpointTests.cs
  10. +1 −0  src/SevenDigital.Api.Wrapper.Integration.Tests/SevenDigital.Api.Wrapper.Integration.Tests.csproj
  11. +121 −0 src/SevenDigital.Api.Wrapper.Unit.Tests/EndpointResolution/EndpointResolverTests.cs
  12. +4 −2 src/SevenDigital.Api.Wrapper.Unit.Tests/FluentAPITests.cs
  13. +1 −0  src/SevenDigital.Api.Wrapper.Unit.Tests/SevenDigital.Api.Wrapper.Unit.Tests.csproj
  14. +33 −17 src/SevenDigital.Api.Wrapper.Unit.Tests/Utility/Http/DictionaryExtensionsTests.cs
  15. +32 −11 src/SevenDigital.Api.Wrapper.Unit.Tests/Utility/Http/EndpointResolverTests.cs
  16. +1 −1  src/SevenDigital.Api.Wrapper.Unit.Tests/Utility/Http/HttpGetResolverTests.cs
  17. +17 −3 src/SevenDigital.Api.Wrapper/EndpointResolution/DictionaryExtensions.cs
  18. +26 −11 src/SevenDigital.Api.Wrapper/EndpointResolution/EndpointResolver.cs
  19. +13 −0 src/SevenDigital.Api.Wrapper/Extensions/HasIpAddressParameter.cs
  20. +11 −11 src/SevenDigital.Api.Wrapper/Extensions/HasKeyParameterExtensions.cs
  21. +39 −17 src/SevenDigital.Api.Wrapper/FluentApi.cs
  22. +1 −0  src/SevenDigital.Api.Wrapper/IFluentApi.cs
  23. +1 −0  src/SevenDigital.Api.Wrapper/SevenDigital.Api.Wrapper.csproj
  24. +6 −6 src/SevenDigital.Api.Wrapper/Utility/Http/HttpGetResolver.cs
  25. +43 −45 src/SevenDigital.Api.Wrapper/Utility/Http/HttpPostResolver.cs
  26. +2 −2 src/SevenDigital.Api.Wrapper/Utility/Http/IUrlResolver.cs
  27. +3 −3 src/WP7/SevenDigital.Api.Wrapper/Utility/Http/HttpGetResolver.cs
View
76 src/SevenDigital.Api.Dynamic.Integration.Tests/DynamicXmlParserTests.cs
@@ -1,18 +1,20 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
+using System.Linq;
using System.Xml.Linq;
using NUnit.Framework;
using SevenDigital.Api.Wrapper;
-using SevenDigital.Api.Wrapper.EndpointResolution;
-using SevenDigital.Api.Wrapper.EndpointResolution.OAuth;
-using SevenDigital.Api.Wrapper.Utility.Http;
-
-namespace SevenDigital.Api.Dynamic.Integration.Tests {
- [TestFixture]
- public class DynamicXmlParserTests {
- private EndpointResolver _endpointResolver;
-
- [SetUp]
- public void SetUp() {
+using SevenDigital.Api.Wrapper.EndpointResolution;
+using SevenDigital.Api.Wrapper.EndpointResolution.OAuth;
+using SevenDigital.Api.Wrapper.Utility.Http;
+
+namespace SevenDigital.Api.Dynamic.Integration.Tests {
+ [TestFixture]
+ public class DynamicXmlParserTests {
+ private EndpointResolver _endpointResolver;
+
+ [SetUp]
+ public void SetUp() {
IOAuthCredentials oAuthCredentials = EssentialDependencyCheck<IOAuthCredentials>.Instance;
IApiUri apiUri = EssentialDependencyCheck<IApiUri>.Instance;
var httpGetResolver = new HttpGetResolver();
@@ -22,39 +24,41 @@ public class DynamicXmlParserTests {
}
[Test]
- public void Can_get_an_artist() {
- const string endpoint = "artist/details";
-
+ public void Can_get_an_artist() {
+ const string endpoint = "artist/details";
+
var endPointInfo = new EndPointInfo { Uri = endpoint, Parameters = new Dictionary<string,string> { { "artistId", "1" } } };
-
+
string xml = _endpointResolver.HitEndpoint(endPointInfo);
- dynamic dx = new DynamicXmlParser(XDocument.Parse(xml));
-
+ dynamic dx = new DynamicXmlParser(XDocument.Parse(xml));
+
var name = dx.artist[0].name.value;
var sortName = dx.artist[0].sortName.value;
- var url = dx.artist[0].url.value;
-
- Assert.That(name, Is.EqualTo("Keane"));
- Assert.That(sortName, Is.EqualTo("Keane"));
- Assert.That(url, Is.StringStarting("http://www.7digital.com/artists/keane/"));
- }
-
+ var url = dx.artist[0].url.value;
+
+ Assert.That(name, Is.EqualTo("Keane"));
+ Assert.That(sortName, Is.EqualTo("Keane"));
+ Assert.That(url, Is.StringStarting("http://www.7digital.com/artists/keane/"));
+ }
+
[Test]
- public void Can_get_an_artists_releases() {
- const string endpoint = "artist/releases";
-
+ public void Can_get_an_artists_releases() {
+ const string endpoint = "artist/releases";
+
var endPointInfo = new EndPointInfo { Uri = endpoint, Parameters = new Dictionary<string,string> { { "artistId", "1" } } };
-
+
string xml = _endpointResolver.HitEndpoint(endPointInfo);
dynamic dx = new DynamicXmlParser(XDocument.Parse(xml));
- var name = dx.releases.release[0].title.value;
- var secondName = dx.releases.release[1].title.value;
+ string [] titles = Enumerable.ToArray(Enumerable.Select<dynamic, string>(dx.releases.release, (Func<dynamic, string>) (r => r.title.value)));
+
+ foreach (var title in titles) {
+ Console.WriteLine(title);
+ }
- Assert.That(name, Is.EqualTo("Night Train"));
- Assert.That(secondName, Is.EqualTo("A Bad Dream"));
- }
- }
-}
+ Assert.That(titles, Has.Member("Night Train").And.Member("Perfect Symmetry"));
+ }
+ }
+}
View
17 src/SevenDigital.Api.Dynamic/DynamicXmlParser.cs
@@ -6,8 +6,8 @@
namespace SevenDigital.Api.Dynamic
{
- public class DynamicXmlParser : DynamicObject, IEnumerable
- {
+ public class DynamicXmlParser : DynamicObject, IEnumerable, IEnumerable<object>
+ {
private readonly List<XElement> _elements;
public DynamicXmlParser(XDocument doc)
@@ -57,11 +57,14 @@ public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out ob
var ndx = (int)indexes[0];
result = new DynamicXmlParser(_elements[ndx]);
return true;
- }
-
- public IEnumerator GetEnumerator()
- {
- return _elements.Select(element => new DynamicXmlParser(element)).GetEnumerator();
+ }
+
+ IEnumerator<object> IEnumerable<object>.GetEnumerator() {
+ return _elements.Select(element => new DynamicXmlParser(element)).GetEnumerator();
+ }
+
+ public IEnumerator GetEnumerator() {
+ return ((IEnumerable<object>) this).GetEnumerator();
}
}
}
View
6 src/SevenDigital.Api.Schema/ParameterDefinitions/Get/HasIpAddressParameter.cs
@@ -0,0 +1,6 @@
+namespace SevenDigital.Api.Schema.ParameterDefinitions.Get
+{
+ public interface HasIpAddressParameter
+ {
+ }
+}
View
2  src/SevenDigital.Api.Schema/SevenDigital.Api.Schema.csproj
@@ -52,6 +52,7 @@
<Compile Include="ParameterDefinitions\Get\HasArtistIdParameter.cs" />
<Compile Include="ParameterDefinitions\Get\HasBasketParameter.cs" />
<Compile Include="ParameterDefinitions\Get\HasChartParameter.cs" />
+ <Compile Include="ParameterDefinitions\Get\HasIpAddressParameter.cs" />
<Compile Include="ParameterDefinitions\Get\HasKeyParameter.cs" />
<Compile Include="ParameterDefinitions\Get\HasLetterParameter.cs" />
<Compile Include="ParameterDefinitions\Get\HasPriceParameter.cs" />
@@ -116,6 +117,7 @@
<Compile Include="Tags\TaggedArtists.cs" />
<Compile Include="Tags\TaggedReleases.cs" />
<Compile Include="Tags\Tags.cs" />
+ <Compile Include="Territories\GeoIpLookup.cs" />
<Compile Include="TrackEndpoint\Track.cs" />
<Compile Include="TrackEndpoint\TrackChart.cs" />
<Compile Include="TrackEndpoint\TrackPreview.cs" />
View
17 src/SevenDigital.Api.Schema/Territories/GeoIpLookup.cs
@@ -0,0 +1,17 @@
+using System.Xml.Serialization;
+using SevenDigital.Api.Schema.Attributes;
+using SevenDigital.Api.Schema.ParameterDefinitions.Get;
+
+namespace SevenDigital.Api.Schema.Territories
+{
+ [ApiEndpoint("country/resolve")]
+ [XmlRoot("GeoIpLookup")]
+ public class GeoIpLookup : HasIpAddressParameter
+ {
+ [XmlElement("ipaddress")]
+ public string IpAddress { get; set; }
+
+ [XmlElement("countryCode")]
+ public string CountryCode { get; set; }
+ }
+}
View
3  src/SevenDigital.Api.Wrapper.ExampleUsage/SevenDigital.Api.Wrapper.ExampleUsage.csproj
@@ -50,6 +50,9 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
+ <Reference Include="nunit.framework">
+ <HintPath>..\..\lib\nunit.framework.dll</HintPath>
+ </Reference>
<Reference Include="System" />
<Reference Include="System.configuration" />
<Reference Include="System.Core" />
View
2  src/SevenDigital.Api.Wrapper.Integration.Tests/App.config
@@ -3,7 +3,7 @@
<appSettings>
<add key="Wrapper.ConsumerKey" value="YOUR_KEY_HERE"/>
<add key="Wrapper.ConsumerSecret" value="YOUR_SECRET_HERE"/>
- <add key="Wrapper.BaseUrl" value="http://api.7digital.com/1.2"/>
+ <add key="Wrapper.BaseUrl" value="http://api.7digital.systest/1.2"/>
<!-- NOTE: These will need to be filled in for the 3 legged oauth tests to pass-->
<add key="Integration.Tests.AccessToken" value=""/>
View
2  ...Digital.Api.Wrapper.Integration.Tests/EndpointTests/ReleaseEndpoint/ReleaseSearchTests.cs
@@ -48,7 +48,5 @@ public void Can_get_multiple_results()
Assert.That(artistSearch.Results.Count, Is.GreaterThan(1));
}
-
-
}
}
View
24 ...i.Wrapper.Integration.Tests/EndpointTests/TerritoriesEndpoint/TerritoriesEndpointTests.cs
@@ -0,0 +1,24 @@
+using System.Linq;
+using NUnit.Framework;
+using SevenDigital.Api.Schema.Merchandising;
+using SevenDigital.Api.Schema.Territories;
+
+namespace SevenDigital.Api.Wrapper.Integration.Tests.EndpointTests.TerritoriesEndpoint
+{
+ [TestFixture]
+ public class TerritoriesEndpointTests
+ {
+ [Test, Ignore("In beta testing")]
+ public void Can_hit_fluent_endpoint_for_territories()
+ {
+ var merchList = Api<GeoIpLookup>
+ .Get
+ .WithIpAddress("84.45.95.241")
+ .WithParameter("shopId", "34")
+ .Please();
+
+ Assert.That(merchList, Is.Not.Null);
+ Assert.That(merchList.CountryCode, Is.EqualTo("7"));
+ }
+ }
+}
View
1  ...enDigital.Api.Wrapper.Integration.Tests/SevenDigital.Api.Wrapper.Integration.Tests.csproj
@@ -70,6 +70,7 @@
<Compile Include="EndpointTests\TagsEndpoint\ReleaseTagsTests.cs" />
<Compile Include="EndpointTests\StatusTests.cs" />
<Compile Include="EndpointTests\TagsEndpoint\TagsTests.cs" />
+ <Compile Include="EndpointTests\TerritoriesEndpoint\TerritoriesEndpointTests.cs" />
<Compile Include="EndpointTests\TrackEndpoint\TrackChartTests.cs" />
<Compile Include="EndpointTests\TrackEndpoint\TrackDetailsTests.cs" />
<Compile Include="EndpointTests\TrackEndpoint\TrackPreviewTests.cs" />
View
121 src/SevenDigital.Api.Wrapper.Unit.Tests/EndpointResolution/EndpointResolverTests.cs
@@ -0,0 +1,121 @@
+using System.Collections.Generic;
+using FakeItEasy;
+using NUnit.Framework;
+using SevenDigital.Api.Wrapper.EndpointResolution;
+using SevenDigital.Api.Wrapper.EndpointResolution.OAuth;
+using SevenDigital.Api.Wrapper.Utility.Http;
+
+namespace SevenDigital.Api.Wrapper.Unit.Tests.EndpointResolution
+{
+ [TestFixture]
+ public class EndpointResolverTests
+ {
+ private EndpointResolver _endpointResolver;
+
+ [SetUp]
+ public void Setup()
+ {
+ var urlResolver = A.Fake<IUrlResolver>();
+ A.CallTo(() => urlResolver.Resolve(A<string>.Ignored, A<string>.Ignored, A<Dictionary<string, string>>.Ignored))
+ .Returns(string.Empty);
+
+ var apiUri = A.Fake<IApiUri>();
+ A.CallTo(() => apiUri.Uri)
+ .Returns("http://uri/");
+
+ _endpointResolver = new EndpointResolver(urlResolver, new UrlSigner(), new AppSettingsCredentials(), apiUri);
+ }
+
+ [Test]
+ public void should_substitue_route_parameters()
+ {
+ var endpointInfo = new EndPointInfo
+ {
+ Uri = "something/{route}",
+ Parameters = new Dictionary<string, string>
+ {
+ {"route","routevalue"}
+ }
+ };
+
+ var result = _endpointResolver.ConstructEndpoint(endpointInfo);
+
+ Assert.That(result,Is.StringContaining("something/routevalue"));
+ }
+
+ [Test]
+ public void should_substitue_multiple_route_parameters()
+ {
+ var endpointInfo = new EndPointInfo
+ {
+ Uri = "something/{firstRoute}/{secondRoute}/thrid/{thirdRoute}",
+ Parameters = new Dictionary<string, string>
+ {
+ {"firstRoute" , "firstValue"},
+ {"secondRoute","secondValue"},
+ {"thirdRoute" , "thirdValue"}
+
+ }
+ };
+
+ var result = _endpointResolver.ConstructEndpoint(endpointInfo);
+
+ Assert.That(result, Is.StringContaining("something/firstvalue/secondvalue/thrid/thirdvalue"));
+ }
+
+ [Test]
+ public void routes_should_be_case_insensitive()
+ {
+ var endpointInfo = new EndPointInfo
+ {
+ Uri = "something/{firstRoUte}/{secOndrouTe}/thrid/{tHirdRoute}",
+ Parameters = new Dictionary<string, string>
+ {
+ {"firstRoute" , "firstValue"},
+ {"secondRoute","secondValue"},
+ {"thirdRoute" , "thirdValue"}
+
+ }
+ };
+
+ var result = _endpointResolver.ConstructEndpoint(endpointInfo);
+
+ Assert.That(result, Is.StringContaining("something/firstvalue/secondvalue/thrid/thirdvalue"));
+ }
+
+ [Test]
+ public void should_handle_dashes_and_numbers()
+ {
+ var endpointInfo = new EndPointInfo
+ {
+ Uri = "something/{route-66}",
+ Parameters = new Dictionary<string, string>
+ {
+ {"route-66","routevalue"}
+ }
+ };
+
+ var result = _endpointResolver.ConstructEndpoint(endpointInfo);
+
+ Assert.That(result, Is.StringContaining("something/routevalue"));
+ }
+
+ [Test]
+ public void should_remove_parameters_that_match()
+ {
+ var endpointInfo = new EndPointInfo
+ {
+ Uri = "something/{route-66}",
+ Parameters = new Dictionary<string, string>
+ {
+ {"route-66","routevalue"}
+ }
+ };
+
+ var result = _endpointResolver.ConstructEndpoint(endpointInfo);
+
+ Assert.That(result, Is.Not.StringContaining("route-66=routevalue"));
+ }
+
+ }
+}
View
6 src/SevenDigital.Api.Wrapper.Unit.Tests/FluentAPITests.cs
@@ -1,7 +1,9 @@
using System;
using System.Linq.Expressions;
+using System.Xml.Serialization;
using FakeItEasy;
using NUnit.Framework;
+using SevenDigital.Api.Schema.Attributes;
using SevenDigital.Api.Wrapper.EndpointResolution;
using SevenDigital.Api.Schema;
using System.Threading;
@@ -86,7 +88,8 @@ public void HitEndpointAsync(EndPointInfo endPointInfo, Action<string> payload)
payload(StubPayload);
}
- public string ConstructEndpoint(EndPointInfo endPointInfo) {
+ public string ConstructEndpoint(EndPointInfo endPointInfo)
+ {
throw new NotImplementedException();
}
@@ -94,5 +97,4 @@ public void HitEndpointAsync(EndPointInfo endPointInfo, Action<string> payload)
}
}
-
}
View
1  src/SevenDigital.Api.Wrapper.Unit.Tests/SevenDigital.Api.Wrapper.Unit.Tests.csproj
@@ -53,6 +53,7 @@
<Compile Include="ApiUri.cs" />
<Compile Include="AppSettingsCredentials.cs" />
<Compile Include="BasketEndpoint\BasketEndpointTests.cs" />
+ <Compile Include="EndpointResolution\EndpointResolverTests.cs" />
<Compile Include="EndpointResolution\OAuth\UrlSignerTests.cs" />
<Compile Include="FluentAPITests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
View
50 src/SevenDigital.Api.Wrapper.Unit.Tests/Utility/Http/DictionaryExtensionsTests.cs
@@ -1,18 +1,34 @@
-using System.Collections.Generic;
-using NUnit.Framework;
-using SevenDigital.Api.Wrapper.EndpointResolution;
-
-namespace SevenDigital.Api.Wrapper.Unit.Tests.Utility.Http
-{
- [TestFixture]
- public class DictionaryExtensionsTests
- {
- [Test]
- public void Should_return_correct_nvc_as_querystring()
- {
- var expected = new Dictionary<string,string>(){{"artistId", "1234"},{"country", "GB"}};
- string querystring = expected.ToQueryString();
- Assert.That(querystring, Is.EqualTo("artistId=1234&country=GB"));
- }
- }
+using System.Collections.Generic;
+using NUnit.Framework;
+using SevenDigital.Api.Wrapper.EndpointResolution;
+
+namespace SevenDigital.Api.Wrapper.Unit.Tests.Utility.Http
+{
+ [TestFixture]
+ public class DictionaryExtensionsTests
+ {
+ [Test]
+ public void Should_return_correct_nvc_as_querystring()
+ {
+ var expected = new Dictionary<string,string> { {"artistId", "1234"},{"country", "GB"}};
+ string querystring = expected.ToQueryString();
+ Assert.That(querystring, Is.EqualTo("artistId=1234&country=GB"));
+ }
+
+ [Test]
+ public void Should_urlencode_if_specified_return_correct_nvc_as_querystring()
+ {
+ var expected = new Dictionary<string, string> { { "q", "Alive & Amplified" }, { "country", "GB" } };
+ string querystring = expected.ToQueryString(true);
+ Assert.That(querystring, Is.EqualTo("q=Alive%20%26%20Amplified&country=GB"));
+ }
+
+ [Test]
+ public void Should_not_urlencode_if_specified_return_correct_nvc_as_querystring()
+ {
+ var expected = new Dictionary<string, string> { { "q", "ou est tu" }, { "country", "GB" } };
+ string querystring = expected.ToQueryString();
+ Assert.That(querystring, Is.EqualTo("q=ou est tu&country=GB"));
+ }
+ }
}
View
43 src/SevenDigital.Api.Wrapper.Unit.Tests/Utility/Http/EndpointResolverTests.cs
@@ -31,23 +31,44 @@ public void Setup()
[Test]
public void Should_fire_resolve_with_correct_values()
{
- A.CallTo(() => _urlResolver.Resolve(A<Uri>.Ignored, A<string>.Ignored, A<Dictionary<string, string>>.Ignored))
+ A.CallTo(() => _urlResolver.Resolve(A<string>.Ignored, A<string>.Ignored, A<Dictionary<string, string>>.Ignored))
.Returns(SERVICE_STATUS);
const string expectedMethod = "GET";
var expectedHeaders = new Dictionary<string, string>();
var endPointState = new EndPointInfo { Uri = "test", HttpMethod = expectedMethod, Headers = expectedHeaders };
- var expected = new Uri(string.Format("{0}/test?oauth_consumer_key={1}", API_URL, _consumerKey));
-
- A.CallTo(() => _urlSigner.SignUrl(A<string>.Ignored, A<string>.Ignored, A<string>.Ignored, null)).Returns(expected);
-
+ var expected = string.Format("{0}/test?oauth_consumer_key={1}", API_URL, _consumerKey);
+
_endpointResolver.HitEndpoint(endPointState);
A.CallTo(() => _urlResolver
- .Resolve(A<Uri>.That.Matches(x => x.PathAndQuery == expected.PathAndQuery), expectedMethod, A<Dictionary<string, string>>.Ignored))
+ .Resolve(expected, expectedMethod, A<Dictionary<string, string>>.Ignored))
.MustHaveHappened();
- }
+ }
+
+ [Test]
+ public void Should_fire_resolve_with_url_encoded_parameters()
+ {
+ A.CallTo(() => _urlResolver.Resolve(A<string>.Ignored, A<string>.Ignored, A<Dictionary<string, string>>.Ignored))
+ .Returns(SERVICE_STATUS);
+
+ const string unEncodedParameterValue = "Alive & Amplified";
+ const string expectedParameterValue = "Alive%20%26%20Amplified";
+
+ var expectedHeaders = new Dictionary<string, string>();
+ var testParameters = new Dictionary<string, string> { { "q", unEncodedParameterValue } };
+
+ var endPointState = new EndPointInfo { Uri = "test", HttpMethod = "GET", Headers = expectedHeaders, Parameters = testParameters };
+ var expected = string.Format("{0}/test?oauth_consumer_key={1}&q={2}", API_URL, _consumerKey, expectedParameterValue);
+
+ _endpointResolver.HitEndpoint(endPointState);
+
+ A.CallTo(() => _urlResolver
+ .Resolve(expected, A<string>.Ignored, A<Dictionary<string, string>>.Ignored))
+ .MustHaveHappened();
+ }
+
[Test]
public void Should_return_xmlnode_if_valid_xml_received()
@@ -107,26 +128,26 @@ public void Should_use_api_uri_provided_by_IApiUri_interface()
A.CallTo(() => apiUri.Uri).MustHaveHappened(Repeated.Exactly.Once);
A.CallTo(() => _urlResolver.Resolve(
- A<Uri>.That.Matches(x => x.ToString().Contains(expectedApiUri)),
+ A<string>.That.Matches(x => x.ToString().Contains(expectedApiUri)),
A<string>.Ignored, A<Dictionary<string, string>>.Ignored))
.MustHaveHappened(Repeated.Exactly.Once);
}
private void Given_a_urlresolver_that_returns_valid_xml()
{
- A.CallTo(() => _urlResolver.Resolve(A<Uri>.Ignored, A<string>.Ignored, A<Dictionary<string, string>>.Ignored)).Returns(
+ A.CallTo(() => _urlResolver.Resolve(A<string>.Ignored, A<string>.Ignored, A<Dictionary<string, string>>.Ignored)).Returns(
SERVICE_STATUS);
}
}
public class FakeUrlResolver : IUrlResolver
{
- public string Resolve(Uri endpoint, string method, Dictionary<string, string> headers)
+ public string Resolve(string endpoint, string method, Dictionary<string, string> headers)
{
throw new NotImplementedException();
}
- public void ResolveAsync(Uri endpoint, string method, Dictionary<string, string> headers, Action<string> payload)
+ public void ResolveAsync(string endpoint, string method, Dictionary<string, string> headers, Action<string> payload)
{
payload(StubPayload);
}
View
2  src/SevenDigital.Api.Wrapper.Unit.Tests/Utility/Http/HttpGetResolverTests.cs
@@ -15,7 +15,7 @@ public void Can_resolve_uri()
{
string apiUrl = "http://api.7digital.com/1.2";
string consumerKey = new AppSettingsCredentials().ConsumerKey;
- string resolve = new HttpGetResolver().Resolve(new Uri(string.Format("{0}/status?oauth_consumer_key={1}", apiUrl, consumerKey)), "GET",
+ string resolve = new HttpGetResolver().Resolve(string.Format("{0}/status?oauth_consumer_key={1}", apiUrl, consumerKey), "GET",
new Dictionary<string,string>());
Assert.That(resolve, Is.Not.Empty);
}
View
20 src/SevenDigital.Api.Wrapper/EndpointResolution/DictionaryExtensions.cs
@@ -1,12 +1,12 @@
-using System.Collections.Generic;
-using System.Net;
+using System;
+using System.Collections.Generic;
using System.Text;
namespace SevenDigital.Api.Wrapper.EndpointResolution
{
public static class DictionaryExtensions
{
- public static string ToQueryString(this Dictionary<string,string> collection)
+ public static string ToQueryString(this IDictionary<string,string> collection)
{
var sb = new StringBuilder();
foreach (var key in collection.Keys)
@@ -14,6 +14,20 @@ public static string ToQueryString(this Dictionary<string,string> collection)
sb.AppendFormat("{0}={1}&", key, collection[key]);
}
return sb.ToString().TrimEnd('&');
+ }
+
+ public static string ToQueryString(this IDictionary<string, string> collection, bool shouldUrlEncode)
+ {
+ var sb = new StringBuilder();
+ foreach (var key in collection.Keys)
+ {
+ var parameter = shouldUrlEncode
+ ? Uri.EscapeDataString(collection[key])
+ : collection[key];
+
+ sb.AppendFormat("{0}={1}&", key, parameter);
+ }
+ return sb.ToString().TrimEnd('&');
}
}
}
View
37 src/SevenDigital.Api.Wrapper/EndpointResolution/EndpointResolver.cs
@@ -1,4 +1,6 @@
using System;
+using System.Linq;
+using System.Text.RegularExpressions;
using SevenDigital.Api.Wrapper.EndpointResolution.OAuth;
using SevenDigital.Api.Wrapper.Utility.Http;
using System.Collections.Generic;
@@ -22,22 +24,21 @@ public EndpointResolver(IUrlResolver urlResolver, IUrlSigner urlSigner, IOAuthCr
public virtual string HitEndpoint(EndPointInfo endPointInfo)
{
- Uri signedUrl = GetSignedUrl(endPointInfo);
-
+ var signedUrl = GetSignedUrl(endPointInfo);
return _urlResolver.Resolve(signedUrl, endPointInfo.HttpMethod, new Dictionary<string, string>());
}
public virtual void HitEndpointAsync(EndPointInfo endPointInfo, Action<string> payload)
{
- Uri signedUrl = GetSignedUrl(endPointInfo);
+ var signedUrl = GetSignedUrl(endPointInfo);
_urlResolver.ResolveAsync(signedUrl, endPointInfo.HttpMethod, new Dictionary<string, string>(), payload);
}
public string ConstructEndpoint(EndPointInfo endPointInfo) {
- return GetSignedUrl(endPointInfo).ToString();
+ return GetSignedUrl(endPointInfo);
}
- private Uri GetSignedUrl(EndPointInfo endPointInfo)
+ private string GetSignedUrl(EndPointInfo endPointInfo)
{
string apiUri = _apiUri.Uri;
@@ -45,15 +46,29 @@ private Uri GetSignedUrl(EndPointInfo endPointInfo)
apiUri = apiUri.Replace("http://", "https://");
var uriString = string.Format("{0}/{1}?oauth_consumer_key={2}&{3}",
- apiUri, endPointInfo.Uri,
+ apiUri, SubstituteRouteParameters(endPointInfo.Uri,endPointInfo.Parameters),
_oAuthCredentials.ConsumerKey,
- endPointInfo.Parameters.ToQueryString()).TrimEnd('&');
+ endPointInfo.Parameters.ToQueryString(true)).TrimEnd('&');
+
+ if (endPointInfo.IsSigned)
+ uriString = _urlSigner.SignUrlAsString(uriString, endPointInfo.UserToken, endPointInfo.UserSecret, _oAuthCredentials);
+
+ return uriString;
+ }
- var signedUrl = new Uri(uriString);
+ private static string SubstituteRouteParameters(string endpointUri, Dictionary<string, string> parameters)
+ {
+ var regex = new Regex("{(.*?)}");
+ var result = regex.Matches(endpointUri);
+ foreach (var match in result)
+ {
+ var key = match.ToString().Remove(match.ToString().Length - 1).Remove(0, 1);
+ var entry = parameters.First(x => x.Key.Equals(key, StringComparison.InvariantCultureIgnoreCase));
+ parameters.Remove(entry.Key);
+ endpointUri = endpointUri.Replace(match.ToString(), entry.Value);
+ }
- if (endPointInfo.IsSigned)
- signedUrl = _urlSigner.SignUrl(uriString, endPointInfo.UserToken, endPointInfo.UserSecret, _oAuthCredentials);
- return signedUrl;
+ return endpointUri.ToLower();
}
}
}
View
13 src/SevenDigital.Api.Wrapper/Extensions/HasIpAddressParameter.cs
@@ -0,0 +1,13 @@
+using SevenDigital.Api.Schema.ParameterDefinitions.Get;
+
+namespace SevenDigital.Api.Wrapper
+{
+ public static class HasIpAddressParameterExtensions
+ {
+ public static IFluentApi<T> WithIpAddress<T>(this IFluentApi<T> api, string ipAddress) where T : HasIpAddressParameter
+ {
+ api.WithParameter("ipaddress", ipAddress);
+ return api;
+ }
+ }
+}
View
22 src/SevenDigital.Api.Wrapper/Extensions/HasKeyParameterExtensions.cs
@@ -1,13 +1,13 @@
using SevenDigital.Api.Schema.ParameterDefinitions.Get;
-namespace SevenDigital.Api.Wrapper
-{
- public static class HasKeyParameterExtensions
- {
- public static IFluentApi<T> WithKey<T>(this IFluentApi<T> api, string keyValue) where T : HasKeyParameter
- {
- api.WithParameter("key", keyValue);
- return api;
- }
- }
-}
+namespace SevenDigital.Api.Wrapper
+{
+ public static class HasKeyParameterExtensions
+ {
+ public static IFluentApi<T> WithKey<T>(this IFluentApi<T> api, string keyValue) where T : HasKeyParameter
+ {
+ api.WithParameter("key", keyValue);
+ return api;
+ }
+ }
+}
View
56 src/SevenDigital.Api.Wrapper/FluentApi.cs
@@ -8,13 +8,16 @@
using SevenDigital.Api.Wrapper.Utility.Http;
using SevenDigital.Api.Wrapper.Utility.Serialization;
-namespace SevenDigital.Api.Wrapper {
- public class FluentApi<T> : IFluentApi<T> where T : class {
+namespace SevenDigital.Api.Wrapper
+{
+ public class FluentApi<T> : IFluentApi<T> where T : class
+ {
private readonly EndPointInfo _endPointInfo = new EndPointInfo();
private readonly IEndpointResolver _endpointResolver;
private readonly IDeSerializer<T> _deserializer;
-
- public FluentApi(IEndpointResolver endpointResolver) {
+
+ public FluentApi(IEndpointResolver endpointResolver)
+ {
_endpointResolver = endpointResolver;
_deserializer = new ApiXmlDeSerializer<T>(new ApiResourceDeSerializer<T>(), new XmlErrorHandler());
@@ -45,57 +48,76 @@ public FluentApi()
: this(new EndpointResolver(new HttpGetResolver(), new UrlSigner(), EssentialDependencyCheck<IOAuthCredentials>.Instance, EssentialDependencyCheck<IApiUri>.Instance)) { }
- public IFluentApi<T> WithEndpoint(string endpoint) {
+ public IFluentApi<T> WithEndpoint(string endpoint)
+ {
_endPointInfo.Uri = endpoint;
return this;
}
- public virtual IFluentApi<T> WithMethod(string methodName) {
+ public virtual IFluentApi<T> WithMethod(string methodName)
+ {
_endPointInfo.HttpMethod = methodName;
return this;
}
- public virtual IFluentApi<T> WithParameter(string parameterName, string parameterValue) {
+ public virtual IFluentApi<T> WithParameter(string parameterName, string parameterValue)
+ {
_endPointInfo.Parameters[parameterName] = parameterValue;
return this;
}
- public virtual IFluentApi<T> ClearParameters() {
+ public virtual IFluentApi<T> ClearParameters()
+ {
_endPointInfo.Parameters.Clear();
return this;
}
- public virtual IFluentApi<T> ForUser(string token, string secret) {
+ public virtual IFluentApi<T> ForUser(string token, string secret)
+ {
_endPointInfo.UserToken = token;
_endPointInfo.UserSecret = secret;
return this;
}
- public virtual IFluentApi<T> ForShop(int shopId) {
+ public virtual IFluentApi<T> ForShop(int shopId)
+ {
WithParameter("shopId", shopId.ToString());
return this;
}
- public virtual T Please() {
- try {
+ public virtual T Please()
+ {
+ try
+ {
var output = _endpointResolver.HitEndpoint(_endPointInfo);
return _deserializer.DeSerialize(output);
- } catch (ApiXmlException apiXmlException) {
+ }
+ catch (ApiXmlException apiXmlException)
+ {
apiXmlException.Uri = _endPointInfo.Uri;
throw;
}
}
- public virtual void PleaseAsync(Action<T> callback) {
+ public virtual string EndpointUrl
+ {
+ get { return _endpointResolver.ConstructEndpoint(_endPointInfo); }
+ }
+
+ public virtual void PleaseAsync(Action<T> callback)
+ {
_endpointResolver.HitEndpointAsync(_endPointInfo, PleaseAsyncEnd(callback));
}
- public string GetCurrentUri() {
+ public string GetCurrentUri()
+ {
return _endpointResolver.ConstructEndpoint(_endPointInfo);
}
- internal Action<string> PleaseAsyncEnd(Action<T> callback) {
- return output => {
+ internal Action<string> PleaseAsyncEnd(Action<T> callback)
+ {
+ return output =>
+ {
T entity = _deserializer.DeSerialize(output);
callback(entity);
};
View
1  src/SevenDigital.Api.Wrapper/IFluentApi.cs
@@ -10,6 +10,7 @@ public interface IFluentApi<T>
IFluentApi<T> ClearParameters();
IFluentApi<T> ForUser(string token, string secret);
IFluentApi<T> WithEndpoint(string endpoint);
+ string EndpointUrl { get; }
T Please();
void PleaseAsync(Action<T> callback);
View
1  src/SevenDigital.Api.Wrapper/SevenDigital.Api.Wrapper.csproj
@@ -43,6 +43,7 @@
<Compile Include="EndpointResolution\AppDomainAssemblyResolver.cs" />
<Compile Include="EndpointResolution\EssentialDependencyCheck.cs" />
<Compile Include="Exceptions\MissingDependencyException.cs" />
+ <Compile Include="Extensions\HasIpAddressParameter.cs" />
<Compile Include="Extensions\HasPurchaseIdParameterExtensions.cs" />
<Compile Include="Extensions\HasArtistIdParameterExtensions.cs" />
<Compile Include="Extensions\HasBasketParameterExtensions.cs" />
View
12 src/SevenDigital.Api.Wrapper/Utility/Http/HttpGetResolver.cs
@@ -7,11 +7,11 @@ namespace SevenDigital.Api.Wrapper.Utility.Http
{
public class HttpGetResolver : IUrlResolver
{
-
- public string Resolve(Uri endpoint, string method, Dictionary<string,string> headers)
+ public string Resolve(string endpoint, string method, Dictionary<string,string> headers)
{
- var webRequest = (HttpWebRequest)WebRequest.Create(endpoint.OriginalString);
- webRequest.Method = method;
+ var webRequest = (HttpWebRequest)WebRequest.Create(endpoint);
+ webRequest.Method = method;
+ webRequest.UserAgent = "7digital .Net Api Wrapper";
foreach (var header in headers)
{
@@ -35,11 +35,11 @@ public string Resolve(Uri endpoint, string method, Dictionary<string,string> hea
return output;
}
- public void ResolveAsync(Uri endpoint, string method, Dictionary<string, string> headers, Action<string> payload)
+ public void ResolveAsync(string endpoint, string method, Dictionary<string, string> headers, Action<string> payload)
{
var client = new WebClient();
client.DownloadDataCompleted += (s, e) => payload(System.Text.Encoding.UTF8.GetString(e.Result));
- client.DownloadDataAsync(endpoint);
+ client.DownloadDataAsync(new Uri(endpoint));
}
}
}
View
88 src/SevenDigital.Api.Wrapper/Utility/Http/HttpPostResolver.cs
@@ -1,51 +1,49 @@
-using System;
+using System;
using System.Collections.Generic;
-using System.ComponentModel;
-using System.Net;
-using System.Text;
-
-namespace SevenDigital.Api.Wrapper.Utility.Http
-{
- public class HttpPostResolver : IUrlResolver
- {
- private readonly IWebClientFactory _webClientFactory;
- private string _parametersAsString = string.Empty;
-
- public string ParametersAsString
- {
- get { return _parametersAsString; }
- set { _parametersAsString = value; }
- }
-
- public HttpPostResolver(IWebClientFactory webClientFactory)
- {
- _webClientFactory = webClientFactory;
- }
- public HttpPostResolver(IWebClientFactory webClientFactory, string parametersAsString)
- {
- _webClientFactory = webClientFactory;
- ParametersAsString = parametersAsString;
- }
-
- public string Resolve(Uri endpoint, string method, Dictionary<string, string> headers)
- {
- using (var webClientWrapper = _webClientFactory.GetWebClient())
- {
-
- webClientWrapper.Encoding = Encoding.UTF8;
- webClientWrapper.Headers = new WebHeaderCollection();
-
- return webClientWrapper.UploadString(endpoint.OriginalString, method, ParametersAsString);
- }
- }
-
-
- public void ResolveAsync(Uri endpoint, string method, Dictionary<string, string> headers, Action<string> payload)
+using System.Net;
+using System.Text;
+
+namespace SevenDigital.Api.Wrapper.Utility.Http
+{
+ public class HttpPostResolver : IUrlResolver
+ {
+ private readonly IWebClientFactory _webClientFactory;
+ private string _parametersAsString = string.Empty;
+
+ public string ParametersAsString
+ {
+ get { return _parametersAsString; }
+ set { _parametersAsString = value; }
+ }
+
+ public HttpPostResolver(IWebClientFactory webClientFactory)
+ {
+ _webClientFactory = webClientFactory;
+ }
+ public HttpPostResolver(IWebClientFactory webClientFactory, string parametersAsString)
+ {
+ _webClientFactory = webClientFactory;
+ ParametersAsString = parametersAsString;
+ }
+
+ public string Resolve(string endpoint, string method, Dictionary<string, string> headers)
+ {
+ using (var webClientWrapper = _webClientFactory.GetWebClient())
+ {
+ webClientWrapper.Encoding = Encoding.UTF8;
+ webClientWrapper.Headers = new WebHeaderCollection();
+ webClientWrapper.Headers[HttpRequestHeader.UserAgent] = "7digital .Net Api Wrapper";
+
+ return webClientWrapper.UploadString(endpoint, method, ParametersAsString);
+ }
+ }
+
+ public void ResolveAsync(string endpoint, string method, Dictionary<string, string> headers, Action<string> payload)
{
throw new NotImplementedException();
//var client = new WebClient();
//client.UploadDataCompleted += (s, e) => payload(Encoding.UTF8.GetString(e.Result));
- //client.UploadDataAsync(endpoint, Encoding.UTF8.GetBytes(ParametersAsString));
- }
- }
+ //client.UploadDataAsync(endpoint, Encoding.UTF8.GetBytes(ParametersAsString));
+ }
+ }
}
View
4 src/SevenDigital.Api.Wrapper/Utility/Http/IUrlResolver.cs
@@ -4,7 +4,7 @@
namespace SevenDigital.Api.Wrapper.Utility.Http
{
public interface IUrlResolver{
- string Resolve(Uri endpoint, string method, Dictionary<string,string> headers);
- void ResolveAsync(Uri endpoint, string method, Dictionary<string, string> headers, Action<string> payload);
+ string Resolve(string endpoint, string method, Dictionary<string,string> headers);
+ void ResolveAsync(string endpoint, string method, Dictionary<string, string> headers, Action<string> payload);
}
}
View
6 src/WP7/SevenDigital.Api.Wrapper/Utility/Http/HttpGetResolver.cs
@@ -7,16 +7,16 @@ namespace SevenDigital.Api.Wrapper.Utility.Http
{
public class HttpGetResolver : IUrlResolver
{
- public string Resolve(Uri endpoint, string method, Dictionary<string,string> headers)
+ public string Resolve(string endpoint, string method, Dictionary<string,string> headers)
{
throw new NotSupportedException("Need to use async in windows mobile");
}
- public void ResolveAsync(Uri endpoint, string method, Dictionary<string, string> headers, Action<string> payload)
+ public void ResolveAsync(string endpoint, string method, Dictionary<string, string> headers, Action<string> payload)
{
var client = new WebClient();
client.DownloadStringCompleted += (s, e) => payload(e.Result);
- client.DownloadStringAsync(endpoint);
+ client.DownloadStringAsync(new Uri(endpoint));
}
}
}

No commit comments for this range

Something went wrong with that request. Please try again.