addressfinder 1.9.1 → 1.10.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 38a7d7f3a73582add0efdff05e575601015d7530e87a475b720c14f150455b97
4
- data.tar.gz: 0230c13f16b6a48eecb940baf8a344d64fc832d9bc508649c4ff215675c4b2ae
3
+ metadata.gz: 8d84bdab006a12ff6f18d90d33986cf03172e1d8fedc52ffca604795631b8420
4
+ data.tar.gz: 933d6673ee1271440c17801ac410047a44761d6e1539de3f7c211cec9ee16bd7
5
5
  SHA512:
6
- metadata.gz: edcb4c8d68f2162090406e40dd9d624f73dff86ed3ebff5dad7d1937715df402ed0a2d568165feb286ba1b703dea73f112f0f1a27604bb90a1aad24477534062
7
- data.tar.gz: ead725e66314a35081276a6f5e2d37c23a709f99af3920aad208a76da711cc45d83e9d067493079b25251db81795ccff98a4ff3a4d05f5f8017346c34aee4b47
6
+ metadata.gz: 27b217ad366baf5b6e46d02ab14410a30133d7adfefb06292a92daedc271266ed7139d83be5d14cdee4a3e1128ee18d6604049cd41405f243496bfc24dc13cf6
7
+ data.tar.gz: 26861692d4d8936ae1f5a581390afb2d04cc1f9a870b43488e6f0e76d4bb33caacdbe92e28ee13e8b92960d1dc5bb410d0a01ffdba6fe83c4917214afbbbdf57
@@ -0,0 +1,31 @@
1
+ name: Ruby
2
+
3
+ on:
4
+ push:
5
+ branches: [ "master" ]
6
+ pull_request:
7
+ branches: [ "master" ]
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ test:
14
+
15
+ runs-on: ubuntu-latest
16
+ strategy:
17
+ matrix:
18
+ ruby-version: ['2.6', '2.7', '3.0', '3.1']
19
+
20
+ steps:
21
+ - uses: actions/checkout@v3
22
+ - name: Set up Ruby
23
+ # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
24
+ # change this to (see https://github.com/ruby/setup-ruby#versioning):
25
+ # uses: ruby/setup-ruby@v1
26
+ uses: ruby/setup-ruby@0a29871fe2b0200a17a4497bae54fe5df0d973aa # v1.115.3
27
+ with:
28
+ ruby-version: ${{ matrix.ruby-version }}
29
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
30
+ - name: Run tests
31
+ run: bundle exec rake
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ # AddressFinder 1.10.0 (August 2023) #
2
+
3
+ * Add support for Email Verification
4
+ * Add support for Phone Verification
5
+ * Add support for Bulk Email Verification
6
+ * Add support for Bulk Phone Verification
7
+
1
8
  # AddressFinder 1.9.1 (October 2022) #
2
9
 
3
10
  * Add missing kwarg `**` for ruby 3
data/README.md CHANGED
@@ -157,6 +157,28 @@ rescue AddressFinder::RequestRejectedError => e
157
157
  end
158
158
  ```
159
159
 
160
+ #### Email Verification
161
+ ```ruby
162
+ begin
163
+ result = AddressFinder.email_verification(email: 'john.doe')
164
+ $stdout.puts "This email address is verified: #{result.is_verified}"
165
+ rescue AddressFinder::RequestRejectedError => e
166
+ response = JSON.parse(e.body)
167
+ $stdout.puts response['message']
168
+ end
169
+ ```
170
+
171
+ #### Phone Verification
172
+ ```ruby
173
+ begin
174
+ result = AddressFinder.phone_verification(phone_number: '1800 152 363', default_country_code: 'AU')
175
+ $stdout.puts "This phone number is verified: #{result.is_verified}"
176
+ rescue AddressFinder::RequestRejectedError => e
177
+ response = JSON.parse(e.body)
178
+ $stdout.puts response['message']
179
+ end
180
+ ```
181
+
160
182
  ## Advanced Usage
161
183
 
162
184
  #### Bulk Operations
@@ -164,7 +186,7 @@ end
164
186
  If you have a series of API requests, you can use the
165
187
  bulk method to re-use the HTTP connection.
166
188
 
167
- **Note:** The bulk method is currently only available for Address Verification (`#verification`).
189
+ **Note:** The bulk method is currently only available for Address Verification, Email Verification and Phone Verification (`#verification`, `#email_verification`, `#phone_verifiction`).
168
190
 
