Skip to content
Merged
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
509 changes: 431 additions & 78 deletions Metron Comicbook Database.yaml

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions src/Metron.Api/Filters/PublisherFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ namespace Metron.Api.Filters;

public sealed class PublisherFilter
{
[QueryParameter("alt_names")]
public string? AltNames { get; set; }

/// <summary>Comic Vine ID</summary>
[QueryParameter("cv_id")]
public int? CvId { get; set; }
Expand All @@ -30,4 +33,8 @@ public sealed class PublisherFilter
/// <summary>A page number within the paginated result set.</summary>
[QueryParameter("page")]
public int? Page { get; set; }

/// <summary>Quick search across name and alternative names</summary>
[QueryParameter("q")]
public string? Q { get; set; }
}
4 changes: 4 additions & 0 deletions src/Metron.Api/Filters/SeriesFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ public sealed class SeriesFilter
[QueryParameter("imprint_name")]
public string? ImprintName { get; set; }

/// <summary>* `af` - Afrikaans</summary>
[QueryParameter("language")]
public string? Language { get; set; }

[QueryParameter("missing_cv_id")]
public bool? MissingCvId { get; set; }

Expand Down
4 changes: 4 additions & 0 deletions src/Metron.Api/Models/Generated/Enums.cs
Original file line number Diff line number Diff line change
Expand Up @@ -552,12 +552,16 @@ public enum CountryEnum
/// <summary>
/// * `USD` - USD
/// * `GBP` - GBP
/// * `EUR` - EUR
/// * `ITL` - ITL
/// </summary>
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum CurrencyEnum
{
USD,
GBP,
EUR,
ITL,
}

/// <summary>
Expand Down
3 changes: 3 additions & 0 deletions src/Metron.Api/Models/Generated/IssueSeries.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,7 @@ public sealed class IssueSeries

[JsonPropertyName("genres")]
public List<Genre>? Genres { get; set; }

[JsonPropertyName("language")]
public string? Language { get; set; }
}
4 changes: 4 additions & 0 deletions src/Metron.Api/Models/Generated/PatchedPublisher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ public sealed class PatchedPublisher
[JsonPropertyName("name")]
public string? Name { get; set; }

/// <summary>Alternative Names</summary>
[JsonPropertyName("alt_names")]
public List<string>? AltNames { get; set; }

/// <summary>Year Founded</summary>
[JsonPropertyName("founded")]
public int? Founded { get; set; }
Expand Down
3 changes: 3 additions & 0 deletions src/Metron.Api/Models/Generated/PatchedSeries.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ public sealed class PatchedSeries
[JsonPropertyName("alt_names")]
public List<string>? AltNames { get; set; }

[JsonPropertyName("language")]
public string? Language { get; set; }

/// <summary>Volume Number</summary>
[JsonPropertyName("volume")]
public int? Volume { get; set; }
Expand Down
4 changes: 4 additions & 0 deletions src/Metron.Api/Models/Generated/Publisher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ public sealed class Publisher
[JsonPropertyName("name")]
public string? Name { get; set; }

/// <summary>Alternative Names</summary>
[JsonPropertyName("alt_names")]
public List<string>? AltNames { get; set; }

/// <summary>Year Founded</summary>
[JsonPropertyName("founded")]
public int? Founded { get; set; }
Expand Down
3 changes: 3 additions & 0 deletions src/Metron.Api/Models/Generated/Series.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ public sealed class Series
[JsonPropertyName("alt_names")]
public List<string>? AltNames { get; set; }

[JsonPropertyName("language")]
public string? Language { get; set; }

/// <summary>Volume Number</summary>
[JsonPropertyName("volume")]
public int? Volume { get; set; }
Expand Down
3 changes: 3 additions & 0 deletions src/Metron.Api/Models/Generated/SeriesRead.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ public sealed class SeriesRead
[JsonPropertyName("alt_names")]
public List<string>? AltNames { get; set; }

[JsonPropertyName("language")]
public string? Language { get; set; }

