diff --git a/README.md b/README.md index f28ebec..3cf6399 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,48 @@ ![.NET build and test](https://github.com/kwtc/tjek-client-dotnet/actions/workflows/ci.yml/badge.svg) -# Kwtc.Tjek.Client.Dotnet -Tjek.com API client for dotnet +# Tjek.com .NET API client +As the heading states this is a .NET API client for tjek.com + +> **Warning** +> This is work in progress +> +> Minor and patch version bumps may break your code until version 1.0.0 is released + +## Supported endpoint status +- [x] /v2/offers/search +- [ ] /v2/offers +- [ ] /v2/offers/{offerId} + +## How to use +Add configuration to appsettings.json + +```json +{ + "TjekClientConfig": { + "ApiKey": "" + } +} +``` +An API key can be requested here: https://etilbudsavis.dk/developers + +The client project includes an extension method that makes registering the client and services in the DI container easy. + +```csharp +builder.Services.AddTjekClientServices(builder.Configuration); +``` + +After registering the services you can inject the client and configuration. + +```csharp +public class MyService +{ + private readonly ITjekClient _tjekClient; + private readonly TjekClientConfig _tjekClientConfig; + + public MyService(ITjekClient tjekClient, IOptions tjekClientConfig) + { + _tjekClient = tjekClient; + _tjekClientConfig = tjekClientConfig.Value; + } +} +``` diff --git a/src/Kwtc.Tjek.Client/ClientConfig.cs b/src/Kwtc.Tjek.Client.Abstractions/Config/TjekClientConfig.cs similarity index 60% rename from src/Kwtc.Tjek.Client/ClientConfig.cs rename to src/Kwtc.Tjek.Client.Abstractions/Config/TjekClientConfig.cs index a88407f..590540c 100644 --- a/src/Kwtc.Tjek.Client/ClientConfig.cs +++ b/src/Kwtc.Tjek.Client.Abstractions/Config/TjekClientConfig.cs @@ -1,6 +1,6 @@ -namespace Kwtc.Tjek.Client; +namespace Kwtc.Tjek.Client.Abstractions.Config; -public class ClientConfig +public class TjekClientConfig { public static string SectionName => "TjekClientConfig"; diff --git a/src/Kwtc.Tjek.Client.Abstractions/IClient.cs b/src/Kwtc.Tjek.Client.Abstractions/IClient.cs deleted file mode 100644 index 66baef9..0000000 --- a/src/Kwtc.Tjek.Client.Abstractions/IClient.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Kwtc.Tjek.Client.Abstractions.Models; - -namespace Kwtc.Tjek.Client.Abstractions; - -public interface IClient -{ - public Task> Search( - string query, - string? dealerId = null, - string? catalogId = null, - string? publicationType = null, - int? limit = null, - CancellationToken cancellationToken = default); -} diff --git a/src/Kwtc.Tjek.Client.Abstractions/ITjekClient.cs b/src/Kwtc.Tjek.Client.Abstractions/ITjekClient.cs new file mode 100644 index 0000000..4cf619c --- /dev/null +++ b/src/Kwtc.Tjek.Client.Abstractions/ITjekClient.cs @@ -0,0 +1,38 @@ +using Kwtc.Tjek.Client.Abstractions.Models; + +namespace Kwtc.Tjek.Client.Abstractions; + +public interface ITjekClient +{ + /// + /// Search for offers + /// + public Task> Search( + string query, + string? dealerId = null, + string? catalogId = null, + string? publicationType = null, + int? limit = null, + CancellationToken cancellationToken = default); + + /// + /// NOT IMPLEMENTED + /// + /// Get list current offers + /// + public Task> List( + string? dealerId = null, + string? catalogId = null, + string? publicationType = null, + int? limit = null, + int? offset = null, + string? orderBy = null, + CancellationToken cancellationToken = default); + + /// + /// NOT IMPLEMENTED + /// + /// Get offer by id + /// + public Task Offer(string id, CancellationToken cancellationToken = default); +} diff --git a/src/Kwtc.Tjek.Client/ServiceCollectionExtensions.cs b/src/Kwtc.Tjek.Client/ServiceCollectionExtensions.cs index 83b8c69..a4424ea 100644 --- a/src/Kwtc.Tjek.Client/ServiceCollectionExtensions.cs +++ b/src/Kwtc.Tjek.Client/ServiceCollectionExtensions.cs @@ -1,4 +1,5 @@ using Kwtc.Tjek.Client.Abstractions; +using Kwtc.Tjek.Client.Abstractions.Config; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -8,13 +9,13 @@ public static class ServiceCollectionExtensions { public static IServiceCollection AddTjekClientServices(this IServiceCollection services, ConfigurationManager configuration) { - var clientConfig = configuration.GetSection(ClientConfig.SectionName).Get(); + var clientConfig = configuration.GetSection(TjekClientConfig.SectionName).Get(); if (clientConfig is null) { throw new InvalidOperationException("Client configuration is missing"); } - services.Configure(configuration.GetSection(ClientConfig.SectionName)); + services.Configure(configuration.GetSection(TjekClientConfig.SectionName)); services.AddHttpClient(Constants.HttpClientName, client => { @@ -23,7 +24,7 @@ public static IServiceCollection AddTjekClientServices(this IServiceCollection s client.DefaultRequestHeaders.Add("X-Api-Key", clientConfig.ApiKey); }); - services.AddTransient(); + services.AddTransient(); return services; } diff --git a/src/Kwtc.Tjek.Client/StringExtensions.cs b/src/Kwtc.Tjek.Client/StringExtensions.cs index 11cff86..1f9acb3 100644 --- a/src/Kwtc.Tjek.Client/StringExtensions.cs +++ b/src/Kwtc.Tjek.Client/StringExtensions.cs @@ -4,6 +4,8 @@ public static class StringExtensions { public static string ToValidUri(this string input) { + // TODO: Improve this method or find alternative + var str = input; str = System.Text.RegularExpressions.Regex.Replace(str, @"[^a-zA-Z0-9\s-æøåÆØÅ?&=]", ""); str = System.Text.RegularExpressions.Regex.Replace(str, @"\s+", " ").Trim(); diff --git a/src/Kwtc.Tjek.Client/Client.cs b/src/Kwtc.Tjek.Client/TjekClient.cs similarity index 76% rename from src/Kwtc.Tjek.Client/Client.cs rename to src/Kwtc.Tjek.Client/TjekClient.cs index be580a2..e75539d 100644 --- a/src/Kwtc.Tjek.Client/Client.cs +++ b/src/Kwtc.Tjek.Client/TjekClient.cs @@ -6,11 +6,11 @@ namespace Kwtc.Tjek.Client; -public class Client : IClient +public class TjekClient : ITjekClient { private readonly IHttpClientFactory httpClientFactory; - public Client(IHttpClientFactory httpClientFactory) + public TjekClient(IHttpClientFactory httpClientFactory) { this.httpClientFactory = httpClientFactory; } @@ -53,6 +53,22 @@ public async Task> Search( return result ?? []; } + /// + /// NOT IMPLEMENTED + /// + public Task> List(string? dealerId = null, string? catalogId = null, string? publicationType = null, int? limit = null, int? offset = null, string? orderBy = null, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + /// + /// NOT IMPLEMENTED + /// + public Task Offer(string id, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + private static string BuildQueryString(IDictionary parameters, StringBuilder builder) { foreach (var parameter in parameters) diff --git a/test/Kwtc.Tjek.Client.Tests/UnitTests/ClientTests.cs b/test/Kwtc.Tjek.Client.Tests/UnitTests/TjekClientTests.cs similarity index 98% rename from test/Kwtc.Tjek.Client.Tests/UnitTests/ClientTests.cs rename to test/Kwtc.Tjek.Client.Tests/UnitTests/TjekClientTests.cs index 02f28ea..8ea700b 100644 --- a/test/Kwtc.Tjek.Client.Tests/UnitTests/ClientTests.cs +++ b/test/Kwtc.Tjek.Client.Tests/UnitTests/TjekClientTests.cs @@ -7,7 +7,7 @@ namespace Kwtc.Tjek.Client.Tests.UnitTests; -public class ClientTests +public class TjekClientTests { private readonly Mock httpClientFactoryMock = new(); @@ -263,8 +263,8 @@ private static HttpClient GetMockedClient(string uri, HttpStatusCode statusCode return httpClient; } - private Client GetSut() + private TjekClient GetSut() { - return new Client(this.httpClientFactoryMock.Object); + return new TjekClient(this.httpClientFactoryMock.Object); } }