169
191
  ```ruby
170
192
  AddressFinder.bulk do |af|
@@ -36,6 +36,14 @@ module AddressFinder
36
36
  end
37
37
  end
38
38
 
39
+ def email_verification(args={})
40
+ AddressFinder::V1::Email::Verification.new(**args.merge(http: http)).perform.result
41
+ end
42
+
43
+ def phone_verification(args={})
44
+ AddressFinder::V1::Phone::Verification.new(**args.merge(http: http)).perform.result
45
+ end
46
+
39
47
  private
40
48
 
41
49
  attr_reader :http, :verification_version, :default_country
@@ -0,0 +1,71 @@
1
+ require 'ostruct'
2
+
3
+ module AddressFinder
4
+ module V1
5
+ class Base
6
+ attr_reader :result
7
+
8
+ def initialize(params:, path:, http:)
9
+ @params = params
10
+ @params[:domain] ||= config.domain if config.domain
11
+ @params[:key] ||= config.api_key
12
+ @params[:secret] ||= config.api_secret
13
+ @params[:format] ||= 'json'
14
+
15
+ @path = path
16
+ @http = http
17
+ end
18
+
19
+ def perform
20
+ build_request
21
+ execute_request
22
+ build_result
23
+
24
+ self
25
+ end
26
+
27
+ private
28
+
29
+ attr_reader :request_uri, :params, :http, :path
30
+ attr_accessor :response_body, :response_status
31
+ attr_writer :result
32
+
33
+ def build_request
34
+ @request_uri = "#{path}?#{encoded_params}"
35
+ end
36
+
37
+ def encoded_params
38
+ Util.encode_and_join_params(params)
39
+ end
40
+
41
+ def execute_request
42
+ request = Net::HTTP::Get.new(request_uri)
43
+
44
+ response = http.request(request)
45
+
46
+ self.response_body = response.body
47
+ self.response_status = response.code
48
+ end
49
+
50
+ def build_result
51
+ case response_status
52
+ when '200'
53
+ self.result = Result.new(response_hash)
54
+ else
55
+ raise AddressFinder::RequestRejectedError.new(response_status, response_body)
56
+ end
57
+ end
58
+
59
+ def response_hash
60
+ @_response_hash ||= MultiJson.load(response_body)
61
+ end
62
+
63
+ def config
64
+ @_config ||= AddressFinder.configuration
65
+ end
66
+
67
+ class Result < OpenStruct
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,16 @@
1
+ require 'addressfinder/v1/base'
2
+
3
+ module AddressFinder
4
+ module V1
5
+ module Email
6
+ class Verification < AddressFinder::V1::Base
7
+ attr_reader :result
8
+
9
+ def initialize(email:, http:, **args)
10
+ params = {email: email}.merge(args)
11
+ super(params: params, path: "/api/email/v1/verification", http: http)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ require 'addressfinder/v1/base'
2
+
3
+ module AddressFinder
4
+ module V1
5
+ module Phone
6
+ class Verification < AddressFinder::V1::Base
7
+ attr_reader :result
8
+
9
+ def initialize(phone_number:, default_country_code:, http:, **args)
10
+ params = {phone_number: phone_number, default_country_code: default_country_code}.merge(args)
11
+ super(params: params, path: "/api/phone/v1/verification", http: http)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -1,3 +1,3 @@
1
1
  module AddressFinder
2
- VERSION = '1.9.1'
2
+ VERSION = '1.10.0'
3
3
  end
data/lib/addressfinder.rb CHANGED
@@ -9,6 +9,8 @@ require 'addressfinder/address_info'
9
9
  require 'addressfinder/address_search'
10
10
  require 'addressfinder/address_autocomplete'
11
11
  require 'addressfinder/bulk'
12
+ require 'addressfinder/v1/email/verification'
13
+ require 'addressfinder/v1/phone/verification'
12
14
  require 'addressfinder/errors'
13
15
  require 'addressfinder/util'
14
16
  require 'addressfinder/http'
@@ -61,6 +63,14 @@ module AddressFinder
61
63
  AddressFinder::AddressInfo.new(params: args, http: AddressFinder::HTTP.new(configuration)).perform.result
62
64
  end
63
65
 
66
+ def email_verification(args={})
67
+ AddressFinder::V1::Email::Verification.new(**args.merge(http: AddressFinder::HTTP.new(configuration))).perform.result
68
+ end
69
+
70
+ def phone_verification(args={})
71
+ AddressFinder::V1::Phone::Verification.new(**args.merge(http: AddressFinder::HTTP.new(configuration))).perform.result
72
+ end
73
+
64
74
  def bulk(&block)
65
75
  AddressFinder::Bulk.new(http: AddressFinder::HTTP.new(configuration), verification_version: configuration.verification_version, default_country: configuration.default_country, &block).perform
66
76
  end
@@ -111,5 +111,97 @@ RSpec.describe AddressFinder::Bulk do
111
111
  AddressFinder::Bulk.new(http: http, verification_version: "v2", default_country: 'nz', &block).perform
112
112
  end
113
113
  end
114
+
115
+ context "email verification with 3 requests in the provided block" do
116
+ let(:response){ double(:response, body: %Q({"success": true}), code: "200") }
117
+ let(:block){
118
+ Proc.new do |proxy|
119
+ proxy.email_verification(email: "john.doe@addressfinder.com")
120
+ proxy.email_verification(email: "jane.doe@addressfinder.com")
121
+ proxy.email_verification(email: "tom.doe@addressfinder.com")
122
+ end
123
+ }
124
+
125
+ it "uses 1 http connection" do
126
+ expect(net_http).to receive(:do_start).once.and_call_original
127
+ expect(net_http).to receive(:transport_request).exactly(3).times.and_return(response)
128
+ expect(net_http).to receive(:do_finish).once.and_call_original
129
+ AddressFinder::Bulk.new(http: http, verification_version: 'v1', default_country: 'nz', &block).perform
130
+ end
131
+
132
+ it "calls the correct class with v1 verification and nz default" do
133
+ allow(net_http).to receive(:do_start).once.and_call_original
134
+ allow(net_http).to receive(:transport_request).exactly(3).times.and_return(response)
135
+ allow(net_http).to receive(:do_finish).once.and_call_original
136
+ expect(AddressFinder::V1::Email::Verification).to receive(:new).exactly(3).times.and_call_original
137
+ AddressFinder::Bulk.new(http: http, verification_version: 'v1', default_country: 'nz', &block).perform
138
+ end
139
+
140
+ it "calls the correct class without a verification version or default country" do
141
+ allow(net_http).to receive(:do_start).once.and_call_original
142
+ allow(net_http).to receive(:transport_request).exactly(3).times.and_return(response)
143
+ allow(net_http).to receive(:do_finish).once.and_call_original
144
+ expect(AddressFinder::V1::Email::Verification).to receive(:new).exactly(3).times.and_call_original
145
+ AddressFinder::Bulk.new(http: http, verification_version: nil, default_country: nil, &block).perform
146
+ end
147
+
148
+ it "re-establishes the http connection and continues where we left off when a Net::OpenTimeout, Net::ReadTimeout or SocketError is raised" do
149
+ expect(http).to receive(:re_establish_connection).exactly(3).times.and_call_original
150
+ expect(net_http).to receive(:do_start).exactly(4).times.and_call_original
151
+ expect(net_http).to receive(:transport_request).once.and_return(response) # john.doe@addressfinder.com (success)
152
+ expect(net_http).to receive(:transport_request).once.and_raise(Net::OpenTimeout) # jane.doe@addressfinder.com (error)
153
+ expect(net_http).to receive(:transport_request).once.and_raise(Net::ReadTimeout) # Retry jane.doe@addressfinder.com (error)
154
+ expect(net_http).to receive(:transport_request).once.and_raise(SocketError) # Retry jane.doe@addressfinder.com (error)
155
+ expect(net_http).to receive(:transport_request).exactly(2).and_return(response) # Retry jane.doe@addressfinder.com (success) & tom.doe@addressfinder.com (success)
156
+ expect(net_http).to receive(:do_finish).exactly(4).times.and_call_original
157
+ AddressFinder::Bulk.new(http: http, verification_version: 'v1', default_country: 'nz', &block).perform
158
+ end
159
+ end
160
+
161
+ context "phone verification with 3 requests in the provided block" do
162
+ let(:response){ double(:response, body: %Q({"success": true}), code: "200") }
163
+ let(:block){
164
+ Proc.new do |proxy|
165
+ proxy.phone_verification(phone_number: "+64274673830", default_country_code: "AU")
166
+ proxy.phone_verification(phone_number: "1800 152 363", default_country_code: "AU")
167
+ proxy.phone_verification(phone_number: "0274673830", default_country_code: "NZ")
168
+ end
169
+ }
170
+
171
+ it "uses 1 http connection" do
172
+ expect(net_http).to receive(:do_start).once.and_call_original
173
+ expect(net_http).to receive(:transport_request).exactly(3).times.and_return(response)
174
+ expect(net_http).to receive(:do_finish).once.and_call_original
175
+ AddressFinder::Bulk.new(http: http, verification_version: 'v1', default_country: 'nz', &block).perform
176
+ end
177
+
178
+ it "calls the correct class with v1 verification and nz default" do
179
+ allow(net_http).to receive(:do_start).once.and_call_original
180
+ allow(net_http).to receive(:transport_request).exactly(3).times.and_return(response)
181
+ allow(net_http).to receive(:do_finish).once.and_call_original
182
+ expect(AddressFinder::V1::Phone::Verification).to receive(:new).exactly(3).times.and_call_original
183
+ AddressFinder::Bulk.new(http: http, verification_version: 'v1', default_country: 'nz', &block).perform
184
+ end
185
+
186
+ it "calls the correct class without a verification version or default country" do
187
+ allow(net_http).to receive(:do_start).once.and_call_original
188
+ allow(net_http).to receive(:transport_request).exactly(3).times.and_return(response)
189
+ allow(net_http).to receive(:do_finish).once.and_call_original
190
+ expect(AddressFinder::V1::Phone::Verification).to receive(:new).exactly(3).times.and_call_original
191
+ AddressFinder::Bulk.new(http: http, verification_version: nil, default_country: nil, &block).perform
192
+ end
193
+
194
+ it "re-establishes the http connection and continues where we left off when a Net::OpenTimeout, Net::ReadTimeout or SocketError is raised" do
195
+ expect(http).to receive(:re_establish_connection).exactly(3).times.and_call_original
196
+ expect(net_http).to receive(:do_start).exactly(4).times.and_call_original
197
+ expect(net_http).to receive(:transport_request).once.and_return(response) # +64274673830 (success)
198
+ expect(net_http).to receive(:transport_request).once.and_raise(Net::OpenTimeout) # 1800 152 363 (error)
199
+ expect(net_http).to receive(:transport_request).once.and_raise(Net::ReadTimeout) # Retry 1800 152 363 (error)
200
+ expect(net_http).to receive(:transport_request).once.and_raise(SocketError) # Retry 1800 152 363 (error)
201
+ expect(net_http).to receive(:transport_request).exactly(2).and_return(response) # Retry 1800 152 363 (success) & 0274673830 (success)
202
+ expect(net_http).to receive(:do_finish).exactly(4).times.and_call_original
203
+ AddressFinder::Bulk.new(http: http, verification_version: 'v1', default_country: 'nz', &block).perform
204
+ end
205
+ end
114
206
  end
115
207
  end
@@ -0,0 +1,148 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe AddressFinder::V1::Email::Verification do
4
+ before do
5
+ AddressFinder.configure do |af|
6
+ af.api_key = "XXX"
7
+ af.api_secret = "YYY"
8
+ af.timeout = 5
9
+ af.retries = 3
10
+ end
11
+ end
12
+
13
+ let(:verification_module){ AddressFinder::V1::Email::Verification.new(**args) }
14
+ let(:http){ AddressFinder::HTTP.new(AddressFinder.configuration) }
15
+ let(:net_http){ http.send(:net_http) }
16
+
17
+ describe "#execute_request" do
18
+ let(:args){ {email: "john.doe@addressfinder.com", http: http} }
19
+
20
+ before do
21
+ WebMock.allow_net_connect!(net_http_connect_on_start: true)
22
+ allow(http).to receive(:sleep)
23
+ allow(verification_module).to receive(:request_uri).and_return("/test/path")
24
+ expect(http).to_not receive(:re_establish_connection)
25
+ end
26
+
27
+ after do
28
+ WebMock.disable_net_connect!
29
+ end
30
+
31
+ subject(:execute_request){ verification_module.send(:execute_request) }
32
+
33
+ it "retries an errored request another time before succeeding" do
34
+ expect(net_http).to receive(:do_start).twice.and_call_original
35
+ expect(net_http).to receive(:transport_request).once.and_raise(Net::OpenTimeout)
36
+ expect(net_http).to receive(:transport_request).once.and_return(double(:response, body: "OK", code: "200"))
37
+ expect(net_http).to receive(:do_finish).twice.and_call_original
38
+ execute_request
39
+ end
40
+
41
+ it "re-raises a Net::OpenTimeout error after 3 retries" do
42
+ expect(net_http).to receive(:do_start).exactly(4).times.and_call_original
43
+ expect(net_http).to receive(:transport_request).exactly(4).times.and_raise(Net::OpenTimeout)
44
+ expect(net_http).to receive(:do_finish).exactly(4).times.and_call_original
45
+ expect{execute_request}.to raise_error(Net::OpenTimeout)
46
+ end
47
+
48
+ it "re-raises a Net::ReadTimeout error after 3 retries" do
49
+ expect(net_http).to receive(:do_start).exactly(4).times.and_call_original
50
+ expect(net_http).to receive(:transport_request).exactly(4).times.and_raise(Net::ReadTimeout)
51
+ expect(net_http).to receive(:do_finish).exactly(4).times.and_call_original
52
+ expect{execute_request}.to raise_error(Net::ReadTimeout)
53
+ end
54
+
55
+ it "re-raises a SocketError error after 3 retries" do
56
+ expect(net_http).to receive(:do_start).exactly(4).times.and_call_original
57
+ expect(net_http).to receive(:transport_request).exactly(4).times.and_raise(SocketError)
58
+ expect(net_http).to receive(:do_finish).exactly(4).times.and_call_original
59
+ expect{execute_request}.to raise_error(SocketError)
60
+ end
61
+ end
62
+
63
+ describe "#build_request" do
64
+ subject(:request_uri){ verification_module.send(:build_request) }
65
+
66
+ context "with email argument" do
67
+ let(:args){ {email: "john.doe@addressfinder.com", http: http} }
68
+
69
+ it { expect(request_uri).to eq("/api/email/v1/verification?email=john.doe%40addressfinder.com&key=XXX&secret=YYY&format=json") }
70
+ end
71
+
72
+ context "with email and format arguments" do
73
+ let(:args){ {email: "john.doe@addressfinder.com", format: "xml", http: http} }
74
+
75
+ it { expect(request_uri).to eq("/api/email/v1/verification?email=john.doe%40addressfinder.com&format=xml&key=XXX&secret=YYY") }
76
+ end
77
+
78
+ context "with a reserved character in the email" do
79
+ let(:args){ {email: "john=doe@addressfinder.com", http: http} }
80
+
81
+ it { expect(request_uri).to eq("/api/email/v1/verification?email=john%3Ddoe%40addressfinder.com&key=XXX&secret=YYY&format=json") }
82
+ end
83
+
84
+ context "with a key override" do
85
+ let(:args){ {email: "john.doe@addressfinder.com", key: "AAA", http: http} }
86
+
87
+ it { expect(request_uri).to eq("/api/email/v1/verification?email=john.doe%40addressfinder.com&key=AAA&secret=YYY&format=json") }
88
+ end
89
+
90
+ context "with a secret override" do
91
+ let(:args){ {email: "john.doe@addressfinder.com", secret: "BBB", http: http} }
92
+
93
+ it { expect(request_uri).to eq("/api/email/v1/verification?email=john.doe%40addressfinder.com&secret=BBB&key=XXX&format=json") }
94
+ end
95
+
96
+ context "with a domain given" do
97
+ let(:args){ {email: "john.doe@addressfinder.com", domain: "testdomain.com", http: http} }
98
+
99
+ it { expect(request_uri).to eq("/api/email/v1/verification?email=john.doe%40addressfinder.com&domain=testdomain.com&key=XXX&secret=YYY&format=json") }
100
+
101
+ context "given in the AF configuration" do
102
+ let(:args){ {email: "john.doe@addressfinder.com", http: http} }
103
+
104
+ it "should use the config domain if set" do
105
+ AddressFinder.configuration.domain = "anotherdomain.com"
106
+ expect(request_uri).to eq("/api/email/v1/verification?email=john.doe%40addressfinder.com&domain=anotherdomain.com&key=XXX&secret=YYY&format=json")
107
+ AddressFinder.configuration.domain = nil # set back to nil after
108
+ end
109
+ end
110
+ end
111
+
112
+ context "with a all arguments included in request" do
113
+ let(:args){ {email: "john.doe@addressfinder.com", domain: "mysite.com", key: "AAA", secret: "BBB", format: "json", http: http} }
114
+
115
+ it { expect(request_uri).to eq("/api/email/v1/verification?email=john.doe%40addressfinder.com&domain=mysite.com&key=AAA&secret=BBB&format=json") }
116
+ end
117
+ end
118
+
119
+ describe "#build_result" do
120
+ let(:args){ {email: "ignored", http: nil} }
121
+
122
+ before do
123
+ verification_module.send("response_body=", body)
124
+ verification_module.send("response_status=", status)
125
+ end
126
+
127
+ subject(:result){ verification_module.send(:build_result) }
128
+
129
+ context "with a successful verification" do
130
+ let(:body){ '{"email_account": "john.doe", "email_domain": "addressfinder.com", "is_verified": true, "success": true}' }
131
+ let(:status){ "200" }
132
+
133
+ it { expect(result.class).to eq(AddressFinder::V1::Email::Verification::Result) }
134
+ it { expect(result.is_verified).to eq(true) }
135
+ it { expect(result.email_account).to eq("john.doe") }
136
+ end
137
+
138
+ context "with an unsuccessful verification" do
139
+ let(:body){ '{"email_account": "jane.doe", "email_domain": "addressfinder.com", "is_verified": false, "not_verified_reason": "The email account does not exist", "success": true}' }
140
+ let(:status){ "200" }
141
+
142
+ it { expect(result.class).to eq(AddressFinder::V1::Email::Verification::Result) }
143
+ it { expect(result.is_verified).to eq(false) }
144
+ it { expect(result.email_account).to eq("jane.doe") }
145
+ it { expect(result.not_verified_reason).to eq("The email account does not exist") }
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,144 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe AddressFinder::V1::Phone::Verification do
4
+ before do
5
+ AddressFinder.configure do |af|
6
+ af.api_key = "XXX"
7
+ af.api_secret = "YYY"
8
+ af.timeout = 5
9
+ af.retries = 3
10
+ end
11
+ end
12
+
13
+ let(:verification_module){ AddressFinder::V1::Phone::Verification.new(**args) }
14
+ let(:http){ AddressFinder::HTTP.new(AddressFinder.configuration) }
15
+ let(:net_http){ http.send(:net_http) }
16
+
17
+ describe "#execute_request" do
18
+ let(:args){ {phone_number: "1800 152 363", default_country_code: "AU", http: http} }
19
+
20
+ before do
21
+ WebMock.allow_net_connect!(net_http_connect_on_start: true)
22
+ allow(http).to receive(:sleep)
23
+ allow(verification_module).to receive(:request_uri).and_return("/test/path")
24
+ expect(http).to_not receive(:re_establish_connection)
25
+ end
26
+
27
+ after do
28
+ WebMock.disable_net_connect!
29
+ end
30
+
31
+ subject(:execute_request){ verification_module.send(:execute_request) }
32
+
33
+ it "retries an errored request another time before succeeding" do
34
+ expect(net_http).to receive(:do_start).twice.and_call_original
35
+ expect(net_http).to receive(:transport_request).once.and_raise(Net::OpenTimeout)
36
+ expect(net_http).to receive(:transport_request).once.and_return(double(:response, body: "OK", code: "200"))
37
+ expect(net_http).to receive(:do_finish).twice.and_call_original
38
+ execute_request
39
+ end
40
+
41
+ it "re-raises a Net::OpenTimeout error after 3 retries" do
42
+ expect(net_http).to receive(:do_start).exactly(4).times.and_call_original
43
+ expect(net_http).to receive(:transport_request).exactly(4).times.and_raise(Net::OpenTimeout)
44
+ expect(net_http).to receive(:do_finish).exactly(4).times.and_call_original
45
+ expect{execute_request}.to raise_error(Net::OpenTimeout)
46
+ end
47
+
48
+ it "re-raises a Net::ReadTimeout error after 3 retries" do
49
+ expect(net_http).to receive(:do_start).exactly(4).times.and_call_original
50
+ expect(net_http).to receive(:transport_request).exactly(4).times.and_raise(Net::ReadTimeout)
51
+ expect(net_http).to receive(:do_finish).exactly(4).times.and_call_original
52
+ expect{execute_request}.to raise_error(Net::ReadTimeout)
53
+ end
54
+
55
+ it "re-raises a SocketError error after 3 retries" do
56
+ expect(net_http).to receive(:do_start).exactly(4).times.and_call_original
57
+ expect(net_http).to receive(:transport_request).exactly(4).times.and_raise(SocketError)
58
+ expect(net_http).to receive(:do_finish).exactly(4).times.and_call_original
59
+ expect{execute_request}.to raise_error(SocketError)
60
+ end
61
+ end
62
+
63
+ describe "#build_request" do
64
+ subject(:request_uri){ verification_module.send(:build_request) }
65
+
66
+ context "with phone number and default country code arguments" do
67
+ let(:args){ {phone_number: "1800 152 363", default_country_code: "AU", http: http} }
68
+
69
+ it { expect(request_uri).to eq("/api/phone/v1/verification?phone_number=1800+152+363&default_country_code=AU&key=XXX&secret=YYY&format=json") }
70
+ end
71
+
72
+ context "with a reserved character in the phone number" do
73
+ let(:args){ {phone_number: "1800= 152 363", default_country_code: "AU", http: http} }
74
+
75
+ it { expect(request_uri).to eq("/api/phone/v1/verification?phone_number=1800%3D+152+363&default_country_code=AU&key=XXX&secret=YYY&format=json") }
76
+ end
77
+
78
+ context "with a key override" do
79
+ let(:args){ {phone_number: "1800 152 363", default_country_code: "AU", key: "AAA", http: http} }
80
+
81
+ it { expect(request_uri).to eq("/api/phone/v1/verification?phone_number=1800+152+363&default_country_code=AU&key=AAA&secret=YYY&format=json") }
82
+ end
83
+
84
+ context "with a secret override" do
85
+ let(:args){ {phone_number: "1800 152 363", default_country_code: "AU", secret: "BBB", http: http} }
86
+
87
+ it { expect(request_uri).to eq("/api/phone/v1/verification?phone_number=1800+152+363&default_country_code=AU&secret=BBB&key=XXX&format=json") }
88
+ end
89
+
90
+ context "with a domain given" do
91
+ let(:args){ {phone_number: "1800 152 363", default_country_code: "AU", domain: "testdomain.com", http: http} }
92
+
93
+ it { expect(request_uri).to eq("/api/phone/v1/verification?phone_number=1800+152+363&default_country_code=AU&domain=testdomain.com&key=XXX&secret=YYY&format=json") }
94
+
95
+ context "given in the AF configuration" do
96
+ let(:args){ {phone_number: "1800 152 363", default_country_code: "AU", http: http} }
97
+
98
+ it "should use the config domain if set" do
99
+ AddressFinder.configuration.domain = "anotherdomain.com"
100
+ expect(request_uri).to eq("/api/phone/v1/verification?phone_number=1800+152+363&default_country_code=AU&domain=anotherdomain.com&key=XXX&secret=YYY&format=json")
101
+ AddressFinder.configuration.domain = nil # set back to nil after
102
+ end
103
+ end
104
+ end
105
+
106
+ context "with a all arguments included in request" do
107
+ let(:args){ {phone_number: "1800 152 363", default_country_code: "NZ", allowed_country_codes: "AU,NZ", mobile_only: true, timeout: "10", domain: "mysite.com", key: "AAA", secret: "BBB", format: "xml", http: http} }
108
+
109
+ it { expect(request_uri).to eq("/api/phone/v1/verification?phone_number=1800+152+363&default_country_code=NZ&allowed_country_codes=AU%2CNZ&mobile_only=true&timeout=10&domain=mysite.com&key=AAA&secret=BBB&format=xml") }
110
+ end
111
+ end
112
+
113
+ describe "#build_result" do
114
+ let(:args){ {phone_number: "ignored", default_country_code: "ignored", http: nil} }
115
+
116
+ before do
117
+ verification_module.send("response_body=", body)
118
+ verification_module.send("response_status=", status)
119
+ end
120
+
121
+ subject(:result){ verification_module.send(:build_result) }
122
+
123
+ context "with a successful verification" do
124
+ let(:body){ '{"raw_international": "+611800152353", "line_type": "toll_free", "line_status": "disconnected", "is_verified": true, "success": true}' }
125
+ let(:status){ "200" }
126
+
127
+ it { expect(result.class).to eq(AddressFinder::V1::Phone::Verification::Result) }
128
+ it { expect(result.is_verified).to eq(true) }
129
+ it { expect(result.raw_international).to eq("+611800152353") }
130
+ it { expect(result.line_type).to eq("toll_free") }
131
+ it { expect(result.line_status).to eq("disconnected") }
132
+ end
133
+
134
+ context "with an unsuccessful verification" do
135
+ let(:body){ '{"is_verified": false, "not_verified_reason": "Phone number format is incorrect", "not_verified_code": "INVALID_FORMAT", "success": true}' }
136
+ let(:status){ "200" }
137
+
138
+ it { expect(result.class).to eq(AddressFinder::V1::Phone::Verification::Result) }
139
+ it { expect(result.is_verified).to eq(false) }
140
+ it { expect(result.not_verified_code).to eq("INVALID_FORMAT") }
141
+ it { expect(result.not_verified_reason).to eq("Phone number format is incorrect") }
142
+ end
143
+ end
144
+ end
@@ -116,7 +116,7 @@ RSpec.describe AddressFinder::V2::Au::Verification do
116
116
 
117
117
  it 'should use the config domain if set' do
118
118
  AddressFinder.configuration.domain = 'anotherdomain.com'
119
- # expect(request_uri).to eq('/api/au/address/v2/verification?q=123&domain=anotherdomain.com&key=XXX&secret=YYY&format=json')
119
+ expect(request_uri).to eq('/api/au/address/v2/verification?q=123&domain=anotherdomain.com&key=XXX&secret=YYY&format=json')
120
120
  AddressFinder.configuration.domain = nil # set back to nil after
121
121
  end
122
122
  end
@@ -71,4 +71,24 @@ RSpec.describe AddressFinder do
71
71
  end
72
72
  end
73
73
  end
74
+
75
+ context "#email_verification" do
76
+ subject(:verification) { AddressFinder.email_verification(args) }
77
+ let(:args){ {email: "john.doe@addressfinder.com"} }
78
+
79
+ it "calls the email verification class" do
80
+ expect(AddressFinder::V1::Email::Verification).to receive_message_chain(:new, :perform, :result)
81
+ subject
82
+ end
83
+ end
84
+
85
+ context "#phone_verification" do
86
+ subject(:verification) { AddressFinder.phone_verification(args) }
87
+ let(:args){ {phone_number: "1800 152 363", default_country_code: "AU"} }
88
+
89
+ it "calls the phone verification class" do
90
+ expect(AddressFinder::V1::Phone::Verification).to receive_message_chain(:new, :perform, :result)
91
+ subject
92
+ end
93
+ end
74
94
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: addressfinder
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.1
4
+ version: 1.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nigel Ramsay
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2022-10-12 00:00:00.000000000 Z
15
+ date: 2023-08-30 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: multi_json
@@ -109,6 +109,7 @@ executables: []
109
109
  extensions: []
110
110
  extra_rdoc_files: []
111
111
  files:
112
+ - ".github/workflows/ruby.yml"
112
113
  - ".gitignore"
113
114
  - ".travis.yml"
114
115
  - CHANGELOG.md
@@ -131,6 +132,9 @@ files:
131
132
  - lib/addressfinder/location_info.rb
132
133
  - lib/addressfinder/location_search.rb
133
134
  - lib/addressfinder/util.rb
135
+ - lib/addressfinder/v1/base.rb
136
+ - lib/addressfinder/v1/email/verification.rb
137
+ - lib/addressfinder/v1/phone/verification.rb
134
138
  - lib/addressfinder/v2/au/verification.rb
135
139
  - lib/addressfinder/verification.rb
136
140
  - lib/addressfinder/version.rb
@@ -141,6 +145,8 @@ files:
141
145
  - spec/lib/addressfinder/location_info_spec.rb
142
146
  - spec/lib/addressfinder/location_search_spec.rb
143
147
  - spec/lib/addressfinder/util_spec.rb
148
+ - spec/lib/addressfinder/v1/email/verification_spec.rb
149
+ - spec/lib/addressfinder/v1/phone/verification_spec.rb
144
150
  - spec/lib/addressfinder/v2/au/verification_spec.rb
145
151
  - spec/lib/addressfinder/verification_spec.rb
146
152
  - spec/lib/addressfinder_spec.rb
@@ -164,7 +170,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
164
170
  - !ruby/object:Gem::Version
165
171
  version: '0'
166
172
  requirements: []
167
- rubygems_version: 3.1.6
173
+ rubygems_version: 3.1.4
168
174
  signing_key:
169
175
  specification_version: 4
170
176
  summary: Provides easy access to AddressFinder APIs
@@ -176,6 +182,8 @@ test_files:
176
182
  - spec/lib/addressfinder/location_info_spec.rb
177
183
  - spec/lib/addressfinder/location_search_spec.rb
178
184
  - spec/lib/addressfinder/util_spec.rb
185
+ - spec/lib/addressfinder/v1/email/verification_spec.rb
186
+ - spec/lib/addressfinder/v1/phone/verification_spec.rb
179
187
  - spec/lib/addressfinder/v2/au/verification_spec.rb
180
188
  - spec/lib/addressfinder/verification_spec.rb
181
189
  - spec/lib/addressfinder_spec.rb