minfraud 1.0.4 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +2 -0
  3. data/.travis.yml +20 -3
  4. data/CHANGELOG.md +31 -3
  5. data/CODE_OF_CONDUCT.md +4 -4
  6. data/Gemfile +9 -2
  7. data/LICENSE.txt +2 -1
  8. data/README.dev.md +4 -0
  9. data/README.md +106 -35
  10. data/lib/maxmind/geoip2/model/city.rb +99 -0
  11. data/lib/maxmind/geoip2/model/country.rb +94 -0
  12. data/lib/maxmind/geoip2/model/insights.rb +38 -0
  13. data/lib/maxmind/geoip2/record/abstract.rb +46 -0
  14. data/lib/maxmind/geoip2/record/city.rb +62 -0
  15. data/lib/maxmind/geoip2/record/continent.rb +61 -0
  16. data/lib/maxmind/geoip2/record/country.rb +78 -0
  17. data/lib/maxmind/geoip2/record/location.rb +97 -0
  18. data/lib/maxmind/geoip2/record/maxmind.rb +41 -0
  19. data/lib/maxmind/geoip2/record/place.rb +52 -0
  20. data/lib/maxmind/geoip2/record/postal.rb +54 -0
  21. data/lib/maxmind/geoip2/record/represented_country.rb +47 -0
  22. data/lib/maxmind/geoip2/record/subdivision.rb +72 -0
  23. data/lib/maxmind/geoip2/record/traits.rb +224 -0
  24. data/lib/minfraud.rb +5 -3
  25. data/lib/minfraud/assessments.rb +14 -5
  26. data/lib/minfraud/components/account.rb +1 -1
  27. data/lib/minfraud/components/addressable.rb +1 -1
  28. data/lib/minfraud/components/custom_inputs.rb +14 -0
  29. data/lib/minfraud/components/device.rb +11 -0
  30. data/lib/minfraud/components/event.rb +12 -1
  31. data/lib/minfraud/components/payment.rb +124 -12
  32. data/lib/minfraud/components/report/transaction.rb +69 -0
  33. data/lib/minfraud/error_handler.rb +36 -16
  34. data/lib/minfraud/http_service.rb +0 -1
  35. data/lib/minfraud/http_service/response.rb +36 -4
  36. data/lib/minfraud/model/abstract.rb +20 -0
  37. data/lib/minfraud/model/address.rb +52 -0
  38. data/lib/minfraud/model/billing_address.rb +11 -0
  39. data/lib/minfraud/model/credit_card.rb +75 -0
  40. data/lib/minfraud/model/device.rb +54 -0
  41. data/lib/minfraud/model/disposition.rb +35 -0
  42. data/lib/minfraud/model/email.rb +54 -0
  43. data/lib/minfraud/model/email_domain.rb +24 -0
  44. data/lib/minfraud/model/error.rb +28 -0
  45. data/lib/minfraud/model/factors.rb +24 -0
  46. data/lib/minfraud/model/geoip2_location.rb +25 -0
  47. data/lib/minfraud/model/insights.rb +68 -0
  48. data/lib/minfraud/model/ip_address.rb +82 -0
  49. data/lib/minfraud/model/issuer.rb +49 -0
  50. data/lib/minfraud/model/score.rb +76 -0
  51. data/lib/minfraud/model/score_ip_address.rb +23 -0
  52. data/lib/minfraud/model/shipping_address.rb +30 -0
  53. data/lib/minfraud/model/subscores.rb +156 -0
  54. data/lib/minfraud/model/warning.rb +63 -0
  55. data/lib/minfraud/report.rb +38 -0
  56. data/lib/minfraud/resolver.rb +2 -1
  57. data/lib/minfraud/version.rb +1 -1
  58. data/minfraud.gemspec +16 -16
  59. metadata +61 -39
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 360e5c67027b7cac3bacd6715aa3afee61de8a75
4
- data.tar.gz: cb6dd240c3436fe0c0c23e7aa6d5ad5c4bcfcae8
2
+ SHA256:
3
+ metadata.gz: 992486331731cfd910c7ae3da4039bfa3b776277ff3eb3fb44ae62816299d2cb
4
+ data.tar.gz: db10a19261bdca8cb64df6f0992a2d102859c670fc47568cdc01e299c17318a6
5
5
  SHA512:
