locales
71 | ) {
72 | this(
73 | locales,
74 | country.getConfidence(),
75 | country.getGeoNameId(),
76 | country.isInEuropeanUnion(),
77 | country.getIsoCode(),
78 | country.getNames()
79 | );
80 | }
81 |
82 | /**
83 | * @return A value from 0-100 indicating MaxMind's confidence that the
84 | * country is correct. This attribute is only available from the
85 | * Insights web service and the GeoIP2 Enterprise database.
86 | */
87 | public Integer getConfidence() {
88 | return this.confidence;
89 | }
90 |
91 | /**
92 | * @return This is true if the country is a member state of the European
93 | * Union.
94 | */
95 | @JsonProperty("is_in_european_union")
96 | public boolean isInEuropeanUnion() {
97 | return this.isInEuropeanUnion;
98 | }
99 |
100 | /**
101 | * @return The two-character ISO
103 | * 3166-1 alpha code for the country.
104 | */
105 | @JsonProperty("iso_code")
106 | public String getIsoCode() {
107 | return this.isoCode;
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/src/main/java/com/maxmind/geoip2/record/Location.java:
--------------------------------------------------------------------------------
1 | package com.maxmind.geoip2.record;
2 |
3 | import com.fasterxml.jackson.annotation.JsonProperty;
4 | import com.maxmind.db.MaxMindDbConstructor;
5 | import com.maxmind.db.MaxMindDbParameter;
6 |
7 | /**
8 | *
9 | * Contains data for the location record associated with an IP address.
10 | *
11 | */
12 | public class Location extends AbstractRecord {
13 |
14 | private final Integer accuracyRadius;
15 | private final Integer averageIncome;
16 | private final Double latitude;
17 | private final Double longitude;
18 | private final Integer metroCode;
19 | private final Integer populationDensity;
20 | private final String timeZone;
21 |
22 | /**
23 | * Constructs a {@code Location} record with {@code null} values for all the fields.
24 | */
25 | public Location() {
26 | this(null, null, null, null, null, null, null);
27 | }
28 |
29 | /**
30 | * Constructs an instance of {@code Location}.
31 | *
32 | * @param accuracyRadius The approximate accuracy radius in kilometers
33 | * around the latitude and longitude for the IP address. This is the radius
34 | * where we have a 67% confidence that the device using the IP address
35 | * resides within the circle centered at the latitude and longitude with
36 | * the provided radius.
37 | * @param averageIncome The average income in US dollars associated with
38 | * the requested IP address. This attribute is only available from the
39 | * Insights web service.
40 | * @param latitude The approximate latitude of the location associated
41 | * with the IP address. This value is not precise and should not be used
42 | * to identify a particular address or household.
43 | * @param longitude The approximate longitude of the location associated
44 | * with the IP address. This value is not precise and should not be used
45 | * to identify a particular address or household.
46 | * @param metroCode The metro code of the location if the location is in
47 | * the US. MaxMind returns the same metro codes as the Google AdWords API.
50 | * @param populationDensity The estimated population per square kilometer
51 | * associated with the IP address. This attribute is only available from
52 | * the Insights web service.
53 | * @param timeZone The time zone associated with location, as specified by
54 | * the IANA Time Zone
55 | * Database, e.g., "America/New_York".
56 | */
57 | @MaxMindDbConstructor
58 | public Location(
59 | @JsonProperty("accuracy_radius") @MaxMindDbParameter(name = "accuracy_radius")
60 | Integer accuracyRadius,
61 | @JsonProperty("average_income") @MaxMindDbParameter(name = "average_income")
62 | Integer averageIncome,
63 | @JsonProperty("latitude") @MaxMindDbParameter(name = "latitude") Double latitude,
64 | @JsonProperty("longitude") @MaxMindDbParameter(name = "longitude") Double longitude,
65 | @JsonProperty("metro_code") @MaxMindDbParameter(name = "metro_code") Integer metroCode,
66 | @JsonProperty("population_density") @MaxMindDbParameter(name = "population_density")
67 | Integer populationDensity,
68 | @JsonProperty("time_zone") @MaxMindDbParameter(name = "time_zone") String timeZone
69 | ) {
70 | this.accuracyRadius = accuracyRadius;
71 | this.averageIncome = averageIncome;
72 | this.latitude = latitude;
73 | this.longitude = longitude;
74 | this.metroCode = metroCode;
75 | this.populationDensity = populationDensity;
76 | this.timeZone = timeZone;
77 | }
78 |
79 | /**
80 | * @return The average income in US dollars associated with the requested
81 | * IP address. This attribute is only available from the Insights web
82 | * service.
83 | */
84 | @JsonProperty("average_income")
85 | public Integer getAverageIncome() {
86 | return this.averageIncome;
87 | }
88 |
89 | /**
90 | * @return The estimated population per square kilometer associated with the
91 | * IP address. This attribute is only available from the Insights web
92 | * service.
93 | */
94 | @JsonProperty("population_density")
95 | public Integer getPopulationDensity() {
96 | return this.populationDensity;
97 | }
98 |
99 | /**
100 | * @return The time zone associated with location, as specified by the IANA Time Zone
102 | * Database, e.g., "America/New_York".
103 | */
104 | @JsonProperty("time_zone")
105 | public String getTimeZone() {
106 | return this.timeZone;
107 | }
108 |
109 | /**
110 | * @return The approximate accuracy radius in kilometers around the
111 | * latitude and longitude for the IP address. This is the radius where we
112 | * have a 67% confidence that the device using the IP address resides
113 | * within the circle centered at the latitude and longitude with the
114 | * provided radius.
115 | */
116 | @JsonProperty("accuracy_radius")
117 | public Integer getAccuracyRadius() {
118 | return this.accuracyRadius;
119 | }
120 |
121 | /**
122 | * @return The metro code is a no-longer-maintained code for targeting
123 | * advertisements in Google.
124 | * @deprecated Code values are no longer maintained.
125 | */
126 | @JsonProperty("metro_code")
127 | @Deprecated
128 | public Integer getMetroCode() {
129 | return this.metroCode;
130 | }
131 |
132 | /**
133 | * @return The approximate latitude of the location associated with the
134 | * IP address. This value is not precise and should not be used to
135 | * identify a particular address or household.
136 | */
137 | public Double getLatitude() {
138 | return this.latitude;
139 | }
140 |
141 | /**
142 | * @return The approximate longitude of the location associated with the
143 | * IP address. This value is not precise and should not be used to
144 | * identify a particular address or household.
145 | */
146 | public Double getLongitude() {
147 | return this.longitude;
148 | }
149 | }
150 |
--------------------------------------------------------------------------------
/src/main/java/com/maxmind/geoip2/record/MaxMind.java:
--------------------------------------------------------------------------------
1 | package com.maxmind.geoip2.record;
2 |
3 | import com.fasterxml.jackson.annotation.JsonProperty;
4 | import com.maxmind.db.MaxMindDbConstructor;
5 | import com.maxmind.db.MaxMindDbParameter;
6 |
7 | /**
8 | *
9 | * Contains data related to your MaxMind account.
10 | *
11 | */
12 | public final class MaxMind extends AbstractRecord {
13 |
14 | private final Integer queriesRemaining;
15 |
16 | /**
17 | * Constructs a {@code MaxMind} record.
18 | */
19 | public MaxMind() {
20 | this(null);
21 | }
22 |
23 | /**
24 | * Constructs a {@code MaxMind} record.
25 | *
26 | * @param queriesRemaining The number of remaining queries in the current web service call.
27 | * This returns {@code null} when called on a database.
28 | */
29 | @MaxMindDbConstructor
30 | public MaxMind(
31 | @JsonProperty("queries_remaining") @MaxMindDbParameter(name = "queries_remaining")
32 | Integer queriesRemaining) {
33 | this.queriesRemaining = queriesRemaining;
34 | }
35 |
36 | /**
37 | * @return The number of remaining queried in your account for the current
38 | * web service. This returns {@code null} when called on a database.
39 | */
40 | @JsonProperty("queries_remaining")
41 | public Integer getQueriesRemaining() {
42 | return this.queriesRemaining;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/com/maxmind/geoip2/record/Postal.java:
--------------------------------------------------------------------------------
1 | package com.maxmind.geoip2.record;
2 |
3 | import com.fasterxml.jackson.annotation.JsonProperty;
4 | import com.maxmind.db.MaxMindDbConstructor;
5 | import com.maxmind.db.MaxMindDbParameter;
6 |
7 | /**
8 | *
9 | * Contains data for the postal record associated with an IP address.
10 | *
11 | */
12 | public final class Postal extends AbstractRecord {
13 |
14 | private final String code;
15 | private final Integer confidence;
16 |
17 | /**
18 | * Constructs a {@code Postal} record.
19 | */
20 | public Postal() {
21 | this(null, null);
22 | }
23 |
24 | /**
25 | * Constructs an instance of {@code Postal}.
26 | *
27 | * @param code The postal code of the location. Postal codes are not available
28 | * for all countries. In some countries, this will only contain part
29 | * of the postal code.
30 | * @param confidence A value from 0-100 indicating MaxMind's confidence that the
31 | * postal code is correct. This attribute is only available from the
32 | * Insights web service and the GeoIP2 Enterprise database.
33 | */
34 | @MaxMindDbConstructor
35 | public Postal(
36 | @JsonProperty("code") @MaxMindDbParameter(name = "code") String code,
37 | @JsonProperty("confidence") @MaxMindDbParameter(name = "confidence") Integer confidence
38 | ) {
39 | this.code = code;
40 | this.confidence = confidence;
41 | }
42 |
43 | /**
44 | * @return The postal code of the location. Postal codes are not available
45 | * for all countries. In some countries, this will only contain part
46 | * of the postal code.
47 | */
48 | public String getCode() {
49 | return this.code;
50 | }
51 |
52 | /**
53 | * @return A value from 0-100 indicating MaxMind's confidence that the
54 | * postal code is correct. This attribute is only available from the
55 | * Insights web service and the GeoIP2 Enterprise database.
56 | */
57 | public Integer getConfidence() {
58 | return this.confidence;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/com/maxmind/geoip2/record/RepresentedCountry.java:
--------------------------------------------------------------------------------
1 | package com.maxmind.geoip2.record;
2 |
3 | import com.fasterxml.jackson.annotation.JacksonInject;
4 | import com.fasterxml.jackson.annotation.JsonProperty;
5 | import com.maxmind.db.MaxMindDbConstructor;
6 | import com.maxmind.db.MaxMindDbParameter;
7 | import java.util.List;
8 | import java.util.Map;
9 |
10 | /**
11 | *
12 | * Contains data for the represented country associated with an IP address.
13 | *
14 | *
15 | * This class contains the country-level data associated with an IP address for
16 | * the IP's represented country. The represented country is the country
17 | * represented by something like a military base.
18 | *
19 | *
20 | * Do not use any of the country names as a database or map key. Use the value
21 | * returned by {@link #getGeoNameId} or {@link #getIsoCode} instead.
22 | *
23 | */
24 | public final class RepresentedCountry extends Country {
25 |
26 | private final String type;
27 |
28 | /**
29 | * Constructs an instance of {@code RepresentedCountry} with no data.
30 | */
31 | public RepresentedCountry() {
32 | this(null, null, null, false, null, null, null);
33 | }
34 |
35 | /**
36 | * Constructs an instance of {@code RepresentedCountry}.
37 | *
38 | * @param locales The locales to use.
39 | * @param confidence This is a value from 0-100 indicating MaxMind's
40 | * confidence that the country is correct.
41 | * @param geoNameId This is a GeoName ID for the country.
42 | * @param isInEuropeanUnion This is true if the country is a member state of
43 | * the European Union.
44 | * @param isoCode This is a string up to three characters long contain the
45 | * country code.
46 | * @param names This is a map from locale codes to the names for the country
47 | * in that locale.
48 | * @param type This is a string indicating the type of entity that is
49 | * representing the country.
50 | */
51 | @MaxMindDbConstructor
52 | public RepresentedCountry(
53 | @JacksonInject("locales") @MaxMindDbParameter(name = "locales") List locales,
54 | @JsonProperty("confidence") @MaxMindDbParameter(name = "confidence") Integer confidence,
55 | @JsonProperty("geoname_id") @MaxMindDbParameter(name = "geoname_id") Long geoNameId,
56 | @JsonProperty("is_in_european_union") @MaxMindDbParameter(name = "is_in_european_union")
57 | Boolean isInEuropeanUnion,
58 | @JsonProperty("iso_code") @MaxMindDbParameter(name = "iso_code") String isoCode,
59 | @JsonProperty("names") @MaxMindDbParameter(name = "names") Map names,
60 | @JsonProperty("type") @MaxMindDbParameter(name = "type") String type
61 | ) {
62 | super(locales, confidence, geoNameId, isInEuropeanUnion, isoCode,
63 | names);
64 | this.type = type;
65 | }
66 |
67 | /**
68 | * Constructs an instance of {@code RepresentedCountry}.
69 | *
70 | * @param country The {@code RepresentedCountry} object to copy.
71 | * @param locales The locales to use.
72 | */
73 | public RepresentedCountry(
74 | RepresentedCountry country,
75 | List locales
76 | ) {
77 | this(
78 | locales,
79 | country.getConfidence(),
80 | country.getGeoNameId(),
81 | country.isInEuropeanUnion(),
82 | country.getIsoCode(),
83 | country.getNames(),
84 | country.getType()
85 | );
86 | }
87 |
88 | /**
89 | * @return A string indicating the type of entity that is representing the
90 | * country. Currently, we only return {@code military} but this could
91 | * expand to include other types in the future.
92 | */
93 | public String getType() {
94 | return this.type;
95 | }
96 |
97 | }
98 |
--------------------------------------------------------------------------------
/src/main/java/com/maxmind/geoip2/record/Subdivision.java:
--------------------------------------------------------------------------------
1 | package com.maxmind.geoip2.record;
2 |
3 | import com.fasterxml.jackson.annotation.JacksonInject;
4 | import com.fasterxml.jackson.annotation.JsonProperty;
5 | import com.maxmind.db.MaxMindDbConstructor;
6 | import com.maxmind.db.MaxMindDbParameter;
7 | import java.util.List;
8 | import java.util.Map;
9 |
10 | /**
11 | *
12 | * Contains data for the subdivisions associated with an IP address.
13 | *
14 | *
15 | * Do not use any of the subdivision names as a database or map key. Use the
16 | * value returned by {@link #getGeoNameId} or {@link #getIsoCode} instead.
17 | *
18 | */
19 | public final class Subdivision extends AbstractNamedRecord {
20 |
21 | private final Integer confidence;
22 | private final String isoCode;
23 |
24 | /**
25 | * Constructs a {@code Subdivision} record.
26 | */
27 | public Subdivision() {
28 | this(null, null, null, null, null);
29 | }
30 |
31 | /**
32 | * Constructs an instance of {@code Subdivision}.
33 | *
34 | * @param locales The locales to use.
35 | * @param confidence This is a value from 0-100 indicating MaxMind's
36 | * confidence that the subdivision is correct.
37 | * @param geoNameId This is a GeoName ID for the subdivision.
38 | * @param isoCode This is a string up to three characters long contain the subdivision code.
39 | * @param names This is a map from locale codes to the names for the subdivision in that locale.
40 | */
41 | @MaxMindDbConstructor
42 | public Subdivision(
43 | @JacksonInject("locales") @MaxMindDbParameter(name = "locales") List locales,
44 | @JsonProperty("confidence") @MaxMindDbParameter(name = "confidence") Integer confidence,
45 | @JsonProperty("geoname_id") @MaxMindDbParameter(name = "geoname_id") Long geoNameId,
46 | @JsonProperty("iso_code") @MaxMindDbParameter(name = "iso_code") String isoCode,
47 | @JsonProperty("names") @MaxMindDbParameter(name = "names") Map names
48 | ) {
49 | super(locales, geoNameId, names);
50 | this.confidence = confidence;
51 | this.isoCode = isoCode;
52 | }
53 |
54 | /**
55 | * Constructs an instance of {@code Subdivision} with the specified parameters.
56 | *
57 | * @param subdivision The {@code Subdivision} object to copy.
58 | * @param locales The locales to use.
59 | */
60 | public Subdivision(
61 | Subdivision subdivision,
62 | List locales
63 | ) {
64 | this(
65 | locales,
66 | subdivision.getConfidence(),
67 | subdivision.getGeoNameId(),
68 | subdivision.getIsoCode(),
69 | subdivision.getNames()
70 | );
71 | }
72 |
73 | /**
74 | * @return This is a value from 0-100 indicating MaxMind's confidence that
75 | * the subdivision is correct. This attribute is only available from
76 | * the Insights web service and the GeoIP2 Enterprise database.
77 | */
78 | @JsonProperty("confidence")
79 | public Integer getConfidence() {
80 | return this.confidence;
81 | }
82 |
83 | /**
84 | * @return This is a string up to three characters long contain the
85 | * subdivision portion of the ISO
87 | * 3166-2code.
88 | */
89 | @JsonProperty("iso_code")
90 | public String getIsoCode() {
91 | return this.isoCode;
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/src/main/java/module-info.java:
--------------------------------------------------------------------------------
1 | @SuppressWarnings("module") // suppress terminal digit warning
2 | module com.maxmind.geoip2 {
3 | requires com.fasterxml.jackson.annotation;
4 | requires com.fasterxml.jackson.databind;
5 | requires com.fasterxml.jackson.datatype.jsr310;
6 | requires transitive com.maxmind.db;
7 | requires java.net.http;
8 |
9 | exports com.maxmind.geoip2;
10 | exports com.maxmind.geoip2.exception;
11 | exports com.maxmind.geoip2.model;
12 | exports com.maxmind.geoip2.record;
13 | }
14 |
--------------------------------------------------------------------------------
/src/test/java/com/maxmind/geoip2/json/File.java:
--------------------------------------------------------------------------------
1 | package com.maxmind.geoip2.json;
2 |
3 | import java.io.IOException;
4 | import java.net.URISyntaxException;
5 | import java.net.URL;
6 | import java.nio.file.Files;
7 | import java.nio.file.Paths;
8 |
9 | public class File {
10 | public static String readJsonFile(String name) throws IOException,
11 | URISyntaxException {
12 | URL resource = File.class
13 | .getResource("/test-data/" + name + ".json");
14 | return Files.readString(Paths.get(resource.toURI()));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/test/java/com/maxmind/geoip2/matchers/CodeMatcher.java:
--------------------------------------------------------------------------------
1 | package com.maxmind.geoip2.matchers;
2 |
3 | import com.maxmind.geoip2.exception.InvalidRequestException;
4 | import org.hamcrest.Description;
5 | import org.hamcrest.TypeSafeMatcher;
6 |
7 | public class CodeMatcher extends TypeSafeMatcher {
8 |
9 | private String foundErrorCode;
10 | private final String expectedErrorCode;
11 |
12 | public static CodeMatcher hasCode(String item) {
13 | return new CodeMatcher(item);
14 | }
15 |
16 | private CodeMatcher(String expectedErrorCode) {
17 | this.expectedErrorCode = expectedErrorCode;
18 | }
19 |
20 | @Override
21 | protected boolean matchesSafely(final InvalidRequestException exception) {
22 | this.foundErrorCode = exception.getCode();
23 | return this.foundErrorCode.equalsIgnoreCase(this.expectedErrorCode);
24 | }
25 |
26 | @Override
27 | public void describeTo(Description description) {
28 | description.appendValue(this.foundErrorCode)
29 | .appendText(" was not found instead of ")
30 | .appendValue(this.expectedErrorCode);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/test/java/com/maxmind/geoip2/matchers/HttpStatusMatcher.java:
--------------------------------------------------------------------------------
1 | package com.maxmind.geoip2.matchers;
2 |
3 | import com.maxmind.geoip2.exception.HttpException;
4 | import org.hamcrest.Description;
5 | import org.hamcrest.TypeSafeMatcher;
6 |
7 | public class HttpStatusMatcher extends TypeSafeMatcher {
8 |
9 | private int foundStatusCode;
10 | private final int expectedStatusCode;
11 |
12 | public static HttpStatusMatcher hasStatus(int item) {
13 | return new HttpStatusMatcher(item);
14 | }
15 |
16 | private HttpStatusMatcher(int expectedStatusCode) {
17 | this.expectedStatusCode = expectedStatusCode;
18 | }
19 |
20 | @Override
21 | protected boolean matchesSafely(final HttpException exception) {
22 | this.foundStatusCode = exception.getHttpStatus();
23 | return this.foundStatusCode == this.expectedStatusCode;
24 | }
25 |
26 | @Override
27 | public void describeTo(Description description) {
28 | description.appendValue(String.valueOf(this.foundStatusCode))
29 | .appendText(" was not found instead of ")
30 | .appendValue(String.valueOf(this.expectedStatusCode));
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/test/java/com/maxmind/geoip2/model/CityResponseTest.java:
--------------------------------------------------------------------------------
1 | package com.maxmind.geoip2.model;
2 |
3 | import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
4 | import static com.github.tomakehurst.wiremock.client.WireMock.get;
5 | import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
6 | import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
7 | import static com.maxmind.geoip2.json.File.readJsonFile;
8 | import static org.junit.jupiter.api.Assertions.assertEquals;
9 | import static org.junit.jupiter.api.Assertions.assertNotNull;
10 | import static org.junit.jupiter.api.Assertions.assertNull;
11 |
12 | import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
13 | import com.github.tomakehurst.wiremock.junit5.WireMockTest;
14 | import com.maxmind.geoip2.WebServiceClient;
15 | import com.maxmind.geoip2.exception.GeoIp2Exception;
16 | import java.io.IOException;
17 | import java.net.InetAddress;
18 | import java.net.URISyntaxException;
19 | import java.util.Arrays;
20 | import java.util.Collections;
21 | import org.junit.jupiter.api.BeforeEach;
22 | import org.junit.jupiter.api.Test;
23 | import org.junit.jupiter.api.extension.RegisterExtension;
24 |
25 | // In addition to testing the CityResponse, this code exercises the locale
26 | // handling of the models
27 | @WireMockTest
28 | public class CityResponseTest {
29 | @RegisterExtension
30 | static WireMockExtension wireMock = WireMockExtension.newInstance()
31 | .options(wireMockConfig().dynamicPort().dynamicHttpsPort())
32 | .build();
33 |
34 | @BeforeEach
35 | public void createClient() throws IOException, GeoIp2Exception,
36 | URISyntaxException {
37 | wireMock.stubFor(get(urlEqualTo("/geoip/v2.1/city/1.1.1.2"))
38 | .willReturn(aResponse()
39 | .withStatus(200)
40 | .withHeader("Content-Type",
41 | "application/vnd.maxmind.com-city+json; charset=UTF-8; version=2.1")
42 | .withBody(readJsonFile("city0"))));
43 | }
44 |
45 |
46 | @Test
47 | public void testNames() throws Exception {
48 | WebServiceClient client = new WebServiceClient.Builder(6, "0123456789")
49 | .host("localhost")
50 | .port(wireMock.getPort())
51 | .disableHttps()
52 | .locales(Arrays.asList("zh-CN", "ru"))
53 | .build();
54 |
55 | CityResponse city = client.city(InetAddress.getByName("1.1.1.2"));
56 | assertEquals(
57 | "北美洲",
58 | city.getContinent().getName(),
59 | "country.getContinent().getName() does not return 北美洲"
60 | );
61 | assertEquals(
62 | "美国",
63 | city.getCountry().getName(),
64 | "country.getCountry().getName() does not return 美国"
65 | );
66 | assertEquals(
67 | city.getCountry()
68 | .getName(), city.getCountry().getName(),
69 | "toString() returns getName()"
70 | );
71 | }
72 |
73 | @Test
74 | public void russianFallback() throws Exception {
75 | WebServiceClient client = new WebServiceClient.Builder(42,
76 | "abcdef123456")
77 | .host("localhost")
78 | .port(wireMock.getPort())
79 | .disableHttps()
80 | .locales(Arrays.asList("as", "ru")).build();
81 |
82 | CityResponse city = client.city(InetAddress.getByName("1.1.1.2"));
83 | assertEquals(
84 | "объединяет государства",
85 | city.getCountry().getName(),
86 | "country.getCountry().getName() does not return объединяет государства"
87 | );
88 |
89 | }
90 |
91 | @Test
92 | public void testFallback() throws Exception {
93 | WebServiceClient client = new WebServiceClient.Builder(42,
94 | "abcdef123456")
95 | .host("localhost")
96 | .port(wireMock.getPort())
97 | .disableHttps()
98 | .locales(Arrays.asList("pt", "en", "zh-CN")).build();
99 | CityResponse city = client.city(InetAddress.getByName("1.1.1.2"));
100 | assertEquals(
101 | "North America",
102 | city.getContinent().getName(),
103 | "en is returned when pt is missing"
104 | );
105 |
106 | }
107 |
108 | @Test
109 | public void noFallback() throws Exception {
110 | WebServiceClient client = new WebServiceClient.Builder(42,
111 | "abcdef123456")
112 | .host("localhost")
113 | .port(wireMock.getPort())
114 | .disableHttps()
115 | .locales(Arrays.asList("pt", "es", "af")).build();
116 | CityResponse city = client.city(InetAddress.getByName("1.1.1.2"));
117 |
118 | assertNull(
119 | city.getContinent().getName(),
120 | "null is returned when locale is not available"
121 | );
122 | }
123 |
124 | @Test
125 | public void noLocale() throws Exception {
126 | WebServiceClient client = new WebServiceClient.Builder(42,
127 | "abcdef123456")
128 | .host("localhost")
129 | .port(wireMock.getPort())
130 | .disableHttps()
131 | .build();
132 | CityResponse city = client.city(InetAddress.getByName("1.1.1.2"));
133 | assertEquals(
134 | "North America",
135 | city.getContinent().getName(),
136 | "en is returned when no locales are specified"
137 | );
138 |
139 | }
140 |
141 | @Test
142 | public void testMissing() throws Exception {
143 | WebServiceClient client = new WebServiceClient.Builder(42,
144 | "abcdef123456")
145 | .host("localhost")
146 | .port(wireMock.getPort())
147 | .disableHttps()
148 | .locales(Collections.singletonList("en")).build();
149 |
150 | CityResponse city = client.city(InetAddress.getByName("1.1.1.2"));
151 | assertNotNull(city.getCity());
152 | assertNull(city.getCity().getName(), "null is returned when names object is missing");
153 | }
154 | }
155 |
--------------------------------------------------------------------------------
/src/test/java/com/maxmind/geoip2/model/CountryResponseTest.java:
--------------------------------------------------------------------------------
1 | package com.maxmind.geoip2.model;
2 |
3 | import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
4 | import static com.github.tomakehurst.wiremock.client.WireMock.get;
5 | import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
6 | import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
7 | import static com.maxmind.geoip2.json.File.readJsonFile;
8 | import static org.junit.jupiter.api.Assertions.assertEquals;
9 | import static org.junit.jupiter.api.Assertions.assertFalse;
10 | import static org.junit.jupiter.api.Assertions.assertTrue;
11 |
12 | import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
13 | import com.github.tomakehurst.wiremock.junit5.WireMockTest;
14 | import com.maxmind.geoip2.WebServiceClient;
15 | import com.maxmind.geoip2.exception.GeoIp2Exception;
16 | import java.io.IOException;
17 | import java.net.InetAddress;
18 | import java.net.URISyntaxException;
19 | import org.junit.jupiter.api.BeforeEach;
20 | import org.junit.jupiter.api.Test;
21 | import org.junit.jupiter.api.extension.RegisterExtension;
22 |
23 | @WireMockTest
24 | public class CountryResponseTest {
25 | @RegisterExtension
26 | static WireMockExtension wireMock = WireMockExtension.newInstance()
27 | .options(wireMockConfig().dynamicPort().dynamicHttpsPort())
28 | .build();
29 |
30 | private CountryResponse country;
31 |
32 | @BeforeEach
33 | public void createClient() throws IOException, GeoIp2Exception,
34 | URISyntaxException {
35 | wireMock.stubFor(get(urlEqualTo("/geoip/v2.1/country/1.1.1.1"))
36 | .willReturn(aResponse()
37 | .withStatus(200)
38 | .withHeader("Content-Type",
39 | "application/vnd.maxmind.com-country+json; charset=UTF-8; version=2.1")
40 | .withBody(readJsonFile("country0"))));
41 |
42 | WebServiceClient client = new WebServiceClient.Builder(6, "0123456789")
43 | .host("localhost")
44 | .port(wireMock.getPort())
45 | .disableHttps()
46 | .build();
47 |
48 | country = client.country(InetAddress.getByName("1.1.1.1"));
49 | }
50 |
51 | @Test
52 | public void testContinent() {
53 | assertEquals(
54 | "NA",
55 | this.country.getContinent().getCode(),
56 | "country.getContinent().getCode() does not return NA"
57 | );
58 | assertEquals(
59 | 42,
60 | this.country.getContinent().getGeoNameId(),
61 | "country.getContinent().getGeoNameId() does not return 42"
62 | );
63 | assertEquals(
64 | "North America",
65 | this.country.getContinent().getName(),
66 | "country.getContinent().getName() does not return North America"
67 | );
68 | }
69 |
70 | @Test
71 | public void testCountry() {
72 | assertFalse(
73 | this.country.getCountry().isInEuropeanUnion(),
74 | "country.getCountry().isInEuropeanUnion() does not return false"
75 | );
76 | assertEquals(
77 | this.country.getCountry().getIsoCode(),
78 | "US",
79 | "country.getCountry().getCode() does not return US"
80 | );
81 | assertEquals(
82 | 1,
83 | (long) this.country.getCountry().getGeoNameId(),
84 | "country.getCountry().getGeoNameId() does not return 1"
85 | );
86 | assertEquals(
87 | Integer.valueOf(56),
88 | this.country.getCountry().getConfidence(),
89 | "country.getCountry().getConfidence() does not return 56"
90 | );
91 | assertEquals(
92 | "United States",
93 | this.country.getCountry().getName(),
94 | "country.getCountry().getName(\"en\") does not return United States"
95 | );
96 | }
97 |
98 | @Test
99 | public void testRegisteredCountry() {
100 | assertFalse(
101 | this.country.getRegisteredCountry().isInEuropeanUnion(),
102 | "country.getRegisteredCountry().isInEuropeanUnion() does not return false"
103 | );
104 | assertEquals(
105 | "CA",
106 | this.country.getRegisteredCountry().getIsoCode(),
107 | "country.getRegisteredCountry().getIsoCode() does not return CA"
108 | );
109 | assertEquals(
110 | 2,
111 | (long) this.country.getRegisteredCountry().getGeoNameId(),
112 | "country.getRegisteredCountry().getGeoNameId() does not return 2"
113 | );
114 | assertEquals(
115 | "Canada",
116 | this.country.getRegisteredCountry().getName(),
117 | "country.getRegisteredCountry().getName(\"en\") does not return United States"
118 | );
119 | }
120 |
121 | @Test
122 | public void testRepresentedCountry() {
123 | assertTrue(
124 | this.country.getRepresentedCountry().isInEuropeanUnion(),
125 | "country.getRepresentedCountry().isInEuropeanUnion() does not return true"
126 | );
127 | assertEquals(
128 | "GB",
129 | this.country.getRepresentedCountry().getIsoCode(),
130 | "country.getRepresentedCountry().getCode() does not return GB"
131 | );
132 | assertEquals(
133 | 4,
134 | (long) this.country.getRepresentedCountry().getGeoNameId(),
135 | "country.getRepresentedCountry().getGeoNameId() does not return 4"
136 | );
137 | assertEquals(
138 | "United Kingdom",
139 | this.country.getRepresentedCountry().getName(),
140 | "country.getRepresentedCountry().getName(\"en\") does not return United Kingdom"
141 | );
142 | assertEquals(
143 | "military",
144 | this.country.getRepresentedCountry().getType(),
145 | "country.getRepresentedCountry().getType() does not return military"
146 | );
147 | }
148 |
149 | @Test
150 | public void testTraits() {
151 |
152 | assertEquals(
153 | "1.2.3.4",
154 | this.country.getTraits().getIpAddress(),
155 | "country.getTraits().getIpAddress does not return 1.2.3.4"
156 | );
157 |
158 | }
159 | }
160 |
--------------------------------------------------------------------------------
/src/test/java/com/maxmind/geoip2/model/InsightsResponseTest.java:
--------------------------------------------------------------------------------
1 | package com.maxmind.geoip2.model;
2 |
3 | import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
4 | import static com.github.tomakehurst.wiremock.client.WireMock.get;
5 | import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
6 | import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
7 | import static com.maxmind.geoip2.json.File.readJsonFile;
8 | import static org.junit.jupiter.api.Assertions.assertEquals;
9 | import static org.junit.jupiter.api.Assertions.assertNotNull;
10 | import static org.junit.jupiter.api.Assertions.assertTrue;
11 | import static org.junit.jupiter.api.Assertions.fail;
12 |
13 | import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
14 | import com.github.tomakehurst.wiremock.junit5.WireMockTest;
15 | import com.maxmind.geoip2.WebServiceClient;
16 | import com.maxmind.geoip2.exception.GeoIp2Exception;
17 | import com.maxmind.geoip2.model.ConnectionTypeResponse.ConnectionType;
18 | import com.maxmind.geoip2.record.Location;
19 | import com.maxmind.geoip2.record.MaxMind;
20 | import com.maxmind.geoip2.record.Postal;
21 | import com.maxmind.geoip2.record.Subdivision;
22 | import com.maxmind.geoip2.record.Traits;
23 | import java.io.IOException;
24 | import java.net.InetAddress;
25 | import java.net.URISyntaxException;
26 | import java.util.List;
27 | import org.junit.jupiter.api.BeforeEach;
28 | import org.junit.jupiter.api.Test;
29 | import org.junit.jupiter.api.extension.RegisterExtension;
30 |
31 | @WireMockTest
32 | public class InsightsResponseTest {
33 | @RegisterExtension
34 | static WireMockExtension wireMock = WireMockExtension.newInstance()
35 | .options(wireMockConfig().dynamicPort().dynamicHttpsPort())
36 | .build();
37 |
38 | private InsightsResponse insights;
39 |
40 | @BeforeEach
41 | public void createClient() throws IOException, GeoIp2Exception,
42 | URISyntaxException {
43 | wireMock.stubFor(get(urlEqualTo("/geoip/v2.1/insights/1.1.1.1"))
44 | .willReturn(aResponse()
45 | .withStatus(200)
46 | .withHeader("Content-Type",
47 | "application/vnd.maxmind.com-insights+json; charset=UTF-8; version=2.1")
48 | .withBody(readJsonFile("insights0"))));
49 | wireMock.stubFor(get(urlEqualTo("/geoip/v2.1/insights/1.1.1.2"))
50 | .willReturn(aResponse()
51 | .withStatus(200)
52 | .withHeader("Content-Type",
53 | "application/vnd.maxmind.com-insights+json; charset=UTF-8; version=2.1")
54 | .withBody(readJsonFile("insights1"))));
55 |
56 | WebServiceClient client = new WebServiceClient.Builder(6, "0123456789")
57 | .host("localhost")
58 | .port(wireMock.getPort())
59 | .disableHttps()
60 | .build();
61 |
62 | this.insights = client.insights(InetAddress.getByName("1.1.1.1"));
63 | }
64 |
65 | @Test
66 | public void testSubdivisionsList() {
67 | List subdivisionsList = this.insights.getSubdivisions();
68 | assertNotNull(subdivisionsList, "city.getSubdivisionsList returns null");
69 | if (subdivisionsList.isEmpty()) {
70 | fail("subdivisionsList is empty");
71 | }
72 | Subdivision subdivision = subdivisionsList.get(0);
73 | assertEquals(
74 | Integer.valueOf(88),
75 | subdivision.getConfidence(),
76 | "subdivision.getConfidence() does not return 88"
77 | );
78 | assertEquals(
79 | 574635,
80 | subdivision.getGeoNameId().intValue(),
81 | "subdivision.getGeoNameId() does not return 574635"
82 | );
83 | assertEquals(
84 | "MN",
85 | subdivision.getIsoCode(),
86 | "subdivision.getCode() does not return MN"
87 | );
88 | }
89 |
90 | @Test
91 | public void mostSpecificSubdivision() {
92 | assertEquals(
93 | "TT",
94 | this.insights.getMostSpecificSubdivision().getIsoCode(),
95 | "Most specific subdivision returns last subdivision"
96 | );
97 | }
98 |
99 | @Test
100 | public void leastSpecificSubdivision() {
101 | assertEquals(
102 | "MN",
103 | this.insights.getLeastSpecificSubdivision().getIsoCode(),
104 | "Most specific subdivision returns first subdivision"
105 | );
106 | }
107 |
108 | @SuppressWarnings("deprecation")
109 | @Test
110 | public void testTraits() {
111 | Traits traits = this.insights.getTraits();
112 |
113 | assertNotNull(traits, "city.getTraits() returns null");
114 | assertEquals(
115 | Long.valueOf(1234),
116 | traits.getAutonomousSystemNumber(),
117 | "traits.getAutonomousSystemNumber() does not return 1234"
118 | );
119 | assertEquals(
120 |
121 | "AS Organization",
122 | traits.getAutonomousSystemOrganization(),
123 | "traits.getAutonomousSystemOrganization() does not return AS Organization"
124 | );
125 | assertEquals(
126 |
127 | ConnectionType.CABLE_DSL,
128 | traits.getConnectionType(),
129 | "traits.getConnectionType() does not return Cable/DSL"
130 | );
131 | assertEquals(
132 | "example.com",
133 | traits.getDomain(),
134 | "traits.getDomain() does not return example.com"
135 | );
136 | assertEquals(
137 | "1.2.3.4",
138 | traits.getIpAddress(),
139 | "traits.getIpAddress() does not return 1.2.3.4"
140 | );
141 | assertTrue(traits.isAnonymous(), "traits.isAnonymous() returns true");
142 | assertTrue(traits.isAnonymousProxy(), "traits.isAnonymousProxy() returns true");
143 | assertTrue(traits.isAnonymousVpn(), "traits.isAnonymousVpn() returns true");
144 | assertTrue(traits.isHostingProvider(), "traits.isHostingProvider() returns true");
145 | assertTrue(traits.isPublicProxy(), "traits.isPublicProxy() returns true");
146 | assertTrue(traits.isResidentialProxy(), "traits.isResidentialProxy() returns true");
147 | assertTrue(traits.isSatelliteProvider(), "traits.isSatelliteProvider() returns true");
148 | assertTrue(traits.isTorExitNode(), "traits.isTorExitNode() returns true");
149 | assertEquals(
150 | "Comcast",
151 | traits.getIsp(),
152 | "traits.getIsp() does not return Comcast"
153 | );
154 | assertEquals(
155 | "Blorg",
156 | traits.getOrganization(),
157 | "traits.getOrganization() does not return Blorg"
158 | );
159 | assertEquals(
160 | "college",
161 | traits.getUserType(),
162 | "traits.getUserType() does not return userType"
163 | );
164 | assertEquals(
165 | Double.valueOf(1.3),
166 | traits.getStaticIpScore(),
167 | "traits.getStaticIpScore() does not return 1.3"
168 | );
169 | assertEquals(
170 | Integer.valueOf(2),
171 | traits.getUserCount(),
172 | "traits.getUserCount() does not return 2"
173 | );
174 | }
175 |
176 | @SuppressWarnings("deprecation")
177 | @Test
178 | public void testLocation() {
179 |
180 | Location location = this.insights.getLocation();
181 |
182 | assertNotNull(location, "city.getLocation() returns null");
183 |
184 | assertEquals(
185 | Integer.valueOf(24626),
186 | location.getAverageIncome(),
187 | "location.getAverageIncome() does not return 24626"
188 | );
189 |
190 | assertEquals(
191 | Integer.valueOf(1500),
192 | location.getAccuracyRadius(),
193 | "location.getAccuracyRadius() does not return 1500"
194 | );
195 |
196 | double latitude = location.getLatitude();
197 | assertEquals(
198 | 44.98,
199 | latitude,
200 | 0.1,
201 | "location.getLatitude() does not return 44.98"
202 | );
203 | double longitude = location.getLongitude();
204 | assertEquals(
205 | 93.2636,
206 | longitude,
207 | 0.1,
208 | "location.getLongitude() does not return 93.2636"
209 | );
210 | assertEquals(
211 | Integer.valueOf(765),
212 | location.getMetroCode(),
213 | "location.getMetroCode() does not return 765"
214 | );
215 | assertEquals(
216 | Integer.valueOf(1341),
217 | location.getPopulationDensity(),
218 | "location.getPopulationDensity() does not return 1341"
219 | );
220 | assertEquals(
221 | "America/Chicago",
222 | location.getTimeZone(),
223 | "location.getTimeZone() does not return America/Chicago"
224 | );
225 | }
226 |
227 | @Test
228 | public void testMaxMind() {
229 | MaxMind maxmind = this.insights.getMaxMind();
230 | assertEquals(
231 | 11, maxmind
232 | .getQueriesRemaining().intValue(),
233 | "Correct number of queries remaining"
234 | );
235 | }
236 |
237 | @Test
238 | public void testPostal() {
239 |
240 | Postal postal = this.insights.getPostal();
241 | assertEquals(
242 | "55401",
243 | postal.getCode(),
244 | "postal.getCode() does not return 55401"
245 | );
246 | assertEquals(
247 | Integer.valueOf(33),
248 | postal.getConfidence(),
249 | "postal.getConfidence() does not return 33"
250 | );
251 | }
252 |
253 | @Test
254 | public void testRepresentedCountry() {
255 | assertNotNull(
256 | this.insights.getRepresentedCountry(),
257 | "city.getRepresentedCountry() returns null"
258 | );
259 |
260 | assertEquals(
261 | "C",
262 | this.insights.getRepresentedCountry().getType(),
263 | "city.getRepresentedCountry().getType() does not return C"
264 | );
265 | assertTrue(
266 | this.insights.getRepresentedCountry().isInEuropeanUnion(),
267 | "city.getRepresentedCountry().isInEuropeanUnion() does not return true"
268 | );
269 | }
270 |
271 | @Test
272 | public void testIsInEuropeanUnion() throws IOException, GeoIp2Exception {
273 | // This uses an alternate fixture where we have the
274 | // is_in_european_union flag set in locations not set in the other
275 | // fixture.
276 | WebServiceClient client = new WebServiceClient.Builder(6, "0123456789")
277 | .host("localhost")
278 | .port(wireMock.getPort())
279 | .disableHttps()
280 | .build();
281 |
282 | InsightsResponse insights = client.insights(
283 | InetAddress.getByName("1.1.1.2"));
284 |
285 | assertTrue(
286 | insights.getCountry().isInEuropeanUnion(),
287 | "getCountry().isInEuropeanUnion() does not return true"
288 | );
289 | assertTrue(
290 | insights.getRegisteredCountry().isInEuropeanUnion(),
291 | "getRegisteredCountry().() isInEuropeanUnion = does not return true"
292 | );
293 | }
294 | }
295 |
--------------------------------------------------------------------------------
/src/test/java/com/maxmind/geoip2/model/JsonTest.java:
--------------------------------------------------------------------------------
1 | package com.maxmind.geoip2.model;
2 |
3 | import static org.junit.jupiter.api.Assertions.assertEquals;
4 |
5 | import com.fasterxml.jackson.databind.InjectableValues;
6 | import com.fasterxml.jackson.databind.JsonNode;
7 | import com.fasterxml.jackson.databind.MapperFeature;
8 | import com.fasterxml.jackson.databind.json.JsonMapper;
9 | import com.fasterxml.jackson.jr.ob.JSON;
10 | import java.io.IOException;
11 | import java.util.Collections;
12 | import org.junit.jupiter.api.Test;
13 |
14 | public class JsonTest {
15 |
16 | @Test
17 | public void testInsightsSerialization() throws IOException {
18 | String json = JSON.std
19 | .composeString()
20 | .startObject()
21 | .startObjectField("maxmind")
22 | .put("queries_remaining", 11)
23 | .end()
24 | .startObjectField("registered_country")
25 | .put("geoname_id", 2)
26 | .startObjectField("names")
27 | .put("en", "Canada")
28 | .end()
29 | .put("is_in_european_union", false)
30 | .put("iso_code", "CA")
31 | .end()
32 | .startObjectField("traits")
33 | .put("autonomous_system_organization", "AS Organization")
34 | .put("autonomous_system_number", 1234)
35 | .put("domain", "example.com")
36 | .put("isp", "Comcast")
37 | .put("ip_address", "1.2.3.4")
38 | .put("is_anonymous", true)
39 | .put("is_anonymous_proxy", true)
40 | .put("is_anonymous_vpn", true)
41 | .put("is_anycast", true)
42 | .put("is_hosting_provider", true)
43 | .put("is_legitimate_proxy", true)
44 | .put("is_public_proxy", true)
45 | .put("is_residential_proxy", true)
46 | .put("is_satellite_provider", true)
47 | .put("is_tor_exit_node", true)
48 | .put("network", "1.2.3.0/24")
49 | .put("organization", "Blorg")
50 | .put("user_type", "college")
51 | // This is here just to simplify the testing. We expect the
52 | // difference
53 | .put("is_legitimate_proxy", false)
54 | .end()
55 | .startObjectField("country")
56 | .startObjectField("names")
57 | .put("en", "United States of America")
58 | .end()
59 | .put("geoname_id", 1)
60 | .put("is_in_european_union", false)
61 | .put("iso_code", "US")
62 | .put("confidence", 99)
63 | .end()
64 | .startObjectField("continent")
65 | .startObjectField("names")
66 | .put("en", "North America")
67 | .end()
68 | .put("code", "NA")
69 | .put("geoname_id", 42)
70 | .end()
71 | .startObjectField("location")
72 | .put("average_income", 24626)
73 | .put("population_density", 1341)
74 | .put("time_zone", "America/Chicago")
75 | .put("accuracy_radius", 1500)
76 | .put("metro_code", 765)
77 | .put("latitude", 44.98)
78 | .put("longitude", 93.2636)
79 | .end()
80 | .startArrayField("subdivisions")
81 | .startObject()
82 | .put("confidence", 88)
83 | .put("iso_code", "MN")
84 | .put("geoname_id", 574635)
85 | .startObjectField("names")
86 | .put("en", "Minnesota")
87 | .end()
88 | .end()
89 | .startObject()
90 | .put("iso_code", "TT")
91 | .end()
92 | .end()
93 | .startObjectField("represented_country")
94 | .put("geoname_id", 3)
95 | .startObjectField("names")
96 | .put("en", "United Kingdom")
97 | .end()
98 | .put("type", "C")
99 | .put("is_in_european_union", true)
100 | .put("iso_code", "GB")
101 | .end()
102 | .startObjectField("postal")
103 | .put("code", "55401")
104 | .put("confidence", 33)
105 | .end()
106 | .startObjectField("city")
107 | .put("confidence", 76)
108 | .put("geoname_id", 9876)
109 | .startObjectField("names")
110 | .put("en", "Minneapolis")
111 | .end()
112 | .end()
113 | .end()
114 | .finish();
115 |
116 | testRoundTrip(InsightsResponse.class, json);
117 | }
118 |
119 | @Test
120 | public void testCitySerialization() throws IOException {
121 | String json = JSON.std
122 | .composeString()
123 | .startObject()
124 | .startObjectField("maxmind")
125 | .put("queries_remaining", 11)
126 | .end()
127 | .startObjectField("registered_country")
128 | .put("geoname_id", 2)
129 | .startObjectField("names")
130 | .put("en", "Canada")
131 | .end()
132 | .put("is_in_european_union", false)
133 | .put("iso_code", "CA")
134 | .end()
135 | .startObjectField("traits")
136 | .put("is_anonymous_proxy", true)
137 | .put("autonomous_system_number", 1234)
138 | .put("isp", "Comcast")
139 | .put("ip_address", "1.2.3.4")
140 | .put("is_satellite_provider", true)
141 | .put("autonomous_system_organization", "AS Organization")
142 | .put("organization", "Blorg")
143 | .put("domain", "example.com")
144 | // These are here just to simplify the testing. We expect the
145 | // difference
146 | .put("is_anonymous", false)
147 | .put("is_anonymous_vpn", false)
148 | .put("is_anycast", true)
149 | .put("is_hosting_provider", false)
150 | .put("is_legitimate_proxy", false)
151 | .put("is_public_proxy", false)
152 | .put("is_residential_proxy", false)
153 | .put("is_tor_exit_node", false)
154 | .put("network", "1.2.3.0/24")
155 | .end()
156 | .startObjectField("country")
157 | .startObjectField("names")
158 | .put("en", "United States of America")
159 | .end()
160 | .put("geoname_id", 1)
161 | .put("is_in_european_union", false)
162 | .put("iso_code", "US")
163 | .end()
164 | .startObjectField("continent")
165 | .startObjectField("names")
166 | .put("en", "North America")
167 | .end()
168 | .put("code", "NA")
169 | .put("geoname_id", 42)
170 | .end()
171 | .startObjectField("location")
172 | .put("time_zone", "America/Chicago")
173 | .put("metro_code", 765)
174 | .put("latitude", 44.98)
175 | .put("longitude", 93.2636)
176 | .end()
177 | .startArrayField("subdivisions")
178 | .startObject()
179 | .put("iso_code", "MN")
180 | .put("geoname_id", 574635)
181 | .startObjectField("names")
182 | .put("en", "Minnesota")
183 | .end()
184 | .end()
185 | .startObject()
186 | .put("iso_code", "TT")
187 | .end()
188 | .end()
189 | .startObjectField("represented_country")
190 | .put("geoname_id", 3)
191 | .startObjectField("names")
192 | .put("en", "United Kingdom")
193 | .end()
194 | .put("type", "C")
195 | .put("is_in_european_union", true)
196 | .put("iso_code", "GB")
197 | .end()
198 | .startObjectField("postal")
199 | .put("code", "55401")
200 | .end()
201 | .startObjectField("city")
202 | .put("geoname_id", 9876)
203 | .startObjectField("names")
204 | .put("en", "Minneapolis")
205 | .end()
206 | .end()
207 | .end()
208 | .finish();
209 |
210 | testRoundTrip(CityResponse.class, json);
211 | }
212 |
213 | @Test
214 | public void testCountrySerialization() throws IOException {
215 | String json = JSON.std
216 | .composeString()
217 | .startObject()
218 | .startObjectField("maxmind")
219 | .put("queries_remaining", 11)
220 | .end()
221 | .startObjectField("registered_country")
222 | .put("geoname_id", 2)
223 | .startObjectField("names")
224 | .put("en", "Canada")
225 | .end()
226 | .put("is_in_european_union", false)
227 | .put("iso_code", "CA")
228 | .end()
229 | .startObjectField("traits")
230 | .put("is_anonymous_proxy", true)
231 | .put("ip_address", "1.2.3.4")
232 | .put("is_satellite_provider", true)
233 | // These are here just to simplify the testing. We expect the
234 | // difference
235 | .put("is_anonymous", false)
236 | .put("is_anonymous_vpn", false)
237 | .put("is_anycast", true)
238 | .put("is_hosting_provider", false)
239 | .put("is_legitimate_proxy", false)
240 | .put("is_public_proxy", false)
241 | .put("is_residential_proxy", false)
242 | .put("is_tor_exit_node", false)
243 | .put("network", "1.2.3.0/24")
244 | .end()
245 | .startObjectField("country")
246 | .startObjectField("names")
247 | .put("en", "United States of America")
248 | .end()
249 | .put("geoname_id", 1)
250 | .put("is_in_european_union", false)
251 | .put("iso_code", "US")
252 | .end()
253 | .startObjectField("continent")
254 | .startObjectField("names")
255 | .put("en", "North America")
256 | .end()
257 | .put("code", "NA")
258 | .put("geoname_id", 42)
259 | .end()
260 | .startObjectField("represented_country")
261 | .put("geoname_id", 3)
262 | .startObjectField("names")
263 | .put("en", "United Kingdom")
264 | .end()
265 | .put("type", "C")
266 | .put("is_in_european_union", true)
267 | .put("iso_code", "GB")
268 | .end()
269 | .end()
270 | .finish();
271 |
272 | testRoundTrip(CountryResponse.class, json);
273 | }
274 |
275 | @Test
276 | public void testAnonymousIPSerialization() throws Exception {
277 | String json = JSON.std
278 | .composeString()
279 | .startObject()
280 | .put("is_anonymous", true)
281 | .put("is_anonymous_vpn", true)
282 | .put("is_hosting_provider", true)
283 | .put("is_public_proxy", true)
284 | .put("is_residential_proxy", false)
285 | .put("is_tor_exit_node", true)
286 | .put("ip_address", "1.1.1.1")
287 | .put("network", "1.1.1.0/24")
288 | .end()
289 | .finish();
290 |
291 | testRoundTrip(AnonymousIpResponse.class, json);
292 | }
293 |
294 | @Test
295 | public void testConnectionTypeSerialization() throws Exception {
296 | String json = JSON.std
297 | .composeString()
298 | .startObject()
299 | .put("connection_type", "Dialup")
300 | .put("ip_address", "1.1.1.1")
301 | .put("network", "1.1.1.0/24")
302 | .end()
303 | .finish();
304 |
305 | testRoundTrip(ConnectionTypeResponse.class, json);
306 | }
307 |
308 | @Test
309 | public void testDomainSerialization() throws Exception {
310 | String json = JSON.std
311 | .composeString()
312 | .startObject()
313 | .put("domain", "gmail.com")
314 | .put("ip_address", "1.1.1.1")
315 | .put("network", "1.1.1.0/24")
316 | .end()
317 | .finish();
318 |
319 | testRoundTrip(DomainResponse.class, json);
320 | }
321 |
322 |
323 | @Test
324 | public void testIspSerialization() throws Exception {
325 | String json = JSON.std
326 | .composeString()
327 | .startObject()
328 | .put("autonomous_system_number", 2121)
329 | .put("autonomous_system_organization", "Google, Inc.")
330 | .put("isp", "ISP, Inc.")
331 | .put("organization", "Google, Inc.")
332 | .put("ip_address", "1.1.1.1")
333 | .put("network", "1.1.1.0/24")
334 | .end()
335 | .finish();
336 |
337 | testRoundTrip(IspResponse.class, json);
338 | }
339 |
340 | protected void testRoundTrip
341 | (Class cls, String json)
342 | throws IOException {
343 | JsonMapper mapper = JsonMapper.builder()
344 | .disable(MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS)
345 | .build();
346 | InjectableValues inject = new InjectableValues.Std().addValue(
347 | "locales", Collections.singletonList("en"));
348 | T response = mapper.readerFor(cls).with(inject).readValue(json);
349 |
350 | JsonNode expectedNode = mapper.readValue(json, JsonNode.class);
351 | JsonNode actualNode = mapper.readValue(response.toJson(), JsonNode.class);
352 |
353 | assertEquals(expectedNode, actualNode);
354 | }
355 | }
356 |
--------------------------------------------------------------------------------
/src/test/resources/test-data/city0.json:
--------------------------------------------------------------------------------
1 | {
2 | "continent": {
3 | "code": "NA",
4 | "geoname_id": 42,
5 | "names": {
6 | "zh-CN": "北美洲",
7 | "en": "North America"
8 | }
9 | },
10 | "country": {
11 | "confidence": 56,
12 | "geoname_id": 1,
13 | "iso_code": "US",
14 | "names": {
15 | "ru": "объединяет государства",
16 | "en": "United States",
17 | "zh-CN": "美国"
18 | }
19 | },
20 | "registered_country": {
21 | "geoname_id": 2,
22 | "iso_code": "CA",
23 | "names": {
24 | "en": "Canada"
25 | }
26 | },
27 | "traits": {
28 | "ip_address": "1.2.3.4"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/test/resources/test-data/country0.json:
--------------------------------------------------------------------------------
1 | {
2 | "traits": {
3 | "ip_address": "1.2.3.4"
4 | },
5 | "continent": {
6 | "names": {
7 | "en": "North America"
8 | },
9 | "geoname_id": 42,
10 | "code": "NA"
11 | },
12 | "country": {
13 | "geoname_id": 1,
14 | "confidence": 56,
15 | "names": {
16 | "en": "United States"
17 | },
18 | "iso_code": "US"
19 | },
20 | "registered_country": {
21 | "geoname_id": 2,
22 | "names": {
23 | "en": "Canada"
24 | },
25 | "iso_code": "CA"
26 | },
27 | "represented_country": {
28 | "geoname_id": 4,
29 | "type": "military",
30 | "names": {
31 | "en": "United Kingdom"
32 | },
33 | "is_in_european_union": true,
34 | "iso_code": "GB"
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/test/resources/test-data/insights0.json:
--------------------------------------------------------------------------------
1 | {
2 | "city": {
3 | "confidence": 76,
4 | "geoname_id": 9876,
5 | "names": {
6 | "en": "Minneapolis"
7 | }
8 | },
9 | "continent": {
10 | "code": "NA",
11 | "geoname_id": 42,
12 | "names": {
13 | "en": "North America"
14 | }
15 | },
16 | "country": {
17 | "confidence": 99,
18 | "geoname_id": 1,
19 | "iso_code": "US",
20 | "names": {
21 | "en": "United States of America"
22 | }
23 | },
24 | "location": {
25 | "accuracy_radius": 1500,
26 | "average_income": 24626,
27 | "latitude": 44.98,
28 | "longitude": 93.2636,
29 | "metro_code": 765,
30 | "population_density": 1341,
31 | "time_zone": "America/Chicago"
32 | },
33 | "maxmind": {
34 | "queries_remaining": 11
35 | },
36 | "postal": {
37 | "code": "55401",
38 | "confidence": 33
39 | },
40 | "registered_country": {
41 | "geoname_id": 2,
42 | "iso_code": "CA",
43 | "names": {
44 | "en": "Canada"
45 | }
46 | },
47 | "represented_country": {
48 | "geoname_id": 3,
49 | "is_in_european_union": true,
50 | "iso_code": "GB",
51 | "names": {
52 | "en": "United Kingdom"
53 | },
54 | "type": "C"
55 | },
56 | "subdivisions": [
57 | {
58 | "confidence": 88,
59 | "geoname_id": 574635,
60 | "iso_code": "MN",
61 | "names": {
62 | "en": "Minnesota"
63 | }
64 | },
65 | {
66 | "iso_code": "TT"
67 | }
68 | ],
69 | "traits": {
70 | "autonomous_system_number": 1234,
71 | "autonomous_system_organization": "AS Organization",
72 | "connection_type": "Cable/DSL",
73 | "domain": "example.com",
74 | "ip_address": "1.2.3.4",
75 | "isp": "Comcast",
76 | "is_anonymous": true,
77 | "is_anonymous_proxy": true,
78 | "is_anonymous_vpn": true,
79 | "is_anycast": true,
80 | "is_hosting_provider": true,
81 | "is_public_proxy": true,
82 | "is_residential_proxy": true,
83 | "is_satellite_provider": true,
84 | "is_tor_exit_node": true,
85 | "organization": "Blorg",
86 | "static_ip_score": 1.3,
87 | "user_count": 2,
88 | "user_type": "college"
89 | }
90 | }
--------------------------------------------------------------------------------
/src/test/resources/test-data/insights1.json:
--------------------------------------------------------------------------------
1 | {
2 | "city": {
3 | "geoname_id": "2655045",
4 | "names": {
5 | "en": "Boxford"
6 | }
7 | },
8 | "continent": {
9 | "code": "EU",
10 | "geoname_id": 6255148,
11 | "names": {
12 | "de": "Europa",
13 | "en": "Europe",
14 | "es": "Europa",
15 | "fr": "Europe",
16 | "ja": "ヨーロッパ",
17 | "pt-BR": "Europa",
18 | "ru": "Европа",
19 | "zh-CN": "欧洲"
20 | }
21 | },
22 | "country": {
23 | "geoname_id": 2635167,
24 | "is_in_european_union": true,
25 | "iso_code": "GB",
26 | "names": {
27 | "de": "Vereinigtes Königreich",
28 | "en": "United Kingdom",
29 | "es": "Reino Unido",
30 | "fr": "Royaume-Uni",
31 | "ja": "イギリス",
32 | "pt-BR": "Reino Unido",
33 | "ru": "Великобритания",
34 | "zh-CN": "英国"
35 | }
36 | },
37 | "location": {
38 | "accuracy_radius": 100,
39 | "latitude": "51.7500",
40 | "longitude": "-1.2500",
41 | "time_zone": "Europe/London"
42 | },
43 | "maxmind": {
44 | "queries_remaining": 11
45 | },
46 | "postal": {
47 | "code": "OX1"
48 | },
49 | "registered_country": {
50 | "geoname_id": 3017382,
51 | "is_in_european_union": true,
52 | "iso_code": "FR",
53 | "names": {
54 | "de": "Frankreich",
55 | "en": "France",
56 | "es": "Francia",
57 | "fr": "France",
58 | "ja": "フランス共和国",
59 | "pt-BR": "França",
60 | "ru": "Франция",
61 | "zh-CN": "法国"
62 | }
63 | },
64 | "subdivisions": [
65 | {
66 | "geoname_id": 6269131,
67 | "iso_code": "ENG",
68 | "names": {
69 | "en": "England",
70 | "es": "Inglaterra",
71 | "fr": "Angleterre",
72 | "pt-BR": "Inglaterra"
73 | }
74 | },
75 | {
76 | "geoname_id": 3333217,
77 | "iso_code": "WBK",
78 | "names": {
79 | "en": "West Berkshire",
80 | "ru": "Западный Беркшир",
81 | "zh-CN": "西伯克郡"
82 | }
83 | }
84 | ],
85 | "traits": {
86 | "autonomous_system_number": 1234,
87 | "autonomous_system_organization": "AS Organization",
88 | "connection_type": "Cable/DSL",
89 | "domain": "example.com",
90 | "ip_address": "1.2.3.4",
91 | "isp": "Comcast",
92 | "is_anonymous": true,
93 | "is_anonymous_proxy": true,
94 | "is_anonymous_vpn": true,
95 | "is_anycast": true,
96 | "is_hosting_provider": true,
97 | "is_public_proxy": true,
98 | "is_satellite_provider": true,
99 | "is_tor_exit_node": true,
100 | "organization": "Blorg",
101 | "static_ip_score": 1.3,
102 | "user_count": 2,
103 | "user_type": "college"
104 | }
105 | }
--------------------------------------------------------------------------------