diff --git a/SpotifyAPI.Web.Tests/Clients/SpotifyClientConfigTest.cs b/SpotifyAPI.Web.Tests/Clients/SpotifyClientConfigTest.cs new file mode 100644 index 00000000..9a8f1233 --- /dev/null +++ b/SpotifyAPI.Web.Tests/Clients/SpotifyClientConfigTest.cs @@ -0,0 +1,59 @@ +using System; +using Moq; +using NUnit.Framework; +using SpotifyAPI.Web.Http; + +namespace SpotifyAPI.Web +{ + [TestFixture] + public class SpotifyClientConfigTest + { + [Test] + public void CreateDefault_CorrectDefaults() + { + var defaultConfig = SpotifyClientConfig.CreateDefault(); + + Assert.IsInstanceOf(typeof(SimplePaginator), defaultConfig.DefaultPaginator); + Assert.IsInstanceOf(typeof(NetHttpClient), defaultConfig.HTTPClient); + Assert.IsInstanceOf(typeof(NewtonsoftJSONSerializer), defaultConfig.JSONSerializer); + Assert.AreEqual(SpotifyUrls.APIV1, defaultConfig.BaseAddress); + Assert.AreEqual(null, defaultConfig.Authenticator); + Assert.AreEqual(null, defaultConfig.HTTPLogger); + Assert.AreEqual(null, defaultConfig.RetryHandler); + } + + [Test] + public void CreateDefault_CorrectDefaultsWithToken() + { + var token = "my-token"; + var tokenType = "Bearer"; + + var defaultConfig = SpotifyClientConfig.CreateDefault(token, tokenType); + + Assert.IsInstanceOf(typeof(SimplePaginator), defaultConfig.DefaultPaginator); + Assert.IsInstanceOf(typeof(NetHttpClient), defaultConfig.HTTPClient); + Assert.IsInstanceOf(typeof(NewtonsoftJSONSerializer), defaultConfig.JSONSerializer); + Assert.AreEqual(SpotifyUrls.APIV1, defaultConfig.BaseAddress); + Assert.AreEqual(null, defaultConfig.HTTPLogger); + Assert.AreEqual(null, defaultConfig.RetryHandler); + + Assert.IsInstanceOf(typeof(TokenHeaderAuthenticator), defaultConfig.Authenticator); + + var tokenHeaderAuth = defaultConfig.Authenticator as TokenHeaderAuthenticator; + Assert.AreEqual(token, tokenHeaderAuth.Token); + Assert.AreEqual(tokenType, tokenHeaderAuth.TokenType); + } + + [Test] + public void WithToken_CreatesNewInstance() + { + var token = "my-token"; + var defaultConfig = SpotifyClientConfig.CreateDefault(); + var tokenConfig = defaultConfig.WithToken(token); + + Assert.AreEqual(token, (tokenConfig.Authenticator as TokenHeaderAuthenticator).Token); + Assert.AreNotEqual(defaultConfig, tokenConfig); + Assert.AreEqual(null, defaultConfig.Authenticator); + } + } +} diff --git a/SpotifyAPI.Web/Clients/SpotifyClient.cs b/SpotifyAPI.Web/Clients/SpotifyClient.cs index b88df1d4..9c5c92af 100644 --- a/SpotifyAPI.Web/Clients/SpotifyClient.cs +++ b/SpotifyAPI.Web/Clients/SpotifyClient.cs @@ -16,8 +16,19 @@ namespace SpotifyAPI.Web public SpotifyClient(SpotifyClientConfig config) { Ensure.ArgumentNotNull(config, nameof(config)); + if (config.Authenticator == null) + { + throw new NullReferenceException("Authenticator in config is null. Please supply it via `WithAuthenticator` or `WithToken`"); + } - _apiConnector = config.CreateAPIConnector(); + _apiConnector = new APIConnector( + config.BaseAddress, + config.Authenticator, + config.JSONSerializer, + config.HTTPClient, + config.RetryHandler, + config.HTTPLogger + ); DefaultPaginator = config.DefaultPaginator; UserProfile = new UserProfileClient(_apiConnector); Browse = new BrowseClient(_apiConnector); diff --git a/SpotifyAPI.Web/Clients/SpotifyClientConfig.cs b/SpotifyAPI.Web/Clients/SpotifyClientConfig.cs index 46c8f88b..5588c55b 100644 --- a/SpotifyAPI.Web/Clients/SpotifyClientConfig.cs +++ b/SpotifyAPI.Web/Clients/SpotifyClientConfig.cs @@ -1,3 +1,4 @@ +using System.Net.Http; using System; using SpotifyAPI.Web.Http; @@ -42,74 +43,116 @@ namespace SpotifyAPI.Web DefaultPaginator = paginator; } - internal IAPIConnector CreateAPIConnector() + public SpotifyClientConfig WithToken(string token, string tokenType = "Bearer") { - return new APIConnector( + Ensure.ArgumentNotNull(token, nameof(token)); + + return new SpotifyClientConfig( + BaseAddress, + new TokenHeaderAuthenticator(token, tokenType), + JSONSerializer, + HTTPClient, + RetryHandler, + HTTPLogger, + DefaultPaginator + ); + } + + public SpotifyClientConfig WithRetryHandler(IRetryHandler retryHandler) + { + return new SpotifyClientConfig( + BaseAddress, + Authenticator, + JSONSerializer, + HTTPClient, + retryHandler, + HTTPLogger, + DefaultPaginator + ); + } + + public SpotifyClientConfig WithAuthenticator(IAuthenticator authenticator) + { + Ensure.ArgumentNotNull(authenticator, nameof(authenticator)); + + return new SpotifyClientConfig( + BaseAddress, + authenticator, + JSONSerializer, + HTTPClient, + RetryHandler, + HTTPLogger, + DefaultPaginator + ); + } + + public SpotifyClientConfig WithHTTPLogger(IHTTPLogger httpLogger) + { + return new SpotifyClientConfig( BaseAddress, Authenticator, JSONSerializer, HTTPClient, RetryHandler, - HTTPLogger + httpLogger, + DefaultPaginator ); } - public void AddToken(string token, string tokenType = "Bearer") - { - Ensure.ArgumentNotNull(token, nameof(token)); - Authenticator = new TokenHeaderAuthenticator(token, tokenType); - } - - public void AddRetryHandler(IRetryHandler retryHandler) - { - RetryHandler = retryHandler; - } - - public void AddAuthenticator(IAuthenticator authenticator) - { - Ensure.ArgumentNotNull(authenticator, nameof(authenticator)); - - Authenticator = authenticator; - } - - public void AddHTTPLogger(IHTTPLogger httpLogger) - { - HTTPLogger = httpLogger; - } - - public void AddHTTPClient(IHTTPClient httpClient) + public SpotifyClientConfig WithHTTPClient(IHTTPClient httpClient) { Ensure.ArgumentNotNull(httpClient, nameof(httpClient)); - HTTPClient = httpClient; + return new SpotifyClientConfig( + BaseAddress, + Authenticator, + JSONSerializer, + httpClient, + RetryHandler, + HTTPLogger, + DefaultPaginator + ); } - public void AddJSONSerializer(IJSONSerializer jsonSerializer) + public SpotifyClientConfig WithJSONSerializer(IJSONSerializer jsonSerializer) { Ensure.ArgumentNotNull(jsonSerializer, nameof(jsonSerializer)); - JSONSerializer = jsonSerializer; + return new SpotifyClientConfig( + BaseAddress, + Authenticator, + jsonSerializer, + HTTPClient, + RetryHandler, + HTTPLogger, + DefaultPaginator + ); } - public void AddDefaultPaginator(IPaginator paginator) + public SpotifyClientConfig WithDefaultPaginator(IPaginator paginator) { - DefaultPaginator = paginator; + Ensure.ArgumentNotNull(paginator, nameof(paginator)); + + return new SpotifyClientConfig( + BaseAddress, + Authenticator, + JSONSerializer, + HTTPClient, + RetryHandler, + HTTPLogger, + paginator + ); } public static SpotifyClientConfig CreateDefault(string token, string tokenType = "Bearer") { - return CreateDefault(options => - { - options.AddToken(token, tokenType); - }); + return CreateDefault().WithAuthenticator(new TokenHeaderAuthenticator(token, tokenType)); } - public static SpotifyClientConfig CreateDefault(Action optionsCallback) + public static SpotifyClientConfig CreateDefault() { - Ensure.ArgumentNotNull(optionsCallback, nameof(optionsCallback)); - - var config = new SpotifyClientConfig( + return new SpotifyClientConfig( SpotifyUrls.APIV1, null, new NewtonsoftJSONSerializer(), @@ -118,13 +161,6 @@ namespace SpotifyAPI.Web null, new SimplePaginator() ); - optionsCallback(config); - - if (config.Authenticator == null) - { - throw new NullReferenceException("The authenticator was not set after the options callback was run. Please specify a token with AddToken or AddAuthenticator"); - } - return config; } } } diff --git a/SpotifyAPI.Web/Models/Request/ArtistsAlbumsRequest.cs b/SpotifyAPI.Web/Models/Request/ArtistsAlbumsRequest.cs index bf9374d9..618db6fa 100644 --- a/SpotifyAPI.Web/Models/Request/ArtistsAlbumsRequest.cs +++ b/SpotifyAPI.Web/Models/Request/ArtistsAlbumsRequest.cs @@ -22,6 +22,7 @@ namespace SpotifyAPI.Web [String("album")] Album, + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1720")] [String("single")] Single,