6
- metadata.gz: c3cb59ad5bde816f3b2f8be3cc1f0699ce18c1728a8267d7e827b28e8fecd0a20c638211f453a0f8dee2ea7c252096193293633ca5ecf4e3a640f632e5201dfb
7
- data.tar.gz: 2b430855a1157e215891a09a1cf0aab79bad1a027e272359a536caf81db8958835e06f591393a9782b22c90655017b91475eff775208f964a4ae0ca44bb1dd43
6
+ metadata.gz: bd6e8c22d6557f26233b1f5c306ab3d358adb9f661f1452d02471ce0b705cd0037ecafc235af86646894bc4ab953c595989011148aa4f658132f6ec7c7218a4f
7
+ data.tar.gz: f8e53c39ef6a07271297e8555808682b9cb662efe43057ea6da9ea9400418b7a59bd168051888e8c69ebda1d9ed6947729e48de5b3a61df25b26536f13589bef
data/.gitignore CHANGED
@@ -1,7 +1,9 @@
1
+ /coverage
1
2
  pkg
2
3
  .project
3
4
  Gemfile.lock
4
5
  .rvmrc
5
6
  *.rbc
7
+ .yardoc
6
8
  *~
7
9
  .DS_Store
@@ -1,5 +1,22 @@
1
- sudo: false
2
1
  language: ruby
2
+
3
3
  rvm:
4
- - 2.3.1
5
- before_install: gem install bundler -v 1.12.5
4
+ - 1.9
5
+ - 2.0
6
+ - 2.1
7
+ - 2.2
8
+ - 2.3
9
+ - 2.4
10
+ - 2.5
11
+ - 2.6
12
+ - 2.7
13
+
14
+ notifications:
15
+ email:
16
+ on_failure: always
17
+ on_success: change
18
+ recipients:
19
+ - dev-ci@maxmind.com
20
+ slack:
21
+ rooms:
22
+ secure: "wuwMo+BWnaBtkt1uGAi4Zd0EARX3B2TXDmBGCtn8r4PLfehh61S6nLQDASNXSk200PmniFM8PyOUNVGVJqWpYQAEMn32WWdy4vTK2c8CsjwfsMhgnOI2YDCzw+jiP+8EfIGBsPO4xA7yrzweP8gkzBtplb3LbaCiW83WfFo9+402yr0/0F9gfWi8qvuIw29XAS1XWhTY4itqGfkSPdOHQz/45ElpLkGlgreuRrih3tAgn9YLb/Uh/6McHfHkL74YwQU3p0NiZcoleWYM0CLpPzyrN8EsbmIT+L75nIVwXnh62Gx2jJWayj7ZzvyKtVKHtLb/LKRs4Dg0UEg65xX1EcBAkC5fn4KG1jQHvi/tdOx1Sfh3hO6OK+68q1R6cQQYy+uG84q8RUjpO6dzFcWpE1yMdbQ5XMKfTh56ZdhXJ803LD2gGeIgcMwJp6HK9tnf0vaPPI9kbr8fqJBUUkciUoqpYzFd5m0ZCUbJsMD0oPY19FSRtfCNQvCbmhYrLy1sQ5FeMzbF0bi2oaUv+JD/A5RKokNMrrwv3nnTtG4vN1hJklQk2VW3sZWl6UjYgzhrbmKABtvPuB+xcYywIu4+JSworpfDwM/PZAKOfd6n+r8OdNV256l8WaNeF6osvXkUR7yxYpytywdQPA0d/z8mxTVoATE3wat7pnmTrqI5fqw=\n"
@@ -1,14 +1,42 @@
1
1
  # Minfraud Changelog
2
2
 