/// <summary>Volume Number</summary>
[JsonPropertyName("volume")]
public int? Volume { get; set; }
Expand Down
59 changes: 59 additions & 0 deletions tests/Metron.Api.Tests/ClientIntegrationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -142,4 +142,63 @@ public async Task Collection_RemoveAsync_SendsDeleteRequest()
Assert.Equal(HttpMethod.Delete, request.Method);
Assert.Equal("https://metron.cloud/api/collection/7/", request.RequestUri!.ToString());
}

[Fact]
public async Task Publisher_ListAsync_BuildsQueryStringFromAltNamesAndQuickSearchFilter()
{
var fake = new FakeHttpMessageHandler();
fake.Enqueue(FakeHttpMessageHandler.Json(HttpStatusCode.OK, """
{"count": 0, "next": null, "previous": null, "results": []}
"""));

using var client = CreateClient(fake);
await client.Publisher.ListAsync(new PublisherFilter { AltNames = "DC", Q = "comics" });

var request = Assert.Single(fake.Requests);
Assert.Contains("alt_names=DC", request.RequestUri!.Query);
Assert.Contains("q=comics", request.RequestUri!.Query);
}

[Fact]
public async Task Publisher_GetAsync_DeserializesAltNames()
{
var fake = new FakeHttpMessageHandler();
fake.Enqueue(FakeHttpMessageHandler.Json(HttpStatusCode.OK, """
{"id": 1, "name": "DC Comics", "alt_names": ["National Comics", "DC"], "modified": "2024-01-01T00:00:00Z"}
"""));

using var client = CreateClient(fake);
var publisher = await client.Publisher.GetAsync(1);

Assert.Equal(["National Comics", "DC"], publisher.AltNames);
}

[Fact]
public async Task Series_ListAsync_BuildsQueryStringFromLanguageFilter()
{
var fake = new FakeHttpMessageHandler();
fake.Enqueue(FakeHttpMessageHandler.Json(HttpStatusCode.OK, """
{"count": 0, "next": null, "previous": null, "results": []}
"""));

using var client = CreateClient(fake);
await client.Series.ListAsync(new SeriesFilter { Language = "it" });

var request = Assert.Single(fake.Requests);
Assert.Contains("language=it", request.RequestUri!.Query);
}

[Fact]
public async Task Series_GetAsync_DeserializesLanguage()
{
var fake = new FakeHttpMessageHandler();
fake.Enqueue(FakeHttpMessageHandler.Json(HttpStatusCode.OK, """
{"id": 1, "name": "Amazing Spider-Man", "language": "it", "modified": "2024-01-01T00:00:00Z"}
"""));

using var client = CreateClient(fake);
var series = await client.Series.GetAsync(1);

Assert.Equal("it", series.Language);
}
}
13 changes: 13 additions & 0 deletions tests/Metron.Api.Tests/MultipartFormDataBuilderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,19 @@ public async Task Build_FormatsDateOnlyAsIso()
Assert.Contains(("cover_date", "2024-03-15"), parts);
}

[Theory]
[InlineData(CurrencyEnum.EUR, "2")]
[InlineData(CurrencyEnum.ITL, "3")]
public async Task Build_SerializesNewCurrencyEnumValues(CurrencyEnum currency, string expected)
{
var item = new AcquireWishListItem { PurchasePriceCurrency = currency };

using var content = MultipartFormDataBuilder.Build(item);
var parts = await ReadPartsAsync(content);

Assert.Contains(("purchase_price_currency", expected), parts);
}

private static async Task<List<(string Name, string Value)>> ReadPartsAsync(MultipartFormDataContent content)
{
var results = new List<(string, string)>();
Expand Down
21 changes: 21 additions & 0 deletions tests/Metron.Api.Tests/QueryStringBuilderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,25 @@ public void Build_EscapesSpecialCharacters()

Assert.Equal("?name=Spider-Man%20%26%20Friends", query);
}

[Fact]
public void Build_IncludesPublisherAltNamesAndQuickSearchFilters()
{
var filter = new PublisherFilter { AltNames = "DC", Q = "comics" };

var query = QueryStringBuilder.Build(filter);

Assert.Contains("alt_names=DC", query);
Assert.Contains("q=comics", query);
}

[Fact]
public void Build_IncludesSeriesLanguageFilter()
{
var filter = new SeriesFilter { Language = "en" };

var query = QueryStringBuilder.Build(filter);

Assert.Equal("?language=en", query);
}
}
Loading