blazeverify 1.3.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e8360a15415041b8575ba7377e2e8246b3bb6d25d1de7d6a25b271f4dee3f64f
4
- data.tar.gz: 0a0128e604f533fdceb0c70c3d13f6aefac86fe8df4dc86ef5a6f504808fdb89
3
+ metadata.gz: 85252fc6012c171412400563d082437bef82d71bc0e950a0acc44ca2d6ef53c9
4
+ data.tar.gz: 8b1975eba455e692aaff0cb033b6b5abd02a6fccfbffc0269981f3624c823670
5
5
  SHA512:
6
- metadata.gz: 50a9e3e1726272e9e787994c1603749875c861d58225438b66bd261271bcf048b52fd6df82b0944767c86035f6fd52044d480fac6152f961f4f0e91f15495f09
7
- data.tar.gz: 3b4cb4349fca91f7ec704feb362619fc5c81d6ea3e9f07f7e7643ab55ba3ce0c7f87a17f13e0dd9f9fa52b1f07935b262e4c926d2932f95558c698d46f18d12d
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.3.1)
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.17.0)
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,18 +38,24 @@ GEM
26
38
  minitest (>= 5.0)
27
39
  ruby-progressbar
28
40
  multipart-post (2.1.1)
29
- net-http-persistent (3.1.0)
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
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
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,7 +27,7 @@ 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'
@@ -36,4 +36,5 @@ Gem::Specification.new do |s|
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,3 +1,3 @@
1
1
  module BlazeVerify
2
- VERSION = '1.3.1'
2
+ VERSION = '2.0.0'
3
3
  end
@@ -61,4 +61,10 @@ class BlazeVerifyTest < Minitest::Test
61
61
  end
62
62
  end
63
63
 
64
+ def test_slow_verification
65
+ assert_raises(BlazeVerify::TimeoutError) do
66
+ BlazeVerify.verify('slow@example.com')
67
+ end
68
+ end
69
+
64
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,4 +1,5 @@
1
1
  $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
2
+ require 'active_model'
2
3
  require 'blazeverify'
3
4
 
4
5
  require 'pry'
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.3.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: 2020-03-02 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
@@ -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