Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding an Interface for DI and CancellationToken for async methods #48

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions src/Taxjar.Tests/Bootstrap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,19 @@ public static void Destroy()

private static TestOptions GetTestOptions()
{
var json = File.ReadAllText("../../../secrets.json");
var options = JsonConvert.DeserializeObject<TestOptions>(json);
return options;
if (File.Exists("../../../secrets.json"))
{
var json = File.ReadAllText("../../../secrets.json");
var options = JsonConvert.DeserializeObject<TestOptions>(json);
return options;
}

return new TestOptions();
}

private class TestOptions
{
public string ApiToken { get; set; }
public string ApiToken { get; set; } = "69c23367-5696-473d-a3e2-2142564cacae";
}
}
}
83 changes: 83 additions & 0 deletions src/Taxjar.Tests/DependencyInjection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#if NETCOREAPP2_1

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;

using NUnit.Framework;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Taxjar.Options;

namespace Taxjar.Tests
{
[TestFixture]
public class DependencyInjection
{
[Test]
public void when_registering_single_client_di()
{
var d = new Dictionary<string, string>
{
{"TaxjarOptions:ApiToken", "69c23367-5696-473d-a3e2-2142564cacae" },
{"TaxjarOptions:ApiUrl", TaxjarConstants.SandboxApiUrl },
{"TaxjarOptions:Timeout", "30" },
};

var configBuilder = new ConfigurationBuilder().AddInMemoryCollection(d);

var services = new ServiceCollection();

services.AddSingleton<IConfiguration>(configBuilder.Build());
services.AddTaxjar();

var sp = services.BuildServiceProvider();

var options = sp.GetRequiredService<IOptionsMonitor<TaxjarOptions>>().Get(nameof(TaxjarOptions));
var clinet = sp.GetRequiredService<ITaxjarApi>();

Assert.AreEqual($"{TaxjarConstants.SandboxApiUrl}/{TaxjarConstants.ApiVersion}/", clinet.apiUrl);
Assert.AreEqual(TaxjarConstants.SandboxApiUrl, options.ApiUrl);
}

[Test]
public void when_registering_two_clients_di()
{
var production = "TaxjarOptionsProduction";
var sandbox = "TaxjarOptionsSandbox";

var d = new Dictionary<string, string>
{
{$"{sandbox}:ApiToken", "69c23367-5696-473d-a3e2-2142564cacae" },
{$"{sandbox}:ApiUrl", TaxjarConstants.SandboxApiUrl },
{$"{sandbox}:Timeout", "40" },

{$"{production}:ApiToken", "eee4b9f8-1c31-41e2-b21b-cd6b7111596d" },
{$"{production}:ApiUrl", TaxjarConstants.DefaultApiUrl },
{$"{production}:Timeout", "30" },
};

var configBuilder = new ConfigurationBuilder().AddInMemoryCollection(d);

var services = new ServiceCollection();

services.AddSingleton<IConfiguration>(configBuilder.Build());
services.AddTaxjar(sandbox);
services.AddTaxjar(production);

var sp = services.BuildServiceProvider();

var sandBoxoptions = sp.GetRequiredService<IOptionsMonitor<TaxjarOptions>>().Get(sandbox);
var clinet = sp.GetServices<ITaxjarApi>();

Assert.AreEqual(2, clinet.Count());
Assert.AreEqual(TaxjarConstants.SandboxApiUrl, sandBoxoptions.ApiUrl);
}
}
}
#endif
15 changes: 5 additions & 10 deletions src/Taxjar.Tests/TaxJar.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netcoreapp2.0;net452</TargetFrameworks>
<TargetFrameworks>netcoreapp2.1;net452</TargetFrameworks>
<RootNamespace>Taxjar.Tests</RootNamespace>
<AssemblyName>TaxJar.Tests</AssemblyName>
<IsPackable>false</IsPackable>
Expand All @@ -15,14 +15,9 @@
</PropertyGroup>

