mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-20 22:58:07 +01:00
Add a system to look up mobile network data
This commit is contained in:
@@ -47,7 +47,7 @@ import org.whispersystems.textsecuregcm.util.ResilienceUtil;
|
||||
class FaultTolerantHttpClientTest {
|
||||
|
||||
@RegisterExtension
|
||||
private final WireMockExtension wireMock = WireMockExtension.newInstance()
|
||||
private static final WireMockExtension wireMock = WireMockExtension.newInstance()
|
||||
.options(wireMockConfig().dynamicPort().dynamicHttpsPort())
|
||||
.build();
|
||||
|
||||
@@ -60,32 +60,34 @@ class FaultTolerantHttpClientTest {
|
||||
retryExecutor = Executors.newSingleThreadScheduledExecutor();
|
||||
}
|
||||
|
||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||
@AfterEach
|
||||
void tearDown() throws InterruptedException {
|
||||
httpExecutor.shutdown();
|
||||
httpExecutor.awaitTermination(1, TimeUnit.SECONDS);
|
||||
|
||||
retryExecutor.shutdown();
|
||||
retryExecutor.awaitTermination(1, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSimpleGet() {
|
||||
void testSimpleGetAsync() {
|
||||
wireMock.stubFor(get(urlEqualTo("/ping"))
|
||||
.willReturn(aResponse()
|
||||
.withHeader("Content-Type", "text/plain")
|
||||
.withBody("Pong!")));
|
||||
|
||||
FaultTolerantHttpClient client = FaultTolerantHttpClient.newBuilder("testSimpleGet", httpExecutor)
|
||||
final FaultTolerantHttpClient client = FaultTolerantHttpClient.newBuilder("testSimpleGet", httpExecutor)
|
||||
.withRetry(null, retryExecutor)
|
||||
.withVersion(HttpClient.Version.HTTP_2)
|
||||
.build();
|
||||
|
||||
HttpRequest request = HttpRequest.newBuilder()
|
||||
.uri(URI.create("http://localhost:" + wireMock.getPort() + "/ping"))
|
||||
.GET()
|
||||
.build();
|
||||
final HttpRequest request = HttpRequest.newBuilder()
|
||||
.uri(URI.create("http://localhost:" + wireMock.getPort() + "/ping"))
|
||||
.GET()
|
||||
.build();
|
||||
|
||||
HttpResponse<String> response = client.sendAsync(request, HttpResponse.BodyHandlers.ofString()).join();
|
||||
final HttpResponse<String> response = client.sendAsync(request, HttpResponse.BodyHandlers.ofString()).join();
|
||||
|
||||
assertThat(response.statusCode()).isEqualTo(200);
|
||||
assertThat(response.body()).isEqualTo("Pong!");
|
||||
@@ -94,24 +96,49 @@ class FaultTolerantHttpClientTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRetryGet() {
|
||||
wireMock.stubFor(get(urlEqualTo("/failure"))
|
||||
.willReturn(aResponse()
|
||||
.withStatus(500)
|
||||
.withHeader("Content-Type", "text/plain")
|
||||
.withBody("Pong!")));
|
||||
void testSimpleGetSync() throws IOException, InterruptedException {
|
||||
wireMock.stubFor(get(urlEqualTo("/ping"))
|
||||
.willReturn(aResponse()
|
||||
.withHeader("Content-Type", "text/plain")
|
||||
.withBody("Pong!")));
|
||||
|
||||
FaultTolerantHttpClient client = FaultTolerantHttpClient.newBuilder("testRetryGet", httpExecutor)
|
||||
final FaultTolerantHttpClient client = FaultTolerantHttpClient.newBuilder("testSimpleGet", httpExecutor)
|
||||
.withRetry(null, retryExecutor)
|
||||
.withVersion(HttpClient.Version.HTTP_2)
|
||||
.build();
|
||||
|
||||
HttpRequest request = HttpRequest.newBuilder()
|
||||
.uri(URI.create("http://localhost:" + wireMock.getPort() + "/failure"))
|
||||
.GET()
|
||||
.build();
|
||||
final HttpRequest request = HttpRequest.newBuilder()
|
||||
.uri(URI.create("http://localhost:" + wireMock.getPort() + "/ping"))
|
||||
.GET()
|
||||
.build();
|
||||
|
||||
HttpResponse<String> response = client.sendAsync(request, HttpResponse.BodyHandlers.ofString()).join();
|
||||
final HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
|
||||
|
||||
assertThat(response.statusCode()).isEqualTo(200);
|
||||
assertThat(response.body()).isEqualTo("Pong!");
|
||||
|
||||
wireMock.verify(1, getRequestedFor(urlEqualTo("/ping")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRetryGetAsync() {
|
||||
wireMock.stubFor(get(urlEqualTo("/failure"))
|
||||
.willReturn(aResponse()
|
||||
.withStatus(500)
|
||||
.withHeader("Content-Type", "text/plain")
|
||||
.withBody("Pong!")));
|
||||
|
||||
final FaultTolerantHttpClient client = FaultTolerantHttpClient.newBuilder("testRetryGet", httpExecutor)
|
||||
.withRetry(null, retryExecutor)
|
||||
.withVersion(HttpClient.Version.HTTP_2)
|
||||
.build();
|
||||
|
||||
final HttpRequest request = HttpRequest.newBuilder()
|
||||
.uri(URI.create("http://localhost:" + wireMock.getPort() + "/failure"))
|
||||
.GET()
|
||||
.build();
|
||||
|
||||
final HttpResponse<String> response = client.sendAsync(request, HttpResponse.BodyHandlers.ofString()).join();
|
||||
|
||||
assertThat(response.statusCode()).isEqualTo(500);
|
||||
assertThat(response.body()).isEqualTo("Pong!");
|
||||
@@ -120,7 +147,33 @@ class FaultTolerantHttpClientTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRetryGetOnException() {
|
||||
void testRetryGetSync() throws IOException, InterruptedException {
|
||||
wireMock.stubFor(get(urlEqualTo("/failure"))
|
||||
.willReturn(aResponse()
|
||||
.withStatus(500)
|
||||
.withHeader("Content-Type", "text/plain")
|
||||
.withBody("Pong!")));
|
||||
|
||||
final FaultTolerantHttpClient client = FaultTolerantHttpClient.newBuilder("testRetryGet", httpExecutor)
|
||||
.withRetry(null, retryExecutor)
|
||||
.withVersion(HttpClient.Version.HTTP_2)
|
||||
.build();
|
||||
|
||||
final HttpRequest request = HttpRequest.newBuilder()
|
||||
.uri(URI.create("http://localhost:" + wireMock.getPort() + "/failure"))
|
||||
.GET()
|
||||
.build();
|
||||
|
||||
final HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
|
||||
|
||||
assertThat(response.statusCode()).isEqualTo(500);
|
||||
assertThat(response.body()).isEqualTo("Pong!");
|
||||
|
||||
wireMock.verify(3, getRequestedFor(urlEqualTo("/failure")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRetryGetAsyncOnException() {
|
||||
final HttpClient mockHttpClient = mock(HttpClient.class);
|
||||
|
||||
final Retry retry = Retry.of("test", new RetryConfiguration().toRetryConfigBuilder()
|
||||
@@ -137,20 +190,47 @@ class FaultTolerantHttpClientTest {
|
||||
when(mockHttpClient.sendAsync(any(), any()))
|
||||
.thenReturn(CompletableFuture.failedFuture(new IOException("test exception")));
|
||||
|
||||
HttpRequest request = HttpRequest.newBuilder()
|
||||
final HttpRequest request = HttpRequest.newBuilder()
|
||||
.uri(URI.create("http://localhost:1234/failure"))
|
||||
.GET()
|
||||
.build();
|
||||
|
||||
try {
|
||||
client.sendAsync(request, HttpResponse.BodyHandlers.ofString()).join();
|
||||
throw new AssertionError("Should have failed!");
|
||||
} catch (CompletionException e) {
|
||||
assertThat(e.getCause()).isInstanceOf(IOException.class);
|
||||
}
|
||||
assertThatThrownBy(() -> client.sendAsync(request, HttpResponse.BodyHandlers.ofString()).join())
|
||||
.isInstanceOf(CompletionException.class)
|
||||
.hasCauseInstanceOf(IOException.class);
|
||||
|
||||
verify(mockHttpClient, times(3)).sendAsync(any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRetryGetSyncOnException() throws IOException, InterruptedException {
|
||||
final HttpClient mockHttpClient = mock(HttpClient.class);
|
||||
|
||||
final Retry retry = Retry.of("test", new RetryConfiguration().toRetryConfigBuilder()
|
||||
.retryOnException(throwable -> throwable instanceof IOException)
|
||||
.build());
|
||||
|
||||
final FaultTolerantHttpClient client = new FaultTolerantHttpClient(
|
||||
List.of(mockHttpClient),
|
||||
Duration.ofSeconds(1),
|
||||
retryExecutor,
|
||||
retry,
|
||||
CircuitBreaker.ofDefaults("test"));
|
||||
|
||||
when(mockHttpClient.send(any(), any()))
|
||||
.thenThrow(IOException.class);
|
||||
|
||||
final HttpRequest request = HttpRequest.newBuilder()
|
||||
.uri(URI.create("http://localhost:1234/failure"))
|
||||
.GET()
|
||||
.build();
|
||||
|
||||
assertThatThrownBy(() -> client.send(request, HttpResponse.BodyHandlers.ofString()))
|
||||
.isInstanceOf(IOException.class);
|
||||
|
||||
verify(mockHttpClient, times(3)).send(any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMultipleClients() throws IOException, InterruptedException {
|
||||
final HttpClient mockHttpClient1 = mock(HttpClient.class);
|
||||
@@ -177,28 +257,31 @@ class FaultTolerantHttpClientTest {
|
||||
.uri(URI.create("http://localhost:" + wireMock.getPort() + "/ping"))
|
||||
.GET()
|
||||
.build();
|
||||
final HttpResponse response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.discarding());
|
||||
|
||||
final AtomicInteger client1Calls = new AtomicInteger(0);
|
||||
final AtomicInteger client2Calls = new AtomicInteger(0);
|
||||
when(mockHttpClient1.sendAsync(any(), any()))
|
||||
.thenAnswer(args -> {
|
||||
client1Calls.incrementAndGet();
|
||||
return CompletableFuture.completedFuture(response);
|
||||
});
|
||||
when(mockHttpClient2.sendAsync(any(), any()))
|
||||
.thenAnswer(args -> {
|
||||
client2Calls.incrementAndGet();
|
||||
return CompletableFuture.completedFuture(response);
|
||||
});
|
||||
try (final HttpClient httpClient = HttpClient.newHttpClient()) {
|
||||
final HttpResponse<Void> response = httpClient.send(request, HttpResponse.BodyHandlers.discarding());
|
||||
|
||||
final int numCalls = 100;
|
||||
for (int i = 0; i < numCalls; i++) {
|
||||
client.sendAsync(request, HttpResponse.BodyHandlers.ofString()).join();
|
||||
final AtomicInteger client1Calls = new AtomicInteger(0);
|
||||
final AtomicInteger client2Calls = new AtomicInteger(0);
|
||||
when(mockHttpClient1.sendAsync(any(), any()))
|
||||
.thenAnswer(_ -> {
|
||||
client1Calls.incrementAndGet();
|
||||
return CompletableFuture.completedFuture(response);
|
||||
});
|
||||
when(mockHttpClient2.sendAsync(any(), any()))
|
||||
.thenAnswer(_ -> {
|
||||
client2Calls.incrementAndGet();
|
||||
return CompletableFuture.completedFuture(response);
|
||||
});
|
||||
|
||||
final int numCalls = 100;
|
||||
for (int i = 0; i < numCalls; i++) {
|
||||
client.sendAsync(request, HttpResponse.BodyHandlers.ofString()).join();
|
||||
}
|
||||
assertThat(client2Calls.get()).isGreaterThan(0);
|
||||
assertThat(client1Calls.get()).isGreaterThan(0);
|
||||
assertThat(client1Calls.get() + client2Calls.get()).isEqualTo(numCalls);
|
||||
}
|
||||
assertThat(client2Calls.get()).isGreaterThan(0);
|
||||
assertThat(client1Calls.get()).isGreaterThan(0);
|
||||
assertThat(client1Calls.get() + client2Calls.get()).isEqualTo(numCalls);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -215,7 +298,8 @@ class FaultTolerantHttpClientTest {
|
||||
ResilienceUtil.getCircuitBreakerRegistry()
|
||||
.addConfiguration(circuitBreakerConfigurationName, circuitBreakerConfiguration.toCircuitBreakerConfig());
|
||||
|
||||
final FaultTolerantHttpClient client = FaultTolerantHttpClient.newBuilder("testNetworkFailureCircuitBreaker", httpExecutor)
|
||||
final FaultTolerantHttpClient client = FaultTolerantHttpClient.newBuilder("testNetworkFailureCircuitBreaker",
|
||||
httpExecutor)
|
||||
.withCircuitBreaker(circuitBreakerConfigurationName)
|
||||
.withRetry(null, retryExecutor)
|
||||
.withVersion(HttpClient.Version.HTTP_2)
|
||||
|
||||
@@ -0,0 +1,364 @@
|
||||
/*
|
||||
* Copyright 2026 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.whispersystems.textsecuregcm.telephony.hlrlookup;
|
||||
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.post;
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
|
||||
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
|
||||
import com.google.i18n.phonenumbers.PhoneNumberUtil;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import javax.annotation.Nullable;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.whispersystems.textsecuregcm.http.FaultTolerantHttpClient;
|
||||
import org.whispersystems.textsecuregcm.telephony.CarrierData;
|
||||
import org.whispersystems.textsecuregcm.telephony.CarrierDataException;
|
||||
|
||||
class HlrLookupCarrierDataProviderTest {
|
||||
|
||||
private HlrLookupCarrierDataProvider hlrLookupCarrierDataProvider;
|
||||
|
||||
@RegisterExtension
|
||||
private static final WireMockExtension WIRE_MOCK_EXTENSION = WireMockExtension.newInstance()
|
||||
.options(wireMockConfig().dynamicPort().dynamicHttpsPort())
|
||||
.build();
|
||||
|
||||
private static final String HLR_LOOKUP_PATH = "/hlr";
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
final FaultTolerantHttpClient faultTolerantHttpClient = FaultTolerantHttpClient.newBuilder("hlrLookupTest", Runnable::run)
|
||||
.build();
|
||||
|
||||
hlrLookupCarrierDataProvider = new HlrLookupCarrierDataProvider("test", "test", faultTolerantHttpClient, URI.create("http://localhost:" + WIRE_MOCK_EXTENSION.getPort() + HLR_LOOKUP_PATH));
|
||||
}
|
||||
|
||||
@Test
|
||||
void lookupCarrierData() throws IOException, CarrierDataException {
|
||||
final String responseJson = """
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"error": "NONE",
|
||||
"uuid": "f066f711-4043-4d54-847d-c273e6491881",
|
||||
"request_parameters": {
|
||||
"telephone_number": "+44(7790) 60 60 23",
|
||||
"save_to_cache": "YES",
|
||||
"input_format": "",
|
||||
"output_format": "",
|
||||
"cache_days_global": 0,
|
||||
"cache_days_private": 0,
|
||||
"get_ported_date": "NO",
|
||||
"get_landline_status": "NO",
|
||||
"usa_status": "NO"
|
||||
},
|
||||
"credits_spent": 1,
|
||||
"detected_telephone_number": "447790606023",
|
||||
"formatted_telephone_number": "",
|
||||
"live_status": "LIVE",
|
||||
"original_network": "AVAILABLE",
|
||||
"original_network_details": {
|
||||
"name": "EE Limited (Orange)",
|
||||
"mccmnc": "23433",
|
||||
"country_name": "United Kingdom",
|
||||
"country_iso3": "GBR",
|
||||
"area": "United Kingdom",
|
||||
"country_prefix": "44"
|
||||
},
|
||||
"current_network": "AVAILABLE",
|
||||
"current_network_details": {
|
||||
"name": "Virgin Mobile",
|
||||
"mccmnc": "23438",
|
||||
"country_name": "United Kingdom",
|
||||
"country_iso3": "GBR",
|
||||
"country_prefix": "44"
|
||||
},
|
||||
"is_ported": "YES",
|
||||
"timestamp": "2022-09-08T10:56:03Z",
|
||||
"telephone_number_type": "MOBILE",
|
||||
"sms_email": "",
|
||||
"mms_email": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
""";
|
||||
|
||||
WIRE_MOCK_EXTENSION.stubFor(post(urlEqualTo(HLR_LOOKUP_PATH))
|
||||
.willReturn(aResponse()
|
||||
.withHeader("Content-Type", "application/json")
|
||||
.withBody(responseJson)));
|
||||
|
||||
final Optional<CarrierData> maybeCarrierData =
|
||||
hlrLookupCarrierDataProvider.lookupCarrierData(PhoneNumberUtil.getInstance().getExampleNumber("US"), Duration.ZERO);
|
||||
|
||||
assertEquals(Optional.of(new CarrierData("Virgin Mobile", CarrierData.LineType.MOBILE, Optional.of("234"), Optional.of("38"))),
|
||||
maybeCarrierData);
|
||||
}
|
||||
|
||||
@Test
|
||||
void lookupCarrierDataNonSuccessStatus() {
|
||||
WIRE_MOCK_EXTENSION.stubFor(post(urlEqualTo(HLR_LOOKUP_PATH))
|
||||
.willReturn(aResponse()
|
||||
.withStatus(500)));
|
||||
|
||||
assertThrows(CarrierDataException.class, () ->
|
||||
hlrLookupCarrierDataProvider.lookupCarrierData(PhoneNumberUtil.getInstance().getExampleNumber("US"), Duration.ZERO));
|
||||
}
|
||||
|
||||
@Test
|
||||
void lookupCarrierDataErrorMessage() {
|
||||
final String responseJson = """
|
||||
{ "error": "UNAUTHORIZED", "message": "Invalid api_key or api_secret" }
|
||||
""";
|
||||
|
||||
WIRE_MOCK_EXTENSION.stubFor(post(urlEqualTo(HLR_LOOKUP_PATH))
|
||||
.willReturn(aResponse()
|
||||
.withHeader("Content-Type", "application/json")
|
||||
.withBody(responseJson)));
|
||||
|
||||
assertThrows(CarrierDataException.class, () ->
|
||||
hlrLookupCarrierDataProvider.lookupCarrierData(PhoneNumberUtil.getInstance().getExampleNumber("US"), Duration.ZERO));
|
||||
}
|
||||
|
||||
@Test
|
||||
void lookupCarrierDataEmptyBody() {
|
||||
WIRE_MOCK_EXTENSION.stubFor(post(urlEqualTo(HLR_LOOKUP_PATH))
|
||||
.willReturn(aResponse()
|
||||
.withHeader("Content-Type", "application/json")
|
||||
.withBody("{}")));
|
||||
|
||||
assertThrows(CarrierDataException.class, () ->
|
||||
hlrLookupCarrierDataProvider.lookupCarrierData(PhoneNumberUtil.getInstance().getExampleNumber("US"), Duration.ZERO));
|
||||
}
|
||||
|
||||
@Test
|
||||
void lookupCarrierDataPerNumberError() {
|
||||
final String responseJson = """
|
||||
{
|
||||
"body": {
|
||||
"results": [
|
||||
{
|
||||
"error": "INTERNAL_ERROR"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
""";
|
||||
|
||||
WIRE_MOCK_EXTENSION.stubFor(post(urlEqualTo(HLR_LOOKUP_PATH))
|
||||
.willReturn(aResponse()
|
||||
.withHeader("Content-Type", "application/json")
|
||||
.withBody(responseJson)));
|
||||
|
||||
assertThrows(CarrierDataException.class, () ->
|
||||
hlrLookupCarrierDataProvider.lookupCarrierData(PhoneNumberUtil.getInstance().getExampleNumber("US"), Duration.ZERO));
|
||||
}
|
||||
|
||||
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
void mccFromMccMnc(@Nullable final String mccMnc, final Optional<String> expectedMcc) {
|
||||
assertEquals(expectedMcc, HlrLookupCarrierDataProvider.mccFromMccMnc(mccMnc));
|
||||
}
|
||||
|
||||
private static List<Arguments> mccFromMccMnc() {
|
||||
return List.of(
|
||||
Arguments.argumentSet("Null mccMnc string", null, Optional.empty()),
|
||||
Arguments.argumentSet("Empty mccMnc string", "", Optional.empty()),
|
||||
Arguments.argumentSet("Blank mccMnc string", " ", Optional.empty()),
|
||||
Arguments.argumentSet("Two-digit MNC", "12345", Optional.of("123")),
|
||||
Arguments.argumentSet("Three-digit MNC", "123456", Optional.of("123"))
|
||||
);
|
||||
}
|
||||
|
||||
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
void mncFromMccMnc(@Nullable final String mccMnc, final Optional<String> expectedMnc) {
|
||||
assertEquals(expectedMnc, HlrLookupCarrierDataProvider.mncFromMccMnc(mccMnc));
|
||||
}
|
||||
|
||||
private static List<Arguments> mncFromMccMnc() {
|
||||
return List.of(
|
||||
Arguments.argumentSet("Null mccMnc string", null, Optional.empty()),
|
||||
Arguments.argumentSet("Empty mccMnc string", "", Optional.empty()),
|
||||
Arguments.argumentSet("Blank mccMnc string", " ", Optional.empty()),
|
||||
Arguments.argumentSet("Two-digit MNC", "12345", Optional.of("45")),
|
||||
Arguments.argumentSet("Three-digit MNC", "123456", Optional.of("456"))
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
void lineType(@Nullable final String lineType, final CarrierData.LineType expectedLineType) {
|
||||
assertEquals(expectedLineType, HlrLookupCarrierDataProvider.lineType(lineType));
|
||||
}
|
||||
|
||||
private static List<Arguments> lineType() {
|
||||
return List.of(
|
||||
Arguments.argumentSet("Null line type", null, CarrierData.LineType.UNKNOWN)
|
||||
);
|
||||
}
|
||||
|
||||
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
void getNetworkDetails(final HlrLookupResult hlrLookupResult, final Optional<NetworkDetails> expectedNetworkDetails) {
|
||||
assertEquals(expectedNetworkDetails, HlrLookupCarrierDataProvider.getNetworkDetails(hlrLookupResult));
|
||||
}
|
||||
|
||||
private static List<Arguments> getNetworkDetails() {
|
||||
final NetworkDetails originalNetwork = new NetworkDetails(
|
||||
"Original network",
|
||||
"123456",
|
||||
"United States of America",
|
||||
"USA",
|
||||
"United States of America",
|
||||
"1");
|
||||
|
||||
final NetworkDetails currentNetwork = new NetworkDetails(
|
||||
"Current network",
|
||||
"654321",
|
||||
"United States of America",
|
||||
"USA",
|
||||
"United States of America",
|
||||
"1");
|
||||
|
||||
return List.of(
|
||||
Arguments.argumentSet("Original and current network",
|
||||
resultWithNetworkDetails(originalNetwork, currentNetwork),
|
||||
Optional.of(currentNetwork)),
|
||||
|
||||
Arguments.argumentSet("Original network only",
|
||||
resultWithNetworkDetails(originalNetwork, null),
|
||||
Optional.of(originalNetwork)),
|
||||
|
||||
Arguments.argumentSet("Current network only",
|
||||
resultWithNetworkDetails(null, currentNetwork),
|
||||
Optional.of(currentNetwork)),
|
||||
|
||||
Arguments.argumentSet("No network details",
|
||||
resultWithNetworkDetails(null, null),
|
||||
Optional.empty())
|
||||
);
|
||||
}
|
||||
|
||||
private static HlrLookupResult resultWithNetworkDetails(@Nullable final NetworkDetails originalNetwork,
|
||||
@Nullable final NetworkDetails currentNetwork) {
|
||||
|
||||
return new HlrLookupResult(null,
|
||||
originalNetwork == null ? "NOT_AVAILABLE" : "AVAILABLE",
|
||||
originalNetwork,
|
||||
currentNetwork == null ? "NOT_AVAILABLE" : "AVAILABLE",
|
||||
currentNetwork,
|
||||
"MOBILE");
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseResponse() throws JsonProcessingException {
|
||||
final String json = """
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"error": "NONE",
|
||||
"uuid": "f066f711-4043-4d54-847d-c273e6491881",
|
||||
"request_parameters": {
|
||||
"telephone_number": "+44(7790) 60 60 23",
|
||||
"save_to_cache": "YES",
|
||||
"input_format": "",
|
||||
"output_format": "",
|
||||
"cache_days_global": 0,
|
||||
"cache_days_private": 0,
|
||||
"get_ported_date": "NO",
|
||||
"get_landline_status": "NO",
|
||||
"usa_status": "NO"
|
||||
},
|
||||
"credits_spent": 1,
|
||||
"detected_telephone_number": "447790606023",
|
||||
"formatted_telephone_number": "",
|
||||
"live_status": "LIVE",
|
||||
"original_network": "AVAILABLE",
|
||||
"original_network_details": {
|
||||
"name": "EE Limited (Orange)",
|
||||
"mccmnc": "23433",
|
||||
"country_name": "United Kingdom",
|
||||
"country_iso3": "GBR",
|
||||
"area": "United Kingdom",
|
||||
"country_prefix": "44"
|
||||
},
|
||||
"current_network": "AVAILABLE",
|
||||
"current_network_details": {
|
||||
"name": "Virgin Mobile",
|
||||
"mccmnc": "23438",
|
||||
"country_name": "United Kingdom",
|
||||
"country_iso3": "GBR",
|
||||
"country_prefix": "44"
|
||||
},
|
||||
"is_ported": "YES",
|
||||
"timestamp": "2022-09-08T10:56:03Z",
|
||||
"telephone_number_type": "MOBILE",
|
||||
"sms_email": "",
|
||||
"mms_email": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
""";
|
||||
|
||||
final HlrLookupResponse response = HlrLookupCarrierDataProvider.parseResponse(json);
|
||||
assertNull(response.error());
|
||||
assertNull(response.message());
|
||||
assertNotNull(response.results());
|
||||
assertEquals(1, response.results().size());
|
||||
|
||||
final HlrLookupResult result = response.results().getFirst();
|
||||
assertEquals("NONE", result.error());
|
||||
assertEquals("MOBILE", result.telephoneNumberType());
|
||||
|
||||
assertEquals("AVAILABLE", result.originalNetwork());
|
||||
assertEquals("EE Limited (Orange)", result.originalNetworkDetails().name());
|
||||
assertEquals("23433", result.originalNetworkDetails().mccmnc());
|
||||
assertEquals("United Kingdom", result.originalNetworkDetails().countryName());
|
||||
assertEquals("GBR", result.originalNetworkDetails().countryIso3());
|
||||
assertEquals("United Kingdom", result.originalNetworkDetails().area());
|
||||
assertEquals("44", result.originalNetworkDetails().countryPrefix());
|
||||
|
||||
assertEquals("AVAILABLE", result.currentNetwork());
|
||||
assertEquals("Virgin Mobile", result.currentNetworkDetails().name());
|
||||
assertEquals("23438", result.currentNetworkDetails().mccmnc());
|
||||
assertEquals("United Kingdom", result.currentNetworkDetails().countryName());
|
||||
assertEquals("GBR", result.currentNetworkDetails().countryIso3());
|
||||
assertNull(result.currentNetworkDetails().area());
|
||||
assertEquals("44", result.currentNetworkDetails().countryPrefix());
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseResponseError() throws JsonProcessingException {
|
||||
final String json = """
|
||||
{ "error": "UNAUTHORIZED", "message": "Invalid api_key or api_secret" }
|
||||
""";
|
||||
|
||||
final HlrLookupResponse response = HlrLookupCarrierDataProvider.parseResponse(json);
|
||||
assertEquals("UNAUTHORIZED", response.error());
|
||||
assertEquals("Invalid api_key or api_secret", response.message());
|
||||
assertNull(response.results());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user