-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'feature/active_record_validator' into develop
* feature/active_record_validator: Updated readme, changed slow requests to return a BlazeVerify::Timeout error. Updated translations to not be namedspaced and also made it so we send accept_all to the API only when necessary. Added options validation to validator and additional test coverage. Added email_validator_test Added active record validator, removed faraday version restriction and updated readme.
- Loading branch information
Showing
11 changed files
with
263 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,8 @@ | |
|
||
This is the official ruby wrapper for the Blaze Verify API. | ||
|
||
It also includes an Active Record (Rails) validator to verify email attributes. | ||
|
||
## Documentation | ||
|
||
See the [Ruby API docs](https://blazeverify.com/docs/api/?ruby). | ||
|
@@ -47,18 +49,14 @@ BlazeVerify.verify('[email protected]') | |
|
||
#### Slow Email Server Handling | ||
|
||
Some email servers are slow to respond. As a result the timeout may be reached | ||
Some email servers are slow to respond. As a result, the timeout may be reached | ||
before we are able to complete the verification process. If this happens, the | ||
verification will continue in the background on our servers. We recommend | ||
sleeping for at least one second and trying your request again. Re-requesting | ||
the same verification with the same options will not impact your credit | ||
allocation within a 5 minute window. | ||
|
||
```ruby | ||
{ | ||
"message" => "Your request is taking longer than normal. Please send your request again." | ||
} | ||
``` | ||
verification will continue in the background on our servers, and a | ||
`BlazeVerify::TimeoutError` will be raised. We recommend sleeping for at least | ||
one second and trying your request again. Re-requesting the same verification | ||
with the same options will not impact your credit allocation within a 5 minute | ||
window. You can test this behavior using a test key and the special | ||
email `[email protected]`. | ||
|
||
### Batch Verification | ||
|
||
|
@@ -98,6 +96,34 @@ batch.status.reason_counts | |
batch.complete? | ||
``` | ||
|
||
### Active Record Validator | ||
|
||
Define a validator on an Active Record model for your email attribute(s). | ||
It'll validate the attribute only when it's present and has changed. | ||
|
||
#### Options | ||
|
||
* `smtp`, `timeout`: Passed directly to API as options. | ||
* `states`: An array of states you'd like to be considered valid. | ||
* `free`, `role`, `disposable`, `accept_all`: If you'd like any of these to be valid. | ||
|
||
```ruby | ||
validates :email, email: { | ||
smtp: true, states: %i[deliverable risky unknown], | ||
free: true, role: true, disposable: false, accept_all: true, timeout: 3 | ||
} | ||
``` | ||
|
||
#### Access Verification Result | ||
|
||
You can define an `attr_accessor` with the following format to gain | ||
access to the verification result. | ||
|
||
```ruby | ||
# [attribute_name]_verification_result | ||
attr_accessor :email_verification_result | ||
``` | ||
|
||
## Development | ||
|
||
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. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
en: | ||
errors: | ||
messages: | ||
undeliverable: is undeliverable | ||
risky: is risky | ||
unknown: is unknown | ||
free: is a free address | ||
role: is a role address | ||
disposable: is a disposable address | ||
accept_all: is an accept-all address |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
# ActiveRecord validator for validating an email address with Blaze Verify | ||
# | ||
# Usage: | ||
# validates :email, presence: true, email: { | ||
# smtp: true, states: %i[deliverable risky unknown], | ||
# free: true, role: true, disposable: false, accept_all: true, | ||
# timeout: 3 | ||
# } | ||
# | ||
# Define an attr_accessor to access verification results. | ||
# attr_accessor :email_verification_result | ||
# | ||
class EmailValidator < ActiveModel::EachValidator | ||
|
||
def validate_each(record, attribute, value) | ||
smtp = boolean_option_or_raise_error(:smtp, true) | ||
|
||
states = options.fetch(:states, %i(deliverable risky unknown)) | ||
allowed_states = %i[deliverable undeliverable risky unknown] | ||
unless (states - allowed_states).empty? | ||
raise ArgumentError, ":states must be an array of symbols containing "\ | ||
"any or all of :#{allowed_states.join(', :')}" | ||
end | ||
|
||
free = boolean_option_or_raise_error(:free, true) | ||
role = boolean_option_or_raise_error(:role, true) | ||
disposable = boolean_option_or_raise_error(:disposable, false) | ||
accept_all = boolean_option_or_raise_error(:accept_all, true) | ||
|
||
timeout = options.fetch(:timeout, 3) | ||
unless timeout.is_a?(Integer) && timeout > 1 | ||
raise ArgumentError, ":timeout must be an Integer greater than 1" | ||
end | ||
|
||
return if record.errors[attribute].present? | ||
return unless value.present? | ||
return unless record.changes[attribute].present? | ||
|
||
api_options = { timeout: timeout, smtp: smtp } | ||
api_options[:accept_all] = true unless accept_all | ||
ev = BlazeVerify.verify(value, api_options) | ||
|
||
result_accessor = "#{attribute}_verification_result" | ||
if record.respond_to?(result_accessor) | ||
record.instance_variable_set("@#{result_accessor}", ev) | ||
end | ||
|
||
error ||= ev.state.to_sym unless states.include?(ev.state.to_sym) | ||
error ||= :free if ev.free? && !free | ||
error ||= :role if ev.role? && !role | ||
error ||= :disposable if ev.disposable? && !disposable | ||
error ||= :accept_all if ev.accept_all? && !accept_all | ||
|
||
record.errors.add(attribute, error) if error | ||
rescue BlazeVerify::Error | ||
# silence errors | ||
end | ||
|
||
private | ||
|
||
def boolean_option_or_raise_error(name, default) | ||
option = options.fetch(name, default) | ||
unless [true, false].include?(option) | ||
raise ArgumentError, ":#{name} must by a Boolean" | ||
end | ||
|
||
option | ||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
module BlazeVerify | ||
VERSION = '1.3.1' | ||
VERSION = '2.0.0' | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -61,4 +61,10 @@ def test_name_and_gender | |
end | ||
end | ||
|
||
def test_slow_verification | ||
assert_raises(BlazeVerify::TimeoutError) do | ||
BlazeVerify.verify('[email protected]') | ||
end | ||
end | ||
|
||
end |
Oops, something went wrong.