<ItemGroup>
<Folder Include="Fixtures\" />
<Folder Include="Infrastructure\" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
<PackageReference Include="NUnit" Version="3.9.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.9.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
<PackageReference Include="RestSharp" Version="106.10.1" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="WireMock.Net.StandAlone" Version="1.0.19.0" />
Expand Down
28 changes: 28 additions & 0 deletions src/Taxjar/DependencyInjection/TaxjarOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#if NETSTANDARD2_0
using System;

namespace Taxjar.Options
{
/// <summary>
/// The options for <see cref="ITaxjarApi"/> client.
/// </summary>
public class TaxjarOptions
{
/// <summary>
/// Taxjar token.
/// </summary>
public string ApiToken { get; set; }

/// <summary>
/// The base url used by <see cref="TaxjarApi"/> client.
/// </summary>
public string ApiUrl { get; set; } = TaxjarConstants.DefaultApiUrl;


/// <summary>
/// Timeout in seconds for the HttpClient.
/// </summary>
public int Timeout { get; set; }
}
}
#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#if NETSTANDARD2_0

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;

using System;

using Taxjar;
using Taxjar.Options;

namespace Microsoft.Extensions.Configuration
{
/// <summary>
/// Add TaxjarApi to Dependency Injection.
/// </summary>
public static class TaxjarServiceCollectionExtensions
{
/// <summary>
/// Adds <see cref="ITaxjarApi"/> client to DI.
/// </summary>
/// <param name="services">The DI services.</param>
/// <param name="namedOption">Add a named options functionality.</param>
/// <param name="configure">The configuration for <see cref="TaxjarOptions"/>.</param>
/// <returns></returns>
public static IServiceCollection AddTaxjar(this IServiceCollection services,
string namedOption = "",
Action<TaxjarOptions, IConfiguration> configure = default)
{
var name = string.IsNullOrEmpty(namedOption) ? nameof(TaxjarOptions) : namedOption;

services.AddOptions<TaxjarOptions>(name)
.Configure<IConfiguration>((o, c) =>
{
c.Bind(name, o);

configure?.Invoke(o, c);
});

services.AddTransient<ITaxjarApi, TaxjarApi>(sp =>
{
var options = sp.GetRequiredService<IOptionsMonitor<TaxjarOptions>>().Get(name);

var baseUrl = options.ApiUrl;

return new TaxjarApi(
options.ApiToken,
new { apiUrl = baseUrl, timeout = options.Timeout });
});

return services;
}
}
}
#endif
113 changes: 113 additions & 0 deletions src/Taxjar/ITaxjarApi.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace Taxjar
{
public interface ITaxjarApi
{
string apiToken { get; set; }


string apiUrl { get; set; }

IDictionary<string, string> headers { get; set; }

/// <summary>
/// Milliseconds.
/// </summary>
int timeout { get; set; }

List<Category> Categories();

Task<List<Category>> CategoriesAsync(CancellationToken cancellationToken = default);

CustomerResponseAttributes CreateCustomer(object parameters);

Task<CustomerResponseAttributes> CreateCustomerAsync(object parameters, CancellationToken cancellationToken = default);

OrderResponseAttributes CreateOrder(object parameters);

Task<OrderResponseAttributes> CreateOrderAsync(object parameters, CancellationToken cancellationToken = default);

RefundResponseAttributes CreateRefund(object parameters);

Task<RefundResponseAttributes> CreateRefundAsync(object parameters, CancellationToken cancellationToken = default);

CustomerResponseAttributes DeleteCustomer(string customerId);

Task<CustomerResponseAttributes> DeleteCustomerAsync(string customerId, CancellationToken cancellationToken = default);

OrderResponseAttributes DeleteOrder(string transactionId, object parameters = null);

Task<OrderResponseAttributes> DeleteOrderAsync(string transactionId, object parameters = null, CancellationToken cancellationToken = default);

RefundResponseAttributes DeleteRefund(string transactionId, object parameters = null);

Task<RefundResponseAttributes> DeleteRefundAsync(string transactionId, object parameters = null, CancellationToken cancellationToken = default);

object GetApiConfig(string key);

List<string> ListCustomers(object parameters = null);

Task<List<string>> ListCustomersAsync(object parameters = null, CancellationToken cancellationToken = default);

List<string> ListOrders(object parameters = null);

Task<List<string>> ListOrdersAsync(object parameters = null, CancellationToken cancellationToken = default);

List<string> ListRefunds(object parameters);

Task<List<string>> ListRefundsAsync(object parameters, CancellationToken cancellationToken = default);

List<NexusRegion> NexusRegions();

Task<List<NexusRegion>> NexusRegionsAsync(CancellationToken cancellationToken = default);

RateResponseAttributes RatesForLocation(string zip, object parameters = null);

Task<RateResponseAttributes> RatesForLocationAsync(string zip, object parameters = null, CancellationToken cancellationToken = default);

void SetApiConfig(string key, object value);

CustomerResponseAttributes ShowCustomer(string customerId);

Task<CustomerResponseAttributes> ShowCustomerAsync(string customerId, CancellationToken cancellationToken = default);

OrderResponseAttributes ShowOrder(string transactionId, object parameters = null);

Task<OrderResponseAttributes> ShowOrderAsync(string transactionId, object parameters = null, CancellationToken cancellationToken = default);

RefundResponseAttributes ShowRefund(string transactionId, object parameters = null);

Task<RefundResponseAttributes> ShowRefundAsync(string transactionId, object parameters = null, CancellationToken cancellationToken = default);

List<SummaryRate> SummaryRates();

Task<List<SummaryRate>> SummaryRatesAsync(CancellationToken cancellationToken = default);

TaxResponseAttributes TaxForOrder(object parameters);

Task<TaxResponseAttributes> TaxForOrderAsync(object parameters, CancellationToken cancellationToken = default);

CustomerResponseAttributes UpdateCustomer(object parameters);

Task<CustomerResponseAttributes> UpdateCustomerAsync(object parameters, CancellationToken cancellationToken = default);

OrderResponseAttributes UpdateOrder(object parameters);

Task<OrderResponseAttributes> UpdateOrderAsync(object parameters, CancellationToken cancellationToken = default);

RefundResponseAttributes UpdateRefund(object parameters);

Task<RefundResponseAttributes> UpdateRefundAsync(object parameters, CancellationToken cancellationToken = default);

List<Address> ValidateAddress(object parameters);

Task<List<Address>> ValidateAddressAsync(object parameters, CancellationToken cancellationToken = default);

ValidationResponseAttributes ValidateVat(object parameters);

Task<ValidationResponseAttributes> ValidateVatAsync(object parameters, CancellationToken cancellationToken = default);
}
}
29 changes: 22 additions & 7 deletions src/Taxjar/Taxjar.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard2.0;net452</TargetFrameworks>
Expand All @@ -20,15 +20,30 @@
<DebugType>portable</DebugType>
</PropertyGroup>

<ItemGroup>
<Folder Include="Entities\" />
<Folder Include="Infrastructure\" />
<Folder Include="Properties\" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="RestSharp" Version="106.10.1" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="Microsoft.Extensions.Configuration.Binder " Version="3.1.10"/>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.1.10" />
<PackageReference Include="Microsoft.Extensions.Options" Version="3.1.10" />
</ItemGroup>

<ItemGroup Label="SourceLink">
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
</ItemGroup>

<PropertyGroup Label="SourceLink Settings">
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>

<!-- https://github.com/kdcllc/Bet.AspNetCore/issues/103 -->
<DebugType>Embedded</DebugType>
<EmbedAllSources>True</EmbedAllSources>
</PropertyGroup>

</Project>
Loading