Skip to content

Commit

Permalink
Additional offer and catalog endpoint support
Browse files Browse the repository at this point in the history
  • Loading branch information
kwtc committed Jul 14, 2024
1 parent b192984 commit 55b2503
Show file tree
Hide file tree
Showing 6 changed files with 216 additions and 57 deletions.
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,17 @@ 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
> Minor and patch version bumps may have breaking changes until version 1.0.0 is released
## Supported endpoint status
- [x] /v2/offers/search
- [ ] /v2/offers
- [ ] /v2/offers/{offerId}
- [x] /v2/offers
- [x] /v2/offers/{offerId}
- [x] /v2/catalogs
- [ ] /v2/catalogs/{catalogId}
- [ ] /v2/catalogs/{catalogId}/pages
- [ ] /v2/catalogs/{catalogId}/hotspots
- [ ] /v2/catalogs/{catalogId}/page_decorations

## How to use
Add configuration to appsettings.json
Expand Down
23 changes: 15 additions & 8 deletions src/Kwtc.Tjek.Client.Abstractions/ITjekClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public interface ITjekClient
/// <summary>
/// Search for offers
/// </summary>
public Task<IReadOnlyList<Offer>> Search(
public Task<IReadOnlyList<Offer>> SearchOffers(
string query,
string? dealerId = null,
string? catalogId = null,
Expand All @@ -16,11 +16,9 @@ public Task<IReadOnlyList<Offer>> Search(
CancellationToken cancellationToken = default);

/// <summary>
/// NOT IMPLEMENTED
///
/// Get list current offers
/// Get list of current offers
/// </summary>
public Task<IReadOnlyList<Offer>> List(
public Task<IReadOnlyList<Offer>> ListOffers(
string? dealerId = null,
string? catalogId = null,
string? publicationType = null,
Expand All @@ -30,9 +28,18 @@ public Task<IReadOnlyList<Offer>> List(
CancellationToken cancellationToken = default);

/// <summary>
/// NOT IMPLEMENTED
///
/// Get offer by id
/// </summary>
public Task<Offer?> Offer(string id, CancellationToken cancellationToken = default);
public Task<Offer?> GetOffer(string id, CancellationToken cancellationToken = default);

/// <summary>
/// Get list of catalogs
/// </summary>
public Task<IReadOnlyList<Catalog>> ListCatalogs(
string? dealerId = null,
string? publicationType = null,
int? limit = null,
int? offset = null,
string? orderBy = null,
CancellationToken cancellationToken = default);
}
69 changes: 69 additions & 0 deletions src/Kwtc.Tjek.Client.Abstractions/Models/Catalog.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
using System.Text.Json.Serialization;

namespace Kwtc.Tjek.Client.Abstractions.Models;

public class Catalog
{
[JsonPropertyName("id")]
public string Id { get; set; } = default!;

[JsonPropertyName("ern")]
public string Ern { get; set; } = default!;

[JsonPropertyName("run_from")]
public string FromDate { get; set; } = default!;

[JsonPropertyName("store_id")]
public string? StoreId { get; set; }

[JsonPropertyName("store_url")]
public string StoreUrl { get; set; } = default!;

[JsonPropertyName("images")]
public Images Images { get; set; } = default!;

[JsonPropertyName("types")]
public string[] Types { get; set; } = default!;

[JsonPropertyName("incito_publication_id")]
public string? IncitoPublicationId { get; set; }

[JsonPropertyName("all_stores")]
public bool AllStores { get; set; }

[JsonPropertyName("dealer_url")]
public string DealerUrl { get; set; } = default!;

[JsonPropertyName("branding")]
public Branding Branding { get; set; } = default!;

[JsonPropertyName("pdf_url")]
public string PdfUrl { get; set; } = default!;

[JsonPropertyName("label")]
public string Label { get; set; } = default!;

[JsonPropertyName("run_till")]
public string ToDate { get; set; } = default!;

[JsonPropertyName("background")]
public string Background { get; set; } = default!;

[JsonPropertyName("category_ids")]
public string[] CategoryIds { get; set; } = default!;

[JsonPropertyName("offer_count")]
public long OfferCount { get; set; }

[JsonPropertyName("page_count")]
public long PageCount { get; set; }

[JsonPropertyName("dealer_id")]
public string DealerId { get; set; } = default!;

[JsonPropertyName("dealer")]
public Dealer Dealer { get; set; } = default!;

[JsonPropertyName("dimensions")]
public Dimensions Dimensions { get; set; } = default!;
}
12 changes: 12 additions & 0 deletions src/Kwtc.Tjek.Client.Abstractions/Models/Dimensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Text.Json.Serialization;

namespace Kwtc.Tjek.Client.Abstractions.Models;

public class Dimensions
{
[JsonPropertyName("width")]
public decimal Width { get; set; }

[JsonPropertyName("height")]
public decimal Height { get; set; }
}
94 changes: 80 additions & 14 deletions src/Kwtc.Tjek.Client/TjekClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public TjekClient(IHttpClientFactory httpClientFactory)
this.httpClientFactory = httpClientFactory;
}

public async Task<IReadOnlyList<Offer>> Search(
public async Task<IReadOnlyList<Offer>> SearchOffers(
string query,
string? dealerId = null,
string? catalogId = null,
Expand All @@ -27,10 +27,9 @@ public async Task<IReadOnlyList<Offer>> Search(

// Build query string
var builder = new StringBuilder();
builder.Append($"?query={query.ToValidUri()}");

var queryString = BuildQueryString(new Dictionary<string, string>
{
{ "query", $"{query}" },
{ "dealer_id", $"{dealerId}" },
{ "catalog_id", $"{catalogId}" },
{ "types", $"{publicationType}" },
Expand All @@ -53,32 +52,99 @@ public async Task<IReadOnlyList<Offer>> Search(
return result ?? [];
}

/// <summary>
/// NOT IMPLEMENTED
/// </summary>
public Task<IReadOnlyList<Offer>> List(string? dealerId = null, string? catalogId = null, string? publicationType = null, int? limit = null, int? offset = null, string? orderBy = null, CancellationToken cancellationToken = default)
public async Task<IReadOnlyList<Offer>> ListOffers(string? dealerId = null, string? catalogId = null, string? publicationType = null, int? limit = null, int? offset = null, string? orderBy = null, CancellationToken cancellationToken = default)
{
// Build query string
var builder = new StringBuilder();
var queryString = BuildQueryString(new Dictionary<string, string>
{
{ "dealer_id", $"{dealerId}" },
{ "catalog_id", $"{catalogId}" },
{ "types", $"{publicationType}" },
{ "order_by", $"{orderBy ?? "page"}" },
{ "offset", $"{offset}" },
{ "limit", $"{limit}" },
}, builder);

var client = this.httpClientFactory.CreateClient(Constants.HttpClientName);
var response = await client.GetAsync($"v2/offers{queryString}", cancellationToken);

response.EnsureSuccessStatusCode();

var contentStream = await response.Content.ReadAsStreamAsync(cancellationToken);
if (contentStream.Length == 0)
{
throw new HttpRequestException(HttpRequestError.InvalidResponse, "Response content is empty");
}

var result = await JsonSerializer.DeserializeAsync<IReadOnlyList<Offer>>(contentStream, cancellationToken: cancellationToken);

return result ?? [];
}

public async Task<Offer?> GetOffer(string id, CancellationToken cancellationToken = default)
{
throw new NotImplementedException();
Guard.IsNotNullOrEmpty(id, nameof(id));

var client = this.httpClientFactory.CreateClient(Constants.HttpClientName);
var response = await client.GetAsync($"v2/offers/{id}", cancellationToken);

response.EnsureSuccessStatusCode();

var contentStream = await response.Content.ReadAsStreamAsync(cancellationToken);
if (contentStream.Length == 0)
{
throw new HttpRequestException(HttpRequestError.InvalidResponse, "Response content is empty");
}

return await JsonSerializer.DeserializeAsync<Offer>(contentStream, cancellationToken: cancellationToken);
}

/// <summary>
/// NOT IMPLEMENTED
/// </summary>
public Task<Offer?> Offer(string id, CancellationToken cancellationToken = default)
public async Task<IReadOnlyList<Catalog>> ListCatalogs(string? dealerId = null, string? publicationType = null, int? limit = null, int? offset = null, string? orderBy = null, CancellationToken cancellationToken = default)
{
throw new NotImplementedException();
// Build query string
var builder = new StringBuilder();
var queryString = BuildQueryString(new Dictionary<string, string>
{
{ "dealer_id", $"{dealerId}" },
{ "types", $"{publicationType}" },
{ "order_by", $"{orderBy}" },
{ "offset", $"{offset}" },
{ "limit", $"{limit}" },
}, builder);

var client = this.httpClientFactory.CreateClient(Constants.HttpClientName);
var response = await client.GetAsync($"v2/catalogs{queryString}", cancellationToken);

response.EnsureSuccessStatusCode();

var contentStream = await response.Content.ReadAsStreamAsync(cancellationToken);
if (contentStream.Length == 0)
{
throw new HttpRequestException(HttpRequestError.InvalidResponse, "Response content is empty");
}

var content = await response.Content.ReadAsStringAsync(cancellationToken);

var result = await JsonSerializer.DeserializeAsync<IReadOnlyList<Catalog>>(contentStream, cancellationToken: cancellationToken);

return result ?? [];
}

private static string BuildQueryString(IDictionary<string, string> parameters, StringBuilder builder)
{
var i = 0;
foreach (var parameter in parameters)
{
if (string.IsNullOrEmpty(parameter.Value))
{
continue;
}

builder.Append($"&{parameter.Key}={parameter.Value.ToValidUri()}");
builder.Append(i == 0 ? "?" : "&");
builder.Append($"{parameter.Key}={parameter.Value.ToValidUri()}");

i++;
}

return builder.ToString();
Expand Down
Loading

0 comments on commit 55b2503

Please sign in to comment.