├── .coveralls.yml ├── .gitignore ├── .rspec ├── .rubocop.yml ├── .travis.yml ├── Gemfile ├── Gemfile.lock ├── LICENSE.txt ├── README.md ├── Rakefile ├── bin ├── console └── setup ├── gemfiles ├── Gemfile-4-0 ├── Gemfile-5-0 └── Gemfile-6-0 ├── lib ├── rails_email_checker.rb └── rails_email_checker │ ├── address.rb │ ├── configuration.rb │ ├── constant.rb │ ├── email_validator.rb │ ├── helper_methods.rb │ └── version.rb ├── rails_email_checker.gemspec ├── spec ├── rails_email_checker_spec.rb ├── spec_helper.rb └── user_model.rb └── vendor ├── blacklist.txt └── whitelist.txt /.coveralls.yml: -------------------------------------------------------------------------------- 1 | service_name: travis-pro 2 | repo_token: 7nKS8dACFw7pKCDfK5m9Ic7ya5MA9v2tb -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.bundle/ 2 | /.yardoc 3 | /_yardoc/ 4 | /coverage/ 5 | /doc/ 6 | /pkg/ 7 | /spec/reports/ 8 | /tmp/ 9 | 10 | # rspec failure tracking 11 | .rspec_status 12 | 13 | # IDE 14 | /.idea 15 | .idea/workspace.xml 16 | .rakeTasks 17 | .generators 18 | 19 | # Gem 20 | *.gem 21 | 22 | # Logs 23 | spec/dummy/log/*.log 24 | spec/dummy/tmp/ -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --format documentation 2 | --color 3 | --require spec_helper 4 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | Documentation: 2 | Enabled: false 3 | Metrics/LineLength: 4 | IgnoredPatterns: ['(\A|\s)#'] 5 | Max: 100 6 | Layout/EmptyLineAfterGuardClause: 7 | Enabled: false 8 | Layout/EmptyLinesAroundBlockBody: 9 | Enabled: false 10 | Style/GuardClause: 11 | Enabled: false 12 | Metrics/MethodLength: 13 | Max: 35 14 | Metrics/AbcSize: 15 | Enabled: false 16 | Metrics/CyclomaticComplexity: 17 | Enabled: false 18 | Metrics/PerceivedComplexity: 19 | Enabled: false -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | os: linux 3 | language: ruby 4 | cache: bundler 5 | rvm: 6 | - 2.5.5 7 | - 2.6.3 8 | - 2.7.0 9 | gemfile: 10 | - gemfiles/Gemfile-4-0 11 | - gemfiles/Gemfile-5-0 12 | - gemfiles/Gemfile-6-0 13 | before_install: gem install bundler 14 | before_script: bundle install 15 | script: bundle exec rspec -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source 'https://rubygems.org' 4 | 5 | # Specify your gem's dependencies in rails_email_checker.gemspec 6 | gemspec 7 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: . 3 | specs: 4 | rails_email_checker (0.1.4) 5 | activemodel (>= 4.2, < 7) 6 | 7 | GEM 8 | remote: https://rubygems.org/ 9 | specs: 10 | activemodel (6.0.3.2) 11 | activesupport (= 6.0.3.2) 12 | activesupport (6.0.3.2) 13 | concurrent-ruby (~> 1.0, >= 1.0.2) 14 | i18n (>= 0.7, < 2) 15 | minitest (~> 5.1) 16 | tzinfo (~> 1.1) 17 | zeitwerk (~> 2.2, >= 2.2.2) 18 | concurrent-ruby (1.1.6) 19 | coveralls (0.8.23) 20 | json (>= 1.8, < 3) 21 | simplecov (~> 0.16.1) 22 | term-ansicolor (~> 1.3) 23 | thor (>= 0.19.4, < 2.0) 24 | tins (~> 1.6) 25 | diff-lcs (1.4.4) 26 | docile (1.3.2) 27 | i18n (1.8.3) 28 | concurrent-ruby (~> 1.0) 29 | json (2.3.1) 30 | minitest (5.14.1) 31 | rake (13.0.1) 32 | rspec (3.9.0) 33 | rspec-core (~> 3.9.0) 34 | rspec-expectations (~> 3.9.0) 35 | rspec-mocks (~> 3.9.0) 36 | rspec-core (3.9.2) 37 | rspec-support (~> 3.9.3) 38 | rspec-expectations (3.9.2) 39 | diff-lcs (>= 1.2.0, < 2.0) 40 | rspec-support (~> 3.9.0) 41 | rspec-mocks (3.9.1) 42 | diff-lcs (>= 1.2.0, < 2.0) 43 | rspec-support (~> 3.9.0) 44 | rspec-support (3.9.3) 45 | simplecov (0.16.1) 46 | docile (~> 1.1) 47 | json (>= 1.8, < 3) 48 | simplecov-html (~> 0.10.0) 49 | simplecov-html (0.10.2) 50 | sync (0.5.0) 51 | term-ansicolor (1.7.1) 52 | tins (~> 1.0) 53 | thor (1.0.1) 54 | thread_safe (0.3.6) 55 | tins (1.25.0) 56 | sync 57 | tzinfo (1.2.7) 58 | thread_safe (~> 0.1) 59 | zeitwerk (2.3.1) 60 | 61 | PLATFORMS 62 | ruby 63 | 64 | DEPENDENCIES 65 | bundler (~> 2.0) 66 | coveralls (~> 0.8) 67 | rails_email_checker! 68 | rake (~> 13.0) 69 | rspec (~> 3.0) 70 | simplecov (~> 0.16) 71 | 72 | BUNDLED WITH 73 | 2.1.4 74 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2020 OpenGems 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RailsEmailChecker 2 | 3 | [![Gem Version](https://badge.fury.io/rb/rails_email_checker.svg)](https://badge.fury.io/rb/redis_web_manager) 4 | [![Maintainability](https://api.codeclimate.com/v1/badges/eecf90541668432d4d41/maintainability)](https://codeclimate.com/github/OpenGems/rails_email_checker/maintainability) 5 | [![Build Status](https://travis-ci.org/OpenGems/rails_email_checker.svg?branch=master)](https://travis-ci.org/OpenGems/redis_web_manager) 6 | [![security](https://hakiri.io/github/OpenGems/rails_email_checker/master.svg)](https://hakiri.io/github/OpenGems/redis_web_manager/master) 7 | ![Gem](https://img.shields.io/gem/dt/rails_email_checker) 8 | [![Coverage Status](https://coveralls.io/repos/github/OpenGems/rails_email_checker/badge.svg?branch=master)](https://coveralls.io/github/OpenGems/rails_email_checker?branch=master) 9 | 10 | ActiveModel email validation. Checks MX records, sub address, regex, whitelisted and blacklisted check 11 | 12 | ## Installation 13 | 14 | Add this line to your application's Gemfile: 15 | 16 | ```ruby 17 | gem 'rails_email_checker' 18 | ``` 19 | 20 | And then execute: 21 | 22 | $ bundle 23 | 24 | Or install it yourself as: 25 | 26 | $ gem install rails_email_checker 27 | 28 | ## Usage 29 | 30 | ### Use with ActiveModel 31 | 32 | To validate that the domain has a good format (regex): 33 | ```ruby 34 | class User < ActiveRecord::Base 35 | validates_email :email, formatted: true 36 | end 37 | ``` 38 | 39 | To validate that the domain is not blacklisted: 40 | ```ruby 41 | class User < ActiveRecord::Base 42 | validates_email :email, blacklisted: true 43 | end 44 | ``` 45 | 46 | To validate that the domain has a MX record: 47 | ```ruby 48 | class User < ActiveRecord::Base 49 | validates_email :email, recorded: true 50 | end 51 | ``` 52 | 53 | To validate that email is not sub addressed: 54 | ```ruby 55 | class User < ActiveRecord::Base 56 | validates_email :email, no_sub_addressed: true 57 | end 58 | ``` 59 | 60 | OR 61 | 62 | Use like that 63 | ```ruby 64 | class User < ActiveRecord::Base 65 | validates :email, email: { no_sub_addressed: true, recorded: true, blacklisted: true } 66 | end 67 | ``` 68 | 69 | ### Use without ActiveModel 70 | ```ruby 71 | address = RailsEmailChecker.address('test@gmail.com') # or RailsEmailChecker::Address.new('test@gmail.com') 72 | address.formatted? # => true 73 | address.sub_addressed? # => false 74 | address.recorded? # => true 75 | address.whitelisted? # => false 76 | address.blacklisted? # => false 77 | ``` 78 | 79 | ## Contributing 80 | 81 | Bug reports and pull requests are welcome on GitHub at https://github.com/OpenGems/rails_email_checker. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct. 82 | 83 | ## License 84 | 85 | The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT). 86 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'bundler/gem_tasks' 4 | require 'rspec/core/rake_task' 5 | 6 | RSpec::Core::RakeTask.new(:spec) 7 | 8 | task default: :spec 9 | -------------------------------------------------------------------------------- /bin/console: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | require 'bundler/setup' 5 | require 'rails_email_checker' 6 | 7 | # You can add fixtures and/or initialization code here to make experimenting 8 | # with your gem easier. You can also use a different console, if you like. 9 | 10 | # (If you use this, don't forget to add pry to your Gemfile!) 11 | # require "pry" 12 | # Pry.start 13 | 14 | require 'irb' 15 | IRB.start(__FILE__) 16 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | IFS=$'\n\t' 4 | set -vx 5 | 6 | bundle install 7 | 8 | # Do any other automated setup that you need to do here 9 | -------------------------------------------------------------------------------- /gemfiles/Gemfile-4-0: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'activemodel', '~> 4.2.0' 4 | 5 | gemspec path: '..' -------------------------------------------------------------------------------- /gemfiles/Gemfile-5-0: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'activemodel', '~> 5.2.0' 4 | 5 | gemspec path: '..' -------------------------------------------------------------------------------- /gemfiles/Gemfile-6-0: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'activemodel', '~> 6.0.2' 4 | 5 | gemspec path: '..' -------------------------------------------------------------------------------- /lib/rails_email_checker.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'rails_email_checker/configuration' 4 | require 'rails_email_checker/constant' 5 | require 'rails_email_checker/email_validator' 6 | require 'rails_email_checker/helper_methods' 7 | require 'rails_email_checker/address' 8 | 9 | module RailsEmailChecker 10 | class << self 11 | attr_writer :configuration 12 | 13 | def configuration 14 | @configuration ||= Configuration.new 15 | end 16 | 17 | def configure 18 | yield(configuration) 19 | end 20 | 21 | def address(value) 22 | Address.new(value) 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /lib/rails_email_checker/address.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'resolv' 4 | 5 | module RailsEmailChecker 6 | class Address 7 | attr_reader :address 8 | 9 | def initialize(address) 10 | @address = address 11 | raise AddressArgument, "Invalid address #{address}" unless valid?(address) 12 | end 13 | 14 | def whitelisted? 15 | domain_include?(configuration.whitelist_domains) 16 | end 17 | 18 | def blacklisted? 19 | domain_include?(configuration.blacklist_domains) 20 | end 21 | 22 | def recorded? 23 | !records.nil? && records.any? 24 | end 25 | 26 | def formatted? 27 | !(address =~ configuration.regex_email).nil? 28 | end 29 | 30 | def sub_addressed? 31 | address.include?('+') 32 | end 33 | 34 | private 35 | 36 | def valid?(value) 37 | value.is_a?(String) && !value.nil? && !value.empty? 38 | end 39 | 40 | def domain_include?(list) 41 | list.include?(domain) 42 | end 43 | 44 | def domain 45 | @domain ||= address.gsub(/.+@/, '\1') 46 | end 47 | 48 | def records 49 | @records ||= dns 50 | end 51 | 52 | def configuration 53 | @configuration ||= RailsEmailChecker.configuration 54 | end 55 | 56 | def dns 57 | Resolv::DNS.open do |dns| 58 | dns.timeouts = configuration.timeouts || 2 59 | dns.getresources(domain, Resolv::DNS::Resource::IN::MX) 60 | end 61 | rescue Resolv::ResolvError, Resolv::ResolvTimeout 62 | nil 63 | end 64 | end 65 | end 66 | -------------------------------------------------------------------------------- /lib/rails_email_checker/configuration.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module RailsEmailChecker 4 | class Configuration 5 | attr_accessor :regex_email, 6 | :blacklist_domains, 7 | :whitelist_domains, 8 | :timeouts 9 | 10 | def initialize 11 | @regex_email = REGEX_EMAIL 12 | @blacklist_domains = default_blacklist_domains 13 | @whitelist_domains = default_whitelist_domains 14 | @timeouts = 2 15 | end 16 | 17 | def add_blacklist_domains(path: nil, domains: nil) 18 | raise ListArgument, 'Path or domains are nil' if valid_argument?(path, domains) 19 | add_blacklist(load_domains(path)) unless path.nil? 20 | add_blacklist(domains) unless domains.nil? 21 | end 22 | 23 | def add_whitelist_domains(path: nil, domains: nil) 24 | raise ListArgument, 'Path or domains are nil' if valid_argument?(path, domains) 25 | add_whitelist(load_domains(path)) unless path.nil? 26 | add_whitelist(domains) unless domains.nil? 27 | end 28 | 29 | private 30 | 31 | def valid_argument?(path, domains) 32 | path.nil? && domains.nil? 33 | end 34 | 35 | def default_blacklist_domains 36 | @default_blacklist_domains ||= load_domains(BLACKLIST_FILE) 37 | end 38 | 39 | def default_whitelist_domains 40 | @default_whitelist_domains ||= load_domains(WHITELIST_FILE) 41 | end 42 | 43 | def load_domains(path) 44 | domains = [] 45 | file = File.open(path, 'r') 46 | file.each_line do |line| 47 | domain = line.strip 48 | domains << domain unless domain.nil? 49 | end 50 | domains 51 | rescue StandardError => e 52 | raise FileNotFound, "File not found: #{e}" 53 | end 54 | 55 | def add_blacklist(domains) 56 | @blacklist_domains.concat(domains) if domains.is_a?(Array) 57 | @blacklist_domains << domains if domains.is_a?(String) 58 | end 59 | 60 | def add_whitelist(domains) 61 | @whitelist_domains.concat(domains) if domains.is_a?(Array) 62 | @whitelist_domains << domains if domains.is_a?(String) 63 | end 64 | end 65 | end 66 | -------------------------------------------------------------------------------- /lib/rails_email_checker/constant.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module RailsEmailChecker 4 | FileNotFound = Class.new(StandardError) 5 | ListArgument = Class.new(StandardError) 6 | AddressArgument = Class.new(StandardError) 7 | 8 | REGEX_EMAIL = /\b[A-Z0-9._%a-z\-]+@(?:[A-Z0-9a-z\-]+\.)+[A-Za-z]{2,6}\z/.freeze 9 | 10 | BLACKLIST_FILE = 'vendor/blacklist.txt' 11 | WHITELIST_FILE = 'vendor/whitelist.txt' 12 | end 13 | -------------------------------------------------------------------------------- /lib/rails_email_checker/email_validator.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'active_model' 4 | require 'active_model/validations' 5 | require 'rails_email_checker' 6 | 7 | class EmailValidator < ActiveModel::EachValidator 8 | def validate_each(record, attribute, value) 9 | if !value.present? || value.nil? 10 | add_error(record, attribute, :blank) 11 | return 12 | end 13 | 14 | address = RailsEmailChecker::Address.new(value) 15 | 16 | return if address.whitelisted? 17 | 18 | if options[:formatted] && !address.formatted? 19 | add_error(record, attribute) 20 | return 21 | end 22 | 23 | if options[:blacklisted] && address.blacklisted? 24 | add_error(record, attribute) 25 | return 26 | end 27 | 28 | if options[:no_sub_addressed] && address.sub_addressed? 29 | add_error(record, attribute) 30 | return 31 | end 32 | 33 | if options[:recorded] && !address.recorded? 34 | add_error(record, attribute) 35 | nil 36 | end 37 | end 38 | 39 | private 40 | 41 | def add_error(record, attribute, key = :invalid) 42 | record.errors.add(attribute, options[:message] || key) 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /lib/rails_email_checker/helper_methods.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module ActiveModel 4 | module Validations 5 | module HelperMethods 6 | def validates_email(*attrs) 7 | validates_with EmailValidator, _merge_attributes(attrs) 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/rails_email_checker/version.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module RailsEmailChecker 4 | VERSION = '0.1.4' 5 | end 6 | -------------------------------------------------------------------------------- /rails_email_checker.gemspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | lib = File.expand_path('lib', __dir__) 4 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 5 | require 'rails_email_checker/version' 6 | 7 | Gem::Specification.new do |spec| 8 | spec.name = 'rails_email_checker' 9 | spec.version = RailsEmailChecker::VERSION 10 | spec.authors = ['Boris BRESCIANI'] 11 | spec.email = ['boris2bresciani@gmail.com'] 12 | 13 | spec.summary = 'ActiveModel email validation. Checks MX records, sub address, regex, etc ..' 14 | spec.description = 'ActiveModel email validation. Checks MX records, sub address, regex, whitelisted and blacklisted check' 15 | spec.homepage = 'https://github.com/OpenGems/rails_email_checker' 16 | spec.license = 'MIT' 17 | 18 | spec.metadata['homepage_uri'] = spec.homepage 19 | spec.metadata['source_code_uri'] = spec.homepage 20 | 21 | spec.files = Dir.chdir(File.expand_path(__dir__)) do 22 | `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } 23 | end 24 | spec.bindir = 'exe' 25 | spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } 26 | spec.require_paths = ['lib'] 27 | 28 | spec.add_development_dependency 'bundler', '~> 2.0' 29 | spec.add_development_dependency 'coveralls', '~> 0.8' 30 | spec.add_development_dependency 'rake', '~> 13.0' 31 | spec.add_development_dependency 'rspec', '~> 3.0' 32 | spec.add_development_dependency 'simplecov', '~> 0.16' 33 | 34 | spec.add_dependency 'activemodel', '>= 4.2', '< 7' 35 | end 36 | -------------------------------------------------------------------------------- /spec/rails_email_checker_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'user_model' 4 | 5 | RSpec.describe RailsEmailChecker do 6 | describe 'Test configuration' do 7 | let(:configuration) do 8 | RailsEmailChecker.configuration 9 | end 10 | 11 | it 'returns a default regex' do 12 | expect(configuration.regex_email).to eql(RailsEmailChecker::REGEX_EMAIL) 13 | end 14 | 15 | it 'returns a default timeouts' do 16 | expect(configuration.timeouts).to eql(2) 17 | end 18 | 19 | it 'returns a default blacklist domains' do 20 | expect(configuration.blacklist_domains).to eql(configuration.send(:default_blacklist_domains)) 21 | end 22 | 23 | it 'returns a default whitelist domains' do 24 | expect(configuration.whitelist_domains).to eql(configuration.send(:default_whitelist_domains)) 25 | end 26 | 27 | it 'returns a new whitelist domains' do 28 | default_size = configuration.send(:default_whitelist_domains).size 29 | configuration.add_whitelist_domains(domains: 'test.com') 30 | expect(configuration.whitelist_domains.size).to eql(default_size + 1) 31 | end 32 | 33 | it 'returns a new blacklist domains' do 34 | default_size = configuration.send(:default_blacklist_domains).size 35 | configuration.add_blacklist_domains(domains: 'test.com') 36 | expect(configuration.blacklist_domains.size).to eql(default_size + 1) 37 | end 38 | 39 | it 'returns a raise error whitelist domains' do 40 | expect do 41 | configuration.add_whitelist_domains(path: 'test') 42 | end.to raise_error(RailsEmailChecker::FileNotFound) 43 | end 44 | 45 | it 'returns a raise error blacklist domains' do 46 | expect do 47 | configuration.add_blacklist_domains(path: 'test') 48 | end.to raise_error(RailsEmailChecker::FileNotFound) 49 | end 50 | 51 | it 'returns a valid configuration' do 52 | RailsEmailChecker.configure do |c| 53 | c.timeouts = 3 54 | end 55 | expect(RailsEmailChecker.configuration.timeouts).to eql(3) 56 | end 57 | end 58 | 59 | describe 'Test lib' do 60 | let(:address) do 61 | RailsEmailChecker.address('test@gmail.com') 62 | end 63 | 64 | it 'returns a raise error address' do 65 | expect do 66 | RailsEmailChecker.address(nil) 67 | end.to raise_error(RailsEmailChecker::AddressArgument) 68 | end 69 | 70 | it 'returns a valid formatted?' do 71 | expect(address.formatted?).to eql(true) 72 | end 73 | 74 | it 'returns a invalid sub_addressed?' do 75 | expect(address.sub_addressed?).to eql(false) 76 | end 77 | 78 | it 'returns a valid recorded?' do 79 | expect(address.recorded?).to eql(true) 80 | end 81 | 82 | it 'returns a valid whitelisted?' do 83 | expect(address.whitelisted?).to eql(true) 84 | end 85 | 86 | it 'returns a valid blacklisted?' do 87 | expect(address.blacklisted?).to eql(false) 88 | end 89 | 90 | it 'returns a invalid recorded?' do 91 | tmp = RailsEmailChecker.address('test@testtesttest.com') 92 | expect(tmp.recorded?).to eql(false) 93 | end 94 | end 95 | 96 | describe 'Test validation' do 97 | it 'returns a invalid valid? (empty)' do 98 | model = User5.new(email: '') 99 | expect(model.valid?).to eql(false) 100 | end 101 | 102 | it 'returns a valid valid? (whitelisted)' do 103 | model = User1.new(email: 'test@gmail.com') 104 | expect(model.valid?).to eql(true) 105 | end 106 | 107 | it 'returns a invalid valid? (formatted)' do 108 | model = User2.new(email: 'test@.com') 109 | expect(model.valid?).to eql(false) 110 | end 111 | 112 | it 'returns a invalid valid? (blacklisted)' do 113 | model = User3.new(email: 'test@yopmail.com') 114 | expect(model.valid?).to eql(false) 115 | end 116 | 117 | it 'returns a invalid valid? (no_sub_addressed)' do 118 | model = User4.new(email: 'test+test@testtesttest.com') 119 | expect(model.valid?).to eql(false) 120 | end 121 | 122 | it 'returns a invalid valid? (recorded)' do 123 | model = User5.new(email: 'test@testtesttest.com') 124 | expect(model.valid?).to eql(false) 125 | end 126 | end 127 | end 128 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'bundler/setup' 4 | require 'simplecov' 5 | require 'coveralls' 6 | 7 | SimpleCov.start 8 | Coveralls.wear! 9 | 10 | require 'rails_email_checker' 11 | 12 | RSpec.configure do |config| 13 | # Enable flags like --only-failures and --next-failure 14 | config.example_status_persistence_file_path = '.rspec_status' 15 | 16 | # Disable RSpec exposing methods globally on `Module` and `main` 17 | config.disable_monkey_patching! 18 | 19 | config.expect_with :rspec do |c| 20 | c.syntax = :expect 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /spec/user_model.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | lib = File.expand_path('lib', __dir__) 4 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 5 | 6 | require 'active_model' 7 | 8 | class User 9 | include ActiveModel::Validations 10 | 11 | def initialize(attributes = {}) 12 | @attributes = attributes 13 | end 14 | 15 | def read_attribute_for_validation(key) 16 | @attributes[key] 17 | end 18 | end 19 | 20 | class User1 < User 21 | validates_email :email 22 | end 23 | 24 | class User2 < User 25 | validates_email :email, formatted: true 26 | end 27 | 28 | class User3 < User 29 | validates_email :email, blacklisted: true 30 | end 31 | 32 | class User4 < User 33 | validates_email :email, no_sub_addressed: true 34 | end 35 | 36 | class User5 < User 37 | validates_email :email, recorded: true 38 | end 39 | -------------------------------------------------------------------------------- /vendor/whitelist.txt: -------------------------------------------------------------------------------- 1 | gmail.com 2 | gmx.com 3 | hotmail.ca 4 | hotmail.com 5 | hotmail.de 6 | hotmail.es 7 | hotmail.fr 8 | hotmail.it 9 | orange.fr 10 | outlook.com 11 | outlook.fr 12 | sfr.fr 13 | --------------------------------------------------------------------------------