blazeverify 1.0.1 → 2.0.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: 2126442e7c72e7fcf5c762adaf1f7d2f35b6a5dbe318f94fbc0a50a97d2b09f5
4
- data.tar.gz: d9d3d84bed564da6bcf9bac42d6b1783984ac0d2cd5f2d317db5ee9de6af5139
3
+ metadata.gz: 85252fc6012c171412400563d082437bef82d71bc0e950a0acc44ca2d6ef53c9
4
+ data.tar.gz: 8b1975eba455e692aaff0cb033b6b5abd02a6fccfbffc0269981f3624c823670
5
5
  SHA512:
6
- metadata.gz: e58d1bbc592f0e70bb3f35aeb026de63ba4e5e71b3a9a7b0a7005bb90080fa774ed2dd8fa86329d5b7903b86ee81a074bab0a1d554ca7d8b52217d6d49ebabc6
7
- data.tar.gz: b672b8659bc76b3dcfa9cf8f2b7371b40f5b87990c98ff6d0574183dcaee2a0f8cb631c86fe8a6028b2fab4bd6380e6eff4c8099b53872989d78b04d7a392eb6
6
+ metadata.gz: 887908fc8069d9ca5bd499f858de54c2b9de5b22f9f034baad6db789f547f70e022f4813644eb6456f0b46d6b6415388befdf8e545b69a52209d2a0b6c720ed3
7
+ data.tar.gz: ab93b482db07925f20d3222445eb8bf63ad618279002d04c292eb5244cba392e527f92e37ca16a5fafe74b6a9ced6beb866e26426423d68543d6a5ade8a1c051
@@ -1,23 +1,35 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- blazeverify (1.0.0)
5
- faraday (~> 0.13)
4
+ blazeverify (1.3.2)
5
+ faraday
6
6
  faraday_middleware
7
7
  net-http-persistent
8
8
 
9
9
  GEM
10
10
  remote: https://rubygems.org/
11
11
  specs:
12
+ activemodel (6.0.3.4)
13
+ activesupport (= 6.0.3.4)
14
+ activesupport (6.0.3.4)
15
+ concurrent-ruby (~> 1.0, >= 1.0.2)
16
+ i18n (>= 0.7, < 2)
17
+ minitest (~> 5.1)
18
+ tzinfo (~> 1.1)
19
+ zeitwerk (~> 2.2, >= 2.2.2)
12
20
  ansi (1.5.0)
13
21
  awesome_print (1.8.0)
14
22
  builder (3.2.3)
15
23
  coderay (1.1.2)
16
- connection_pool (2.2.2)
17
- faraday (0.15.4)
24
+ concurrent-ruby (1.1.7)
25
+ connection_pool (2.2.3)
26
+ faraday (1.1.0)
18
27
  multipart-post (>= 1.2, < 3)
19
- faraday_middleware (0.13.1)
20
- faraday (>= 0.7.4, < 1.0)
28
+ ruby2_keywords
29
+ faraday_middleware (1.0.0)
30
+ faraday (~> 1.0)
31
+ i18n (1.8.5)
32
+ concurrent-ruby (~> 1.0)
21
33
  method_source (0.9.2)
22
34
  minitest (5.11.3)
23
35
  minitest-reporters (1.3.6)
@@ -26,25 +38,31 @@ GEM
26
38
  minitest (>= 5.0)
27
39
  ruby-progressbar
28
40
  multipart-post (2.1.1)
29
- net-http-persistent (3.0.1)
41
+ net-http-persistent (4.0.0)
30
42
  connection_pool (~> 2.2)
31
43
  pry (0.12.2)
32
44
  coderay (~> 1.1.0)
33
45
  method_source (~> 0.9.0)
34
- rake (10.5.0)
46
+ rake (13.0.1)
35
47
  ruby-progressbar (1.10.1)
48
+ ruby2_keywords (0.0.2)
49
+ thread_safe (0.3.6)
50
+ tzinfo (1.2.8)
51
+ thread_safe (~> 0.1)
52
+ zeitwerk (2.4.1)
36
53
 
37
54
  PLATFORMS
38
55
  ruby
39
56
 
40
57
  DEPENDENCIES
58
+ activemodel
41
59
  awesome_print
42
60
  blazeverify!
43
61
  bundler
44
62
  minitest (~> 5.0)
45
63
  minitest-reporters
46
64
  pry
