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/appveyor.yml b/appveyor.yml index 46bf967..a31bf02 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 0.3.{build} +version: 0.4.{build} configuration: Release notifications: - provider: Webhook diff --git a/src/Untappd.Net.UnitTests/Authentication/TestAuthenticationHelper.cs b/src/Untappd.Net.UnitTests/Authentication/TestAuthenticationHelper.cs index 7ea9b41..32c1741 100644 --- a/src/Untappd.Net.UnitTests/Authentication/TestAuthenticationHelper.cs +++ b/src/Untappd.Net.UnitTests/Authentication/TestAuthenticationHelper.cs @@ -1,7 +1,7 @@ using System; using NUnit.Framework; using Untappd.Net.Authentication; -using Untappd.Net.Client; +using Untappd.Net.OAuth; namespace Untappd.Net.UnitTests.Authentication { diff --git a/src/Untappd.Net.UnitTests/Client/TestAuthenticatedUntappdCredentials.cs b/src/Untappd.Net.UnitTests/Client/TestAuthenticatedUntappdCredentials.cs index 9209952..9b0fac7 100644 --- a/src/Untappd.Net.UnitTests/Client/TestAuthenticatedUntappdCredentials.cs +++ b/src/Untappd.Net.UnitTests/Client/TestAuthenticatedUntappdCredentials.cs @@ -1,6 +1,6 @@ using System; using NUnit.Framework; -using Untappd.Net.Client; +using Untappd.Net.Authentication; namespace Untappd.Net.UnitTests.Client { @@ -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/Client/TestUnAuthenticatedUntappdCredentials.cs b/src/Untappd.Net.UnitTests/Client/TestUnAuthenticatedUntappdCredentials.cs index 535e46b..612de67 100644 --- a/src/Untappd.Net.UnitTests/Client/TestUnAuthenticatedUntappdCredentials.cs +++ b/src/Untappd.Net.UnitTests/Client/TestUnAuthenticatedUntappdCredentials.cs @@ -1,6 +1,6 @@ using System; using NUnit.Framework; -using Untappd.Net.Client; +using Untappd.Net.Authentication; namespace Untappd.Net.UnitTests.Client { diff --git a/src/Untappd.Net.UnitTests/Request/TestRepository.cs b/src/Untappd.Net.UnitTests/Request/TestRepository.cs index b2ad545..c31e186 100644 --- a/src/Untappd.Net.UnitTests/Request/TestRepository.cs +++ b/src/Untappd.Net.UnitTests/Request/TestRepository.cs @@ -1,13 +1,15 @@ using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Threading.Tasks; using Moq; using Newtonsoft.Json; using NUnit.Framework; using RestSharp; -using Untappd.Net.Client; using Untappd.Net.Request; using Untappd.Net.Responses.BeerInfo; using Untappd.Net.Responses.Actions; +using System.IO; +using Untappd.Net.Authentication; namespace Untappd.Net.UnitTests.Request { @@ -18,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(); @@ -27,8 +32,7 @@ namespace Untappd.Net.UnitTests.Request request.Setup(a => a.AddParameter(It.IsAny(), It.IsAny())); var response = new Mock(); - var obj = JsonConvert.SerializeObject(new BeerInfo()); - response.Setup(a => a.Content).Returns(obj); + response.Setup(a => a.Content).Returns(File.ReadAllText("../../Responses/json/BeerInfo.json")); client.Setup(a => a.Execute(It.IsAny())).Callback(() => { }).Returns(response.Object); @@ -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.UnitTests/Responses/TestDeserializer.cs b/src/Untappd.Net.UnitTests/Responses/TestDeserializer.cs index 7a3889f..aec075e 100644 --- a/src/Untappd.Net.UnitTests/Responses/TestDeserializer.cs +++ b/src/Untappd.Net.UnitTests/Responses/TestDeserializer.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.IO; using Newtonsoft.Json; using NUnit.Framework; -using Untappd.Net.Client; +using Untappd.Net.Authentication; using Untappd.Net.Request; using Untappd.Net.Responses.BeerInfo; using Untappd.Net.Responses.BeerSearch; diff --git a/src/Untappd.Net/Client/AuthenticatedUntappdCredentials.cs b/src/Untappd.Net/Authentication/AuthenticatedUntappdCredentials.cs similarity index 63% rename from src/Untappd.Net/Client/AuthenticatedUntappdCredentials.cs rename to src/Untappd.Net/Authentication/AuthenticatedUntappdCredentials.cs index 4a0eb55..c216fe2 100644 --- a/src/Untappd.Net/Client/AuthenticatedUntappdCredentials.cs +++ b/src/Untappd.Net/Authentication/AuthenticatedUntappdCredentials.cs @@ -1,23 +1,25 @@ using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; -namespace Untappd.Net.Client +namespace Untappd.Net.Authentication { 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/Authentication/IAuthenticatedUntappdCredentials.cs similarity index 57% rename from src/Untappd.Net/Client/IAuthenticatedUntappdCredentials.cs rename to src/Untappd.Net/Authentication/IAuthenticatedUntappdCredentials.cs index 629bec2..9e0900c 100644 --- a/src/Untappd.Net/Client/IAuthenticatedUntappdCredentials.cs +++ b/src/Untappd.Net/Authentication/IAuthenticatedUntappdCredentials.cs @@ -1,7 +1,6 @@ -namespace Untappd.Net.Client +namespace Untappd.Net.Authentication { public interface IAuthenticatedUntappdCredentials : IUntappdCredentials { - string AccessToken { get; } } } diff --git a/src/Untappd.Net/Client/IUnAuthenticatedUntappdCredentials.cs b/src/Untappd.Net/Authentication/IUnAuthenticatedUntappdCredentials.cs similarity index 72% rename from src/Untappd.Net/Client/IUnAuthenticatedUntappdCredentials.cs rename to src/Untappd.Net/Authentication/IUnAuthenticatedUntappdCredentials.cs index 770b596..b2ff2fb 100644 --- a/src/Untappd.Net/Client/IUnAuthenticatedUntappdCredentials.cs +++ b/src/Untappd.Net/Authentication/IUnAuthenticatedUntappdCredentials.cs @@ -1,5 +1,5 @@  -namespace Untappd.Net.Client +namespace Untappd.Net.Authentication { public interface IUnAuthenticatedUntappdCredentials : IUntappdCredentials { diff --git a/src/Untappd.Net/Authentication/IUntappdCredentials.cs b/src/Untappd.Net/Authentication/IUntappdCredentials.cs new file mode 100644 index 0000000..1c43b11 --- /dev/null +++ b/src/Untappd.Net/Authentication/IUntappdCredentials.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace Untappd.Net.Authentication +{ + public interface IUntappdCredentials + { + IReadOnlyDictionary AuthenticationData { get; } + } +} diff --git a/src/Untappd.Net/Client/UntappdCredentials.cs b/src/Untappd.Net/Authentication/UnAuthenticatedUntappdCredentials.cs similarity index 51% rename from src/Untappd.Net/Client/UntappdCredentials.cs rename to src/Untappd.Net/Authentication/UnAuthenticatedUntappdCredentials.cs index 73b6a73..ae9a674 100644 --- a/src/Untappd.Net/Client/UntappdCredentials.cs +++ b/src/Untappd.Net/Authentication/UnAuthenticatedUntappdCredentials.cs @@ -1,22 +1,17 @@ using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; -namespace Untappd.Net.Client +namespace Untappd.Net.Authentication { - public abstract class UntappdCredentials : IUntappdCredentials + public class UnAuthenticatedUntappdCredentials : UntappdCredentials, IUnAuthenticatedUntappdCredentials { - 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) + public UnAuthenticatedUntappdCredentials(string clientId, string clientSecret) { if (string.IsNullOrWhiteSpace(clientId)) { @@ -26,8 +21,10 @@ namespace Untappd.Net.Client { throw new ArgumentNullException("clientSecret"); } - ClientId = string.Copy(clientId); - ClientSecret = string.Copy(clientSecret); + AuthenticationData = new ReadOnlyDictionary(new Dictionary() + { + {"client_id", clientId}, {"client_secret", clientSecret} + }); } } } diff --git a/src/Untappd.Net/Authentication/UntappdCredentials.cs b/src/Untappd.Net/Authentication/UntappdCredentials.cs new file mode 100644 index 0000000..8e265e6 --- /dev/null +++ b/src/Untappd.Net/Authentication/UntappdCredentials.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace Untappd.Net.Authentication +{ + public abstract class UntappdCredentials : IUntappdCredentials + { + public IReadOnlyDictionary AuthenticationData { get; protected set; } + } +} diff --git a/src/Untappd.Net/Client/IUntappdCredentials.cs b/src/Untappd.Net/Client/IUntappdCredentials.cs deleted file mode 100644 index dad9dba..0000000 --- a/src/Untappd.Net/Client/IUntappdCredentials.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Untappd.Net.Client -{ - public interface IUntappdCredentials - { - string ClientId { get; } - string ClientSecret { get; } - } -} diff --git a/src/Untappd.Net/Client/UnAuthenticatedUntappdCredentials.cs b/src/Untappd.Net/Client/UnAuthenticatedUntappdCredentials.cs deleted file mode 100644 index 39f4b68..0000000 --- a/src/Untappd.Net/Client/UnAuthenticatedUntappdCredentials.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Untappd.Net.Client -{ - public class UnAuthenticatedUntappdCredentials : UntappdCredentials, IUnAuthenticatedUntappdCredentials - { - /// - /// UnAuthenticated request. Pass your API id and secret - /// - /// - /// - public UnAuthenticatedUntappdCredentials(string clientId, string clientSecret) - : base(clientId, clientSecret) - { - } - } -} 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/Authentication/AuthenticationHelper.cs b/src/Untappd.Net/OAuth/AuthenticationHelper.cs similarity index 88% rename from src/Untappd.Net/Authentication/AuthenticationHelper.cs rename to src/Untappd.Net/OAuth/AuthenticationHelper.cs index ddb9226..198f210 100644 --- a/src/Untappd.Net/Authentication/AuthenticationHelper.cs +++ b/src/Untappd.Net/OAuth/AuthenticationHelper.cs @@ -1,7 +1,7 @@ using System; -using Untappd.Net.Client; +using Untappd.Net.Authentication; -namespace Untappd.Net.Authentication +namespace Untappd.Net.OAuth { public static class AuthenticationHelper { @@ -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/Request/Repository.cs b/src/Untappd.Net/Request/Repository.cs index ad0af81..f557c14 100644 --- a/src/Untappd.Net/Request/Repository.cs +++ b/src/Untappd.Net/Request/Repository.cs @@ -1,7 +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.Exception; +using System; +using Untappd.Net.Authentication; namespace Untappd.Net.Request { @@ -9,43 +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; } - private TResult ExecuteRequest() + internal Repository ConfigureRequest(IUntappdCredentials credentials, string endPoint, IDictionary bodyParameters = null, Method webMethod = Method.GET) { - var response = Client.Execute(Request); - return JsonConvert.DeserializeObject(response.Content); + ConfigureRequest(endPoint, bodyParameters, webMethod); + foreach (var untappdCredential in credentials.AuthenticationData) + { + Request.AddParameter(untappdCredential.Key, untappdCredential.Value); + } + return this; + } + + private TResult ExecuteRequest() + where TResult : class + { + 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 08a21c4..1daabad 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.Authentication; +using Untappd.Net.Exception; namespace Untappd.Net.Request { @@ -13,15 +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(result.EndPoint(urlParameter), bodyParameters); - Request.AddParameter("client_id", credentials.ClientId); - Request.AddParameter("client_secret", credentials.ClientSecret); - return ExecuteRequest(); + return ConfigureRequest(credentials, result.EndPoint(urlParameter), bodyParameters) + .ExecuteRequest(); } /// @@ -31,15 +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(result.EndPoint(urlParameter), bodyParameters); - Request.AddParameter("client_id", credentials.ClientId); - Request.AddParameter("client_secret", credentials.ClientSecret); - return ExecuteRequestAsync(); + return ConfigureRequest(credentials, result.EndPoint(urlParameter), bodyParameters) + .ExecuteRequestAsync(); } /// @@ -49,14 +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(result.EndPoint(urlParameter), bodyParameters); - Request.AddParameter("access_token", credentials.AccessToken); - return ExecuteRequest(); + return ConfigureRequest(credentials, result.EndPoint(urlParameter), bodyParameters) + .ExecuteRequest(); } /// @@ -66,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 ee1e3d7..f5bffbb 100644 --- a/src/Untappd.Net/Request/RepositoryPost.cs +++ b/src/Untappd.Net/Request/RepositoryPost.cs @@ -1,5 +1,5 @@ using System.Threading.Tasks; -using Untappd.Net.Client; +using Untappd.Net.Authentication; namespace Untappd.Net.Request { @@ -13,9 +13,8 @@ namespace Untappd.Net.Request /// returns dynamic since often the return doesn't matter public dynamic Post(IAuthenticatedUntappdCredentials credentials, IAction action) { - ConfigureRequest(action.EndPoint, action.BodyParameters, action.RequestMethod); - Request.AddParameter("access_token", credentials.AccessToken); - return ExecuteRequest(); + return ConfigureRequest(credentials, action.EndPoint, action.BodyParameters, action.RequestMethod) + .ExecuteRequest(); } /// @@ -26,9 +25,8 @@ namespace Untappd.Net.Request /// returns dynamic since often the return doesn't matter public Task PostAsync(IAuthenticatedUntappdCredentials credentials, IAction action) { - ConfigureRequest(action.EndPoint, action.BodyParameters, action.RequestMethod); - Request.AddParameter("access_token", credentials.AccessToken); - return ExecuteRequestAsync(); + return ConfigureRequest(credentials, action.EndPoint, action.BodyParameters, action.RequestMethod) + .ExecuteRequestAsync(); } } } diff --git a/src/Untappd.Net/Responses/BeerInfo.cs b/src/Untappd.Net/Responses/BeerInfo.cs index aadc620..f21f4dd 100644 --- a/src/Untappd.Net/Responses/BeerInfo.cs +++ b/src/Untappd.Net/Responses/BeerInfo.cs @@ -128,6 +128,7 @@ namespace Untappd.Net.Responses.BeerInfo public string CountryName { get; set; } [JsonProperty("contact")] + [JsonConverter(typeof(SingleObjectArrayConverter))] public Contact Contact { get; set; } [JsonProperty("location")] @@ -241,6 +242,7 @@ namespace Untappd.Net.Responses.BeerInfo public string CountryName { get; set; } [JsonProperty("contact")] + [JsonConverter(typeof(SingleObjectArrayConverter))] public Contact2 Contact { get; set; } [JsonProperty("location")] @@ -350,6 +352,7 @@ namespace Untappd.Net.Responses.BeerInfo public int IsPrivate { get; set; } [JsonProperty("contact")] + [JsonConverter(typeof(SingleObjectArrayConverter))] public object Contact { get; set; } } @@ -444,6 +447,7 @@ namespace Untappd.Net.Responses.BeerInfo public string CountryName { get; set; } [JsonProperty("contact")] + [JsonConverter(typeof(SingleObjectArrayConverter))] public Contact3 Contact { get; set; } [JsonProperty("location")] @@ -758,6 +762,7 @@ namespace Untappd.Net.Responses.BeerInfo public string CountryName { get; set; } [JsonProperty("contact")] + [JsonConverter(typeof(SingleObjectArrayConverter))] public Contact4 Contact { get; set; } [JsonProperty("location")] @@ -910,6 +915,7 @@ namespace Untappd.Net.Responses.BeerInfo public Media Media { get; set; } [JsonProperty("checkins")] + [JsonConverter(typeof(SingleObjectArrayConverter))] public Checkins Checkins { get; set; } [JsonProperty("similar")] @@ -937,6 +943,7 @@ namespace Untappd.Net.Responses.BeerInfo public Meta Meta { get; set; } [JsonProperty("notifications")] + [JsonConverter(typeof(SingleObjectArrayConverter))] public Notifications Notifications { get; set; } [JsonProperty("response")] diff --git a/src/Untappd.Net/Responses/BeerSearch.cs b/src/Untappd.Net/Responses/BeerSearch.cs index 81291f8..2b5d83c 100644 --- a/src/Untappd.Net/Responses/BeerSearch.cs +++ b/src/Untappd.Net/Responses/BeerSearch.cs @@ -264,6 +264,7 @@ namespace Untappd.Net.Responses.BeerSearch public Meta Meta { get; set; } [JsonProperty("notifications")] + [JsonConverter(typeof(SingleObjectArrayConverter))] public Notifications Notifications { get; set; } [JsonProperty("response")] diff --git a/src/Untappd.Net/Responses/BreweryInfo.cs b/src/Untappd.Net/Responses/BreweryInfo.cs index 4e80784..f5365ed 100644 --- a/src/Untappd.Net/Responses/BreweryInfo.cs +++ b/src/Untappd.Net/Responses/BreweryInfo.cs @@ -892,6 +892,7 @@ namespace Untappd.Net.Responses.BreweryInfo public Media Media { get; set; } [JsonProperty("checkins")] + [JsonConverter(typeof(SingleObjectArrayConverter))] public Checkins Checkins { get; set; } [JsonProperty("beer_list")] @@ -913,6 +914,7 @@ namespace Untappd.Net.Responses.BreweryInfo public Meta Meta { get; set; } [JsonProperty("notifications")] + [JsonConverter(typeof(SingleObjectArrayConverter))] public Notifications Notifications { get; set; } [JsonProperty("response")] diff --git a/src/Untappd.Net/Responses/BrewerySearch.cs b/src/Untappd.Net/Responses/BrewerySearch.cs index 5a06784..8999559 100644 --- a/src/Untappd.Net/Responses/BrewerySearch.cs +++ b/src/Untappd.Net/Responses/BrewerySearch.cs @@ -152,6 +152,7 @@ namespace Untappd.Net.Responses.BrewerySearch public Meta Meta { get; set; } [JsonProperty("notifications")] + [JsonConverter(typeof(SingleObjectArrayConverter))] public Notifications Notifications { get; set; } [JsonProperty("response")] diff --git a/src/Untappd.Net/Responses/Feeds/ActivityFeed.cs b/src/Untappd.Net/Responses/Feeds/ActivityFeed.cs index ab79fa5..01aa653 100644 --- a/src/Untappd.Net/Responses/Feeds/ActivityFeed.cs +++ b/src/Untappd.Net/Responses/Feeds/ActivityFeed.cs @@ -502,6 +502,7 @@ namespace Untappd.Net.Responses.Feeds.ActivityFeed public bool Mg { get; set; } [JsonProperty("checkins")] + [JsonConverter(typeof(SingleObjectArrayConverter))] public Checkins Checkins { get; set; } [JsonProperty("pagination")] diff --git a/src/Untappd.Net/Responses/Feeds/UserActivityFeed.cs b/src/Untappd.Net/Responses/Feeds/UserActivityFeed.cs index 2585ca0..a8fbe48 100644 --- a/src/Untappd.Net/Responses/Feeds/UserActivityFeed.cs +++ b/src/Untappd.Net/Responses/Feeds/UserActivityFeed.cs @@ -472,6 +472,7 @@ namespace Untappd.Net.Responses.Feeds.UserActivityFeed public Pagination Pagination { get; set; } [JsonProperty("checkins")] + [JsonConverter(typeof(SingleObjectArrayConverter))] public Checkins Checkins { get; set; } } diff --git a/src/Untappd.Net/Responses/UserBadges.cs b/src/Untappd.Net/Responses/UserBadges.cs index ded1d26..cb4f23e 100644 --- a/src/Untappd.Net/Responses/UserBadges.cs +++ b/src/Untappd.Net/Responses/UserBadges.cs @@ -219,6 +219,7 @@ namespace Untappd.Net.Responses.UserBadges public Meta Meta { get; set; } [JsonProperty("notifications")] + [JsonConverter(typeof(SingleObjectArrayConverter))] public Notifications Notifications { get; set; } [JsonProperty("response")] diff --git a/src/Untappd.Net/Responses/UserDistinctBeer.cs b/src/Untappd.Net/Responses/UserDistinctBeer.cs index 5ceea9c..9601394 100644 --- a/src/Untappd.Net/Responses/UserDistinctBeer.cs +++ b/src/Untappd.Net/Responses/UserDistinctBeer.cs @@ -231,6 +231,7 @@ namespace Untappd.Net.Responses.UserDistinctBeer public Meta Meta { get; set; } [JsonProperty("notifications")] + [JsonConverter(typeof(SingleObjectArrayConverter))] public Notifications Notifications { get; set; } [JsonProperty("response")] diff --git a/src/Untappd.Net/Responses/UserFriends.cs b/src/Untappd.Net/Responses/UserFriends.cs index 6e8cf50..7b1750f 100644 --- a/src/Untappd.Net/Responses/UserFriends.cs +++ b/src/Untappd.Net/Responses/UserFriends.cs @@ -142,6 +142,7 @@ namespace Untappd.Net.Responses.UserFriends public Meta Meta { get; set; } [JsonProperty("notifications")] + [JsonConverter(typeof(SingleObjectArrayConverter))] public Notifications Notifications { get; set; } [JsonProperty("response")] diff --git a/src/Untappd.Net/Responses/UserInfo.cs b/src/Untappd.Net/Responses/UserInfo.cs index 3b09293..ca2ab7c 100644 --- a/src/Untappd.Net/Responses/UserInfo.cs +++ b/src/Untappd.Net/Responses/UserInfo.cs @@ -5,7 +5,7 @@ using Untappd.Net.Request; namespace Untappd.Net.Responses.UserInfo { - public sealed class ResponseTime + public class ResponseTime { [JsonProperty("time")] @@ -31,12 +31,6 @@ namespace Untappd.Net.Responses.UserInfo [JsonProperty("code")] public int Code { get; set; } - [JsonProperty("error_detail")] - public string ErrorDetail { get; set; } - - [JsonProperty("error_type")] - public string ErrorType { get; set; } - [JsonProperty("response_time")] public ResponseTime ResponseTime { get; set; } @@ -44,6 +38,35 @@ namespace Untappd.Net.Responses.UserInfo public InitTime InitTime { get; set; } } + public class UnreadCount + { + + [JsonProperty("comments")] + public int Comments { get; set; } + + [JsonProperty("toasts")] + public int Toasts { get; set; } + + [JsonProperty("friends")] + public int Friends { get; set; } + + [JsonProperty("messages")] + public int Messages { get; set; } + + [JsonProperty("news")] + public int News { get; set; } + } + + public class Notifications + { + + [JsonProperty("type")] + public string Type { get; set; } + + [JsonProperty("unread_count")] + public UnreadCount UnreadCount { get; set; } + } + public class Stats { @@ -215,7 +238,7 @@ namespace Untappd.Net.Responses.UserInfo public string Bio { get; set; } [JsonProperty("relationship")] - public object Relationship { get; set; } + public string Relationship { get; set; } [JsonProperty("user_avatar")] public string UserAvatar { get; set; } @@ -315,6 +338,118 @@ namespace Untappd.Net.Responses.UserInfo public int BreweryActive { get; set; } } + public class Item3 + { + + [JsonProperty("category_name")] + public string CategoryName { get; set; } + + [JsonProperty("category_id")] + public string CategoryId { get; set; } + + [JsonProperty("is_primary")] + public bool IsPrimary { get; set; } + } + + public class Categories + { + + [JsonProperty("count")] + public int Count { get; set; } + + [JsonProperty("items")] + public IList Items { get; set; } + } + + public class Location3 + { + + [JsonProperty("venue_address")] + public string VenueAddress { get; set; } + + [JsonProperty("venue_city")] + public string VenueCity { get; set; } + + [JsonProperty("venue_state")] + public string VenueState { get; set; } + + [JsonProperty("venue_country")] + public string VenueCountry { get; set; } + + [JsonProperty("lat")] + public double Lat { get; set; } + + [JsonProperty("lng")] + public double Lng { get; set; } + } + + public class Contact4 + { + + [JsonProperty("twitter")] + public string Twitter { get; set; } + + [JsonProperty("venue_url")] + public string VenueUrl { get; set; } + } + + public class Foursquare + { + + [JsonProperty("foursquare_id")] + public string FoursquareId { get; set; } + + [JsonProperty("foursquare_url")] + public string FoursquareUrl { get; set; } + } + + public class VenueIcon + { + + [JsonProperty("sm")] + public string Sm { get; set; } + + [JsonProperty("md")] + public string Md { get; set; } + + [JsonProperty("lg")] + public string Lg { get; set; } + } + + public class Venue + { + + [JsonProperty("venue_id")] + public int VenueId { get; set; } + + [JsonProperty("venue_name")] + public string VenueName { get; set; } + + [JsonProperty("primary_category")] + public string PrimaryCategory { get; set; } + + [JsonProperty("parent_category_id")] + public string ParentCategoryId { get; set; } + + [JsonProperty("categories")] + public Categories Categories { get; set; } + + [JsonProperty("location")] + public Location3 Location { get; set; } + + [JsonProperty("contact")] + public Contact4 Contact { get; set; } + + [JsonProperty("public_venue")] + public bool PublicVenue { get; set; } + + [JsonProperty("foursquare")] + public Foursquare Foursquare { get; set; } + + [JsonProperty("venue_icon")] + public VenueIcon VenueIcon { get; set; } + } + public class Comments { @@ -359,10 +494,10 @@ namespace Untappd.Net.Responses.UserInfo public string AccountType { get; set; } [JsonProperty("brewery_details")] - public object BreweryDetails { get; set; } + public IList BreweryDetails { get; set; } } - public class Item3 + public class Item4 { [JsonProperty("uid")] @@ -391,10 +526,10 @@ namespace Untappd.Net.Responses.UserInfo public int Count { get; set; } [JsonProperty("auth_toast")] - public object AuthToast { get; set; } + public bool AuthToast { get; set; } [JsonProperty("items")] - public IList Items { get; set; } + public IList Items { get; set; } } public class Photo @@ -413,7 +548,7 @@ namespace Untappd.Net.Responses.UserInfo public string PhotoImgOg { get; set; } } - public class Item4 + public class Item5 { [JsonProperty("photo_id")] @@ -430,7 +565,7 @@ namespace Untappd.Net.Responses.UserInfo public int Count { get; set; } [JsonProperty("items")] - public IList Items { get; set; } + public IList Items { get; set; } } public class Source @@ -456,7 +591,7 @@ namespace Untappd.Net.Responses.UserInfo public string Lg { get; set; } } - public class Item5 + public class Item6 { [JsonProperty("badge_id")] @@ -485,7 +620,7 @@ namespace Untappd.Net.Responses.UserInfo public int Count { get; set; } [JsonProperty("items")] - public IList Items { get; set; } + public IList Items { get; set; } } public class Item2 @@ -513,7 +648,8 @@ namespace Untappd.Net.Responses.UserInfo public Brewery2 Brewery { get; set; } [JsonProperty("venue")] - public object Venue { get; set; } + [JsonConverter(typeof(SingleObjectArrayConverter))] + public Venue Venue { get; set; } [JsonProperty("comments")] public Comments Comments { get; set; } @@ -616,7 +752,7 @@ namespace Untappd.Net.Responses.UserInfo public bool WishList { get; set; } } - public class Contact4 + public class Contact5 { [JsonProperty("twitter")] @@ -632,7 +768,7 @@ namespace Untappd.Net.Responses.UserInfo public string Url { get; set; } } - public class Location3 + public class Location4 { [JsonProperty("brewery_city")] @@ -667,16 +803,128 @@ namespace Untappd.Net.Responses.UserInfo public string CountryName { get; set; } [JsonProperty("contact")] - public Contact4 Contact { get; set; } + public Contact5 Contact { get; set; } [JsonProperty("location")] - public Location3 Location { get; set; } + public Location4 Location { get; set; } [JsonProperty("brewery_active")] public int BreweryActive { get; set; } } - public class Item6 + public class Item8 + { + + [JsonProperty("category_name")] + public string CategoryName { get; set; } + + [JsonProperty("category_id")] + public string CategoryId { get; set; } + + [JsonProperty("is_primary")] + public bool IsPrimary { get; set; } + } + + public class Categories2 + { + + [JsonProperty("count")] + public int Count { get; set; } + + [JsonProperty("items")] + public IList Items { get; set; } + } + + public class Location5 + { + + [JsonProperty("venue_address")] + public string VenueAddress { get; set; } + + [JsonProperty("venue_city")] + public string VenueCity { get; set; } + + [JsonProperty("venue_state")] + public string VenueState { get; set; } + + [JsonProperty("venue_country")] + public string VenueCountry { get; set; } + + [JsonProperty("lat")] + public double Lat { get; set; } + + [JsonProperty("lng")] + public double Lng { get; set; } + } + + public class Contact6 + { + + [JsonProperty("twitter")] + public string Twitter { get; set; } + + [JsonProperty("venue_url")] + public string VenueUrl { get; set; } + } + + public class Foursquare2 + { + + [JsonProperty("foursquare_id")] + public string FoursquareId { get; set; } + + [JsonProperty("foursquare_url")] + public string FoursquareUrl { get; set; } + } + + public class VenueIcon2 + { + + [JsonProperty("sm")] + public string Sm { get; set; } + + [JsonProperty("md")] + public string Md { get; set; } + + [JsonProperty("lg")] + public string Lg { get; set; } + } + + public class Venue2 + { + + [JsonProperty("venue_id")] + public int VenueId { get; set; } + + [JsonProperty("venue_name")] + public string VenueName { get; set; } + + [JsonProperty("primary_category")] + public string PrimaryCategory { get; set; } + + [JsonProperty("parent_category_id")] + public string ParentCategoryId { get; set; } + + [JsonProperty("categories")] + public Categories2 Categories { get; set; } + + [JsonProperty("location")] + public Location5 Location { get; set; } + + [JsonProperty("contact")] + public Contact6 Contact { get; set; } + + [JsonProperty("public_venue")] + public bool PublicVenue { get; set; } + + [JsonProperty("foursquare")] + public Foursquare2 Foursquare { get; set; } + + [JsonProperty("venue_icon")] + public VenueIcon2 VenueIcon { get; set; } + } + + public class Item7 { [JsonProperty("photo_id")] @@ -701,7 +949,7 @@ namespace Untappd.Net.Responses.UserInfo public Brewery3 Brewery { get; set; } [JsonProperty("venue")] - public object Venue { get; set; } + public Venue2 Venue { get; set; } } public class Media2 @@ -711,14 +959,14 @@ namespace Untappd.Net.Responses.UserInfo public int Count { get; set; } [JsonProperty("items")] - public IList Items { get; set; } + public IList Items { get; set; } } - public class Contact5 + public class Contact7 { [JsonProperty("facebook")] - public string Facebook { get; set; } + public int Facebook { get; set; } [JsonProperty("twitter")] public string Twitter { get; set; } @@ -726,39 +974,51 @@ namespace Untappd.Net.Responses.UserInfo public class Badge { + [JsonProperty("badges_to_facebook")] public int BadgesToFacebook { get; set; } + [JsonProperty("badges_to_twitter")] public int BadgesToTwitter { get; set; } } public class Checkin { + [JsonProperty("checkin_to_facebook")] public int CheckinToFacebook { get; set; } + [JsonProperty("checkin_to_twitter")] public int CheckinToTwitter { get; set; } + [JsonProperty("checkin_to_foursquare")] public int CheckinToFoursquare { get; set; } } public class Navigation { + [JsonProperty("default_to_checkin")] public int DefaultToCheckin { get; set; } } public class Settings { + [JsonProperty("badge")] public Badge Badge { get; set; } + [JsonProperty("checkin")] + [JsonConverter(typeof(SingleObjectArrayConverter))] public Checkin Checkin { get; set; } + [JsonProperty("navigation")] public Navigation Navigation { get; set; } + [JsonProperty("email_address")] public string EmailAddress { get; set; } } + public class User { @@ -805,7 +1065,7 @@ namespace Untappd.Net.Responses.UserInfo public int IsSupporter { get; set; } [JsonProperty("relationship")] - public object Relationship { get; set; } + public string Relationship { get; set; } [JsonProperty("untappd_url")] public string UntappdUrl { get; set; } @@ -820,13 +1080,14 @@ namespace Untappd.Net.Responses.UserInfo public RecentBrews RecentBrews { get; set; } [JsonProperty("checkins")] + [JsonConverter(typeof(SingleObjectArrayConverter))] public Checkins Checkins { get; set; } [JsonProperty("media")] public Media2 Media { get; set; } [JsonProperty("contact")] - public Contact5 Contact { get; set; } + public Contact7 Contact { get; set; } [JsonProperty("date_joined")] public string DateJoined { get; set; } @@ -835,28 +1096,6 @@ namespace Untappd.Net.Responses.UserInfo public Settings Settings { get; set; } } - public class UnreadCount - { - [JsonProperty("comments")] - public int Comments { get; set; } - [JsonProperty("toasts")] - public int Toasts { get; set; } - [JsonProperty("friends")] - public int Friends { get; set; } - [JsonProperty("messages")] - public int Messages { get; set; } - [JsonProperty("news")] - public int news { get; set; } - } - - public class Notifications - { - [JsonProperty("type")] - public string Type { get; set; } - [JsonProperty("unread_count")] - public UnreadCount UnreadCount { get; set; } - } - public class Response { diff --git a/src/Untappd.Net/Responses/UserWishlist.cs b/src/Untappd.Net/Responses/UserWishlist.cs index 378bce2..8edae98 100644 --- a/src/Untappd.Net/Responses/UserWishlist.cs +++ b/src/Untappd.Net/Responses/UserWishlist.cs @@ -223,6 +223,7 @@ namespace Untappd.Net.Responses.UserWishlist public Meta Meta { get; set; } [JsonProperty("notifications")] + [JsonConverter(typeof(SingleObjectArrayConverter))] public Notifications Notifications { get; set; } [JsonProperty("response")] diff --git a/src/Untappd.Net/Responses/VenueInfo.cs b/src/Untappd.Net/Responses/VenueInfo.cs index 13b6494..82fbcac 100644 --- a/src/Untappd.Net/Responses/VenueInfo.cs +++ b/src/Untappd.Net/Responses/VenueInfo.cs @@ -271,6 +271,7 @@ namespace Untappd.Net.Responses.VenueInfo public string CountryName { get; set; } [JsonProperty("contact")] + [JsonConverter(typeof(SingleObjectArrayConverter))] public Contact2 Contact { get; set; } [JsonProperty("location")] @@ -405,6 +406,7 @@ namespace Untappd.Net.Responses.VenueInfo public Location3 Location { get; set; } [JsonProperty("contact")] + [JsonConverter(typeof(SingleObjectArrayConverter))] public Contact3 Contact { get; set; } [JsonProperty("public_venue")] @@ -562,6 +564,7 @@ namespace Untappd.Net.Responses.VenueInfo public string CountryName { get; set; } [JsonProperty("contact")] + [JsonConverter(typeof(SingleObjectArrayConverter))] public Contact4 Contact { get; set; } [JsonProperty("location")] @@ -671,6 +674,7 @@ namespace Untappd.Net.Responses.VenueInfo public Location5 Location { get; set; } [JsonProperty("contact")] + [JsonConverter(typeof(SingleObjectArrayConverter))] public Contact5 Contact { get; set; } [JsonProperty("public_venue")] @@ -1074,6 +1078,7 @@ namespace Untappd.Net.Responses.VenueInfo public string CountryName { get; set; } [JsonProperty("contact")] + [JsonConverter(typeof(SingleObjectArrayConverter))] public Contact6 Contact { get; set; } [JsonProperty("location")] @@ -1150,7 +1155,7 @@ namespace Untappd.Net.Responses.VenueInfo public Categories Categories { get; set; } [JsonProperty("stats")] - public Stats Stats { get; set; } + public Stats Stats { get; set; } [JsonProperty("venue_icon")] public VenueIcon VenueIcon { get; set; } @@ -1162,6 +1167,7 @@ namespace Untappd.Net.Responses.VenueInfo public Location Location { get; set; } [JsonProperty("contact")] + [JsonConverter(typeof(SingleObjectArrayConverter))] public Contact Contact { get; set; } [JsonProperty("foursquare")] @@ -1171,6 +1177,7 @@ namespace Untappd.Net.Responses.VenueInfo public Media Media { get; set; } [JsonProperty("checkins")] + [JsonConverter(typeof(SingleObjectArrayConverter))] public Checkins Checkins { get; set; } [JsonProperty("top_beers")] @@ -1192,6 +1199,7 @@ namespace Untappd.Net.Responses.VenueInfo public Meta Meta { get; set; } [JsonProperty("notifications")] + [JsonConverter(typeof(SingleObjectArrayConverter))] public Notifications Notifications { get; set; } [JsonProperty("response")] diff --git a/src/Untappd.Net/Untappd.Net.csproj b/src/Untappd.Net/Untappd.Net.csproj index a57e78c..c980f55 100644 --- a/src/Untappd.Net/Untappd.Net.csproj +++ b/src/Untappd.Net/Untappd.Net.csproj @@ -46,7 +46,8 @@ - + + @@ -60,12 +61,12 @@ - - - - - - + + + + + +