From 022d8b683e5e5d021f3ea8d68bdc0107c700952c Mon Sep 17 00:00:00 2001 From: Tommy Parnell Date: Mon, 11 May 2015 18:55:31 -0400 Subject: [PATCH] stopping for now --- .gitignore | 2 + .../TestAuthenticatedUntappdCredentials.cs | 2 +- .../Request/TestRepository.cs | 31 +++++-- .../Authentication/AuthenticationHelper.cs | 6 +- .../Client/AuthenticatedUntappdCredentials.cs | 10 ++- .../IAuthenticatedUntappdCredentials.cs | 1 - src/Untappd.Net/Client/IUntappdCredentials.cs | 8 +- .../UnAuthenticatedUntappdCredentials.cs | 21 ++++- src/Untappd.Net/Client/UntappdCredentials.cs | 28 +----- .../Exception/HttpErrorException.cs | 38 ++++++++ src/Untappd.Net/Request/Repository.cs | 90 +++++++++++++++---- src/Untappd.Net/Request/RepositoryGet.cs | 30 ++++--- src/Untappd.Net/Request/RepositoryPost.cs | 8 +- src/Untappd.Net/Untappd.Net.csproj | 1 + 14 files changed, 191 insertions(+), 85 deletions(-) create mode 100644 src/Untappd.Net/Exception/HttpErrorException.cs diff --git a/.gitignore b/.gitignore index ff13331..cee0cb8 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,8 @@ *.userprefs **/.settings +NDependOut +*.ndproj # Build results [Dd]ebug/ [Dd]ebugPublic/ diff --git a/src/Untappd.Net.UnitTests/Client/TestAuthenticatedUntappdCredentials.cs b/src/Untappd.Net.UnitTests/Client/TestAuthenticatedUntappdCredentials.cs index 9209952..5e6ed50 100644 --- a/src/Untappd.Net.UnitTests/Client/TestAuthenticatedUntappdCredentials.cs +++ b/src/Untappd.Net.UnitTests/Client/TestAuthenticatedUntappdCredentials.cs @@ -21,7 +21,7 @@ namespace Untappd.Net.UnitTests.Client Assert.AreEqual(token, "awesome"); token = "newString"; //Make sure the reference is not copied over - Assert.AreEqual("awesome", t.AccessToken); + Assert.AreEqual("awesome", t.AuthenticationData["access_token"]); } } } diff --git a/src/Untappd.Net.UnitTests/Request/TestRepository.cs b/src/Untappd.Net.UnitTests/Request/TestRepository.cs index 585acb6..e976997 100644 --- a/src/Untappd.Net.UnitTests/Request/TestRepository.cs +++ b/src/Untappd.Net.UnitTests/Request/TestRepository.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Threading.Tasks; using Moq; using Newtonsoft.Json; @@ -19,8 +20,11 @@ namespace Untappd.Net.UnitTests.Request public void ConfirmRequestWorks() { var mockCreds = new Mock(); - mockCreds.Setup(a => a.ClientId).Returns("id"); - mockCreds.Setup(a => a.ClientSecret).Returns("secret"); + mockCreds.Setup(a => a.AuthenticationData).Returns(new ReadOnlyDictionary(new Dictionary() + { + {"client_id", "id"}, + {"client_secret", "secret"} + })); var bodyParam = new Dictionary {{"key", "value"}}; var client = new Mock(); var request = new Mock(); @@ -38,16 +42,19 @@ namespace Untappd.Net.UnitTests.Request var repository = new Repository(client.Object, request.Object); repository.Get(mockCreds.Object, "awesome", bodyParam); - request.Verify(a => a.AddParameter("client_id", mockCreds.Object.ClientId)); - request.Verify(a => a.AddParameter("client_secret", mockCreds.Object.ClientSecret)); + request.Verify(a => a.AddParameter("client_id", mockCreds.Object.AuthenticationData["client_id"])); + request.Verify(a => a.AddParameter("client_secret", mockCreds.Object.AuthenticationData["client_secret"])); request.Verify(a => a.AddParameter("key", "value")); repository.GetAsync(mockCreds.Object, "awesome", bodyParam).Wait(); - request.Verify(a => a.AddParameter("client_id", mockCreds.Object.ClientId)); - request.Verify(a => a.AddParameter("client_secret", mockCreds.Object.ClientSecret)); + request.Verify(a => a.AddParameter("client_id", mockCreds.Object.AuthenticationData["client_id"])); + request.Verify(a => a.AddParameter("client_secret", mockCreds.Object.AuthenticationData["client_secret"])); request.Verify(a => a.AddParameter("key", "value")); var mockAuthCreds = new Mock(); - mockAuthCreds.Setup(a => a.AccessToken).Returns("accessToken"); + mockAuthCreds.Setup(a => a.AuthenticationData).Returns(new ReadOnlyDictionary(new Dictionary() + { + {"access_token", "accessToken"} + })); repository.Get(mockAuthCreds.Object, "awesome", bodyParam); request.Verify(a => a.AddParameter("key", "value")); @@ -56,12 +63,18 @@ namespace Untappd.Net.UnitTests.Request request.Verify(a => a.AddParameter("key", "value")); request.Verify(a => a.AddParameter("access_token", "accessToken")); - mockAuthCreds.Setup(a => a.AccessToken).Returns("PostaccessToken"); + mockAuthCreds.Setup(a => a.AuthenticationData).Returns(new ReadOnlyDictionary(new Dictionary() + { + {"access_token", "PostaccessToken"} + })); var checkin = new CheckIn("-5", "EST", 1044097) { Shout = "Awesome Brew", Rating = 4 }; repository.Post(mockAuthCreds.Object, checkin); request.Verify(a => a.AddParameter("access_token", "PostaccessToken")); - mockAuthCreds.Setup(a => a.AccessToken).Returns("PostAsyncaccessToken"); + mockAuthCreds.Setup(a => a.AuthenticationData).Returns(new ReadOnlyDictionary(new Dictionary() + { + {"access_token", "PostAsyncaccessToken"} + })); repository.PostAsync(mockAuthCreds.Object, checkin).Wait(); request.Verify(a => a.AddParameter("access_token", "PostAsyncaccessToken")); } diff --git a/src/Untappd.Net/Authentication/AuthenticationHelper.cs b/src/Untappd.Net/Authentication/AuthenticationHelper.cs index ddb9226..4b4aa30 100644 --- a/src/Untappd.Net/Authentication/AuthenticationHelper.cs +++ b/src/Untappd.Net/Authentication/AuthenticationHelper.cs @@ -24,7 +24,7 @@ namespace Untappd.Net.Authentication } return string.Format("{0}/?client_id={1}&response_type=code&redirect_url={2}", Constants.BaseRequestString, - credentials.ClientId, redirectUrl); + credentials.AuthenticationData["client_id"], redirectUrl); } /// @@ -51,8 +51,8 @@ namespace Untappd.Net.Authentication } return string.Format("{0}/?client_id={1}&client_secret={2}&response_type=code&redirect_url={3}&code={4}", Constants.OAuthTokenEndPoint, - credentials.ClientId, - credentials.ClientSecret, + credentials.AuthenticationData["client_id"], + credentials.AuthenticationData["client_secret"], redirectUrl, code); } diff --git a/src/Untappd.Net/Client/AuthenticatedUntappdCredentials.cs b/src/Untappd.Net/Client/AuthenticatedUntappdCredentials.cs index 4a0eb55..9970162 100644 --- a/src/Untappd.Net/Client/AuthenticatedUntappdCredentials.cs +++ b/src/Untappd.Net/Client/AuthenticatedUntappdCredentials.cs @@ -1,23 +1,25 @@ using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; namespace Untappd.Net.Client { public class AuthenticatedUntappdCredentials : UntappdCredentials, IAuthenticatedUntappdCredentials { - public string AccessToken { get; private set; } /// /// Pass your authenticated access token /// /// - /// - /// public AuthenticatedUntappdCredentials(string accessToken) { if (string.IsNullOrWhiteSpace(accessToken)) { throw new ArgumentNullException("accessToken"); } - AccessToken = string.Copy(accessToken); + AuthenticationData = new ReadOnlyDictionary(new Dictionary() + { + {"access_token", accessToken} + }); } } } diff --git a/src/Untappd.Net/Client/IAuthenticatedUntappdCredentials.cs b/src/Untappd.Net/Client/IAuthenticatedUntappdCredentials.cs index 629bec2..2b55242 100644 --- a/src/Untappd.Net/Client/IAuthenticatedUntappdCredentials.cs +++ b/src/Untappd.Net/Client/IAuthenticatedUntappdCredentials.cs @@ -2,6 +2,5 @@ { public interface IAuthenticatedUntappdCredentials : IUntappdCredentials { - string AccessToken { get; } } } diff --git a/src/Untappd.Net/Client/IUntappdCredentials.cs b/src/Untappd.Net/Client/IUntappdCredentials.cs index dad9dba..9f2ebf7 100644 --- a/src/Untappd.Net/Client/IUntappdCredentials.cs +++ b/src/Untappd.Net/Client/IUntappdCredentials.cs @@ -1,8 +1,10 @@ -namespace Untappd.Net.Client +using System.Collections; +using System.Collections.Generic; + +namespace Untappd.Net.Client { public interface IUntappdCredentials { - string ClientId { get; } - string ClientSecret { get; } + IReadOnlyDictionary AuthenticationData { get; } } } diff --git a/src/Untappd.Net/Client/UnAuthenticatedUntappdCredentials.cs b/src/Untappd.Net/Client/UnAuthenticatedUntappdCredentials.cs index 39f4b68..78f0b29 100644 --- a/src/Untappd.Net/Client/UnAuthenticatedUntappdCredentials.cs +++ b/src/Untappd.Net/Client/UnAuthenticatedUntappdCredentials.cs @@ -1,4 +1,8 @@ -namespace Untappd.Net.Client +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; + +namespace Untappd.Net.Client { public class UnAuthenticatedUntappdCredentials : UntappdCredentials, IUnAuthenticatedUntappdCredentials { @@ -8,8 +12,19 @@ /// /// public UnAuthenticatedUntappdCredentials(string clientId, string clientSecret) - : base(clientId, clientSecret) - { + { + if (string.IsNullOrWhiteSpace(clientId)) + { + throw new ArgumentNullException("clientId"); + } + if (string.IsNullOrWhiteSpace(clientSecret)) + { + throw new ArgumentNullException("clientSecret"); + } + AuthenticationData = new ReadOnlyDictionary(new Dictionary() + { + {"client_id", clientId}, {"client_secret", clientSecret} + }); } } } diff --git a/src/Untappd.Net/Client/UntappdCredentials.cs b/src/Untappd.Net/Client/UntappdCredentials.cs index 73b6a73..15c10ee 100644 --- a/src/Untappd.Net/Client/UntappdCredentials.cs +++ b/src/Untappd.Net/Client/UntappdCredentials.cs @@ -1,33 +1,11 @@ using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; namespace Untappd.Net.Client { public abstract class UntappdCredentials : IUntappdCredentials { - public string ClientId { get; private set; } - public string ClientSecret { get; private set; } - - protected UntappdCredentials() - { - } - - /// - /// UnAuthenticated request. Pass your API id and secret - /// - /// - /// - protected UntappdCredentials(string clientId, string clientSecret) - { - if (string.IsNullOrWhiteSpace(clientId)) - { - throw new ArgumentNullException("clientId"); - } - if (string.IsNullOrWhiteSpace(clientSecret)) - { - throw new ArgumentNullException("clientSecret"); - } - ClientId = string.Copy(clientId); - ClientSecret = string.Copy(clientSecret); - } + public IReadOnlyDictionary AuthenticationData { get; protected set; } } } diff --git a/src/Untappd.Net/Exception/HttpErrorException.cs b/src/Untappd.Net/Exception/HttpErrorException.cs new file mode 100644 index 0000000..90d1cb2 --- /dev/null +++ b/src/Untappd.Net/Exception/HttpErrorException.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json; +using RestSharp; + +namespace Untappd.Net.Exception +{ + public sealed class HttpErrorException : BaseUntappdException + { + public override string Message + { + get + { + return _message; + } + } + + private readonly string _message; + public HttpErrorException(IRestRequest request, IRestResponse response) + { + var code = (int) response.StatusCode; + if (code == 200) + { + throw new BaseUntappdException( + "HttpError is being throw with a 200 error. Something has gone horribly wrong"); + } + + _message = string.Format("HttpError {0} was returned with Message: {1}{2}", code, Environment.NewLine, + response.ErrorMessage); + Data.Add("Request Object", JsonConvert.SerializeObject(request)); + Data.Add("Response Object", JsonConvert.SerializeObject(response)); + } + } +} diff --git a/src/Untappd.Net/Request/Repository.cs b/src/Untappd.Net/Request/Repository.cs index a6f7781..6687c21 100644 --- a/src/Untappd.Net/Request/Repository.cs +++ b/src/Untappd.Net/Request/Repository.cs @@ -1,8 +1,12 @@ using System.Collections.Generic; +using System.Net; using System.Threading.Tasks; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using RestSharp; using Untappd.Net.Client; +using Untappd.Net.Exception; +using System; namespace Untappd.Net.Request { @@ -10,57 +14,105 @@ namespace Untappd.Net.Request { internal IRestClient Client; internal IRestRequest Request; + private bool FailFast { get; set; } + /// + /// Event to listen to when failFast is set to false + /// This allows you to capture the excpetion, before its swallowed + /// + public event UnhandledExceptionEventHandler OnExceptionThrown; - public Repository() + /// + /// Make a repository + /// + /// Should we throw exceptions? or just return null + public Repository(bool failFast = true) { Client = new RestClient(Constants.BaseRequestString); Request = new RestRequest(); + FailFast = failFast; } + [Obsolete("This constructor is used for mocking purposes only", false)] internal Repository(IRestClient client, IRestRequest request) { Client = client; Request = request; } - internal void ConfigureRequest(string endPoint, IDictionary bodyParameters = null , Method webMethod = Method.GET) + internal Repository ConfigureRequest(string endPoint, IDictionary bodyParameters = null, Method webMethod = Method.GET) { Request.Resource = endPoint; Request.Method = webMethod; - if (Request.Parameters != null) Request.Parameters.Clear(); + if (Request.Parameters != null && Request.Parameters.Count > 0) + { + Request.Parameters.Clear(); + } - if (bodyParameters == null) return; + if (bodyParameters == null) return this; foreach (var param in bodyParameters) { Request.AddParameter(param.Key, param.Value); } - + return this; } - internal void ConfigureRequest(IUnAuthenticatedUntappdCredentials credentials, string endPoint, IDictionary bodyParameters = null, Method webMethod = Method.GET) + internal Repository ConfigureRequest(IUntappdCredentials credentials, string endPoint, IDictionary bodyParameters = null, Method webMethod = Method.GET) { ConfigureRequest(endPoint, bodyParameters, webMethod); - Request.AddParameter("client_id", credentials.ClientId); - Request.AddParameter("client_secret", credentials.ClientSecret); - - } - - internal void ConfigureRequest(IAuthenticatedUntappdCredentials credentials, string endPoint, IDictionary bodyParameters = null, Method webMethod = Method.GET) - { - ConfigureRequest(endPoint, bodyParameters, webMethod); - Request.AddParameter("access_token", credentials.AccessToken); + foreach (var untappdCredential in credentials.AuthenticationData) + { + Request.AddParameter(untappdCredential.Key, untappdCredential.Value); + } + return this; } private TResult ExecuteRequest() + where TResult : class { - var response = Client.Execute(Request); - return JsonConvert.DeserializeObject(response.Content); + return ProcessExecution(Client.Execute(Request)); } private async Task ExecuteRequestAsync() + where TResult : class { - var response = await Client.ExecuteTaskAsync(Request); - return JsonConvert.DeserializeObject(response.Content); + return ProcessExecution(await Client.ExecuteTaskAsync(Request)); + } + + private TResult ProcessExecution(IRestResponse response) + where TResult : class + { + //if the return type is not 200 throw errors + if (response.StatusCode != HttpStatusCode.OK) + { + var excpetion = new HttpErrorException(Request, response); + if (OnExceptionThrown != null) + { + OnExceptionThrown(this, new UnhandledExceptionEventArgs(excpetion, FailFast)); + } + if (FailFast) + { + throw excpetion; + } + return null; + } + //try to deserialize + try + { + return JsonConvert.DeserializeObject(response.Content); + } + catch(System.Exception e) + { + if (OnExceptionThrown != null) + { + OnExceptionThrown(this, new UnhandledExceptionEventArgs(e, FailFast)); + } + if (FailFast) + { + throw; + } + + return null; + } } } } diff --git a/src/Untappd.Net/Request/RepositoryGet.cs b/src/Untappd.Net/Request/RepositoryGet.cs index 3204038..9cecc19 100644 --- a/src/Untappd.Net/Request/RepositoryGet.cs +++ b/src/Untappd.Net/Request/RepositoryGet.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using Untappd.Net.Client; +using Untappd.Net.Exception; namespace Untappd.Net.Request { @@ -13,13 +14,14 @@ namespace Untappd.Net.Request /// Pass in a credentials object /// this is the main parameter for a request. ie v4/user/checkins/urlParameter. Consult the untappd docs, this can be null for a few requests /// Any additional params you wish to add to the request + /// /// public TResult Get(IUnAuthenticatedUntappdCredentials credentials, string urlParameter, IDictionary bodyParameters = null) - where TResult : IUnAuthenticatedRequest, new() + where TResult : class, IUnAuthenticatedRequest, new() { var result = new TResult(); - ConfigureRequest(credentials, result.EndPoint(urlParameter), bodyParameters); - return ExecuteRequest(); + return ConfigureRequest(credentials, result.EndPoint(urlParameter), bodyParameters) + .ExecuteRequest(); } /// @@ -29,13 +31,14 @@ namespace Untappd.Net.Request /// /// /// + /// /// public Task GetAsync(IUnAuthenticatedUntappdCredentials credentials, string urlParameter, IDictionary bodyParameters = null) - where TResult : IUnAuthenticatedRequest, new() + where TResult : class, IUnAuthenticatedRequest, new() { var result = new TResult(); - ConfigureRequest(credentials, result.EndPoint(urlParameter), bodyParameters); - return ExecuteRequestAsync(); + return ConfigureRequest(credentials, result.EndPoint(urlParameter), bodyParameters) + .ExecuteRequestAsync(); } /// @@ -45,13 +48,14 @@ namespace Untappd.Net.Request /// Pass in a credentials object /// this is the main parameter for a request. ie v4/user/checkins/urlParameter. Consult the untappd docs, this can be null for a few requests /// Any additional params you wish to add to the request + /// /// public TResult Get(IAuthenticatedUntappdCredentials credentials, string urlParameter = "", IDictionary bodyParameters = null) - where TResult : IAuthenticatedRequest, new() + where TResult : class,IAuthenticatedRequest, new() { var result = new TResult(); - ConfigureRequest(credentials, result.EndPoint(urlParameter), bodyParameters); - return ExecuteRequest(); + return ConfigureRequest(credentials, result.EndPoint(urlParameter), bodyParameters) + .ExecuteRequest(); } /// @@ -61,14 +65,14 @@ namespace Untappd.Net.Request /// /// /// + /// /// public Task GetAsync(IAuthenticatedUntappdCredentials credentials, string urlParameter = "", IDictionary bodyParameters = null) - where TResult : IAuthenticatedRequest, new() + where TResult : class,IAuthenticatedRequest, new() { var result = new TResult(); - ConfigureRequest(result.EndPoint(urlParameter), bodyParameters); - Request.AddParameter("access_token", credentials.AccessToken); - return ExecuteRequestAsync(); + return ConfigureRequest(credentials, result.EndPoint(urlParameter), bodyParameters) + .ExecuteRequestAsync(); } } } diff --git a/src/Untappd.Net/Request/RepositoryPost.cs b/src/Untappd.Net/Request/RepositoryPost.cs index c6610ec..aa48e59 100644 --- a/src/Untappd.Net/Request/RepositoryPost.cs +++ b/src/Untappd.Net/Request/RepositoryPost.cs @@ -13,8 +13,8 @@ namespace Untappd.Net.Request /// returns dynamic since often the return doesn't matter public dynamic Post(IAuthenticatedUntappdCredentials credentials, IAction action) { - ConfigureRequest(credentials, action.EndPoint, action.BodyParameters, action.RequestMethod); - return ExecuteRequest(); + return ConfigureRequest(credentials, action.EndPoint, action.BodyParameters, action.RequestMethod) + .ExecuteRequest(); } /// @@ -25,8 +25,8 @@ namespace Untappd.Net.Request /// returns dynamic since often the return doesn't matter public Task PostAsync(IAuthenticatedUntappdCredentials credentials, IAction action) { - ConfigureRequest(credentials, action.EndPoint, action.BodyParameters, action.RequestMethod); - return ExecuteRequestAsync(); + return ConfigureRequest(credentials, action.EndPoint, action.BodyParameters, action.RequestMethod) + .ExecuteRequestAsync(); } } } diff --git a/src/Untappd.Net/Untappd.Net.csproj b/src/Untappd.Net/Untappd.Net.csproj index a57e78c..e1d4cc9 100644 --- a/src/Untappd.Net/Untappd.Net.csproj +++ b/src/Untappd.Net/Untappd.Net.csproj @@ -47,6 +47,7 @@ +