47
- rake (~> 10.0)
65
+ rake (~> 13.0)
48
66
 
49
67
  BUNDLED WITH
50
68
  1.17.3
data/README.md CHANGED
@@ -5,9 +5,11 @@
5
5
 
6
6
  This is the official ruby wrapper for the Blaze Verify API.
7
7
 
8
+ It also includes an Active Record (Rails) validator to verify email attributes.
9
+
8
10
  ## Documentation
9
11
 
10
- See the [Ruby API docs](https://blazeverify.com/docs/api#ruby).
12
+ See the [Ruby API docs](https://blazeverify.com/docs/api/?ruby).
11
13
 
12
14
  ## Installation
13
15
 
@@ -47,18 +49,14 @@ BlazeVerify.verify('jarrett@blazeverify.com')
47
49
 
48
50
  #### Slow Email Server Handling
49
51
 
50
- Some email servers are slow to respond. As a result the timeout may be reached
52
+ Some email servers are slow to respond. As a result, the timeout may be reached
51
53
  before we are able to complete the verification process. If this happens, the
52
- verification will continue in the background on our servers. We recommend
53
- sleeping for at least one second and trying your request again. Re-requesting
54
- the same verification with the same options will not impact your credit
55
- allocation within a 5 minute window.
56
-
57
- ```ruby
58
- {
59
- "message" => "Your request is taking longer than normal. Please send your request again."
60
- }
61
- ```
54
+ verification will continue in the background on our servers, and a
55
+ `BlazeVerify::TimeoutError` will be raised. We recommend sleeping for at least
56
+ one second and trying your request again. Re-requesting the same verification
57
+ with the same options will not impact your credit allocation within a 5 minute
58
+ window. You can test this behavior using a test key and the special
59
+ email `slow@example.com`.
62
60
 
63
61
  ### Batch Verification
64
62
 
@@ -98,6 +96,34 @@ batch.status.reason_counts
98
96
  batch.complete?
99
97
  ```
100
98
 
99
+ ### Active Record Validator
100
+
101
+ Define a validator on an Active Record model for your email attribute(s).
102
+ It'll validate the attribute only when it's present and has changed.
103
+
104
+ #### Options
105
+
106
+ * `smtp`, `timeout`: Passed directly to API as options.
107
+ * `states`: An array of states you'd like to be considered valid.
108
+ * `free`, `role`, `disposable`, `accept_all`: If you'd like any of these to be valid.
109
+
110
+ ```ruby
111
+ validates :email, email: {
112
+ smtp: true, states: %i[deliverable risky unknown],
113
+ free: true, role: true, disposable: false, accept_all: true, timeout: 3
114
+ }
115
+ ```
116
+
117
+ #### Access Verification Result
118
+
119
+ You can define an `attr_accessor` with the following format to gain
120
+ access to the verification result.
121
+
122
+ ```ruby
123
+ # [attribute_name]_verification_result
124
+ attr_accessor :email_verification_result
125
+ ```
126
+
101
127
  ## Development
102
128
 
103
129
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -27,13 +27,14 @@ Gem::Specification.new do |s|
27
27
  end
28
28
  s.require_paths = ['lib']
29
29
 
30
- s.add_dependency 'faraday', '~> 0.13'
30
+ s.add_dependency 'faraday'
31
31
  s.add_dependency 'faraday_middleware'
32
32
  s.add_dependency 'net-http-persistent'
33
33
  s.add_development_dependency 'bundler'
34
- s.add_development_dependency 'rake', '~> 10.0'
34
+ s.add_development_dependency 'rake', '~> 13.0'
35
35
  s.add_development_dependency 'pry'
36
36
  s.add_development_dependency 'awesome_print'
37
37
  s.add_development_dependency 'minitest', '~> 5.0'
38
38
  s.add_development_dependency 'minitest-reporters'
39
+ s.add_development_dependency 'activemodel'
39
40
  end
@@ -0,0 +1,10 @@
1
+ en:
2
+ errors:
3
+ messages:
4
+ undeliverable: is undeliverable
5
+ risky: is risky
6
+ unknown: is unknown
7
+ free: is a free address
8
+ role: is a role address
9
+ disposable: is a disposable address
10
+ accept_all: is an accept-all address
@@ -7,6 +7,10 @@ require 'blazeverify/resources/api_resource'
7
7
  require 'blazeverify/resources/account'
8
8
  require 'blazeverify/resources/batch_status'
9
9
  require 'blazeverify/resources/verification'
10
+ if defined?(ActiveModel)
11
+ require 'blazeverify/email_validator'
12
+ I18n.load_path += Dir.glob(File.expand_path('../../config/locales/**/*', __FILE__))
13
+ end
10
14
 
11
15
  module BlazeVerify
12
16
  @max_network_retries = 1
@@ -26,7 +30,9 @@ module BlazeVerify
26
30
  response = client.request(:get, 'verify', opts)
27
31
 
28
32
  if response.status == 249
29
- response.body
33
+ raise BlazeVerify::TimeoutError.new(
34
+ code: response.status, message: response.body
35
+ )
30
36
  else
31
37
  Verification.new(response.body)
32
38
  end
@@ -37,4 +43,23 @@ module BlazeVerify
37
43
  response = client.request(:get, 'account')
38
44
  Account.new(response.body)
39
45
  end
46
+
47
+
48
+ class Error < StandardError
49
+ attr_accessor :code, :message
50
+
51
+ def initialize(code: nil, message: nil)
52
+ @code = code
53
+ @message = message
54
+ end
55
+ end
56
+ class BadRequestError < Error; end
57
+ class UnauthorizedError < Error; end
58
+ class PaymentRequiredError < Error; end
59
+ class ForbiddenError < Error; end
60
+ class NotFoundError < Error; end
61
+ class TooManyRequestsError < Error; end
62
+ class InternalServerError < Error; end
63
+ class ServiceUnavailableError < Error; end
64
+ class TimeoutError < Error; end
40
65
  end
@@ -67,21 +67,4 @@ module BlazeVerify
67
67
  false
68
68
  end
69
69
  end
70
-
71
- class Error < StandardError
72
- attr_accessor :code, :message
73
-
74
- def initialize(code: nil, message: nil)
75
- @code = code
76
- @message = message
77
- end
78
- end
79
- class BadRequestError < Error; end
80
- class UnauthorizedError < Error; end
81
- class PaymentRequiredError < Error; end
82
- class ForbiddenError < Error; end
83
- class NotFoundError < Error; end
84
- class TooManyRequestsError < Error; end
85
- class InternalServerError < Error; end
86
- class ServiceUnavailableError < Error; end
87
70
  end
@@ -0,0 +1,70 @@
1
+ # ActiveRecord validator for validating an email address with Blaze Verify
2
+ #
3
+ # Usage:
4
+ # validates :email, presence: true, email: {
5
+ # smtp: true, states: %i[deliverable risky unknown],
6
+ # free: true, role: true, disposable: false, accept_all: true,
7
+ # timeout: 3
8
+ # }
9
+ #
10
+ # Define an attr_accessor to access verification results.
11
+ # attr_accessor :email_verification_result
12
+ #
13
+ class EmailValidator < ActiveModel::EachValidator
14
+
15
+ def validate_each(record, attribute, value)
16
+ smtp = boolean_option_or_raise_error(:smtp, true)
17
+
18
+ states = options.fetch(:states, %i(deliverable risky unknown))
19
+ allowed_states = %i[deliverable undeliverable risky unknown]
20
+ unless (states - allowed_states).empty?
21
+ raise ArgumentError, ":states must be an array of symbols containing "\
22
+ "any or all of :#{allowed_states.join(', :')}"
23
+ end
24
+
25
+ free = boolean_option_or_raise_error(:free, true)
26
+ role = boolean_option_or_raise_error(:role, true)
27
+ disposable = boolean_option_or_raise_error(:disposable, false)
28
+ accept_all = boolean_option_or_raise_error(:accept_all, true)
29
+
30
+ timeout = options.fetch(:timeout, 3)
31
+ unless timeout.is_a?(Integer) && timeout > 1
32
+ raise ArgumentError, ":timeout must be an Integer greater than 1"
33
+ end
34
+
35
+ return if record.errors[attribute].present?
36
+ return unless value.present?
37
+ return unless record.changes[attribute].present?
38
+
39
+ api_options = { timeout: timeout, smtp: smtp }
40
+ api_options[:accept_all] = true unless accept_all
41
+ ev = BlazeVerify.verify(value, api_options)
42
+
43
+ result_accessor = "#{attribute}_verification_result"
44
+ if record.respond_to?(result_accessor)
45
+ record.instance_variable_set("@#{result_accessor}", ev)
46
+ end
47
+
48
+ error ||= ev.state.to_sym unless states.include?(ev.state.to_sym)
49
+ error ||= :free if ev.free? && !free
50
+ error ||= :role if ev.role? && !role
51
+ error ||= :disposable if ev.disposable? && !disposable
52
+ error ||= :accept_all if ev.accept_all? && !accept_all
53
+
54
+ record.errors.add(attribute, error) if error
55
+ rescue BlazeVerify::Error
56
+ # silence errors
57
+ end
58
+
59
+ private
60
+
61
+ def boolean_option_or_raise_error(name, default)
62
+ option = options.fetch(name, default)
63
+ unless [true, false].include?(option)
64
+ raise ArgumentError, ":#{name} must by a Boolean"
65
+ end
66
+
67
+ option
68
+ end
69
+
70
+ end
@@ -1,7 +1,9 @@
1
1
  module BlazeVerify
2
2
  class Verification < APIResource
3
- attr_accessor :accept_all, :did_you_mean, :disposable, :domain, :email,
4
- :free, :reason, :role, :score, :state, :tag, :user
3
+ attr_accessor :accept_all, :did_you_mean, :disposable, :domain, :duration,
4
+ :email, :free, :mx_record, :reason, :role, :score,
5
+ :smtp_provider, :state, :tag, :user, :first_name, :last_name,
6
+ :full_name, :gender
5
7
 
6
8
  %w(accept_all disposable free role).each do |method|
7
9
  define_method("#{method}?") do
@@ -1,3 +1,3 @@
1
1
  module BlazeVerify
2
- VERSION = '1.0.1'
2
+ VERSION = '2.0.0'
3
3
  end
@@ -15,6 +15,7 @@ class BlazeVerifyTest < Minitest::Test
15
15
  refute_nil @result.score
16
16
  refute_nil @result.state
17
17
  refute_nil @result.user
18
+ refute_nil @result.duration
18
19
  end
19
20
 
20
21
  def test_verification_state
@@ -39,11 +40,31 @@ class BlazeVerifyTest < Minitest::Test
39
40
  end
40
41
 
41
42
  def test_account
42
- BlazeVerify.api_key = 'test_7aff7fc0142c65f86a00'
43
43
  account = BlazeVerify.account
44
44
 
45
45
  refute_nil account.owner_email
46
46
  refute_nil account.available_credits
47
47
  end
48
48
 
49
+ def test_name_and_gender
50
+ result = BlazeVerify.verify('johndoe@blazeverify.com')
51
+ if %w(deliverable risky unknown).include?(result.state)
52
+ assert result.first_name, 'John'
53
+ assert result.last_name, 'Doe'
54
+ assert result.first_name, 'John Doe'
55
+ assert result.gender, 'male'
56
+ else
57
+ assert_nil result.first_name
58
+ assert_nil result.last_name
59
+ assert_nil result.full_name
60
+ assert_nil result.gender
61
+ end
62
+ end
63
+
64
+ def test_slow_verification
65
+ assert_raises(BlazeVerify::TimeoutError) do
66
+ BlazeVerify.verify('slow@example.com')
67
+ end
68
+ end
69
+
49
70
  end
@@ -0,0 +1,85 @@
1
+ require 'test_helper'
2
+
3
+ class EmailValidatorTest < Minitest::Test
4
+
5
+ def user_class(
6
+ smtp: true, states: %i[deliverable risky unknown], free: true, role: true,
7
+ accept_all: true, disposable: true, timeout: 3
8
+ )
9
+ Class.new do
10
+ include ActiveModel::Model
11
+ attr_accessor :email, :email_verification_result
12
+
13
+ validates :email, presence: true, email: {
14
+ smtp: smtp, states: states,
15
+ free: free, role: role, disposable: disposable, accept_all: accept_all,
16
+ timeout: timeout
17
+ }
18
+
19
+ def self.name
20
+ 'TestClass'
21
+ end
22
+
23
+ # stub changes to always be true
24
+ def changes
25
+ { email: true }
26
+ end
27
+ end
28
+ end
29
+
30
+ def setup
31
+ BlazeVerify.api_key = 'test_7aff7fc0142c65f86a00'
32
+ sleep(0.25)
33
+ end
34
+
35
+ def test_valid
36
+ @user = user_class.new(email: 'deliverable@example.com')
37
+
38
+ assert @user.valid?
39
+ assert @user.errors.empty?
40
+ end
41
+
42
+ def test_invalid
43
+ @user = user_class.new(email: 'undeliverable@example.com')
44
+
45
+ assert !@user.valid?
46
+ assert @user.errors[:email].present?
47
+ end
48
+
49
+ def test_verification_result
50
+ @user = user_class.new(email: 'undeliverable@example.com')
51
+ @user.valid?
52
+
53
+ refute_nil @user.email_verification_result
54
+ assert @user.email_verification_result.state, :undeliverable
55
+ end
56
+
57
+ def test_boolean_options
58
+ %i[smtp free role disposable accept_all].each do |option|
59
+ invalid_user = user_class(option => 'string').new
60
+ valid_user = user_class.new
61
+
62
+ assert !valid_user.valid?
63
+ assert_raises(ArgumentError) { invalid_user.valid? }
64
+ end
65
+ end
66
+
67
+ def test_states_option
68
+ invalid_user = user_class(states: %i[invalid_state]).new
69
+ valid_user = user_class.new
70
+
71
+ assert !valid_user.valid?
72
+ assert_raises(ArgumentError) { invalid_user.valid? }
73
+ end
74
+
75
+ def test_timeout_option
76
+ invalid_user1 = user_class(timeout: 'string').new
77
+ invalid_user2 = user_class(timeout: 1).new
78
+ valid_user = user_class.new
79
+
80
+ assert !valid_user.valid?
81
+ assert_raises(ArgumentError) { invalid_user1.valid? }
82
+ assert_raises(ArgumentError) { invalid_user2.valid? }
83
+ end
84
+
85
+ end
@@ -1,6 +1,8 @@
1
1
  $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
2
+ require 'active_model'
2
3
  require 'blazeverify'
3
4
 
5
+ require 'pry'
4
6
  require 'minitest/autorun'
5
7
  require 'minitest/reporters'
6
8
  Minitest::Reporters.use! [
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: blazeverify
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Blaze Verify
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-06-14 00:00:00.000000000 Z
11
+ date: 2020-11-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '0.13'
19
+ version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '0.13'
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: faraday_middleware
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -72,14 +72,14 @@ dependencies:
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '10.0'
75
+ version: '13.0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '10.0'
82
+ version: '13.0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: pry
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -136,6 +136,20 @@ dependencies:
136
136
  - - ">="
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: activemodel
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
139
153
  description: Email Verification that’s astonishingly easy and low-cost. See https://blazeverify.com
140
154
  for details.
141
155
  email: support@blazeverify.com
@@ -157,9 +171,11 @@ files:
157
171
  - bin/console
158
172
  - bin/setup
159
173
  - blazeverify.gemspec
174
+ - config/locales/en.yml
160
175
  - lib/blazeverify.rb
161
176
  - lib/blazeverify/batch.rb
162
177
  - lib/blazeverify/client.rb
178
+ - lib/blazeverify/email_validator.rb
163
179
  - lib/blazeverify/resources/account.rb
164
180
  - lib/blazeverify/resources/api_resource.rb
165
181
  - lib/blazeverify/resources/batch_status.rb
@@ -167,6 +183,7 @@ files:
167
183
  - lib/blazeverify/version.rb
168
184
  - test/blazeverify/batch_test.rb
169
185
  - test/blazeverify_test.rb
186
+ - test/email_validator_test.rb
170
187
  - test/test_helper.rb
171
188
  homepage: https://blazeverify.com
172
189
  licenses:
@@ -175,7 +192,7 @@ metadata:
175
192
  bug_tracker_uri: https://github.com/blazeverify/blazeverify-ruby/issues
176
193
  documentation_uri: https://docs.blazeverify.com/?ruby
177
194
  source_code_uri: https://github.com/blazeverify/blazeverify-ruby
178
- post_install_message:
195
+ post_install_message:
179
196
  rdoc_options: []
180
197
  require_paths:
181
198
  - lib
@@ -190,11 +207,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
190
207
  - !ruby/object:Gem::Version
191
208
  version: '0'
192
209
  requirements: []
193
- rubygems_version: 3.0.3
194
- signing_key:
210
+ rubygems_version: 3.0.8
211
+ signing_key:
195
212
  specification_version: 4
196
213
  summary: Ruby bindings for the Blaze Verify API
197
214
  test_files:
198
215
  - test/blazeverify/batch_test.rb
199
216
  - test/blazeverify_test.rb
217
+ - test/email_validator_test.rb
200
218
  - test/test_helper.rb