Skip to content

Commit

Permalink
Ensure all requests have some user agent string and API version attac…
Browse files Browse the repository at this point in the history
…hed. Re: #47
  • Loading branch information
bchavez committed Dec 2, 2018
1 parent 4c52cfa commit 6a36cea
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 6 deletions.
4 changes: 4 additions & 0 deletions HISTORY.md
@@ -1,3 +1,7 @@
## v5.0.4
* Ensures all requests have a `User-Agent` string, including `Data` requests.
* Added missing `CancellationToken` to `GetCurrenciesAsync()`

## v5.0.3
* PR #47: Extra DI interfaces for DI support. Notification event and transaction status constants. Changed `Transaction.Description` return from object to string. Thanks granthoff1107!

Expand Down
8 changes: 7 additions & 1 deletion Source/Coinbase.Tests/ExtensionsForTesting.cs
Expand Up @@ -3,6 +3,7 @@
using FluentAssertions;
using Flurl.Http.Testing;
using Newtonsoft.Json;
using Z.ExtensionMethods;

namespace Coinbase.Tests
{
Expand All @@ -29,5 +30,10 @@ public static HttpCallAssertion ShouldHaveRequestBody(this HttpTest test, string
test.CallLog.First().RequestBody.Should().Be(json);
return new HttpCallAssertion(test.CallLog);
}

public static bool IsAppVeyor(this OperatingSystem os)
{
return Environment.GetEnvironmentVariable("APPVEYOR").IsNotNullOrWhiteSpace();
}
}
}
}
16 changes: 16 additions & 0 deletions Source/Coinbase.Tests/Integration/DataTests.cs
Expand Up @@ -4,15 +4,31 @@
using System.Net.Http;
using System.Threading.Tasks;
using FluentAssertions;
using Flurl.Http;
using Flurl.Http.Configuration;
using NUnit.Framework;
using Z.ExtensionMethods;

namespace Coinbase.Tests.Integration
{
public class DataTests
{
private CoinbaseClient client;

[OneTimeSetUp]
public void BeforeAllTests()
{
if( !Environment.OSVersion.IsAppVeyor() )
{
var webProxy = new WebProxy("http://localhost.:8888", BypassOnLocal: false);

FlurlHttp.Configure(settings =>
{
settings.HttpClientFactory = new ProxyFactory(webProxy);
});
}
}

[SetUp]
public void BeforeEachTest()
{
Expand Down
25 changes: 20 additions & 5 deletions Source/Coinbase/CoinbaseClient.Data.cs
Expand Up @@ -40,7 +40,7 @@ public interface IDataEndpoint
/// <summary>
/// List known currencies. Currency codes will conform to the ISO 4217 standard where possible. Currencies which have or had no representation in ISO 4217 may use a custom code (e.g. BTC).
/// </summary>
Task<PagedResponse<Currency>> GetCurrenciesAsync();
Task<PagedResponse<Currency>> GetCurrenciesAsync(CancellationToken cancellationToken = default);

/// <summary>
/// Get the API server time.
Expand All @@ -60,6 +60,7 @@ public partial class CoinbaseClient : IDataEndpoint
Task<Response<Money>> IDataEndpoint.GetBuyPriceAsync(string currencyPair, CancellationToken cancellationToken)
{
return this.PricesEndpoint
.WithClient(this)
.AppendPathSegments(currencyPair, "buy")
.GetJsonAsync<Response<Money>>(cancellationToken);
}
Expand All @@ -72,6 +73,7 @@ Task<Response<Money>> IDataEndpoint.GetBuyPriceAsync(string currencyPair, Cancel
Task<Response<Money>> IDataEndpoint.GetSellPriceAsync(string currencyPair, CancellationToken cancellationToken)
{
return this.PricesEndpoint
.WithClient(this)
.AppendPathSegments(currencyPair, "sell")
.GetJsonAsync<Response<Money>>(cancellationToken);
}
Expand All @@ -85,6 +87,7 @@ Task<Response<Money>> IDataEndpoint.GetSellPriceAsync(string currencyPair, Cance
Task<Response<Money>> IDataEndpoint.GetSpotPriceAsync(string currencyPair, DateTime? date, CancellationToken cancellationToken)
{
var req = this.PricesEndpoint
.WithClient(this)
.AppendPathSegments(currencyPair, "spot");

if (!(date is null))
Expand All @@ -101,7 +104,8 @@ Task<Response<Money>> IDataEndpoint.GetSpotPriceAsync(string currencyPair, DateT
/// <param name="currency">Base currency (default: USD)</param>
Task<Response<ExchangeRates>> IDataEndpoint.GetExchangeRatesAsync(string currency, CancellationToken cancellationToken)
{
var req = this.ExchangeRatesEndpoint;
var req = this.ExchangeRatesEndpoint
.WithClient(this);

if (!(currency is null))
{
Expand All @@ -114,9 +118,11 @@ Task<Response<ExchangeRates>> IDataEndpoint.GetExchangeRatesAsync(string currenc
/// <summary>
/// List known currencies. Currency codes will conform to the ISO 4217 standard where possible. Currencies which have or had no representation in ISO 4217 may use a custom code (e.g. BTC).
/// </summary>
Task<PagedResponse<Currency>> IDataEndpoint.GetCurrenciesAsync()
Task<PagedResponse<Currency>> IDataEndpoint.GetCurrenciesAsync(CancellationToken cancellationToken)
{
return this.CurrenciesEndpoint.GetJsonAsync<PagedResponse<Currency>>();
return this.CurrenciesEndpoint
.WithClient(this)
.GetJsonAsync<PagedResponse<Currency>>(cancellationToken);
}


Expand All @@ -125,7 +131,16 @@ Task<PagedResponse<Currency>> IDataEndpoint.GetCurrenciesAsync()
/// </summary>
Task<Response<Time>> IDataEndpoint.GetCurrentTimeAsync(CancellationToken cancellationToken)
{
return this.TimeEndpoint.GetJsonAsync<Response<Time>>(cancellationToken);
// Manually make this request outside the scope of .WithClient(this)
// because when UseTimeApi =true and when the user makes the first request,
// we need to know the server time but if we use .WithClient(this),
// we'll get stuck in a recursive situation with no base case
// to resolve the actual server time. So, we have to make this
// request out of scope of this configured client.
return this.TimeEndpoint
.WithHeader(HeaderNames.Version, ApiVersionDate)
.WithHeader("User-Agent", UserAgent)
.GetJsonAsync<Response<Time>>(cancellationToken);
}

}
Expand Down

0 comments on commit 6a36cea

Please sign in to comment.