bitip/src/clients/dotnet/Bitip.Client.Tests/GetBatchIpLocationTests.cs

317 lines
12 KiB
C#

// Copyright (c) 2025 Tudor Stanciu
using Bitip.Client.Models;
using Bitip.Client.Tests.Helpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
namespace Bitip.Client.Tests
{
/// <summary>
/// Unit tests for IBitipClient.GetBatchIpLocation method (batch lookup).
/// </summary>
public class GetBatchIpLocationTests
{
[Fact]
public async Task GetBatchIpLocation_WithValidIps_ReturnsSucceeded()
{
// Arrange
var ips = new List<string> { "8.8.8.8", "1.1.1.1" };
var expectedResponse = new BatchIpLookupResponse
{
Succeeded = new List<IpLocation>
{
new IpLocation
{
Ip = "8.8.8.8",
Country = "United States",
CountryCode = "US",
IsInEuropeanUnion = false,
Region = "California",
City = "Mountain View",
Latitude = 37.4056,
Longitude = -122.0775,
Timezone = "America/Los_Angeles"
},
new IpLocation
{
Ip = "1.1.1.1",
Country = "Australia",
CountryCode = "AU",
IsInEuropeanUnion = false,
Region = "Queensland",
City = "Brisbane",
Latitude = -27.4679,
Longitude = 153.0281,
Timezone = "Australia/Brisbane"
}
},
Failed = new List<BatchIpLookupError>()
};
var client = BitipClientTestFixture.CreateMockedClientWithResponse(expectedResponse, "lookup/batch", HttpMethod.Post);
// Act
var result = await client.GetBatchIpLocation(ips);
// Assert
Assert.NotNull(result);
var succeededList = result.Succeeded.ToList();
var failedList = result.Failed.ToList();
Assert.Equal(2, succeededList.Count);
Assert.Empty(failedList);
Assert.Equal("8.8.8.8", succeededList[0].Ip);
Assert.Equal("United States", succeededList[0].Country);
Assert.Equal("1.1.1.1", succeededList[1].Ip);
Assert.Equal("Australia", succeededList[1].Country);
}
[Fact]
public async Task GetBatchIpLocation_WithMixedSuccessAndErrors_ReturnsBoth()
{
// Arrange
var ips = new List<string> { "8.8.8.8", "192.168.1.1" };
var expectedResponse = new BatchIpLookupResponse
{
Succeeded = new List<IpLocation>
{
new IpLocation
{
Ip = "8.8.8.8",
Country = "United States",
CountryCode = "US",
IsInEuropeanUnion = false,
Region = "California",
City = "Mountain View"
}
},
Failed = new List<BatchIpLookupError>
{
new BatchIpLookupError
{
Ip = "192.168.1.1",
Error = "Private IP addresses are not supported"
}
}
};
var client = BitipClientTestFixture.CreateMockedClientWithResponse(expectedResponse, "lookup/batch", HttpMethod.Post);
// Act
var result = await client.GetBatchIpLocation(ips);
// Assert
Assert.NotNull(result);
var succeededList = result.Succeeded.ToList();
var failedList = result.Failed.ToList();
Assert.Single(succeededList);
Assert.Single(failedList);
Assert.Equal("United States", succeededList[0].Country);
Assert.Contains("Private IP", failedList[0].Error);
}
[Fact]
public async Task GetBatchIpLocation_WithNullList_ThrowsArgumentNullException()
{
// Arrange
var client = BitipClientTestFixture.CreateMockedClient(mock => { });
// Act & Assert
await Assert.ThrowsAsync<ArgumentNullException>(async () =>
await client.GetBatchIpLocation(null!));
}
[Fact]
public async Task GetBatchIpLocation_WithEmptyList_ThrowsArgumentException()
{
// Arrange
var client = BitipClientTestFixture.CreateMockedClient(mock => { });
// Act & Assert
await Assert.ThrowsAsync<ArgumentException>(async () =>
await client.GetBatchIpLocation(new List<string>()));
}
[Fact]
public async Task GetBatchIpLocation_WithInvalidIp_ReturnsInFailed()
{
// Arrange - Mix of valid and invalid IPs
var ips = new List<string> { "8.8.8.8", "invalid-ip", "1.1.1.1" };
// Mock response for the valid IPs only (invalid ones handled client-side)
var expectedResponse = new BatchIpLookupResponse
{
Succeeded = new List<IpLocation>
{
new IpLocation
{
Ip = "8.8.8.8",
Country = "United States",
CountryCode = "US",
IsInEuropeanUnion = false,
Region = "California",
City = "Mountain View"
},
new IpLocation
{
Ip = "1.1.1.1",
Country = "Australia",
CountryCode = "AU",
IsInEuropeanUnion = false,
Region = "Queensland",
City = "Brisbane"
}
},
Failed = new List<BatchIpLookupError>()
};
var client = BitipClientTestFixture.CreateMockedClientWithResponse(expectedResponse, "lookup/batch", HttpMethod.Post);
// Act
var result = await client.GetBatchIpLocation(ips);
// Assert
Assert.NotNull(result);
var succeededList = result.Succeeded.ToList();
var failedList = result.Failed.ToList();
Assert.Equal(2, succeededList.Count); // Valid IPs
Assert.Single(failedList); // Invalid IP
// Check valid IPs succeeded
Assert.Equal("8.8.8.8", succeededList[0].Ip);
Assert.Equal("1.1.1.1", succeededList[1].Ip);
// Check invalid IP has error
Assert.Equal("invalid-ip", failedList[0].Ip);
Assert.Contains("Invalid IP", failedList[0].Error);
}
[Fact]
public async Task GetBatchIpLocation_WithCancellation_ThrowsTaskCanceledException()
{
// Arrange
var ips = new List<string> { "8.8.8.8", "1.1.1.1" };
var client = BitipClientTestFixture.CreateCancelledClient();
var cts = new CancellationTokenSource();
cts.Cancel();
// Act & Assert
await Assert.ThrowsAsync<TaskCanceledException>(async () =>
await client.GetBatchIpLocation(ips, cts.Token));
}
[Fact]
public async Task GetBatchIpLocation_WithServerError_ThrowsHttpRequestException()
{
// Arrange
var ips = new List<string> { "8.8.8.8" };
var client = BitipClientTestFixture.CreateClientWithError(
HttpStatusCode.InternalServerError,
"Internal Server Error",
"Failed to process batch lookup");
// Act & Assert
await Assert.ThrowsAsync<HttpRequestException>(async () =>
await client.GetBatchIpLocation(ips));
}
[Fact]
public async Task GetBatchIpLocation_WithSingleIp_ReturnsResult()
{
// Arrange
var ips = new List<string> { "8.8.8.8" };
var expectedResponse = new BatchIpLookupResponse
{
Succeeded = new List<IpLocation>
{
new IpLocation
{
Ip = "8.8.8.8",
Country = "United States",
CountryCode = "US",
IsInEuropeanUnion = false,
Region = "California",
City = "Mountain View"
}
},
Failed = new List<BatchIpLookupError>()
};
var client = BitipClientTestFixture.CreateMockedClientWithResponse(expectedResponse, "lookup/batch", HttpMethod.Post);
// Act
var result = await client.GetBatchIpLocation(ips);
// Assert
Assert.NotNull(result);
var succeededList = result.Succeeded.ToList();
Assert.Single(succeededList);
Assert.Empty(result.Failed);
Assert.Equal("8.8.8.8", succeededList[0].Ip);
}
[Fact]
public async Task GetBatchIpLocation_WithMultipleIps_ReturnsAllResults()
{
// Arrange
var ips = new List<string> { "8.8.8.8", "1.1.1.1", "9.9.9.9" };
var expectedResponse = new BatchIpLookupResponse
{
Succeeded = new List<IpLocation>
{
new IpLocation { Ip = "8.8.8.8", Country = "United States", CountryCode = "US", IsInEuropeanUnion = false, Region = "California", City = "Mountain View" },
new IpLocation { Ip = "1.1.1.1", Country = "Australia", CountryCode = "AU", IsInEuropeanUnion = false, Region = "Queensland", City = "Brisbane" },
new IpLocation { Ip = "9.9.9.9", Country = "United States", CountryCode = "US", IsInEuropeanUnion = false, Region = "California", City = "Oakland" }
},
Failed = new List<BatchIpLookupError>()
};
var client = BitipClientTestFixture.CreateMockedClientWithResponse(expectedResponse, "lookup/batch", HttpMethod.Post);
// Act
var result = await client.GetBatchIpLocation(ips);
// Assert
Assert.NotNull(result);
var succeededList = result.Succeeded.ToList();
Assert.Equal(3, succeededList.Count);
Assert.Empty(result.Failed);
Assert.All(succeededList, r => Assert.NotNull(r.Ip));
}
[Fact]
public async Task GetBatchIpLocation_WithOnlyInvalidIps_ReturnsAllInFailed()
{
// Arrange - Only invalid IPs (no API call should be made)
var ips = new List<string> { "invalid-ip", "not-an-ip", "xyz" };
var client = BitipClientTestFixture.CreateMockedClient(mock => { });
// Act
var result = await client.GetBatchIpLocation(ips);
// Assert
Assert.NotNull(result);
Assert.Empty(result.Succeeded);
var failedList = result.Failed.ToList();
Assert.Equal(3, failedList.Count);
Assert.All(failedList, r =>
{
Assert.NotNull(r.Error);
Assert.Contains("Invalid IP", r.Error);
});
}
}
}