diff --git a/src/IPData/Http/Serializer/IntJsonConverter.cs b/src/IPData/Http/Serializer/IntJsonConverter.cs new file mode 100644 index 0000000..82dd6db --- /dev/null +++ b/src/IPData/Http/Serializer/IntJsonConverter.cs @@ -0,0 +1,30 @@ +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace IPData.Http.Serializer +{ + internal class IntJsonConverter : JsonConverter + { + public override int Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.String) + { + var stringValue = reader.GetString(); + if (int.TryParse(stringValue, out var value)) + { + return value; + } + + throw new JsonException($"Unable to convert \"{stringValue}\" to System.Int32."); + } + + return reader.GetInt32(); + } + + public override void Write(Utf8JsonWriter writer, int value, JsonSerializerOptions options) + { + writer.WriteNumberValue(value); + } + } +} diff --git a/src/IPData/Models/IPLookupResult.cs b/src/IPData/Models/IPLookupResult.cs index 4f8e819..e69f754 100644 --- a/src/IPData/Models/IPLookupResult.cs +++ b/src/IPData/Models/IPLookupResult.cs @@ -4,6 +4,7 @@ using System.Linq.Expressions; using System.Text.Json.Serialization; using IPData.Helpers.Extensions; +using IPData.Http.Serializer; namespace IPData.Models { @@ -88,6 +89,7 @@ public class IPLookupResult public int? Status { get; set; } [JsonPropertyName("count")] + [JsonConverter(typeof(IntJsonConverter))] public int Count { get; set; } internal static string FieldName(Expression> expression) diff --git a/test/Unit/IPData.Tests/DataSources/TestData/IPLookupResult.json b/test/Unit/IPData.Tests/DataSources/TestData/IPLookupResult.json index 1acfaa5..f7332c0 100644 --- a/test/Unit/IPData.Tests/DataSources/TestData/IPLookupResult.json +++ b/test/Unit/IPData.Tests/DataSources/TestData/IPLookupResult.json @@ -67,5 +67,6 @@ "is_bogon": false, "blocklists": [] }, - "status": 200 + "status": 200, + "count": "213586" } diff --git a/test/Unit/IPData.Tests/Http/Serializer/JsonSerializerTests.cs b/test/Unit/IPData.Tests/Http/Serializer/JsonSerializerTests.cs index 5920b41..7e9a6cc 100644 --- a/test/Unit/IPData.Tests/Http/Serializer/JsonSerializerTests.cs +++ b/test/Unit/IPData.Tests/Http/Serializer/JsonSerializerTests.cs @@ -21,6 +21,32 @@ public void Deserialize_WhenCalled_ReturnedIPLookupResult(string json) actual.Should().NotBeNull(); } + [Fact] + public void Deserialize_CountAsString_ParsedCorrectly() + { + // Arrange - API returns count as a string (issue #35) + var json = "{\"count\": \"213586\"}"; + + // Act + var actual = _sut.Deserialize(json); + + // Assert + actual.Count.Should().Be(213586); + } + + [Fact] + public void Deserialize_CountAsNumber_ParsedCorrectly() + { + // Arrange + var json = "{\"count\": 213586}"; + + // Act + var actual = _sut.Deserialize(json); + + // Assert + actual.Count.Should().Be(213586); + } + [Theory, AutoMoqData] public void SerializeIPLookupResult_WhenCalled_ReturnedString(IPLookupResult ipInfo) {