3
- ## v1.0.4
3
+ ## v1.1.0 (2020-06-19)
4
+
5
+ * Adds support for the minFraud Report Transaction API. Reporting
6
+ transactions to MaxMind helps us detect about 10-50% more fraud and
7
+ reduce false positives for you.
8
+ * Adds support for the new credit card output `/credit_card/is_business`.
9
+ This indicates whether the card is a business card. It may be accessed
10
+ via `response.credit_credit.is_business` on the minFraud Insights and
11
+ Factors response objects.
12
+ * Adds support for the new email domain output `/email/domain/first_seen`.
13
+ This may be accessed via `response.email.domain.first_seen` on the
14
+ minFraud Insights and Factors response objects.
15
+ * Rename `ErrorHandler#inspect` to `ErrorHandler#examine` in order not to
16
+ break LSP.
17
+ * Adds classes for the Score, Insights, and Factors responses. This allows
18
+ us to provide API documentation for the various response attributes.
19
+ * Removes `hashie` as a required dependency.
20
+ * Adds new processor types to `Minfraud::Components::Payment`: `:affirm`,
21
+ `:afterpay`, `:cardpay`, `:ccavenue`, `:cetelem`, `:ct_payments`,
22
+ `:dalenys`, `:datacash`, `:dotpay`, `:ecommpay`, `:epx`, `:g2a_pay`,
23
+ `:gocardless`, `:interac`, `:klarna`, `:mercanet`, `:oney`, `:payeezy`,
24
+ `:paylike`, `:payment_express`, `:paysafecard`, `:posconnect`,
25
+ `:smartdebit`, `:synapsefi`, and others.
26
+ * Adds support for passing custom inputs to minFraud. GitHub #6.
27
+ * Adds `:email_change`, `:password_reset`, and `:payout_change` as types to
28
+ `Minfraud::Components::Event`.
29
+ * Adds support for the `session_id` and `session_age` inputs.
30
+
31
+ ## v1.0.4 (2016-12-23)
4
32
 
5
33
  * Prevents boolean value conversion to string to avoid warnings
6
34
  * Adds `amount` attribute to the `Minfraud::Components::Order` instances
7
35
 
8
- ## v1.0.3
36
+ ## v1.0.3 (2016-11-24)
9
37
  * Adds `token` attribute to the `Minfraud::Components::CreditCard` instances
10
38
  according to the MinFraud Release Notes introduced on November 17, 2016
11
39
 
12
- ## v1.0.2
40
+ ## v1.0.2 (2016-10-11)
13
41
 
14
42
  * Adds support for Ruby >= 1.9
@@ -35,7 +35,7 @@ This code of conduct applies both within project spaces and in public spaces
35
35
  when an individual is representing the project or its community.
36
36
 
37
37
  Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
- reported by contacting a project maintainer at kushnir.yb@gmail.com. All
38
+ reported by contacting a project maintainer at support@maxmind.com. All
39
39
  complaints will be reviewed and investigated and will result in a response that
40
40
  is deemed necessary and appropriate to the circumstances. Maintainers are
41
41
  obligated to maintain confidentiality with regard to the reporter of an
@@ -43,7 +43,7 @@ incident.
43
43
 
44
44
  This Code of Conduct is adapted from the [Contributor Covenant][homepage],
45
45
  version 1.3.0, available at
