maxmind-geoip2 1.4.0 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/README.md +1 -1
- data/lib/maxmind/geoip2/record/traits.rb +9 -1
- data/lib/maxmind/geoip2/version.rb +1 -1
- metadata +9 -91
- data/CLAUDE.md +0 -390
- data/Gemfile +0 -5
- data/Gemfile.lock +0 -126
- data/README.dev.md +0 -4
- data/Rakefile +0 -14
- data/maxmind-geoip2.gemspec +0 -41
- data/test/data/LICENSE-APACHE +0 -202
- data/test/data/LICENSE-MIT +0 -17
- data/test/data/MaxMind-DB-spec.md +0 -573
- data/test/data/README.md +0 -11
- data/test/data/bad-data/README.md +0 -7
- data/test/data/bad-data/libmaxminddb/libmaxminddb-offset-integer-overflow.mmdb +0 -0
- data/test/data/bad-data/maxminddb-golang/cyclic-data-structure.mmdb +0 -0
- data/test/data/bad-data/maxminddb-golang/invalid-bytes-length.mmdb +0 -1
- data/test/data/bad-data/maxminddb-golang/invalid-data-record-offset.mmdb +0 -0
- data/test/data/bad-data/maxminddb-golang/invalid-map-key-length.mmdb +0 -0
- data/test/data/bad-data/maxminddb-golang/invalid-string-length.mmdb +0 -1
- data/test/data/bad-data/maxminddb-golang/metadata-is-an-uint128.mmdb +0 -1
- data/test/data/bad-data/maxminddb-golang/unexpected-bytes.mmdb +0 -0
- data/test/data/bad-data/maxminddb-python/bad-unicode-in-map-key.mmdb +0 -0
- data/test/data/cmd/write-test-data/main.go +0 -68
- data/test/data/go.mod +0 -13
- data/test/data/go.sum +0 -16
- data/test/data/pkg/writer/decoder.go +0 -178
- data/test/data/pkg/writer/geoip2.go +0 -184
- data/test/data/pkg/writer/ip.go +0 -39
- data/test/data/pkg/writer/maxmind.go +0 -246
- data/test/data/pkg/writer/nestedstructures.go +0 -73
- data/test/data/pkg/writer/writer.go +0 -61
- data/test/data/source-data/GeoIP-Anonymous-Plus-Test.json +0 -175
- data/test/data/source-data/GeoIP2-Anonymous-IP-Test.json +0 -55
- data/test/data/source-data/GeoIP2-City-Test.json +0 -13272
- data/test/data/source-data/GeoIP2-Connection-Type-Test.json +0 -127
- data/test/data/source-data/GeoIP2-Country-Test.json +0 -15978
- data/test/data/source-data/GeoIP2-DensityIncome-Test.json +0 -14
- data/test/data/source-data/GeoIP2-Domain-Test.json +0 -457
- data/test/data/source-data/GeoIP2-Enterprise-Test.json +0 -1110
- data/test/data/source-data/GeoIP2-IP-Risk-Test.json +0 -31
- data/test/data/source-data/GeoIP2-ISP-Test.json +0 -12605
- data/test/data/source-data/GeoIP2-Precision-Enterprise-Sandbox-Test.json +0 -296
- data/test/data/source-data/GeoIP2-Precision-Enterprise-Test.json +0 -3189
- data/test/data/source-data/GeoIP2-Static-IP-Score-Test.json +0 -2147
- data/test/data/source-data/GeoIP2-User-Count-Test.json +0 -2855
- data/test/data/source-data/GeoLite2-ASN-Test.json +0 -4120
- data/test/data/source-data/GeoLite2-City-Test.json +0 -12969
- data/test/data/source-data/GeoLite2-Country-Test.json +0 -11369
- data/test/data/test-data/GeoIP-Anonymous-Plus-Test.mmdb +0 -0
- data/test/data/test-data/GeoIP2-Anonymous-IP-Test.mmdb +0 -0
- data/test/data/test-data/GeoIP2-City-Test-Broken-Double-Format.mmdb +0 -0
- data/test/data/test-data/GeoIP2-City-Test-Invalid-Node-Count.mmdb +0 -0
- data/test/data/test-data/GeoIP2-City-Test.mmdb +0 -0
- data/test/data/test-data/GeoIP2-Connection-Type-Test.mmdb +0 -0
- data/test/data/test-data/GeoIP2-Country-Test.mmdb +0 -0
- data/test/data/test-data/GeoIP2-DensityIncome-Test.mmdb +0 -0
- data/test/data/test-data/GeoIP2-Domain-Test.mmdb +0 -0
- data/test/data/test-data/GeoIP2-Enterprise-Test.mmdb +0 -0
- data/test/data/test-data/GeoIP2-IP-Risk-Test.mmdb +0 -0
- data/test/data/test-data/GeoIP2-ISP-Test.mmdb +0 -0
- data/test/data/test-data/GeoIP2-Precision-Enterprise-Test.mmdb +0 -0
- data/test/data/test-data/GeoIP2-Static-IP-Score-Test.mmdb +0 -0
- data/test/data/test-data/GeoIP2-User-Count-Test.mmdb +0 -0
- data/test/data/test-data/GeoLite2-ASN-Test.mmdb +0 -0
- data/test/data/test-data/GeoLite2-City-Test.mmdb +0 -0
- data/test/data/test-data/GeoLite2-Country-Test.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-no-ipv4-search-tree.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-string-value-entries.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-broken-pointers-24.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-broken-search-tree-24.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-decoder.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-ipv4-24.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-ipv4-28.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-ipv4-32.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-ipv6-24.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-ipv6-28.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-ipv6-32.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-metadata-pointers.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-mixed-24.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-mixed-28.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-mixed-32.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-nested.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-pointer-decoder.mmdb +0 -0
- data/test/data/test-data/README.md +0 -42
- data/test/data/test-data/maps-with-pointers.raw +0 -0
- data/test/data/tidyall.ini +0 -5
- data/test/test_client.rb +0 -467
- data/test/test_model_country.rb +0 -95
- data/test/test_model_names.rb +0 -50
- data/test/test_reader.rb +0 -589
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
## How to generate test data
|
|
2
|
-
Use the [write-test-data](https://github.com/maxmind/MaxMind-DB/blob/main/cmd/write-test-data)
|
|
3
|
-
go tool to create a small set of test databases with a variety of data and
|
|
4
|
-
record sizes.
|
|
5
|
-
|
|
6
|
-
These test databases are useful for testing code that reads MaxMind DB files.
|
|
7
|
-
|
|
8
|
-
There are several ways to figure out what IP addresses are actually in the
|
|
9
|
-
test databases. You can take a look at the
|
|
10
|
-
[source-data directory](https://github.com/maxmind/MaxMind-DB/tree/main/source-data)
|
|
11
|
-
in this repository. This directory contains JSON files which are used to
|
|
12
|
-
generate many (but not all) of the database files.
|
|
13
|
-
|
|
14
|
-
You can also use the
|
|
15
|
-
[mmdb-dump-database script](https://github.com/maxmind/MaxMind-DB-Reader-perl/blob/main/eg/mmdb-dump-database)
|
|
16
|
-
in the
|
|
17
|
-
[MaxMind-DB-Reader-perl repository](https://github.com/maxmind/MaxMind-DB-Reader-perl).
|
|
18
|
-
|
|
19
|
-
## Static test data
|
|
20
|
-
Some of the test files are remnants of the
|
|
21
|
-
[old perl test data writer](https://github.com/maxmind/MaxMind-DB/blob/f0a85c671c5b6e9c5e514bd66162724ee1dedea3/test-data/write-test-data.pl)
|
|
22
|
-
and cannot be generated with the go tool. These databases are intentionally broken,
|
|
23
|
-
and exploited functionality simply not available in the go mmdbwriter:
|
|
24
|
-
|
|
25
|
-
- MaxMind-DB-test-broken-pointers-24.mmdb
|
|
26
|
-
- MaxMind-DB-test-broken-search-tree-24.mmdb
|
|
27
|
-
- MaxMind-DB-test-pointer-decoder.mmdb
|
|
28
|
-
- GeoIP2-City-Test-Broken-Double-Format.mmdb
|
|
29
|
-
- GeoIP2-City-Test-Invalid-Node-Count.mmdb
|
|
30
|
-
- maps-with-pointers.raw
|
|
31
|
-
|
|
32
|
-
## Usage
|
|
33
|
-
```
|
|
34
|
-
Usage of ./write-test-data:
|
|
35
|
-
-source string
|
|
36
|
-
Source data directory
|
|
37
|
-
-target string
|
|
38
|
-
Destination directory for the generated mmdb files
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
Example:
|
|
42
|
-
`./write-test-data --source ../../source-data --target ../../test-data`
|
|
Binary file
|
data/test/data/tidyall.ini
DELETED
data/test/test_client.rb
DELETED
|
@@ -1,467 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'json'
|
|
4
|
-
require 'maxmind/geoip2'
|
|
5
|
-
require 'minitest/autorun'
|
|
6
|
-
require 'webmock/minitest'
|
|
7
|
-
|
|
8
|
-
class ClientTest < Minitest::Test
|
|
9
|
-
COUNTRY = {
|
|
10
|
-
'continent' => {
|
|
11
|
-
'code' => 'NA',
|
|
12
|
-
'geoname_id' => 42,
|
|
13
|
-
'names' => { 'en' => 'North America' },
|
|
14
|
-
},
|
|
15
|
-
'country' => {
|
|
16
|
-
'geoname_id' => 1,
|
|
17
|
-
'iso_code' => 'US',
|
|
18
|
-
'names' => { 'en' => 'United States of America' },
|
|
19
|
-
},
|
|
20
|
-
'maxmind' => {
|
|
21
|
-
'queries_remaining' => 11,
|
|
22
|
-
},
|
|
23
|
-
'traits' => {
|
|
24
|
-
'ip_address' => '1.2.3.4',
|
|
25
|
-
'is_anycast' => true,
|
|
26
|
-
'network' => '1.2.3.0/24',
|
|
27
|
-
},
|
|
28
|
-
}.freeze
|
|
29
|
-
|
|
30
|
-
INSIGHTS = {
|
|
31
|
-
'anonymizer' => {
|
|
32
|
-
'confidence' => 85,
|
|
33
|
-
'is_anonymous' => true,
|
|
34
|
-
'is_anonymous_vpn' => true,
|
|
35
|
-
'is_hosting_provider' => false,
|
|
36
|
-
'is_public_proxy' => false,
|
|
37
|
-
'is_residential_proxy' => true,
|
|
38
|
-
'is_tor_exit_node' => false,
|
|
39
|
-
'network_last_seen' => '2025-10-15',
|
|
40
|
-
'provider_name' => 'NordVPN',
|
|
41
|
-
},
|
|
42
|
-
'continent' => {
|
|
43
|
-
'code' => 'NA',
|
|
44
|
-
'geoname_id' => 42,
|
|
45
|
-
'names' => { 'en' => 'North America' },
|
|
46
|
-
},
|
|
47
|
-
'country' => {
|
|
48
|
-
'geoname_id' => 1,
|
|
49
|
-
'iso_code' => 'US',
|
|
50
|
-
'names' => { 'en' => 'United States of America' },
|
|
51
|
-
},
|
|
52
|
-
'maxmind' => {
|
|
53
|
-
'queries_remaining' => 11,
|
|
54
|
-
},
|
|
55
|
-
'traits' => {
|
|
56
|
-
'ip_address' => '1.2.3.40',
|
|
57
|
-
'ip_risk_snapshot' => 45.5,
|
|
58
|
-
'is_anycast' => true,
|
|
59
|
-
'is_residential_proxy' => true,
|
|
60
|
-
'network' => '1.2.3.0/24',
|
|
61
|
-
'static_ip_score' => 1.3,
|
|
62
|
-
'user_count' => 2,
|
|
63
|
-
},
|
|
64
|
-
}.freeze
|
|
65
|
-
|
|
66
|
-
CONTENT_TYPES = {
|
|
67
|
-
country: 'application/vnd.maxmind.com-country+json; charset=UTF-8; version=2.1',
|
|
68
|
-
}.freeze
|
|
69
|
-
|
|
70
|
-
def test_country
|
|
71
|
-
record = request(:country, '1.2.3.4')
|
|
72
|
-
|
|
73
|
-
assert_instance_of(MaxMind::GeoIP2::Model::Country, record)
|
|
74
|
-
|
|
75
|
-
assert_equal(42, record.continent.geoname_id)
|
|
76
|
-
assert_equal('NA', record.continent.code)
|
|
77
|
-
assert_equal({ 'en' => 'North America' }, record.continent.names)
|
|
78
|
-
assert_equal('North America', record.continent.name)
|
|
79
|
-
|
|
80
|
-
assert_equal(1, record.country.geoname_id)
|
|
81
|
-
refute(record.country.in_european_union?)
|
|
82
|
-
assert_equal('US', record.country.iso_code)
|
|
83
|
-
assert_equal({ 'en' => 'United States of America' }, record.country.names)
|
|
84
|
-
assert_equal('United States of America', record.country.name)
|
|
85
|
-
|
|
86
|
-
assert_equal(11, record.maxmind.queries_remaining)
|
|
87
|
-
|
|
88
|
-
refute(record.registered_country.in_european_union?)
|
|
89
|
-
|
|
90
|
-
assert(record.traits.anycast?)
|
|
91
|
-
assert_equal('1.2.3.0/24', record.traits.network)
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
def test_insights
|
|
95
|
-
record = request(:insights, '1.2.3.40')
|
|
96
|
-
|
|
97
|
-
assert_instance_of(MaxMind::GeoIP2::Model::Insights, record)
|
|
98
|
-
|
|
99
|
-
assert_equal(42, record.continent.geoname_id)
|
|
100
|
-
|
|
101
|
-
# Test anonymizer object
|
|
102
|
-
assert_equal(85, record.anonymizer.confidence)
|
|
103
|
-
assert(record.anonymizer.anonymous?)
|
|
104
|
-
assert(record.anonymizer.anonymous_vpn?)
|
|
105
|
-
refute(record.anonymizer.hosting_provider?)
|
|
106
|
-
refute(record.anonymizer.public_proxy?)
|
|
107
|
-
assert(record.anonymizer.residential_proxy?)
|
|
108
|
-
refute(record.anonymizer.tor_exit_node?)
|
|
109
|
-
assert_equal(Date.parse('2025-10-15'), record.anonymizer.network_last_seen)
|
|
110
|
-
assert_equal('NordVPN', record.anonymizer.provider_name)
|
|
111
|
-
|
|
112
|
-
# Test traits
|
|
113
|
-
assert(record.traits.anycast?)
|
|
114
|
-
assert(record.traits.residential_proxy?)
|
|
115
|
-
assert_equal('1.2.3.0/24', record.traits.network)
|
|
116
|
-
assert_in_delta(1.3, record.traits.static_ip_score)
|
|
117
|
-
assert_equal(2, record.traits.user_count)
|
|
118
|
-
assert_in_delta(45.5, record.traits.ip_risk_snapshot)
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
def test_city
|
|
122
|
-
record = request(:city, '1.2.3.4')
|
|
123
|
-
|
|
124
|
-
assert_instance_of(MaxMind::GeoIP2::Model::City, record)
|
|
125
|
-
|
|
126
|
-
assert_equal('1.2.3.0/24', record.traits.network)
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
def test_me
|
|
130
|
-
record = request(:city, 'me')
|
|
131
|
-
|
|
132
|
-
assert_instance_of(MaxMind::GeoIP2::Model::City, record)
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
def test_no_body_error
|
|
136
|
-
assert_raises(
|
|
137
|
-
JSON::ParserError,
|
|
138
|
-
) { request(:country, '1.2.3.5') }
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
def test_bad_body_error
|
|
142
|
-
assert_raises(
|
|
143
|
-
JSON::ParserError,
|
|
144
|
-
) { request(:country, '2.2.3.5') }
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
def test_non_json_success_response
|
|
148
|
-
error = assert_raises(
|
|
149
|
-
MaxMind::GeoIP2::HTTPError,
|
|
150
|
-
) { request(:country, '3.2.3.5') }
|
|
151
|
-
|
|
152
|
-
assert_equal(
|
|
153
|
-
'Received a success response for country but it is not JSON: extra bad body',
|
|
154
|
-
error.message,
|
|
155
|
-
)
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
def test_invalid_ip_error_from_web_service
|
|
159
|
-
error = assert_raises(
|
|
160
|
-
MaxMind::GeoIP2::AddressInvalidError,
|
|
161
|
-
) { request(:country, '1.2.3.6') }
|
|
162
|
-
|
|
163
|
-
assert_equal(
|
|
164
|
-
'The value "1.2.3" is not a valid IP address',
|
|
165
|
-
error.message,
|
|
166
|
-
)
|
|
167
|
-
end
|
|
168
|
-
|
|
169
|
-
def test_invalid_ip_error_from_client
|
|
170
|
-
error = assert_raises(
|
|
171
|
-
MaxMind::GeoIP2::AddressInvalidError,
|
|
172
|
-
) { request(:country, '1.2.3') }
|
|
173
|
-
|
|
174
|
-
assert_equal(
|
|
175
|
-
'The value "1.2.3" is not a valid IP address',
|
|
176
|
-
error.message,
|
|
177
|
-
)
|
|
178
|
-
end
|
|
179
|
-
|
|
180
|
-
def test_no_error_body_ip_error
|
|
181
|
-
assert_raises(
|
|
182
|
-
JSON::ParserError,
|
|
183
|
-
) { request(:country, '1.2.3.7') }
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
def test_missing_key_ip_error
|
|
187
|
-
error = assert_raises(
|
|
188
|
-
MaxMind::GeoIP2::HTTPError,
|
|
189
|
-
) { request(:country, '1.2.3.71') }
|
|
190
|
-
|
|
191
|
-
assert_equal(
|
|
192
|
-
'Received client error response (400) that is JSON but does not specify code or error keys: {"code":"HI"}',
|
|
193
|
-
error.message,
|
|
194
|
-
)
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
def test_weird_error_body_ip_error
|
|
198
|
-
error = assert_raises(
|
|
199
|
-
MaxMind::GeoIP2::HTTPError,
|
|
200
|
-
) { request(:country, '1.2.3.8') }
|
|
201
|
-
|
|
202
|
-
assert_equal(
|
|
203
|
-
'Received client error response (400) that is JSON but does not specify code or error keys: {"weird":42}',
|
|
204
|
-
error.message,
|
|
205
|
-
)
|
|
206
|
-
end
|
|
207
|
-
|
|
208
|
-
def test_500_error
|
|
209
|
-
error = assert_raises(
|
|
210
|
-
MaxMind::GeoIP2::HTTPError,
|
|
211
|
-
) { request(:country, '1.2.3.10') }
|
|
212
|
-
|
|
213
|
-
assert_equal(
|
|
214
|
-
'Received server error response (500) for country with body foo',
|
|
215
|
-
error.message,
|
|
216
|
-
)
|
|
217
|
-
end
|
|
218
|
-
|
|
219
|
-
def test_300_response
|
|
220
|
-
error = assert_raises(
|
|
221
|
-
MaxMind::GeoIP2::HTTPError,
|
|
222
|
-
) { request(:country, '1.2.3.11') }
|
|
223
|
-
|
|
224
|
-
assert_equal(
|
|
225
|
-
'Received unexpected response (300) for country with body bar',
|
|
226
|
-
error.message,
|
|
227
|
-
)
|
|
228
|
-
end
|
|
229
|
-
|
|
230
|
-
def test_406_error
|
|
231
|
-
error = assert_raises(
|
|
232
|
-
MaxMind::GeoIP2::HTTPError,
|
|
233
|
-
) { request(:country, '1.2.3.12') }
|
|
234
|
-
|
|
235
|
-
assert_equal(
|
|
236
|
-
'Received client error response (406) for country but it is not JSON: Cannot satisfy your Accept-Charset requirements',
|
|
237
|
-
error.message,
|
|
238
|
-
)
|
|
239
|
-
end
|
|
240
|
-
|
|
241
|
-
def test_address_not_found_error
|
|
242
|
-
error = assert_raises(
|
|
243
|
-
MaxMind::GeoIP2::AddressNotFoundError,
|
|
244
|
-
) { request(:country, '1.2.3.13') }
|
|
245
|
-
|
|
246
|
-
assert_equal(
|
|
247
|
-
'The address "1.2.3.13" is not in our database.',
|
|
248
|
-
error.message,
|
|
249
|
-
)
|
|
250
|
-
end
|
|
251
|
-
|
|
252
|
-
def test_address_reserved_error
|
|
253
|
-
error = assert_raises(
|
|
254
|
-
MaxMind::GeoIP2::AddressReservedError,
|
|
255
|
-
) { request(:country, '1.2.3.14') }
|
|
256
|
-
|
|
257
|
-
assert_equal(
|
|
258
|
-
'The address "1.2.3.14" is a private address.',
|
|
259
|
-
error.message,
|
|
260
|
-
)
|
|
261
|
-
end
|
|
262
|
-
|
|
263
|
-
def test_authorization_error
|
|
264
|
-
error = assert_raises(
|
|
265
|
-
MaxMind::GeoIP2::AuthenticationError,
|
|
266
|
-
) { request(:country, '1.2.3.15') }
|
|
267
|
-
|
|
268
|
-
assert_equal(
|
|
269
|
-
'An account ID and license key are required to use this service.',
|
|
270
|
-
error.message,
|
|
271
|
-
)
|
|
272
|
-
end
|
|
273
|
-
|
|
274
|
-
def test_missing_license_key_error
|
|
275
|
-
error = assert_raises(
|
|
276
|
-
MaxMind::GeoIP2::AuthenticationError,
|
|
277
|
-
) { request(:country, '1.2.3.16') }
|
|
278
|
-
|
|
279
|
-
assert_equal(
|
|
280
|
-
'A license key is required to use this service.',
|
|
281
|
-
error.message,
|
|
282
|
-
)
|
|
283
|
-
end
|
|
284
|
-
|
|
285
|
-
def test_missing_account_id_error
|
|
286
|
-
error = assert_raises(
|
|
287
|
-
MaxMind::GeoIP2::AuthenticationError,
|
|
288
|
-
) { request(:country, '1.2.3.17') }
|
|
289
|
-
|
|
290
|
-
assert_equal(
|
|
291
|
-
'An account ID is required to use this service.',
|
|
292
|
-
error.message,
|
|
293
|
-
)
|
|
294
|
-
end
|
|
295
|
-
|
|
296
|
-
def test_insufficient_funds_error
|
|
297
|
-
error = assert_raises(
|
|
298
|
-
MaxMind::GeoIP2::InsufficientFundsError,
|
|
299
|
-
) { request(:country, '1.2.3.18') }
|
|
300
|
-
|
|
301
|
-
assert_equal(
|
|
302
|
-
'The license key you have provided is out of queries.',
|
|
303
|
-
error.message,
|
|
304
|
-
)
|
|
305
|
-
end
|
|
306
|
-
|
|
307
|
-
def test_unexpected_code_error
|
|
308
|
-
error = assert_raises(
|
|
309
|
-
MaxMind::GeoIP2::InvalidRequestError,
|
|
310
|
-
) { request(:country, '1.2.3.19') }
|
|
311
|
-
|
|
312
|
-
assert_equal(
|
|
313
|
-
'Whoa!',
|
|
314
|
-
error.message,
|
|
315
|
-
)
|
|
316
|
-
end
|
|
317
|
-
|
|
318
|
-
def request(method, ip_address)
|
|
319
|
-
response = get_response(ip_address)
|
|
320
|
-
|
|
321
|
-
stub_request(:get, /geoip/)
|
|
322
|
-
.to_return(
|
|
323
|
-
body: response[:body],
|
|
324
|
-
headers: response[:headers],
|
|
325
|
-
status: response[:status],
|
|
326
|
-
)
|
|
327
|
-
|
|
328
|
-
client = MaxMind::GeoIP2::Client.new(
|
|
329
|
-
account_id: 42,
|
|
330
|
-
license_key: 'abcdef123456',
|
|
331
|
-
)
|
|
332
|
-
|
|
333
|
-
client.send(method, ip_address)
|
|
334
|
-
end
|
|
335
|
-
|
|
336
|
-
def get_response(ip_address)
|
|
337
|
-
responses = {
|
|
338
|
-
'me' => {
|
|
339
|
-
body: JSON.generate(COUNTRY),
|
|
340
|
-
headers: { 'Content-Type': CONTENT_TYPES[:country] },
|
|
341
|
-
status: 200,
|
|
342
|
-
},
|
|
343
|
-
'1.2.3' => {},
|
|
344
|
-
'1.2.3.4' => {
|
|
345
|
-
body: JSON.generate(COUNTRY),
|
|
346
|
-
headers: { 'Content-Type': CONTENT_TYPES[:country] },
|
|
347
|
-
status: 200,
|
|
348
|
-
},
|
|
349
|
-
'1.2.3.5' => {
|
|
350
|
-
body: '',
|
|
351
|
-
headers: { 'Content-Type': CONTENT_TYPES[:country] },
|
|
352
|
-
status: 200,
|
|
353
|
-
},
|
|
354
|
-
'2.2.3.5' => {
|
|
355
|
-
body: 'bad body',
|
|
356
|
-
headers: { 'Content-Type': CONTENT_TYPES[:country] },
|
|
357
|
-
status: 200,
|
|
358
|
-
},
|
|
359
|
-
'3.2.3.5' => {
|
|
360
|
-
body: 'extra bad body',
|
|
361
|
-
headers: {},
|
|
362
|
-
status: 200,
|
|
363
|
-
},
|
|
364
|
-
'1.2.3.40' => {
|
|
365
|
-
body: JSON.generate(INSIGHTS),
|
|
366
|
-
headers: { 'Content-Type': CONTENT_TYPES[:country] },
|
|
367
|
-
status: 200,
|
|
368
|
-
},
|
|
369
|
-
'1.2.3.6' => {
|
|
370
|
-
body: JSON.generate({
|
|
371
|
-
'code' => 'IP_ADDRESS_INVALID',
|
|
372
|
-
'error' => 'The value "1.2.3" is not a valid IP address',
|
|
373
|
-
}),
|
|
374
|
-
headers: { 'Content-Type': CONTENT_TYPES[:country] },
|
|
375
|
-
status: 400,
|
|
376
|
-
},
|
|
377
|
-
'1.2.3.7' => {
|
|
378
|
-
body: '',
|
|
379
|
-
headers: { 'Content-Type': CONTENT_TYPES[:country] },
|
|
380
|
-
status: 400,
|
|
381
|
-
},
|
|
382
|
-
'1.2.3.71' => {
|
|
383
|
-
body: JSON.generate({ code: 'HI' }),
|
|
384
|
-
headers: { 'Content-Type': CONTENT_TYPES[:country] },
|
|
385
|
-
status: 400,
|
|
386
|
-
},
|
|
387
|
-
'1.2.3.8' => {
|
|
388
|
-
body: JSON.generate({ weird: 42 }),
|
|
389
|
-
headers: { 'Content-Type': CONTENT_TYPES[:country] },
|
|
390
|
-
status: 400,
|
|
391
|
-
},
|
|
392
|
-
'1.2.3.10' => {
|
|
393
|
-
body: 'foo',
|
|
394
|
-
headers: { 'Content-Type': CONTENT_TYPES[:country] },
|
|
395
|
-
status: 500,
|
|
396
|
-
},
|
|
397
|
-
'1.2.3.11' => {
|
|
398
|
-
body: 'bar',
|
|
399
|
-
headers: { 'Content-Type': CONTENT_TYPES[:country] },
|
|
400
|
-
status: 300,
|
|
401
|
-
},
|
|
402
|
-
'1.2.3.12' => {
|
|
403
|
-
body: 'Cannot satisfy your Accept-Charset requirements',
|
|
404
|
-
headers: {},
|
|
405
|
-
status: 406,
|
|
406
|
-
},
|
|
407
|
-
'1.2.3.13' => {
|
|
408
|
-
body: JSON.generate({
|
|
409
|
-
'code' => 'IP_ADDRESS_NOT_FOUND',
|
|
410
|
-
'error' => 'The address "1.2.3.13" is not in our database.',
|
|
411
|
-
}),
|
|
412
|
-
headers: { 'Content-Type': CONTENT_TYPES[:country] },
|
|
413
|
-
status: 400,
|
|
414
|
-
},
|
|
415
|
-
'1.2.3.14' => {
|
|
416
|
-
body: JSON.generate({
|
|
417
|
-
'code' => 'IP_ADDRESS_RESERVED',
|
|
418
|
-
'error' => 'The address "1.2.3.14" is a private address.',
|
|
419
|
-
}),
|
|
420
|
-
headers: { 'Content-Type': CONTENT_TYPES[:country] },
|
|
421
|
-
status: 400,
|
|
422
|
-
},
|
|
423
|
-
'1.2.3.15' => {
|
|
424
|
-
body: JSON.generate({
|
|
425
|
-
'code' => 'AUTHORIZATION_INVALID',
|
|
426
|
-
'error' => 'An account ID and license key are required to use this service.',
|
|
427
|
-
}),
|
|
428
|
-
headers: { 'Content-Type': CONTENT_TYPES[:country] },
|
|
429
|
-
status: 401,
|
|
430
|
-
},
|
|
431
|
-
'1.2.3.16' => {
|
|
432
|
-
body: JSON.generate({
|
|
433
|
-
'code' => 'LICENSE_KEY_REQUIRED',
|
|
434
|
-
'error' => 'A license key is required to use this service.',
|
|
435
|
-
}),
|
|
436
|
-
headers: { 'Content-Type': CONTENT_TYPES[:country] },
|
|
437
|
-
status: 401,
|
|
438
|
-
},
|
|
439
|
-
'1.2.3.17' => {
|
|
440
|
-
body: JSON.generate({
|
|
441
|
-
'code' => 'ACCOUNT_ID_REQUIRED',
|
|
442
|
-
'error' => 'An account ID is required to use this service.',
|
|
443
|
-
}),
|
|
444
|
-
headers: { 'Content-Type': CONTENT_TYPES[:country] },
|
|
445
|
-
status: 401,
|
|
446
|
-
},
|
|
447
|
-
'1.2.3.18' => {
|
|
448
|
-
body: JSON.generate({
|
|
449
|
-
'code' => 'INSUFFICIENT_FUNDS',
|
|
450
|
-
'error' => 'The license key you have provided is out of queries.',
|
|
451
|
-
}),
|
|
452
|
-
headers: { 'Content-Type': CONTENT_TYPES[:country] },
|
|
453
|
-
status: 402,
|
|
454
|
-
},
|
|
455
|
-
'1.2.3.19' => {
|
|
456
|
-
body: JSON.generate({
|
|
457
|
-
'code' => 'UNEXPECTED',
|
|
458
|
-
'error' => 'Whoa!',
|
|
459
|
-
}),
|
|
460
|
-
headers: { 'Content-Type': CONTENT_TYPES[:country] },
|
|
461
|
-
status: 400,
|
|
462
|
-
},
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
responses[ip_address]
|
|
466
|
-
end
|
|
467
|
-
end
|