email_address 0.1.2 → 0.2.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 +5 -5
- data/.github/workflows/ci.yml +18 -0
- data/Gemfile +1 -1
- data/README.md +255 -123
- data/Rakefile +2 -3
- data/email_address.gemspec +27 -22
- data/lib/email_address/active_record_validator.rb +10 -11
- data/lib/email_address/address.rb +126 -80
- data/lib/email_address/canonical_email_address_type.rb +16 -12
- data/lib/email_address/config.rb +102 -51
- data/lib/email_address/email_address_type.rb +17 -13
- data/lib/email_address/exchanger.rb +44 -33
- data/lib/email_address/host.rb +217 -105
- data/lib/email_address/local.rb +127 -87
- data/lib/email_address/messages.yaml +21 -0
- data/lib/email_address/rewriter.rb +144 -0
- data/lib/email_address/version.rb +1 -1
- data/lib/email_address.rb +48 -53
- data/test/activerecord/test_ar.rb +17 -13
- data/test/activerecord/user.rb +31 -30
- data/test/email_address/test_address.rb +84 -21
- data/test/email_address/test_config.rb +10 -10
- data/test/email_address/test_exchanger.rb +6 -7
- data/test/email_address/test_host.rb +59 -21
- data/test/email_address/test_local.rb +49 -36
- data/test/email_address/test_rewriter.rb +11 -0
- data/test/test_aliasing.rb +53 -0
- data/test/test_email_address.rb +15 -19
- data/test/test_helper.rb +9 -8
- metadata +43 -21
- data/.travis.yml +0 -10
data/lib/email_address.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
3
|
+
# EmailAddress parses and validates email addresses against RFC standard,
|
4
|
+
# conventional, canonical, formats and other special uses.
|
2
5
|
module EmailAddress
|
3
|
-
|
4
6
|
require "email_address/config"
|
5
7
|
require "email_address/exchanger"
|
6
8
|
require "email_address/host"
|
7
9
|
require "email_address/local"
|
10
|
+
require "email_address/rewriter"
|
8
11
|
require "email_address/address"
|
9
12
|
require "email_address/version"
|
10
13
|
require "email_address/active_record_validator" if defined?(ActiveModel)
|
@@ -13,61 +16,53 @@ module EmailAddress
|
|
13
16
|
require "email_address/canonical_email_address_type"
|
14
17
|
end
|
15
18
|
|
16
|
-
#
|
17
|
-
#
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
# @!method self.valid?(email_address, options={})
|
20
|
+
# Proxy method to {EmailAddress::Address#valid?}
|
21
|
+
# @!method self.error(email_address)
|
22
|
+
# Proxy method to {EmailAddress::Address#error}
|
23
|
+
# @!method self.normal(email_address)
|
24
|
+
# Proxy method to {EmailAddress::Address#normal}
|
25
|
+
# @!method self.redact(email_address, options={})
|
26
|
+
# Proxy method to {EmailAddress::Address#redact}
|
27
|
+
# @!method self.munge(email_address, options={})
|
28
|
+
# Proxy method to {EmailAddress::Address#munge}
|
29
|
+
# @!method self.base(email_address, options{})
|
30
|
+
# Returns the base form of the email address, the mailbox
|
31
|
+
# without optional puncuation removed, no tag, and the host name.
|
32
|
+
# @!method self.canonical(email_address, options{})
|
33
|
+
# Proxy method to {EmailAddress::Address#canonical}
|
34
|
+
# @!method self.reference(email_address, form=:base, options={})
|
35
|
+
# Returns the reference form of the email address, by default
|
36
|
+
# the MD5 digest of the Base Form the the address.
|
37
|
+
# @!method self.srs(email_address, sending_domain, options={})
|
38
|
+
# Returns the address encoded for SRS forwarding. Pass a local
|
39
|
+
# secret to use in options[:secret]
|
40
|
+
class << self
|
41
|
+
(%i[valid? error normal redact munge canonical reference base srs] &
|
42
|
+
Address.public_instance_methods
|
43
|
+
).each do |proxy_method|
|
44
|
+
define_method(proxy_method) do |*args, &block|
|
45
|
+
Address.new(*args).public_send(proxy_method, &block)
|
46
|
+
end
|
47
|
+
end
|
21
48
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
49
|
+
# Creates an instance of this email address.
|
50
|
+
# This is a short-cut to EmailAddress::Address.new
|
51
|
+
def new(email_address, config = {}, locale = "en")
|
52
|
+
Address.new(email_address, config, locale)
|
53
|
+
end
|
26
54
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
self.new(email_address, config).error
|
31
|
-
end
|
55
|
+
def new_redacted(email_address, config = {}, locale = "en")
|
56
|
+
Address.new(Address.new(email_address, config, locale).redact)
|
57
|
+
end
|
32
58
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
end
|
37
|
-
|
38
|
-
# Shortcut to normalize the given email address
|
39
|
-
def self.redact(email_address, config={})
|
40
|
-
EmailAddress::Address.new(email_address, config).redact
|
41
|
-
end
|
42
|
-
|
43
|
-
# Shortcut to munge the given email address for web publishing
|
44
|
-
# returns ma_____@do_____.com
|
45
|
-
def self.munge(email_address, config={})
|
46
|
-
EmailAddress::Address.new(email_address, config).munge
|
47
|
-
end
|
48
|
-
|
49
|
-
def self.new_redacted(email_address, config={})
|
50
|
-
EmailAddress::Address.new(EmailAddress::Address.new(email_address, config).redact)
|
51
|
-
end
|
52
|
-
|
53
|
-
# Returns the Canonical form of the email address. This form is what should
|
54
|
-
# be considered unique for an email account, lower case, and no address tags.
|
55
|
-
def self.canonical(email_address, config={})
|
56
|
-
EmailAddress::Address.new(email_address, config).canonical
|
57
|
-
end
|
58
|
-
|
59
|
-
def self.new_canonical(email_address, config={})
|
60
|
-
EmailAddress::Address.new(EmailAddress::Address.new(email_address, config).canonical, config)
|
61
|
-
end
|
62
|
-
|
63
|
-
# Returns the Reference form of the email address, defined as the MD5
|
64
|
-
# digest of the Canonical form.
|
65
|
-
def self.reference(email_address, config={})
|
66
|
-
EmailAddress::Address.new(email_address, config).reference
|
67
|
-
end
|
59
|
+
def new_canonical(email_address, config = {}, locale = "en")
|
60
|
+
Address.new(Address.new(email_address, config, locale).canonical, config)
|
61
|
+
end
|
68
62
|
|
69
|
-
|
70
|
-
|
71
|
-
|
63
|
+
# Does the email address match any of the given rules
|
64
|
+
def matches?(email_address, rules, config = {}, locale = "en")
|
65
|
+
Address.new(email_address, config, locale).matches?(rules)
|
66
|
+
end
|
72
67
|
end
|
73
68
|
end
|
@@ -1,23 +1,27 @@
|
|
1
|
-
|
2
|
-
require_relative '../test_helper'
|
1
|
+
require_relative "../test_helper"
|
3
2
|
|
4
3
|
class TestAR < MiniTest::Test
|
5
|
-
require_relative
|
4
|
+
require_relative "user"
|
6
5
|
|
7
6
|
def test_validation
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
# Disabled JRuby checks... weird CI failures. Hopefully someone can help?
|
8
|
+
if RUBY_PLATFORM != "java" # jruby
|
9
|
+
user = User.new(email: "Pat.Jones+ASDF#GMAIL.com")
|
10
|
+
assert_equal false, user.valid?
|
11
|
+
assert user.errors.messages[:email].first
|
12
|
+
user = User.new(email: "Pat.Jones+ASDF@GMAIL.com")
|
13
|
+
assert_equal true, user.valid?
|
14
|
+
end
|
13
15
|
end
|
14
16
|
|
15
17
|
def test_datatype
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
18
|
+
# Disabled JRuby checks... weird CI failures. Hopefully someone can help?
|
19
|
+
if RUBY_PLATFORM != "java" # jruby
|
20
|
+
if defined?(ActiveRecord) && ::ActiveRecord::VERSION::MAJOR >= 5
|
21
|
+
user = User.new(email: "Pat.Jones+ASDF@GMAIL.com")
|
22
|
+
assert_equal "pat.jones+asdf@gmail.com", user.email
|
23
|
+
assert_equal "patjones@gmail.com", user.canonical_email
|
24
|
+
end
|
20
25
|
end
|
21
26
|
end
|
22
|
-
|
23
27
|
end
|
data/test/activerecord/user.rb
CHANGED
@@ -6,35 +6,38 @@ class ApplicationRecord < ActiveRecord::Base
|
|
6
6
|
self.abstract_class = true
|
7
7
|
end
|
8
8
|
|
9
|
-
dbfile = ENV[
|
9
|
+
dbfile = ENV["EMAIL_ADDRESS_TEST_DB"] || "/tmp/email_address.gem.db"
|
10
10
|
File.unlink(dbfile) if File.exist?(dbfile)
|
11
11
|
|
12
12
|
# Connection: JRuby vs. MRI
|
13
|
-
|
14
|
-
|
15
|
-
require
|
16
|
-
require
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
13
|
+
# Disabled JRuby checks... weird CI failures. Hopefully someone can help?
|
14
|
+
if RUBY_PLATFORM == "java" # jruby
|
15
|
+
# require "jdbc/sqlite3"
|
16
|
+
# require "java"
|
17
|
+
# require "activerecord-jdbcsqlite3-adapter"
|
18
|
+
# Jdbc::SQLite3.load_driver
|
19
|
+
# ActiveRecord::Base.establish_connection(
|
20
|
+
# adapter: "jdbc",
|
21
|
+
# driver: "org.sqlite.JDBC",
|
22
|
+
# url: "jdbc:sqlite:" + dbfile
|
23
|
+
# )
|
23
24
|
else
|
24
|
-
require
|
25
|
+
require "sqlite3"
|
25
26
|
ActiveRecord::Base.establish_connection(
|
26
|
-
:
|
27
|
-
:
|
27
|
+
adapter: "sqlite3",
|
28
|
+
database: dbfile
|
28
29
|
)
|
29
|
-
end
|
30
30
|
|
31
|
-
|
32
|
-
|
31
|
+
# The following would be executed for both JRuby/MRI
|
32
|
+
ApplicationRecord.connection.execute(
|
33
|
+
"create table users ( email varchar, canonical_email varchar)"
|
34
|
+
)
|
33
35
|
|
34
|
-
if defined?(ActiveRecord) && ::ActiveRecord::VERSION::MAJOR >= 5
|
35
|
-
|
36
|
-
|
37
|
-
|
36
|
+
if defined?(ActiveRecord) && ::ActiveRecord::VERSION::MAJOR >= 5
|
37
|
+
ActiveRecord::Type.register(:email_address, EmailAddress::EmailAddressType)
|
38
|
+
ActiveRecord::Type.register(:canonical_email_address,
|
39
|
+
EmailAddress::CanonicalEmailAddressType)
|
40
|
+
end
|
38
41
|
end
|
39
42
|
|
40
43
|
################################################################################
|
@@ -42,30 +45,28 @@ end
|
|
42
45
|
################################################################################
|
43
46
|
|
44
47
|
class User < ApplicationRecord
|
45
|
-
|
46
48
|
if defined?(ActiveRecord) && ::ActiveRecord::VERSION::MAJOR >= 5
|
47
49
|
attribute :email, :email_address
|
48
50
|
attribute :canonical_email, :canonical_email_address
|
49
51
|
end
|
50
52
|
|
51
53
|
validates_with EmailAddress::ActiveRecordValidator,
|
52
|
-
fields: %i
|
54
|
+
fields: %i[email canonical_email]
|
53
55
|
|
54
56
|
def email=(email_address)
|
55
57
|
self[:canonical_email] = email_address
|
56
|
-
self[:email]
|
58
|
+
self[:email] = email_address
|
57
59
|
end
|
58
60
|
|
59
61
|
def self.find_by_email(email)
|
60
|
-
user
|
61
|
-
user ||=
|
62
|
-
user ||=
|
62
|
+
user = find_by(email: EmailAddress.normal(email))
|
63
|
+
user ||= find_by(canonical_email: EmailAddress.canonical(email))
|
64
|
+
user ||= find_by(canonical_email: EmailAddress.redacted(email))
|
63
65
|
user
|
64
66
|
end
|
65
67
|
|
66
68
|
def redact!
|
67
|
-
self[:canonical_email] = EmailAddress.redact(
|
68
|
-
self[:email]
|
69
|
+
self[:canonical_email] = EmailAddress.redact(canonical_email)
|
70
|
+
self[:email] = self[:canonical_email]
|
69
71
|
end
|
70
|
-
|
71
72
|
end
|
@@ -1,5 +1,4 @@
|
|
1
|
-
|
2
|
-
require_relative '../test_helper'
|
1
|
+
require_relative "../test_helper"
|
3
2
|
|
4
3
|
class TestAddress < Minitest::Test
|
5
4
|
def test_address
|
@@ -22,67 +21,131 @@ class TestAddress < Minitest::Test
|
|
22
21
|
def test_host
|
23
22
|
a = EmailAddress.new("User+tag@example.com")
|
24
23
|
assert_equal "example.com", a.hostname
|
25
|
-
#assert_equal :default, a.provider
|
24
|
+
# assert_equal :default, a.provider
|
26
25
|
end
|
27
26
|
|
28
27
|
# ADDRESS
|
29
28
|
def test_forms
|
30
29
|
a = EmailAddress.new("User+tag@example.com")
|
31
30
|
assert_equal "user+tag@example.com", a.to_s
|
31
|
+
assert_equal "user@example.com", a.base
|
32
32
|
assert_equal "user@example.com", a.canonical
|
33
33
|
assert_equal "{63a710569261a24b3766275b7000ce8d7b32e2f7}@example.com", a.redact
|
34
34
|
assert_equal "{b58996c504c5638798eb6b511e6f49af}@example.com", a.redact(:md5)
|
35
35
|
assert_equal "b58996c504c5638798eb6b511e6f49af", a.reference
|
36
|
+
assert_equal "6bdd00c53645790ad9bbcb50caa93880", EmailAddress.reference("Gmail.User+tag@gmail.com")
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_sha1
|
40
|
+
a = EmailAddress.new("User+tag@example.com")
|
41
|
+
assert_equal "63a710569261a24b3766275b7000ce8d7b32e2f7", a.sha1
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_sha1_with_secret
|
45
|
+
a = EmailAddress.new("User+tag@example.com", sha1_secret: "test-secret")
|
46
|
+
assert_equal "122df4ec3ce7121db6edc06a9e29eab39a7e8007", a.sha1
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_sha256
|
50
|
+
a = EmailAddress.new("User+tag@example.com")
|
51
|
+
assert_equal "b4c9a289323b21a01c3e940f150eb9b8c542587f1abfd8f0e1cc1ffc5e475514", a.sha256
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_sha256_with_secret
|
55
|
+
a = EmailAddress.new("User+tag@example.com", sha256_secret: "test-secret")
|
56
|
+
assert_equal "480899ff53ccd446cc123f0c5685869644af445e788f1b559054919674307a07", a.sha256
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_google_hosted
|
60
|
+
a = EmailAddress.new("Ex.am.ple+tag@boomer.com")
|
61
|
+
assert_equal a.canonical, "ex.am.ple@boomer.com"
|
36
62
|
end
|
37
63
|
|
38
64
|
# COMPARISON & MATCHING
|
39
65
|
def test_compare
|
40
|
-
a =
|
41
|
-
#e = EmailAddress.new("user@example.com")
|
66
|
+
a = "User+tag@example.com"
|
67
|
+
# e = EmailAddress.new("user@example.com")
|
42
68
|
n = EmailAddress.new(a)
|
43
69
|
c = EmailAddress.new_canonical(a)
|
44
|
-
#r = EmailAddress.new_redacted(a)
|
70
|
+
# r = EmailAddress.new_redacted(a)
|
45
71
|
assert_equal true, n == "user+tag@example.com"
|
46
|
-
assert_equal true, n >
|
72
|
+
assert_equal true, n > "b@example.com"
|
47
73
|
assert_equal true, n.same_as?(c)
|
48
74
|
assert_equal true, n.same_as?(a)
|
49
75
|
end
|
50
76
|
|
51
77
|
def test_matches
|
52
78
|
a = EmailAddress.new("User+tag@gmail.com")
|
53
|
-
assert_equal false,
|
54
|
-
assert_equal
|
55
|
-
assert_equal
|
56
|
-
assert_equal
|
79
|
+
assert_equal false, a.matches?("mail.com")
|
80
|
+
assert_equal "google", a.matches?("google")
|
81
|
+
assert_equal "user+tag@", a.matches?("user+tag@")
|
82
|
+
assert_equal "user*@gmail*", a.matches?("user*@gmail*")
|
57
83
|
end
|
58
84
|
|
59
85
|
def test_empty_address
|
60
86
|
a = EmailAddress.new("")
|
61
|
-
assert_equal "{
|
87
|
+
assert_equal "{9a78211436f6d425ec38f5c4e02270801f3524f8}", a.redact
|
62
88
|
assert_equal "", a.to_s
|
63
89
|
assert_equal "", a.canonical
|
64
|
-
assert_equal "
|
90
|
+
assert_equal "518ed29525738cebdac49c49e60ea9d3", a.reference
|
65
91
|
end
|
66
92
|
|
67
93
|
# VALIDATION
|
68
94
|
def test_valid
|
69
|
-
assert EmailAddress.valid?("User+tag@example.com",
|
70
|
-
assert !
|
71
|
-
assert EmailAddress.new("ɹᴉɐℲuǝll∀@ɹᴉɐℲuǝll∀.ws", local_encoding: :uncode,
|
95
|
+
assert EmailAddress.valid?("User+tag@example.com", host_validation: :a), "valid 1"
|
96
|
+
assert !EmailAddress.valid?("User%tag@example.com", host_validation: :a), "valid 2"
|
97
|
+
assert EmailAddress.new("ɹᴉɐℲuǝll∀@ɹᴉɐℲuǝll∀.ws", local_encoding: :uncode, host_validation: :syntax), "valid unicode"
|
72
98
|
end
|
73
99
|
|
74
|
-
def
|
75
|
-
e = EmailAddress.new("User+tag.gmail.ws")
|
76
|
-
assert_equal
|
100
|
+
def test_localhost
|
101
|
+
e = EmailAddress.new("User+tag.gmail.ws") # No domain means localhost
|
102
|
+
assert_equal "", e.hostname
|
77
103
|
assert_equal false, e.valid? # localhost not allowed by default
|
104
|
+
assert_equal EmailAddress.error("user1"), "Invalid Domain Name"
|
105
|
+
assert_equal EmailAddress.error("user1", host_local: true), "This domain is not configured to accept email"
|
106
|
+
assert_equal EmailAddress.error("user1@localhost", host_local: true), "This domain is not configured to accept email"
|
107
|
+
assert_nil EmailAddress.error("user2@localhost", host_local: true, dns_lookup: :off, host_validation: :syntax)
|
78
108
|
end
|
79
109
|
|
80
110
|
def test_regexen
|
81
111
|
assert "First.Last+TAG@example.com".match(EmailAddress::Address::CONVENTIONAL_REGEX)
|
82
112
|
assert "First.Last+TAG@example.com".match(EmailAddress::Address::STANDARD_REGEX)
|
83
|
-
|
84
|
-
|
113
|
+
assert_nil "First.Last+TAGexample.com".match(EmailAddress::Address::STANDARD_REGEX)
|
114
|
+
assert_nil "First#Last+TAGexample.com".match(EmailAddress::Address::CONVENTIONAL_REGEX)
|
85
115
|
assert "aasdf-34-.z@example.com".match(EmailAddress::Address::RELAXED_REGEX)
|
86
116
|
end
|
87
117
|
|
118
|
+
def test_srs
|
119
|
+
ea = "first.LAST+tag@gmail.com"
|
120
|
+
e = EmailAddress.new(ea)
|
121
|
+
s = e.srs("example.com")
|
122
|
+
assert s.match(EmailAddress::Address::SRS_FORMAT_REGEX)
|
123
|
+
assert EmailAddress.new(s).to_s == e.to_s
|
124
|
+
end
|
125
|
+
|
126
|
+
# Quick Regression tests for addresses that should have been valid (but fixed)
|
127
|
+
def test_issues
|
128
|
+
assert true, EmailAddress.valid?("test@jiff.com", dns_lookup: :mx) # #7
|
129
|
+
assert true, EmailAddress.valid?("w.-asdf-_@hotmail.com") # #8
|
130
|
+
assert true, EmailAddress.valid?("first_last@hotmail.com") # #8
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_issue9
|
134
|
+
assert !EmailAddress.valid?("example.user@foo.")
|
135
|
+
assert !EmailAddress.valid?("ogog@sss.c")
|
136
|
+
assert !EmailAddress.valid?("example.user@foo.com/")
|
137
|
+
end
|
138
|
+
|
139
|
+
def test_relaxed_normal
|
140
|
+
assert !EmailAddress.new("a.c.m.e.-industries@foo.com").valid?
|
141
|
+
assert true, EmailAddress.new("a.c.m.e.-industries@foo.com", local_format: :relaxed).valid?
|
142
|
+
end
|
143
|
+
|
144
|
+
def test_nil_address
|
145
|
+
assert_nil EmailAddress.new(nil).normal, "Expected a nil input to make nil output"
|
146
|
+
end
|
147
|
+
|
148
|
+
def test_nonstandard_tag
|
149
|
+
assert EmailAddress.valid?("asdfas+-@icloud.com")
|
150
|
+
end
|
88
151
|
end
|
@@ -1,28 +1,28 @@
|
|
1
|
-
require_relative
|
1
|
+
require_relative "../test_helper"
|
2
2
|
|
3
3
|
class TestConfig < MiniTest::Test
|
4
4
|
def test_setting
|
5
|
-
assert_equal :mx,
|
5
|
+
assert_equal :mx, EmailAddress::Config.setting(:dns_lookup)
|
6
6
|
assert_equal :off, EmailAddress::Config.setting(:dns_lookup, :off)
|
7
7
|
assert_equal :off, EmailAddress::Config.setting(:dns_lookup)
|
8
8
|
EmailAddress::Config.setting(:dns_lookup, :mx)
|
9
9
|
end
|
10
10
|
|
11
11
|
def test_configure
|
12
|
-
assert_equal :mx,
|
13
|
-
assert_equal true,
|
14
|
-
EmailAddress::Config.configure(local_downcase:false, dns_lookup: :off)
|
15
|
-
assert_equal :off,
|
12
|
+
assert_equal :mx, EmailAddress::Config.setting(:dns_lookup)
|
13
|
+
assert_equal true, EmailAddress::Config.setting(:local_downcase)
|
14
|
+
EmailAddress::Config.configure(local_downcase: false, dns_lookup: :off)
|
15
|
+
assert_equal :off, EmailAddress::Config.setting(:dns_lookup)
|
16
16
|
assert_equal false, EmailAddress::Config.setting(:local_downcase)
|
17
|
-
EmailAddress::Config.configure(local_downcase:true, dns_lookup: :mx)
|
17
|
+
EmailAddress::Config.configure(local_downcase: true, dns_lookup: :mx)
|
18
18
|
end
|
19
19
|
|
20
20
|
def test_provider
|
21
|
-
|
22
|
-
EmailAddress::Config.provider(:github, host_match: %w
|
21
|
+
assert_nil EmailAddress::Config.provider(:github)
|
22
|
+
EmailAddress::Config.provider(:github, host_match: %w[github.com], local_format: :standard)
|
23
23
|
assert_equal :standard, EmailAddress::Config.provider(:github)[:local_format]
|
24
24
|
assert_equal :github, EmailAddress::Host.new("github.com").provider
|
25
25
|
EmailAddress::Config.providers.delete(:github)
|
26
|
-
|
26
|
+
assert_nil EmailAddress::Config.provider(:github)
|
27
27
|
end
|
28
28
|
end
|
@@ -1,13 +1,12 @@
|
|
1
|
-
|
2
|
-
require_relative '../test_helper'
|
1
|
+
require_relative "../test_helper"
|
3
2
|
|
4
3
|
class TestExchanger < MiniTest::Test
|
5
4
|
def test_exchanger
|
6
5
|
e = EmailAddress::Exchanger.new("gmail.com")
|
7
6
|
assert_equal true, e.mxers.size > 1
|
8
7
|
assert_equal :google, e.provider
|
9
|
-
assert_equal
|
10
|
-
assert_equal
|
8
|
+
assert_equal "google.com", e.domains.first
|
9
|
+
assert_equal "google.com", e.matches?("google.com")
|
11
10
|
assert_equal false, e.matches?("fa00:1450:4013:c01::1a/16")
|
12
11
|
assert_equal false, e.matches?("127.0.0.1/24")
|
13
12
|
assert_equal true, e.mx_ips.size > 1
|
@@ -18,8 +17,8 @@ class TestExchanger < MiniTest::Test
|
|
18
17
|
assert_equal 0, e.mxers.size
|
19
18
|
end
|
20
19
|
|
21
|
-
|
22
|
-
#def test_dns
|
20
|
+
# assert_equal true, a.has_dns_a_record? # example.com has no MX'ers
|
21
|
+
# def test_dns
|
23
22
|
# good = EmailAddress::Exchanger.new("gmail.com")
|
24
23
|
# bad = EmailAddress::Exchanger.new("exampldkeie4iufe.com")
|
25
24
|
# assert_equal true, good.has_dns_a_record?
|
@@ -27,5 +26,5 @@ class TestExchanger < MiniTest::Test
|
|
27
26
|
# assert_equal "gmail.com", good.dns_a_record.first
|
28
27
|
# assert(/google.com\z/, good.mxers.first.first)
|
29
28
|
# #assert_equal 'google.com', good.domains.first
|
30
|
-
#end
|
29
|
+
# end
|
31
30
|
end
|
@@ -1,6 +1,4 @@
|
|
1
|
-
|
2
|
-
require_relative '../test_helper'
|
3
|
-
|
1
|
+
require_relative "../test_helper"
|
4
2
|
|
5
3
|
class TestHost < MiniTest::Test
|
6
4
|
def test_host
|
@@ -10,16 +8,16 @@ class TestHost < MiniTest::Test
|
|
10
8
|
assert_equal "example", a.registration_name
|
11
9
|
assert_equal "com", a.tld
|
12
10
|
assert_equal "ex*****", a.munge
|
13
|
-
|
11
|
+
assert_nil a.subdomains
|
14
12
|
end
|
15
|
-
|
13
|
+
|
16
14
|
def test_dns_enabled
|
17
15
|
a = EmailAddress::Host.new("example.com")
|
18
16
|
assert_instance_of TrueClass, a.dns_enabled?
|
19
|
-
|
20
|
-
|
17
|
+
a = EmailAddress::Host.new("example.com", host_validation: :syntax)
|
18
|
+
assert_instance_of FalseClass, a.dns_enabled?
|
19
|
+
a = EmailAddress::Host.new("example.com", dns_lookup: :off)
|
21
20
|
assert_instance_of FalseClass, a.dns_enabled?
|
22
|
-
EmailAddress::Config.configure(dns_lookup: old_setting)
|
23
21
|
end
|
24
22
|
|
25
23
|
def test_foreign_host
|
@@ -53,40 +51,54 @@ class TestHost < MiniTest::Test
|
|
53
51
|
|
54
52
|
def test_dmarc
|
55
53
|
d = EmailAddress::Host.new("yahoo.com").dmarc
|
56
|
-
assert_equal
|
54
|
+
assert_equal "reject", d[:p]
|
57
55
|
d = EmailAddress::Host.new("example.com").dmarc
|
58
56
|
assert_equal true, d.empty?
|
59
57
|
end
|
60
58
|
|
61
59
|
def test_ipv4
|
62
|
-
h = EmailAddress::Host.new("[127.0.0.1]", host_allow_ip:true)
|
60
|
+
h = EmailAddress::Host.new("[127.0.0.1]", host_allow_ip: true, host_local: true)
|
63
61
|
assert_equal "127.0.0.1", h.ip_address
|
64
62
|
assert_equal true, h.valid?
|
65
63
|
end
|
66
64
|
|
67
65
|
def test_ipv6
|
68
|
-
h = EmailAddress::Host.new("[IPv6:::1]", host_allow_ip:true)
|
66
|
+
h = EmailAddress::Host.new("[IPv6:::1]", host_allow_ip: true, host_local: true)
|
69
67
|
assert_equal "::1", h.ip_address
|
70
68
|
assert_equal true, h.valid?
|
71
69
|
end
|
72
70
|
|
73
71
|
def test_comment
|
74
72
|
h = EmailAddress::Host.new("(oops)gmail.com")
|
75
|
-
assert_equal
|
76
|
-
assert_equal
|
73
|
+
assert_equal "gmail.com", h.to_s
|
74
|
+
assert_equal "oops", h.comment
|
77
75
|
h = EmailAddress::Host.new("gmail.com(oops)")
|
78
|
-
assert_equal
|
79
|
-
assert_equal
|
76
|
+
assert_equal "gmail.com", h.to_s
|
77
|
+
assert_equal "oops", h.comment
|
80
78
|
end
|
81
79
|
|
82
80
|
def test_matches
|
83
81
|
h = EmailAddress::Host.new("yahoo.co.jp")
|
84
82
|
assert_equal false, h.matches?("gmail.com")
|
85
|
-
assert_equal
|
86
|
-
assert_equal
|
87
|
-
assert_equal
|
88
|
-
assert_equal
|
89
|
-
assert_equal
|
83
|
+
assert_equal "yahoo.co.jp", h.matches?("yahoo.co.jp")
|
84
|
+
assert_equal ".co.jp", h.matches?(".co.jp")
|
85
|
+
assert_equal ".jp", h.matches?(".jp")
|
86
|
+
assert_equal "yahoo.", h.matches?("yahoo.")
|
87
|
+
assert_equal "yah*.jp", h.matches?("yah*.jp")
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_ipv4_matches
|
91
|
+
h = EmailAddress::Host.new("[123.123.123.8]", host_allow_ip: true)
|
92
|
+
assert_equal "123.123.123.8", h.ip_address
|
93
|
+
assert_equal false, h.matches?("127.0.0.0/8")
|
94
|
+
assert_equal "123.123.123.0/24", h.matches?("123.123.123.0/24")
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_ipv6_matches
|
98
|
+
h = EmailAddress::Host.new("[IPV6:2001:db8::1]", host_allow_ip: true)
|
99
|
+
assert_equal "2001:db8::1", h.ip_address
|
100
|
+
assert_equal false, h.matches?("2002:db8::/118")
|
101
|
+
assert_equal "2001:db8::/118", h.matches?("2001:db8::/118")
|
90
102
|
end
|
91
103
|
|
92
104
|
def test_regexen
|
@@ -94,6 +106,32 @@ class TestHost < MiniTest::Test
|
|
94
106
|
assert "xn--5ca.com".match EmailAddress::Host::CANONICAL_HOST_REGEX
|
95
107
|
assert "[127.0.0.1]".match EmailAddress::Host::STANDARD_HOST_REGEX
|
96
108
|
assert "[IPv6:2001:dead::1]".match EmailAddress::Host::STANDARD_HOST_REGEX
|
97
|
-
|
109
|
+
assert_nil "[256.0.0.1]".match(EmailAddress::Host::STANDARD_HOST_REGEX)
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_hosted_service
|
113
|
+
assert EmailAddress.valid?("test@jiff.com", dns_lookup: :mx)
|
114
|
+
assert !EmailAddress.valid?("test@gmail.com", dns_lookup: :mx)
|
115
|
+
end
|
116
|
+
|
117
|
+
def test_yahoo_bad_tld
|
118
|
+
assert !EmailAddress.valid?("test@yahoo.badtld")
|
119
|
+
assert !EmailAddress.valid?("test@yahoo.wtf") # Registered, but MX IP = 0.0.0.0
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_bad_formats
|
123
|
+
assert !EmailAddress::Host.new("ya hoo.com").valid?
|
124
|
+
assert EmailAddress::Host.new("ya hoo.com", host_remove_spaces: true).valid?
|
125
|
+
end
|
126
|
+
|
127
|
+
def test_errors
|
128
|
+
assert_nil EmailAddress::Host.new("yahoo.com").error
|
129
|
+
assert_equal EmailAddress::Host.new("example.com").error, "This domain is not configured to accept email"
|
130
|
+
assert_equal EmailAddress::Host.new("yahoo.wtf").error, "Domain name not registered"
|
131
|
+
assert_nil EmailAddress::Host.new("ajsdfhajshdfklasjhd.wtf", host_validation: :syntax).error
|
132
|
+
assert_equal EmailAddress::Host.new("ya hoo.com", host_validation: :syntax).error, "Invalid Domain Name"
|
133
|
+
assert_equal EmailAddress::Host.new("[127.0.0.1]").error, "IP Addresses are not allowed"
|
134
|
+
assert_equal EmailAddress::Host.new("[127.0.0.666]", host_allow_ip: true).error, "This is not a valid IPv4 address"
|
135
|
+
assert_equal EmailAddress::Host.new("[IPv6::12t]", host_allow_ip: true).error, "This is not a valid IPv6 address"
|
98
136
|
end
|
99
137
|
end
|