creditsafe 0.5.1 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +17 -17
  3. data/.gitignore +2 -2
  4. data/.rspec +1 -1
  5. data/.rubocop.yml +11 -11
  6. data/.ruby-version +1 -1
  7. data/CHANGELOG.md +41 -37
  8. data/Gemfile +5 -5
  9. data/Gemfile.lock +127 -125
  10. data/LICENSE.txt +22 -22
  11. data/README.md +138 -138
  12. data/creditsafe.gemspec +35 -35
  13. data/data/creditsafe-live.xml +342 -342
  14. data/data/creditsafe-test.xml +342 -342
  15. data/lib/creditsafe.rb +4 -4
  16. data/lib/creditsafe/client.rb +158 -156
  17. data/lib/creditsafe/errors.rb +16 -14
  18. data/lib/creditsafe/match_type.rb +115 -115
  19. data/lib/creditsafe/messages.rb +97 -97
  20. data/lib/creditsafe/namespace.rb +20 -20
  21. data/lib/creditsafe/request/company_report.rb +42 -42
  22. data/lib/creditsafe/request/find_company.rb +98 -98
  23. data/lib/creditsafe/version.rb +5 -5
  24. data/spec/creditsafe/client_spec.rb +369 -372
  25. data/spec/creditsafe/messages_spec.rb +76 -76
  26. data/spec/fixtures/company-report-not-found.xml +13 -13
  27. data/spec/fixtures/company-report-request.xml +1 -1
  28. data/spec/fixtures/company-report-successful.xml +582 -582
  29. data/spec/fixtures/error-fault.xml +8 -8
  30. data/spec/fixtures/error-invalid-credentials.html +31 -31
  31. data/spec/fixtures/find-companies-error-no-text.xml +11 -11
  32. data/spec/fixtures/find-companies-error.xml +11 -11
  33. data/spec/fixtures/find-companies-none-found.xml +13 -13
  34. data/spec/fixtures/find-companies-request.xml +1 -1
  35. data/spec/fixtures/find-companies-successful-multi.xml +493 -493
  36. data/spec/fixtures/find-companies-successful.xml +29 -29
  37. data/spec/spec_helper.rb +14 -14
  38. metadata +4 -4
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: true
2
-
3
- require "creditsafe/errors"
4
- require "creditsafe/client"
1
+ # frozen_string_literal: true
2
+
3
+ require "creditsafe/errors"
4
+ require "creditsafe/client"
@@ -1,156 +1,158 @@
1
- # frozen_string_literal: true
2
-
3
- require "securerandom"
4
- require "savon"
5
- require "excon"
6
-
7
- require "creditsafe/errors"
8
- require "creditsafe/messages"
9
- require "creditsafe/namespace"
10
-
11
- require "creditsafe/request/company_report"
12
- require "creditsafe/request/find_company"
13
-
14
- require "active_support/notifications"
15
-
16
- module Creditsafe
17
- class Client
18
- ENVIRONMENTS = %i[live test].freeze
19
-
20
- def initialize(username: nil, password: nil, savon_opts: {},
21
- environment: :live, log_level: :warn)
22
- raise ArgumentError, "Username must be provided" if username.nil?
23
- raise ArgumentError, "Password must be provided" if password.nil?
24
-
25
- unless ENVIRONMENTS.include?(environment.to_sym)
26
- raise ArgumentError, "Environment needs to be one of #{ENVIRONMENTS.join('/')}"
27
- end
28
-
29
- @environment = environment.to_s
30
- @log_level = log_level
31
- @username = username
32
- @password = password
33
- @savon_opts = savon_opts
34
- end
35
-
36
- def find_company(search_criteria = {})
37
- request = Creditsafe::Request::FindCompany.new(search_criteria)
38
- response = invoke_soap(:find_companies, request.message)
39
-
40
- companies = response.
41
- fetch(:find_companies_response).
42
- fetch(:find_companies_result).
43
- fetch(:companies)
44
-
45
- companies.nil? ? nil : companies.fetch(:company)
46
- end
47
-
48
- def company_report(creditsafe_id, custom_data: nil)
49
- request =
50
- Creditsafe::Request::CompanyReport.new(creditsafe_id, custom_data)
51
- response = invoke_soap(:retrieve_company_online_report, request.message)
52
-
53
- response.
54
- fetch(:retrieve_company_online_report_response).
55
- fetch(:retrieve_company_online_report_result).
56
- fetch(:reports).
57
- fetch(:report)
58
- end
59
-
60
- def inspect
61
- "#<#{self.class} @username='#{@username}'>"
62
- end
63
-
64
- private
65
-
66
- def handle_message_for_response(response)
67
- [
68
- *response.xpath("//q1:Message"),
69
- *response.xpath("//xmlns:Message"),
70
- ].each do |message|
71
- api_message = Creditsafe::Messages.for_code(message.attributes["Code"].value)
72
-
73
- api_error_message = api_message.message
74
- api_error_message += " (#{message.text})" unless message.text.blank?
75
-
76
- raise api_message.error_class, api_error_message if api_message.error?
77
- end
78
- end
79
-
80
- # rubocop:disable Style/RescueStandardError
81
- # rubocop:disable Metrics/MethodLength
82
- def invoke_soap(message_type, message)
83
- started = Time.now
84
- notification_payload = { request: message }
85
-
86
- response = client.call(message_type, message: message)
87
- handle_message_for_response(response)
88
- notification_payload[:response] = response.body
89
- rescue => raw_error
90
- processed_error = handle_error(raw_error)
91
- notification_payload[:error] = processed_error
92
- raise processed_error
93
- ensure
94
- publish("creditsafe.#{message_type}", started, Time.now,
95
- SecureRandom.hex(10), notification_payload)
96
- end
97
- # rubocop:enable Metrics/MethodLength
98
- # rubocop:enable Style/RescueStandardError
99
-
100
- def publish(*args)
101
- ActiveSupport::Notifications.publish(*args)
102
- end
103
-
104
- # There's a potential bug in the creditsafe API where they actually return
105
- # an HTTP 401 if you're unauthorized, hence the sad special case below
106
- #
107
- # rubocop:disable Metrics/MethodLength
108
- def handle_error(error)
109
- case error
110
- when Savon::SOAPFault
111
- return UnknownApiError.new(error.message)
112
- when Savon::HTTPError
113
- if error.to_hash[:code] == 401
114
- return AccountError.new("Unauthorized: invalid credentials")
115
- end
116
- return UnknownApiError.new(error.message)
117
- when Excon::Errors::Error
118
- return HttpError.new("Error making HTTP request: #{error.message}")
119
- end
120
- error
121
- end
122
- # rubocop:enable Metrics/MethodLength
123
-
124
- def client
125
- @client ||= build_savon_client
126
- end
127
-
128
- def auth_header
129
- auth_value = "Basic " + Base64.encode64("#{@username}:#{@password}").chomp
130
- { "Authorization" => auth_value }
131
- end
132
-
133
- # rubocop:disable Metrics/MethodLength
134
- def build_savon_client
135
- options = {
136
- env_namespace: "soapenv",
137
- namespace_identifier: Creditsafe::Namespace::OPER,
138
- namespaces: Creditsafe::Namespace::ALL,
139
- wsdl: wsdl_path,
140
- headers: auth_header,
141
- convert_request_keys_to: :none,
142
- adapter: :excon,
143
- log: true,
144
- log_level: @log_level,
145
- pretty_print_xml: true,
146
- }
147
- Savon.client(options.merge(@savon_opts))
148
- end
149
- # rubocop:enable Metrics/MethodLength
150
-
151
- def wsdl_path
152
- root_dir = File.join(File.dirname(__FILE__), "..", "..")
153
- File.join(root_dir, "data", "creditsafe-#{@environment}.xml")
154
- end
155
- end
156
- end
1
+ # frozen_string_literal: true
2
+
3
+ require "securerandom"
4
+ require "savon"
5
+ require "excon"
6
+
7
+ require "creditsafe/errors"
8
+ require "creditsafe/messages"
9
+ require "creditsafe/namespace"
10
+
11
+ require "creditsafe/request/company_report"
12
+ require "creditsafe/request/find_company"
13
+
14
+ require "active_support/notifications"
15
+
16
+ module Creditsafe
17
+ class Client
18
+ ENVIRONMENTS = %i[live test].freeze
19
+
20
+ def initialize(username: nil, password: nil, savon_opts: {},
21
+ environment: :live, log_level: :warn)
22
+ raise ArgumentError, "Username must be provided" if username.nil?
23
+ raise ArgumentError, "Password must be provided" if password.nil?
24
+
25
+ unless ENVIRONMENTS.include?(environment.to_sym)
26
+ raise ArgumentError, "Environment needs to be one of #{ENVIRONMENTS.join('/')}"
27
+ end
28
+
29
+ @environment = environment.to_s
30
+ @log_level = log_level
31
+ @username = username
32
+ @password = password
33
+ @savon_opts = savon_opts
34
+ end
35
+
36
+ def find_company(search_criteria = {})
37
+ request = Creditsafe::Request::FindCompany.new(search_criteria)
38
+ response = invoke_soap(:find_companies, request.message)
39
+
40
+ companies = response.
41
+ fetch(:find_companies_response).
42
+ fetch(:find_companies_result).
43
+ fetch(:companies)
44
+
45
+ companies.nil? ? nil : companies.fetch(:company)
46
+ end
47
+
48
+ def company_report(creditsafe_id, custom_data: nil)
49
+ request =
50
+ Creditsafe::Request::CompanyReport.new(creditsafe_id, custom_data)
51
+ response = invoke_soap(:retrieve_company_online_report, request.message)
52
+
53
+ response.
54
+ fetch(:retrieve_company_online_report_response).
55
+ fetch(:retrieve_company_online_report_result).
56
+ fetch(:reports).
57
+ fetch(:report)
58
+ end
59
+
60
+ def inspect
61
+ "#<#{self.class} @username='#{@username}'>"
62
+ end
63
+
64
+ private
65
+
66
+ def handle_message_for_response(response)
67
+ [
68
+ *response.xpath("//q1:Message"),
69
+ *response.xpath("//xmlns:Message"),
70
+ ].each do |message|
71
+ api_message = Creditsafe::Messages.for_code(message.attributes["Code"].value)
72
+
73
+ api_error_message = api_message.message
74
+ api_error_message += " (#{message.text})" unless message.text.blank?
75
+
76
+ raise api_message.error_class, api_error_message if api_message.error?
77
+ end
78
+ end
79
+
80
+ # rubocop:disable Style/RescueStandardError
81
+ # rubocop:disable Metrics/MethodLength
82
+ def invoke_soap(message_type, message)
83
+ started = Time.now
84
+ notification_payload = { request: message }
85
+
86
+ response = client.call(message_type, message: message)
87
+ handle_message_for_response(response)
88
+ notification_payload[:response] = response.body
89
+ rescue Excon::Errors::Timeout
90
+ raise TimeoutError
91
+ rescue => raw_error
92
+ processed_error = handle_error(raw_error)
93
+ notification_payload[:error] = processed_error
94
+ raise processed_error
95
+ ensure
96
+ publish("creditsafe.#{message_type}", started, Time.now,
97
+ SecureRandom.hex(10), notification_payload)
98
+ end
99
+ # rubocop:enable Metrics/MethodLength
100
+ # rubocop:enable Style/RescueStandardError
101
+
102
+ def publish(*args)
103
+ ActiveSupport::Notifications.publish(*args)
104
+ end
105
+
106
+ # There's a potential bug in the creditsafe API where they actually return
107
+ # an HTTP 401 if you're unauthorized, hence the sad special case below
108
+ #
109
+ # rubocop:disable Metrics/MethodLength
110
+ def handle_error(error)
111
+ case error
112
+ when Savon::SOAPFault
113
+ return UnknownApiError.new(error.message)
114
+ when Savon::HTTPError
115
+ if error.to_hash[:code] == 401
116
+ return AccountError.new("Unauthorized: invalid credentials")
117
+ end
118
+ return UnknownApiError.new(error.message)
119
+ when Excon::Errors::Error
120
+ return HttpError.new("Error making HTTP request: #{error.message}")
121
+ end
122
+ error
123
+ end
124
+ # rubocop:enable Metrics/MethodLength
125
+
126
+ def client
127
+ @client ||= build_savon_client
128
+ end
129
+
130
+ def auth_header
131
+ auth_value = "Basic " + Base64.encode64("#{@username}:#{@password}").chomp
132
+ { "Authorization" => auth_value }
133
+ end
134
+
135
+ # rubocop:disable Metrics/MethodLength
136
+ def build_savon_client
137
+ options = {
138
+ env_namespace: "soapenv",
139
+ namespace_identifier: Creditsafe::Namespace::OPER,
140
+ namespaces: Creditsafe::Namespace::ALL,
141
+ wsdl: wsdl_path,
142
+ headers: auth_header,
143
+ convert_request_keys_to: :none,
144
+ adapter: :excon,
145
+ log: true,
146
+ log_level: @log_level,
147
+ pretty_print_xml: true,
148
+ }
149
+ Savon.client(options.merge(@savon_opts))
150
+ end
151
+ # rubocop:enable Metrics/MethodLength
152
+
153
+ def wsdl_path
154
+ root_dir = File.join(File.dirname(__FILE__), "..", "..")
155
+ File.join(root_dir, "data", "creditsafe-#{@environment}.xml")
156
+ end
157
+ end
158
+ end
@@ -1,14 +1,16 @@
1
- # frozen_string_literal: true
2
-
3
- module Creditsafe
4
- class Error < StandardError; end
5
-
6
- class HttpError < Error; end
7
- class ApiError < Error; end
8
-
9
- class DataError < ApiError; end
10
- class AccountError < ApiError; end
11
- class RequestError < ApiError; end
12
- class ProcessingError < ApiError; end
13
- class UnknownApiError < ApiError; end
14
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Creditsafe
4
+ class Error < StandardError; end
5
+
6
+ class HttpError < Error; end
7
+ class ApiError < Error; end
8
+
9
+ class TimeoutError < HttpError; end
10
+
11
+ class DataError < ApiError; end
12
+ class AccountError < ApiError; end
13
+ class RequestError < ApiError; end
14
+ class ProcessingError < ApiError; end
15
+ class UnknownApiError < ApiError; end
16
+ end
@@ -1,115 +1,115 @@
1
- # frozen_string_literal: true
2
-
3
- module Creditsafe
4
- module MatchType
5
- MATCH_BEGINNING = "MatchBeginning"
6
- MATCH_BLOCK = "MatchBlock"
7
- EXACT_VALUE = "ExactValue"
8
- MATCH_WORDS = "MatchWords"
9
- CLOSEST_KEYWORDS = "ClosestKeywords"
10
- MATCH_BLOCK_OR_WORDS = "MatchBlockOrWords"
11
- MATCH_ANY_PARTS = "MatchAnyParts"
12
-
13
- ALLOWED = {
14
- DE: [MATCH_BEGINNING, MATCH_BLOCK, EXACT_VALUE, MATCH_WORDS],
15
- FR: [MATCH_BEGINNING, CLOSEST_KEYWORDS, EXACT_VALUE],
16
- GB: [MATCH_BEGINNING, MATCH_BLOCK_OR_WORDS, EXACT_VALUE],
17
- IE: [MATCH_BEGINNING, MATCH_BLOCK, MATCH_WORDS],
18
- GL: [MATCH_BEGINNING],
19
- CH: [CLOSEST_KEYWORDS],
20
- LI: [CLOSEST_KEYWORDS],
21
- NL: [MATCH_BEGINNING, MATCH_BLOCK_OR_WORDS, MATCH_WORDS],
22
- CZ: [MATCH_BLOCK_OR_WORDS],
23
- IS: [MATCH_BEGINNING],
24
- LT: [MATCH_ANY_PARTS],
25
- MT: [MATCH_BEGINNING, MATCH_BLOCK],
26
- SK: [MATCH_BLOCK_OR_WORDS],
27
- BE: [MATCH_BEGINNING, MATCH_BLOCK_OR_WORDS, MATCH_WORDS],
28
- SE: [MATCH_BLOCK_OR_WORDS, CLOSEST_KEYWORDS],
29
- PL: [CLOSEST_KEYWORDS],
30
- NO: [CLOSEST_KEYWORDS],
31
- PT: [MATCH_BEGINNING],
32
- LU: [MATCH_BEGINNING, MATCH_BLOCK, EXACT_VALUE],
33
- CA: [MATCH_BEGINNING],
34
- ES: [EXACT_VALUE, CLOSEST_KEYWORDS],
35
- US: [MATCH_BEGINNING, CLOSEST_KEYWORDS],
36
- PR: [MATCH_BEGINNING, CLOSEST_KEYWORDS],
37
- AS: [MATCH_BEGINNING, CLOSEST_KEYWORDS],
38
- FM: [MATCH_BEGINNING, CLOSEST_KEYWORDS],
39
- GU: [MATCH_BEGINNING, CLOSEST_KEYWORDS],
40
- MH: [MATCH_BEGINNING, CLOSEST_KEYWORDS],
41
- MP: [MATCH_BEGINNING, CLOSEST_KEYWORDS],
42
- PW: [MATCH_BEGINNING, CLOSEST_KEYWORDS],
43
- VI: [MATCH_BEGINNING, CLOSEST_KEYWORDS],
44
- SI: [MATCH_BLOCK_OR_WORDS],
45
- AL: [MATCH_BLOCK_OR_WORDS],
46
- BA: [MATCH_BLOCK_OR_WORDS],
47
- HR: [MATCH_BLOCK_OR_WORDS],
48
- MK: [MATCH_BLOCK_OR_WORDS],
49
- BG: [MATCH_BLOCK_OR_WORDS],
50
- RO: [MATCH_BLOCK_OR_WORDS],
51
- ME: [MATCH_BLOCK_OR_WORDS],
52
- RS: [MATCH_BLOCK_OR_WORDS],
53
- LV: [MATCH_BLOCK_OR_WORDS],
54
- EE: [MATCH_BLOCK_OR_WORDS],
55
- UA: [MATCH_BLOCK_OR_WORDS],
56
- MD: [MATCH_BLOCK_OR_WORDS],
57
- RU: [MATCH_BLOCK_OR_WORDS],
58
- AM: [MATCH_BLOCK_OR_WORDS],
59
- AZ: [MATCH_BLOCK_OR_WORDS],
60
- BY: [MATCH_BLOCK_OR_WORDS],
61
- GE: [MATCH_BLOCK_OR_WORDS],
62
- KZ: [MATCH_BLOCK_OR_WORDS],
63
- UZ: [MATCH_BLOCK_OR_WORDS],
64
- TJ: [MATCH_BLOCK_OR_WORDS],
65
- TM: [MATCH_BLOCK_OR_WORDS],
66
- KG: [MATCH_BLOCK_OR_WORDS],
67
- KM: [MATCH_BLOCK_OR_WORDS],
68
- HK: [MATCH_BLOCK_OR_WORDS],
69
- AT: [MATCH_WORDS],
70
- IT: [CLOSEST_KEYWORDS, EXACT_VALUE],
71
- BR: [CLOSEST_KEYWORDS],
72
- HU: [MATCH_BEGINNING],
73
- TW: [MATCH_BEGINNING],
74
- KR: [MATCH_BLOCK_OR_WORDS],
75
- FI: [CLOSEST_KEYWORDS],
76
- MX: [CLOSEST_KEYWORDS],
77
- DK: [MATCH_BEGINNING],
78
- AU: [CLOSEST_KEYWORDS],
79
- CN: [CLOSEST_KEYWORDS],
80
- IN: [CLOSEST_KEYWORDS],
81
- BD: [CLOSEST_KEYWORDS],
82
- LK: [CLOSEST_KEYWORDS],
83
- PK: [CLOSEST_KEYWORDS],
84
- NP: [CLOSEST_KEYWORDS],
85
- TH: [CLOSEST_KEYWORDS],
86
- MY: [CLOSEST_KEYWORDS],
87
- VN: [CLOSEST_KEYWORDS],
88
- KH: [CLOSEST_KEYWORDS],
89
- MM: [CLOSEST_KEYWORDS],
90
- LA: [CLOSEST_KEYWORDS],
91
- AF: [CLOSEST_KEYWORDS],
92
- ID: [CLOSEST_KEYWORDS],
93
- NZ: [CLOSEST_KEYWORDS],
94
- SG: [CLOSEST_KEYWORDS],
95
- BH: [CLOSEST_KEYWORDS],
96
- BJ: [CLOSEST_KEYWORDS],
97
- BF: [CLOSEST_KEYWORDS],
98
- CD: [CLOSEST_KEYWORDS],
99
- EG: [CLOSEST_KEYWORDS],
100
- JO: [CLOSEST_KEYWORDS],
101
- KW: [CLOSEST_KEYWORDS],
102
- LB: [CLOSEST_KEYWORDS],
103
- OM: [CLOSEST_KEYWORDS],
104
- PS: [CLOSEST_KEYWORDS],
105
- QA: [CLOSEST_KEYWORDS],
106
- SA: [CLOSEST_KEYWORDS],
107
- SD: [CLOSEST_KEYWORDS],
108
- SY: [CLOSEST_KEYWORDS],
109
- AE: [CLOSEST_KEYWORDS],
110
- EH: [CLOSEST_KEYWORDS],
111
- YE: [CLOSEST_KEYWORDS],
112
- GR: [MATCH_BLOCK_OR_WORDS, CLOSEST_KEYWORDS],
113
- }.freeze
114
- end
115
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Creditsafe
4
+ module MatchType
5
+ MATCH_BEGINNING = "MatchBeginning"
6
+ MATCH_BLOCK = "MatchBlock"
7
+ EXACT_VALUE = "ExactValue"
8
+ MATCH_WORDS = "MatchWords"
9
+ CLOSEST_KEYWORDS = "ClosestKeywords"
10
+ MATCH_BLOCK_OR_WORDS = "MatchBlockOrWords"
11
+ MATCH_ANY_PARTS = "MatchAnyParts"
12
+
13
+ ALLOWED = {
14
+ DE: [MATCH_BEGINNING, MATCH_BLOCK, EXACT_VALUE, MATCH_WORDS],
15
+ FR: [MATCH_BEGINNING, CLOSEST_KEYWORDS, EXACT_VALUE],
16
+ GB: [MATCH_BEGINNING, MATCH_BLOCK_OR_WORDS, EXACT_VALUE],
17
+ IE: [MATCH_BEGINNING, MATCH_BLOCK, MATCH_WORDS],
18
+ GL: [MATCH_BEGINNING],
19
+ CH: [CLOSEST_KEYWORDS],
20
+ LI: [CLOSEST_KEYWORDS],
21
+ NL: [MATCH_BEGINNING, MATCH_BLOCK_OR_WORDS, MATCH_WORDS],
22
+ CZ: [MATCH_BLOCK_OR_WORDS],
23
+ IS: [MATCH_BEGINNING],
24
+ LT: [MATCH_ANY_PARTS],
25
+ MT: [MATCH_BEGINNING, MATCH_BLOCK],
26
+ SK: [MATCH_BLOCK_OR_WORDS],
27
+ BE: [MATCH_BEGINNING, MATCH_BLOCK_OR_WORDS, MATCH_WORDS],
28
+ SE: [MATCH_BLOCK_OR_WORDS, CLOSEST_KEYWORDS],
29
+ PL: [CLOSEST_KEYWORDS],
30
+ NO: [CLOSEST_KEYWORDS],
31
+ PT: [MATCH_BEGINNING],
32
+ LU: [MATCH_BEGINNING, MATCH_BLOCK, EXACT_VALUE],
33
+ CA: [MATCH_BEGINNING],
34
+ ES: [EXACT_VALUE, CLOSEST_KEYWORDS],
35
+ US: [MATCH_BEGINNING, CLOSEST_KEYWORDS],
36
+ PR: [MATCH_BEGINNING, CLOSEST_KEYWORDS],
37
+ AS: [MATCH_BEGINNING, CLOSEST_KEYWORDS],
38
+ FM: [MATCH_BEGINNING, CLOSEST_KEYWORDS],
39
+ GU: [MATCH_BEGINNING, CLOSEST_KEYWORDS],
40
+ MH: [MATCH_BEGINNING, CLOSEST_KEYWORDS],
41
+ MP: [MATCH_BEGINNING, CLOSEST_KEYWORDS],
42
+ PW: [MATCH_BEGINNING, CLOSEST_KEYWORDS],
43
+ VI: [MATCH_BEGINNING, CLOSEST_KEYWORDS],
44
+ SI: [MATCH_BLOCK_OR_WORDS],
45
+ AL: [MATCH_BLOCK_OR_WORDS],
46
+ BA: [MATCH_BLOCK_OR_WORDS],
47
+ HR: [MATCH_BLOCK_OR_WORDS],
48
+ MK: [MATCH_BLOCK_OR_WORDS],
49
+ BG: [MATCH_BLOCK_OR_WORDS],
50
+ RO: [MATCH_BLOCK_OR_WORDS],
51
+ ME: [MATCH_BLOCK_OR_WORDS],
52
+ RS: [MATCH_BLOCK_OR_WORDS],
53
+ LV: [MATCH_BLOCK_OR_WORDS],
54
+ EE: [MATCH_BLOCK_OR_WORDS],
55
+ UA: [MATCH_BLOCK_OR_WORDS],
56
+ MD: [MATCH_BLOCK_OR_WORDS],
57
+ RU: [MATCH_BLOCK_OR_WORDS],
58
+ AM: [MATCH_BLOCK_OR_WORDS],
59
+ AZ: [MATCH_BLOCK_OR_WORDS],
60
+ BY: [MATCH_BLOCK_OR_WORDS],
61
+ GE: [MATCH_BLOCK_OR_WORDS],
62
+ KZ: [MATCH_BLOCK_OR_WORDS],
63
+ UZ: [MATCH_BLOCK_OR_WORDS],
64
+ TJ: [MATCH_BLOCK_OR_WORDS],
65
+ TM: [MATCH_BLOCK_OR_WORDS],
66
+ KG: [MATCH_BLOCK_OR_WORDS],
67
+ KM: [MATCH_BLOCK_OR_WORDS],
68
+ HK: [MATCH_BLOCK_OR_WORDS],
69
+ AT: [MATCH_WORDS],
70
+ IT: [CLOSEST_KEYWORDS, EXACT_VALUE],
71
+ BR: [CLOSEST_KEYWORDS],
72
+ HU: [MATCH_BEGINNING],
73
+ TW: [MATCH_BEGINNING],
74
+ KR: [MATCH_BLOCK_OR_WORDS],
75
+ FI: [CLOSEST_KEYWORDS],
76
+ MX: [CLOSEST_KEYWORDS],
77
+ DK: [MATCH_BEGINNING],
78
+ AU: [CLOSEST_KEYWORDS],
79
+ CN: [CLOSEST_KEYWORDS],
80
+ IN: [CLOSEST_KEYWORDS],
81
+ BD: [CLOSEST_KEYWORDS],
82
+ LK: [CLOSEST_KEYWORDS],
83
+ PK: [CLOSEST_KEYWORDS],
84
+ NP: [CLOSEST_KEYWORDS],
85
+ TH: [CLOSEST_KEYWORDS],
86
+ MY: [CLOSEST_KEYWORDS],
87
+ VN: [CLOSEST_KEYWORDS],
88
+ KH: [CLOSEST_KEYWORDS],
89
+ MM: [CLOSEST_KEYWORDS],
90
+ LA: [CLOSEST_KEYWORDS],
91
+ AF: [CLOSEST_KEYWORDS],
92
+ ID: [CLOSEST_KEYWORDS],
93
+ NZ: [CLOSEST_KEYWORDS],
94
+ SG: [CLOSEST_KEYWORDS],
95
+ BH: [CLOSEST_KEYWORDS],
96
+ BJ: [CLOSEST_KEYWORDS],
97
+ BF: [CLOSEST_KEYWORDS],
98
+ CD: [CLOSEST_KEYWORDS],
99
+ EG: [CLOSEST_KEYWORDS],
100
+ JO: [CLOSEST_KEYWORDS],
101
+ KW: [CLOSEST_KEYWORDS],
102
+ LB: [CLOSEST_KEYWORDS],
103
+ OM: [CLOSEST_KEYWORDS],
104
+ PS: [CLOSEST_KEYWORDS],
105
+ QA: [CLOSEST_KEYWORDS],
106
+ SA: [CLOSEST_KEYWORDS],
107
+ SD: [CLOSEST_KEYWORDS],
108
+ SY: [CLOSEST_KEYWORDS],
109
+ AE: [CLOSEST_KEYWORDS],
110
+ EH: [CLOSEST_KEYWORDS],
111
+ YE: [CLOSEST_KEYWORDS],
112
+ GR: [MATCH_BLOCK_OR_WORDS, CLOSEST_KEYWORDS],
113
+ }.freeze
114
+ end
115
+ end