46
- [http://contributor-covenant.org/version/1/3/0/][version]
46
+ [https://contributor-covenant.org/version/1/3/0/][version]
47
47
 
48
- [homepage]: http://contributor-covenant.org
49
- [version]: http://contributor-covenant.org/version/1/3/0/
48
+ [homepage]: https://contributor-covenant.org
49
+ [version]: https://contributor-covenant.org/version/1/3/0/
data/Gemfile CHANGED
@@ -1,5 +1,12 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in minfraud.gemspec
4
- gem 'coveralls', require: false
3
+ # coveralls fails on Ruby 1.9. My understanding is we don't need to run this on
4
+ # more than one version anyway, so restrict to the current latest.
5
+ version_pieces = RUBY_VERSION.split('.')
6
+ major_version = version_pieces[0]
7
+ minor_version = version_pieces[1]
8
+ if major_version == '2' && minor_version == '7'
9
+ gem 'coveralls', require: false
10
+ end
11
+
5
12
  gemspec
@@ -1,6 +1,7 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2016 kushnir.yb
3
+ Copyright (c) 2016-2020 kushnir.yb
4
+ Copyright (c) 2020 MaxMind, Inc.
4
5
 
5
6
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
7
  of this software and associated documentation files (the "Software"), to deal
@@ -0,0 +1,4 @@
1
+ # How to release
2
+
3
+ See
4
+ [here](https://github.com/maxmind/MaxMind-DB-Reader-ruby/blob/master/README.dev.md).
data/README.md CHANGED
@@ -1,12 +1,18 @@
1
- # Simple Ruby Wrapper to the MaxMind minFraud API
1
+ # Ruby API for MaxMind minFraud Services
2
2
 
3
- [![Code Climate](https://codeclimate.com/github/kushniryb/minfraud-api-v2/badges/gpa.svg)](https://codeclimate.com/github/kushniryb/minfraud-api-v2)
4
- [![Coverage Status](https://coveralls.io/repos/github/kushniryb/minfraud-api-v2/badge.svg?branch=master)](https://coveralls.io/github/kushniryb/minfraud-api-v2?branch=master)
5
- [![Build Status](https://travis-ci.org/kushniryb/minfraud-api-v2.svg?branch=master)](https://travis-ci.org/kushniryb/minfraud-api-v2)
3
+ ## Description
6
4
 
7
- Compatible with version minFraud API v2.0
5
+ This package provides an API for the [MaxMind minFraud web
6
+ services](https://dev.maxmind.com/minfraud/). This includes minFraud Score,
7
+ Insights, and Factors. It also includes our [minFraud Report Transaction
8
+ API](https://dev.maxmind.com/minfraud/report-transaction/).
8
9
 
9
- [minFraud API documentation](http://dev.maxmind.com/minfraud/)
10
+ The legacy minFraud Standard and Premium services are not supported by this
11
+ API.
12
+
13
+ ## Requirements
14
+
15
+ This gem works with Ruby 1.9 and above.
10
16
 
11
17
  ## Installation
12
18
 
@@ -27,81 +33,146 @@ Or install it yourself as:
27
33
  $ gem install minfraud
28
34
  ```
29
35
 
30
- ## Configuration
36
+ ## Usage
37
+
38
+ ### Configuration
31
39
 
32
- User Id and License Key are required to work with minFraud API
40
+ An account ID and license key are required to work with the web services.
33
41
 
34
42
  ```ruby
35
43
  Minfraud.configure do |c|
36
44
  c.license_key = 'your_license_key'
37
45
  c.user_id = 'your_user_id'
38
46
  end
39
- ```
47
+ ````
48
+
49
+ ### Making a minFraud Score, Insights, or Factors Request
40
50
 
41
- ## Usage
42
51
  ```ruby
43
- # You can either provide a hash of params to initializer
52
+ # You can either provide a hash of parameters to the initializer
44
53
  assessment = Minfraud::Assessments.new(
45
54
  device: {
46
55
  ip_address: '1.2.3.4.5'
47
56
  }
48
57
  )
49
- # or create a component and assign them to assessments object directly, e.g
58
+ # or create a component and assign them to the assessments object directly
50
59
  device = Minfraud::Components::Device.new(ip_address: '1.2.3.4.5')
51
60
  assessment = Minfraud::Assessments.new(device: device)
52
61
  # or
53
62
  assessment = Minfraud::Assessments.new
54
63
  assessment.device = device
55
- # There are multiple components that reflect minFraud request top level keys
56
64
 
57
- # Some components will raise an error if provided with the wrong values for attributes, e.g
65
+ # There are multiple components that reflect the minFraud request top level
66
+ # keys.
67
+
68
+ # Some components will raise an error if provided with the wrong values for
69
+ # attributes, e.g
58
70
  event = Minfraud::Components::Event.new(type: 'foobar') # => Minfraud::NotEnumValueError
59
- # You can check the list of permitted values for the attribute by calling a class method
71
+
72
+ # You can check the list of permitted values for the attribute by calling a
73
+ # class method
60
74
  Minfraud::Components::Event.type_values # => ["account_creation", "account_login", ....]
61
75
 
62
- # You can now call 3 different minFraud endpoints: score, insights, factors
76
+ # You can now call 3 different minFraud endpoints: score, insights and factors
77
+ assessment.score
63
78
  assessment.insights
64
79
  assessment.factors
65
80
 
66
81
  result = assessment.score # => Minfraud::Response instance
67
82
 
68
83
  result.status # => Response status code
69
- result.code # => minFraud specific response code
70
- result.body # => Mashified body
84
+ result.code # => minFraud-specific response code
85
+ result.body # => Response body
71
86
  result.headers # => Response headers
72
87
 
73
- # You can also change data inbetween requests
88
+ # You can change data between requests
74
89
  first_request = assessment.insights
75
90
  assessment.device.ip_address = '22.22.22.33'
76
91
  second_request = assessment.insights
77
92
  ```
78
93
 
79
- ### Exception handling
94
+ See the [API documentation](https://www.rubydoc.info/gems/minfraud) for
95
+ more details.
80
96
 
81
- Gem is supplied with four different types of exceptions:
82
- ```ruby
83
- # Raised if unpermitted key is provided to Minfraud::Assessments initializer
84
- class RequestFormatError < BaseError; end
97
+ ### Reporting a Transaction to MaxMind
98
+
99
+ MaxMind encourages the use of this API, as data received through this
100
+ channel is continually used to improve the accuracy of their fraud
101
+ detection algorithms.
85
102
 
86
- # Raised if IP address is absent / it is reserved / JSON body can not be decoded
87
- class ClientError < BaseError; end
103
+ To use the Report Transactions API, create a new
104
+ `Minfraud::Components::Report::Transaction` object. An IP address and a
105
+ valid tag are required arguments for this API. Additional params may also
106
+ be set, as documented below.
88
107
 
89
- # Raised if there are some problems with the user id and / or license key
90
- class AuthorizationError < BaseError; end
108
+ If the report is successful, nothing is returned. If the report fails, an
109
+ exception with be thrown.
91
110
 
92
- # Raised if minFraud returns an error, or if there is an HTTP error
93
- class ServerError < BaseError; end
111
+ See the API documentation for more details.
94
112
 
95
- # Raised if an attribute value doesn't belong to the predefined set of values
96
- class NotEnumValueError < BaseError; end
113
+ ```ruby
114
+ # The report_transaction method only makes use of a transaction component:
115
+ txn = Minfraud::Components::Report::Transaction.new(
116
+ ip_address: '1.2.3.4',
117
+ tag: :suspected_fraud,
118
+ maxmind_id: '12345678',
119
+ minfraud_id: '58fa38d8-4b87-458b-a22b-f00eda1aa20d',
120
+ notes: 'notes go here',
121
+ transaction_id: '1FA254yZ'
122
+ )
123
+ reporter = Minfraud::Report.new(transaction: txn)
124
+ reporter.report_transaction
97
125
  ```
98
126
 
127
+ See the [API documentation](https://www.rubydoc.info/gems/minfraud) for
128
+ more details.
129
+
130
+ ### Exceptions
131
+
132
+ The gem supplies several distinct exception-types:
133
+
134
+ * `RequestFormatError` - Raised if unpermitted key is provided to the
135
+ `Minfraud::Assessments` initializer
136
+ * `ClientError` - Raised if the IP address is absent, reserved or the JSON
137
+ body cannot be decoded
138
+ * `AuthorizationError` - Raised if there are problems with the account ID
139
+ and/or license key
140
+ * `ServerError` - Raised if minFraud returns an error or if there is an
141
+ HTTP error
142
+ * `NotEnumValueError` - Raised if an attribute value doesn't belong to the
143
+ predefined set of values
144
+
145
+ ## Support
146
+
147
+ Please report all issues with this code using the
148
+ [GitHub issue tracker](https://github.com/maxmind/minfraud-api-ruby/issues).
149
+
150
+ If you are having an issue with the minFraud service that is not specific
151
+ to the client API, please see
152
+ [our support page](https://www.maxmind.com/en/support).
153
+
99
154
  ## Contributing
100
155
 
101
- Bug reports and pull requests are welcome on GitHub [here](https://github.com/kushniryb/minfraud-api-v2). This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
156
+ Bug reports and pull requests are welcome on
157
+ [GitHub](https://github.com/maxmind/minfraud-api-ruby). This project is
158
+ intended to be a safe, welcoming space for collaboration, and contributors
159
+ are expected to adhere to the [Contributor
160
+ Covenant](https://contributor-covenant.org) code of conduct.
161
+
162
+ ## Versioning
163
+
164
+ This API uses [Semantic Versioning](https://semver.org/).
165
+
166
+ ## Copyright and License
167
+
168
+ Copyright (c) 2016-2020 kushnir.yb.
102
169
 
170
+ Copyright (c) 2020 MaxMind, Inc.
103
171
 
104
- ## License
172
+ The gem is available as open source under the terms of the [MIT
173
+ License](https://opensource.org/licenses/MIT).
105
174
 
106
- The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
175
+ ## Thank You
107
176
 
177
+ This gem is the work of the creator and original maintainer kushnir.yb
178
+ (@kushniryb).
@@ -0,0 +1,99 @@
1
+ # Copyright (c) 2020 by MaxMind, Inc.
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ # SOFTWARE.
20
+
21
+ # frozen_string_literal: true
22
+
23
+ require 'maxmind/geoip2/model/country'
24
+ require 'maxmind/geoip2/record/city'
25
+ require 'maxmind/geoip2/record/location'
26
+ require 'maxmind/geoip2/record/postal'
27
+ require 'maxmind/geoip2/record/subdivision'
28
+
29
+ module MaxMind
30
+ module GeoIP2
31
+ module Model
32
+ # Model class for the data returned by the GeoIP2 City web service and
33
+ # database. It is also used for GeoLite2 City lookups.
34
+ #
35
+ # The only difference between the City and Insights model classes is which
36
+ # fields in each record may be populated. See
37
+ # https://dev.maxmind.com/geoip/geoip2/web-services for more details.
38
+ #
39
+ # See {MaxMind::GeoIP2::Model::Country} for inherited methods.
40
+ class City < Country
41
+ # City data for the IP address.
42
+ #
43
+ # @return [MaxMind::GeoIP2::Record::City]
44
+ attr_reader :city
45
+
46
+ # Location data for the IP address.
47
+ #
48
+ # @return [MaxMind::GeoIP2::Record::Location]
49
+ attr_reader :location
50
+
51
+ # Postal data for the IP address.
52
+ #
53
+ # @return [MaxMind::GeoIP2::Record::Postal]
54
+ attr_reader :postal
55
+
56
+ # The country subdivisions for the IP address.
57
+ #
58
+ # The number and type of subdivisions varies by country, but a subdivision
59
+ # is typically a state, province, country, etc. Subdivisions are ordered
60
+ # from most general (largest) to most specific (smallest).
61
+ #
62
+ # If the response did not contain any subdivisions, this attribute will be
63
+ # an empty array.
64
+ #
65
+ # @return [Array<MaxMind::GeoIP2::Record::Subdivision>]
66
+ attr_reader :subdivisions
67
+
68
+ # @!visibility private
69
+ def initialize(record, locales)
70
+ super(record, locales)
71
+ @city = MaxMind::GeoIP2::Record::City.new(record['city'], locales)
72
+ @location = MaxMind::GeoIP2::Record::Location.new(record['location'])
73
+ @postal = MaxMind::GeoIP2::Record::Postal.new(record['postal'])
74
+ @subdivisions = create_subdivisions(record['subdivisions'], locales)
75
+ end
76
+
77
+ # The most specific subdivision returned.
78
+ #
79
+ # If the response did not contain any subdivisions, this method returns
80
+ # nil.
81
+ #
82
+ # @return [MaxMind::GeoIP2::Record::Subdivision, nil]
83
+ def most_specific_subdivision
84
+ @subdivisions.last
85
+ end
86
+
87
+ private
88
+
89
+ def create_subdivisions(subdivisions, locales)
90
+ return [] if subdivisions.nil?
91
+
92
+ subdivisions.map do |s|
93
+ MaxMind::GeoIP2::Record::Subdivision.new(s, locales)
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end