Skip to content

Commit 03b4480

Browse files
Merge pull request #31 from ipdata/claude/migrate-ipdata-references-TUE1b
Claude/migrate ipdata references tue1b
2 parents 64b294c + 59438e9 commit 03b4480

11 files changed

Lines changed: 310 additions & 880 deletions

.github/README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
- [Currency](#currency)
2020
- [Threat](#threat)
2121
- [EU Endpoint](#eu-endpoint)
22+
- [Dependency Injection](#dependency-injection)
2223
- [Migrating from v2 to v3](#migrating-from-v2-to-v3)
2324
- [Contributing](#contributing)
2425
- [Versioning](#versioning)
@@ -143,6 +144,41 @@ var client = new IPDataClient("API_KEY", new Uri("https://eu-api.ipdata.co"));
143144
var ipInfo = await client.Lookup("8.8.8.8");
144145
```
145146

147+
## Dependency Injection
148+
149+
If you're using ASP.NET Core, you can register `IPDataClient` with `IHttpClientFactory` to benefit from managed connection pooling and handler lifetimes:
150+
151+
```csharp
152+
// In Program.cs or Startup.cs
153+
services.AddHttpClient("ipdata");
154+
services.AddSingleton<IIPDataClient>(sp =>
155+
{
156+
var factory = sp.GetRequiredService<IHttpClientFactory>();
157+
var httpClient = factory.CreateClient("ipdata");
158+
return new IPDataClient("API_KEY", httpClient);
159+
});
160+
```
161+
162+
Then inject `IIPDataClient` wherever you need it:
163+
164+
```csharp
165+
public class MyService
166+
{
167+
private readonly IIPDataClient _ipDataClient;
168+
169+
public MyService(IIPDataClient ipDataClient)
170+
{
171+
_ipDataClient = ipDataClient;
172+
}
173+
174+
public async Task<string> GetCountry(string ip)
175+
{
176+
var result = await _ipDataClient.Lookup(ip);
177+
return result.CountryName;
178+
}
179+
}
180+
```
181+
146182
## Migrating from v2 to v3
147183

148184
v3.0.0 renames all public types to follow [.NET naming conventions](https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/capitalization-conventions) for two-letter acronyms. It also adds EU endpoint support and a `Company` lookup.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"name": "T-Mobile",
3+
"mcc": "310",
4+
"mnc": "160"
5+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"name": "Google LLC",
3+
"domain": "google.com",
4+
"network": "8.8.8.0/24",
5+
"type": "business"
6+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
{
2+
"ip": "91.225.201.108",
3+
"is_eu": false,
4+
"city": "Lviv",
5+
"region": "L'vivs'ka Oblast'",
6+
"region_code": "46",
7+
"region_type": "oblast",
8+
"country_name": "Ukraine",
9+
"country_code": "UA",
10+
"continent_name": "Europe",
11+
"continent_code": "EU",
12+
"latitude": 49.8486,
13+
"longitude": 24.0323,
14+
"postal": "79000",
15+
"calling_code": "380",
16+
"flag": "https://ipdata.co/flags/ua.png",
17+
"emoji_flag": "\uD83C\uDDFA\uD83C\uDDE6",
18+
"emoji_unicode": "U+1F1FA U+1F1E6",
19+
"asn": {
20+
"asn": "AS49824",
21+
"name": "PC \"Astra-net\"",
22+
"domain": "astra.in.ua",
23+
"route": "91.225.200.0/22",
24+
"type": "isp"
25+
},
26+
"company": {
27+
"name": "Astra-net",
28+
"domain": "astra.in.ua",
29+
"network": "91.225.200.0/22",
30+
"type": "isp"
31+
},
32+
"carrier": {
33+
"name": "Kyivstar",
34+
"mcc": "255",
35+
"mnc": "03"
36+
},
37+
"languages": [
38+
{
39+
"name": "Ukrainian",
40+
"native": "\u0423\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430",
41+
"code": "uk"
42+
}
43+
],
44+
"currency": {
45+
"name": "Ukrainian Hryvnia",
46+
"code": "UAH",
47+
"symbol": "\u20B4",
48+
"native": "\u20B4",
49+
"plural": "Ukrainian hryvnias"
50+
},
51+
"time_zone": {
52+
"name": "Europe/Kiev",
53+
"abbr": "EET",
54+
"offset": "+0200",
55+
"is_dst": false,
56+
"current_time": "2020-01-30T23:16:19.129316+02:00"
57+
},
58+
"threat": {
59+
"is_tor": false,
60+
"is_icloud_relay": false,
61+
"is_proxy": false,
62+
"is_datacenter": false,
63+
"is_anonymous": false,
64+
"is_known_attacker": false,
65+
"is_known_abuser": false,
66+
"is_threat": false,
67+
"is_bogon": false,
68+
"blocklists": []
69+
},
70+
"status": 200
71+
}

test/Unit/IPData.Tests/DataSources/TestDataSource.cs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using System.Collections.Generic;
2+
using System.IO;
3+
using System.Reflection;
24

35
namespace IPData.Tests.DataSources
46
{
@@ -13,17 +15,29 @@ public static IEnumerable<object[]> EmptyOrWhitespaceString()
1315

1416
public static IEnumerable<object[]> IPLookupResultData()
1517
{
16-
yield return new object[] { "{\"ip\":\"91.225.201.108\",\"is_eu\":false,\"city\":\"Lviv\",\"region\":\"L'vivs'ka Oblast'\",\"region_code\":\"46\",\"region_type\":\"oblast\",\"country_name\":\"Ukraine\",\"country_code\":\"UA\",\"continent_name\":\"Europe\",\"continent_code\":\"EU\",\"latitude\":49.8486,\"longitude\":24.0323,\"postal\":\"79000\",\"calling_code\":\"380\",\"flag\":\"https:\\/\\/ipdata.co\\/flags\\/ua.png\",\"emoji_flag\":\"\uD83C\uDDFA\uD83C\uDDE6\",\"emoji_unicode\":\"U+1F1FA U+1F1E6\",\"asn\":{\"asn\":\"AS49824\",\"name\":\"PC \\\"Astra-net\\\"\",\"domain\":\"astra.in.ua\",\"route\":\"91.225.200.0\\/22\",\"type\":\"isp\"},\"company\":{\"name\":\"Astra-net\",\"domain\":\"astra.in.ua\",\"network\":\"91.225.200.0\\/22\",\"type\":\"isp\"},\"carrier\":{\"name\":\"Kyivstar\",\"mcc\":\"255\",\"mnc\":\"03\"},\"languages\":[{\"name\":\"Ukrainian\",\"native\":\"\u0423\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430\",\"code\":\"uk\"}],\"currency\":{\"name\":\"Ukrainian Hryvnia\",\"code\":\"UAH\",\"symbol\":\"\u20B4\",\"native\":\"\u20B4\",\"plural\":\"Ukrainian hryvnias\"},\"time_zone\":{\"name\":\"Europe\\/Kiev\",\"abbr\":\"EET\",\"offset\":\"+0200\",\"is_dst\":false,\"current_time\":\"2020-01-30T23:16:19.129316+02:00\"},\"threat\":{\"is_tor\":false,\"is_icloud_relay\":false,\"is_proxy\":false,\"is_datacenter\":false,\"is_anonymous\":false,\"is_known_attacker\":false,\"is_known_abuser\":false,\"is_threat\":false,\"is_bogon\":false,\"blocklists\":[]},\"status\":200}" };
18+
yield return new object[] { ReadJsonFile("IPLookupResult.json") };
1719
}
1820

1921
public static IEnumerable<object[]> CarrierData()
2022
{
21-
yield return new object[] { "{\"name\":\"T-Mobile\",\"mcc\":\"310\",\"mnc\":\"160\"\r\n}" };
23+
yield return new object[] { ReadJsonFile("Carrier.json") };
2224
}
2325

2426
public static IEnumerable<object[]> CompanyData()
2527
{
26-
yield return new object[] { "{\"name\":\"Google LLC\",\"domain\":\"google.com\",\"network\":\"8.8.8.0\\/24\",\"type\":\"business\"}" };
28+
yield return new object[] { ReadJsonFile("Company.json") };
29+
}
30+
31+
private static string ReadJsonFile(string fileName)
32+
{
33+
var assembly = Assembly.GetExecutingAssembly();
34+
var resourceName = $"IPData.Tests.DataSources.TestData.{fileName}";
35+
36+
using (var stream = assembly.GetManifestResourceStream(resourceName))
37+
using (var reader = new StreamReader(stream))
38+
{
39+
return reader.ReadToEnd();
40+
}
2741
}
2842
}
2943
}

test/Unit/IPData.Tests/Exceptions/BadRequestExceptionTests.cs

Lines changed: 0 additions & 50 deletions
This file was deleted.
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
using System.Collections.Generic;
2+
using System.Net;
3+
using FluentAssertions;
4+
using IPData.Exceptions;
5+
using Xunit;
6+
7+
namespace IPData.Tests.Exceptions
8+
{
9+
public class DerivedExceptionTests
10+
{
11+
public static IEnumerable<object[]> ExceptionStatusCodeData()
12+
{
13+
yield return new object[] { new BadRequestException(), HttpStatusCode.BadRequest };
14+
yield return new object[] { new ForbiddenException(), HttpStatusCode.Forbidden };
15+
yield return new object[] { new UnauthorizedException(), HttpStatusCode.Unauthorized };
16+
}
17+
18+
public static IEnumerable<object[]> ExceptionData()
19+
{
20+
yield return new object[] { new BadRequestException() };
21+
yield return new object[] { new ForbiddenException() };
22+
yield return new object[] { new UnauthorizedException() };
23+
}
24+
25+
[Theory]
26+
[MemberData(nameof(ExceptionStatusCodeData))]
27+
public void Exception_WhenCreate_ShouldReturnCorrectStatusCode(
28+
ApiException sut, HttpStatusCode expectedStatusCode)
29+
{
30+
sut.StatusCode.Should().Be(expectedStatusCode);
31+
}
32+
33+
[Theory]
34+
[MemberData(nameof(ExceptionData))]
35+
public void Exception_WhenCreateWithoutParams_ShouldReturnApiError(
36+
ApiException sut)
37+
{
38+
sut.ApiError.Should().NotBeNull();
39+
}
40+
41+
public static IEnumerable<object[]> ExceptionWithContentData()
42+
{
43+
var content = "test error message";
44+
yield return new object[] { new BadRequestException(content), content };
45+
yield return new object[] { new ForbiddenException(content), content };
46+
yield return new object[] { new UnauthorizedException(content), content };
47+
}
48+
49+
[Theory]
50+
[MemberData(nameof(ExceptionWithContentData))]
51+
public void Exception_WhenCreateWithContent_ShouldReturnApiErrorWithMessage(
52+
ApiException sut, string expectedMessage)
53+
{
54+
sut.ApiError.Message.Should().Be(expectedMessage);
55+
}
56+
57+
[Theory]
58+
[MemberData(nameof(ExceptionWithContentData))]
59+
public void Exception_WhenCreateWithContent_ShouldBeMessage(
60+
ApiException sut, string expectedMessage)
61+
{
62+
sut.Message.Should().Be(expectedMessage);
63+
}
64+
}
65+
}

test/Unit/IPData.Tests/Exceptions/ForbiddenExceptionTests.cs

Lines changed: 0 additions & 50 deletions
This file was deleted.

test/Unit/IPData.Tests/Exceptions/UnauthorizedExceptionTests.cs

Lines changed: 0 additions & 50 deletions
This file was deleted.

0 commit comments

Comments
 (0)