email_address 0.0.3 → 0.1.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.
@@ -1,3 +1,3 @@
1
1
  module EmailAddress
2
- VERSION = "0.0.3"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -0,0 +1,22 @@
1
+ # encoding: UTF-8
2
+ require_relative '../test_helper'
3
+
4
+ class TestAR < MiniTest::Test
5
+ require_relative 'user.rb'
6
+
7
+ def test_validation
8
+ user = User.new(email:"Pat.Jones+ASDF#GMAIL.com")
9
+ assert_equal false, user.valid?
10
+ user = User.new(email:"Pat.Jones+ASDF@GMAIL.com")
11
+ assert_equal true, user.valid?
12
+ end
13
+
14
+ def test_datatype
15
+ if defined?(ActiveRecord) && ::ActiveRecord::VERSION::MAJOR >= 5
16
+ user = User.new(email:"Pat.Jones+ASDF@GMAIL.com")
17
+ assert_equal 'pat.jones+asdf@gmail.com', user.email
18
+ assert_equal 'patjones@gmail.com', user.canonical_email
19
+ end
20
+ end
21
+
22
+ end
@@ -0,0 +1,71 @@
1
+ ################################################################################
2
+ # ActiveRecord Test Setup ...
3
+ ################################################################################
4
+
5
+ class ApplicationRecord < ActiveRecord::Base
6
+ self.abstract_class = true
7
+ end
8
+
9
+ dbfile = ENV['EMAIL_ADDRESS_TEST_DB'] || "/tmp/email_address.gem.db"
10
+ File.unlink(dbfile) if File.exist?(dbfile)
11
+
12
+ # Connection: JRuby vs. MRI
13
+ if RUBY_PLATFORM == 'java' # jruby
14
+ require 'jdbc/sqlite3'
15
+ require 'java'
16
+ require 'activerecord-jdbcsqlite3-adapter'
17
+ Jdbc::SQLite3.load_driver
18
+ ActiveRecord::Base.establish_connection(
19
+ :adapter => 'jdbc',
20
+ :driver => "org.sqlite.JDBC",
21
+ :url => "jdbc:sqlite:" + dbfile
22
+ )
23
+ else
24
+ require 'sqlite3'
25
+ ActiveRecord::Base.establish_connection(
26
+ :adapter => 'sqlite3',
27
+ :database => dbfile
28
+ )
29
+ end
30
+
31
+ ApplicationRecord.connection.execute(
32
+ "create table users ( email varchar, canonical_email varchar)")
33
+
34
+ if defined?(ActiveRecord) && ::ActiveRecord::VERSION::MAJOR >= 5
35
+ ActiveRecord::Type.register(:email_address, EmailAddress::EmailAddressType)
36
+ ActiveRecord::Type.register(:canonical_email_address,
37
+ EmailAddress::CanonicalEmailAddressType)
38
+ end
39
+
40
+ ################################################################################
41
+ # User Model
42
+ ################################################################################
43
+
44
+ class User < ApplicationRecord
45
+
46
+ if defined?(ActiveRecord) && ::ActiveRecord::VERSION::MAJOR >= 5
47
+ attribute :email, :email_address
48
+ attribute :canonical_email, :canonical_email_address
49
+ end
50
+
51
+ validates_with EmailAddress::ActiveRecordValidator,
52
+ fields: %i(email canonical_email)
53
+
54
+ def email=(email_address)
55
+ self[:canonical_email] = email_address
56
+ self[:email] = email_address
57
+ end
58
+
59
+ def self.find_by_email(email)
60
+ user = self.find_by(email: EmailAddress.normal(email))
61
+ user ||= self.find_by(canonical_email: EmailAddress.canonical(email))
62
+ user ||= self.find_by(canonical_email: EmailAddress.redacted(email))
63
+ user
64
+ end
65
+
66
+ def redact!
67
+ self[:canonical_email] = EmailAddress.redact(self.canonical_email)
68
+ self[:email] = self[:canonical_email]
69
+ end
70
+
71
+ end
@@ -6,47 +6,73 @@ class TestAddress < Minitest::Test
6
6
  a = EmailAddress.new("User+tag@example.com")
7
7
  assert_equal "user+tag", a.local.to_s
8
8
  assert_equal "example.com", a.host.to_s
9
- assert_equal :unknown, a.provider
9
+ assert_equal "us*****@ex*****", a.munge
10
+ assert_equal :default, a.provider
10
11
  end
11
12
 
12
- def test_noramlize
13
- a = EmailAddress.new("User+tag@Example.com")
14
- assert_equal "user+tag@example.com", a.normalize
13
+ # LOCAL
14
+ def test_local
15
+ a = EmailAddress.new("User+tag@example.com")
16
+ assert_equal "user", a.mailbox
17
+ assert_equal "user+tag", a.left
18
+ assert_equal "tag", a.tag
19
+ end
20
+
21
+ # HOST
22
+ def test_host
23
+ a = EmailAddress.new("User+tag@example.com")
24
+ assert_equal "example.com", a.hostname
25
+ #assert_equal :default, a.provider
15
26
  end
16
27
 
17
- def test_canonical
18
- a = EmailAddress.new("User+tag@Example.com")
28
+ # ADDRESS
29
+ def test_forms
30
+ a = EmailAddress.new("User+tag@example.com")
31
+ assert_equal "user+tag@example.com", a.to_s
19
32
  assert_equal "user@example.com", a.canonical
20
- a = EmailAddress.new("first.last+tag@gmail.com")
21
- assert_equal "firstlast@gmail.com", a.canonical
33
+ assert_equal "{63a710569261a24b3766275b7000ce8d7b32e2f7}@example.com", a.redact
34
+ assert_equal "b58996c504c5638798eb6b511e6f49af", a.reference
35
+ end
36
+
37
+ # COMPARISON & MATCHING
38
+ def test_compare
39
+ a = ("User+tag@example.com")
40
+ #e = EmailAddress.new("user@example.com")
41
+ n = EmailAddress.new(a)
42
+ c = EmailAddress.new_canonical(a)
43
+ #r = EmailAddress.new_redacted(a)
44
+ assert_equal true, n == "user+tag@example.com"
45
+ assert_equal true, n > "b@example.com"
46
+ assert_equal true, n.same_as?(c)
47
+ assert_equal true, n.same_as?(a)
22
48
  end
23
49
 
24
- def test_digest
25
- a = EmailAddress.new("User+tag@Example.com")
26
- assert_equal "b58996c504c5638798eb6b511e6f49af", a.md5
27
- assert_equal "63a710569261a24b3766275b7000ce8d7b32e2f7", a.sha1
28
- assert_equal "63a710569261a24b3766275b7000ce8d7b32e2f7@example.com", a.redact
50
+ def test_matches
51
+ a = EmailAddress.new("User+tag@gmail.com")
52
+ assert_equal false, a.matches?('mail.com')
53
+ assert_equal 'google', a.matches?('google')
54
+ assert_equal 'user+tag@', a.matches?('user+tag@')
55
+ assert_equal 'user*@gmail*', a.matches?('user*@gmail*')
29
56
  end
30
57
 
31
- def test_idn
32
- a = EmailAddress.new("User+tag@ɹᴉɐℲuǝll∀.ws")
33
- assert_equal "user@xn--ull-6eb78cvh231oq7gdzb.ws", a.canonical
34
- assert_equal "9c06226d81149f59b4df32bb426c64a0cbafcea5@xn--ull-6eb78cvh231oq7gdzb.ws", a.redact
58
+ # VALIDATION
59
+ def test_valid
60
+ assert EmailAddress.valid?("User+tag@example.com", dns_lookup: :a), "valid 1"
61
+ assert ! EmailAddress.valid?("User%tag@example.com", dns_lookup: :a), "valid 2"
62
+ assert EmailAddress.new("ɹᴉɐℲuǝll∀@ɹᴉɐℲuǝll∀.ws", local_encoding: :uncode, dns_lookup: :off ), "valid unicode"
35
63
  end
36
64
 
37
65
  def test_no_domain
38
66
  e = EmailAddress.new("User+tag.gmail.ws")
39
- assert_equal false, e.valid?
67
+ assert_equal '', e.hostname
68
+ assert_equal false, e.valid? # localhost not allowed by default
40
69
  end
41
70
 
42
- def test_equality
43
- a = EmailAddress.new("User+tag@Example.com")
44
- b = EmailAddress.new("user@Example.com")
45
- c = EmailAddress.new( EmailAddress.new("USER@Example.com").redact)
46
- assert a != b
47
- assert a < b
48
- assert b > a
49
- assert a.same_as?(b)
50
- assert a.same_as?(c)
71
+ def test_regexen
72
+ assert "First.Last+TAG@example.com".match(EmailAddress::Address::CONVENTIONAL_REGEX)
73
+ assert "First.Last+TAG@example.com".match(EmailAddress::Address::STANDARD_REGEX)
74
+ assert_equal nil, "First.Last+TAGexample.com".match(EmailAddress::Address::STANDARD_REGEX)
75
+ assert_equal nil, "First#Last+TAGexample.com".match(EmailAddress::Address::CONVENTIONAL_REGEX)
51
76
  end
77
+
52
78
  end
@@ -1,13 +1,28 @@
1
1
  require_relative '../test_helper'
2
2
 
3
3
  class TestConfig < MiniTest::Test
4
- def test_setup
5
- EmailAddress::Config.setup do
6
- provider :disposable, domains:%w(mailenator)
7
- option :downcase_mailboxes, true
8
- end
9
- assert_equal true, EmailAddress::Config.providers.has_key?(:disposable)
10
- assert_equal true, EmailAddress::Config.options[:downcase_mailboxes]
4
+ def test_setting
5
+ assert_equal :mx, EmailAddress::Config.setting(:dns_lookup)
6
+ assert_equal :off, EmailAddress::Config.setting(:dns_lookup, :off)
7
+ assert_equal :off, EmailAddress::Config.setting(:dns_lookup)
8
+ EmailAddress::Config.setting(:dns_lookup, :mx)
9
+ end
10
+
11
+ def test_configure
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
+ assert_equal false, EmailAddress::Config.setting(:local_downcase)
17
+ EmailAddress::Config.configure(local_downcase:true, dns_lookup: :mx)
18
+ end
19
+
20
+ def test_provider
21
+ assert_equal nil, EmailAddress::Config.provider(:github)
22
+ EmailAddress::Config.provider(:github, host_match: %w(github.com), local_format: :standard)
23
+ assert_equal :standard, EmailAddress::Config.provider(:github)[:local_format]
24
+ assert_equal :github, EmailAddress::Host.new("github.com").provider
25
+ EmailAddress::Config.providers.delete(:github)
26
+ assert_equal nil, EmailAddress::Config.provider(:github)
11
27
  end
12
-
13
28
  end
@@ -3,17 +3,29 @@ require_relative '../test_helper'
3
3
 
4
4
  class TestExchanger < MiniTest::Test
5
5
  def test_exchanger
6
- a = EmailAddress::Exchanger.new("example.com")
7
- assert_equal true, a.has_dns_a_record? # example.com has no MX'ers
6
+ e = EmailAddress::Exchanger.new("gmail.com")
7
+ assert_equal true, e.mxers.size > 1
8
+ assert_equal :google, e.provider
9
+ assert_equal 'google.com', e.domains.first
10
+ assert_equal 'google.com', e.matches?("google.com")
11
+ assert_equal false, e.matches?("fa00:1450:4013:c01::1a/16")
12
+ assert_equal false, e.matches?("127.0.0.1/24")
13
+ assert_equal true, e.mx_ips.size > 1
8
14
  end
9
15
 
10
- def test_dns
11
- good = EmailAddress::Exchanger.new("gmail.com")
12
- bad = EmailAddress::Exchanger.new("exampldkeie4iufe.com")
13
- assert_equal true, good.has_dns_a_record?
14
- assert_equal false, bad.has_dns_a_record?
15
- assert_equal "gmail.com", good.dns_a_record.first
16
- assert(/google.com\z/, good.mxers.first.first)
17
- assert_equal 'google.com', good.domains.first
16
+ def test_not_found
17
+ e = EmailAddress::Exchanger.new("oops.gmail.com")
18
+ assert_equal 0, e.mxers.size
18
19
  end
20
+
21
+ #assert_equal true, a.has_dns_a_record? # example.com has no MX'ers
22
+ #def test_dns
23
+ # good = EmailAddress::Exchanger.new("gmail.com")
24
+ # bad = EmailAddress::Exchanger.new("exampldkeie4iufe.com")
25
+ # assert_equal true, good.has_dns_a_record?
26
+ # assert_equal false, bad.has_dns_a_record?
27
+ # assert_equal "gmail.com", good.dns_a_record.first
28
+ # assert(/google.com\z/, good.mxers.first.first)
29
+ # #assert_equal 'google.com', good.domains.first
30
+ #end
19
31
  end
@@ -9,7 +9,8 @@ class TestHost < MiniTest::Test
9
9
  assert_equal "example.com", a.domain_name
10
10
  assert_equal "example", a.registration_name
11
11
  assert_equal "com", a.tld
12
- assert_equal "", a.subdomains
12
+ assert_equal "ex*****", a.munge
13
+ assert_equal nil, a.subdomains
13
14
  end
14
15
 
15
16
  def test_foreign_host
@@ -17,27 +18,28 @@ class TestHost < MiniTest::Test
17
18
  assert_equal "my.yahoo.co.jp", a.host_name
18
19
  assert_equal "yahoo.co.jp", a.domain_name
19
20
  assert_equal "yahoo", a.registration_name
20
- assert_equal "co.jp", a.tld
21
+ assert_equal "co.jp", a.tld2
21
22
  assert_equal "my", a.subdomains
22
23
  end
23
24
 
24
25
  def test_ip_host
25
26
  a = EmailAddress::Host.new("[127.0.0.1]")
26
- assert_equal "[127.0.0.1]", a.host_name
27
+ assert_equal "[127.0.0.1]", a.name
27
28
  assert_equal "127.0.0.1", a.ip_address
28
-
29
29
  end
30
30
 
31
31
  def test_unicode_host
32
32
  a = EmailAddress::Host.new("å.com")
33
- assert_equal "xn--5ca.com", a.dns_host_name
33
+ assert_equal "xn--5ca.com", a.dns_name
34
+ a = EmailAddress::Host.new("xn--5ca.com", host_encoding: :unicode)
35
+ assert_equal "å.com", a.to_s
34
36
  end
35
37
 
36
38
  def test_provider
37
39
  a = EmailAddress::Host.new("my.yahoo.co.jp")
38
40
  assert_equal :yahoo, a.provider
39
41
  a = EmailAddress::Host.new("example.com")
40
- assert_equal :unknown, a.provider
42
+ assert_equal :default, a.provider
41
43
  end
42
44
 
43
45
  def test_dmarc
@@ -46,4 +48,43 @@ class TestHost < MiniTest::Test
46
48
  d = EmailAddress::Host.new("example.com").dmarc
47
49
  assert_equal true, d.empty?
48
50
  end
51
+
52
+ def test_ipv4
53
+ h = EmailAddress::Host.new("[127.0.0.1]", host_allow_ip:true)
54
+ assert_equal "127.0.0.1", h.ip_address
55
+ assert_equal true, h.valid?
56
+ end
57
+
58
+ def test_ipv6
59
+ h = EmailAddress::Host.new("[IPv6:::1]", host_allow_ip:true)
60
+ assert_equal "::1", h.ip_address
61
+ assert_equal true, h.valid?
62
+ end
63
+
64
+ def test_comment
65
+ h = EmailAddress::Host.new("(oops)gmail.com")
66
+ assert_equal 'gmail.com', h.to_s
67
+ assert_equal 'oops', h.comment
68
+ h = EmailAddress::Host.new("gmail.com(oops)")
69
+ assert_equal 'gmail.com', h.to_s
70
+ assert_equal 'oops', h.comment
71
+ end
72
+
73
+ def test_matches
74
+ h = EmailAddress::Host.new("yahoo.co.jp")
75
+ assert_equal false, h.matches?("gmail.com")
76
+ assert_equal 'yahoo.co.jp', h.matches?("yahoo.co.jp")
77
+ assert_equal '.co.jp', h.matches?(".co.jp")
78
+ assert_equal '.jp', h.matches?(".jp")
79
+ assert_equal 'yahoo.', h.matches?("yahoo.")
80
+ assert_equal 'yah*.jp', h.matches?("yah*.jp")
81
+ end
82
+
83
+ def test_regexen
84
+ assert "asdf.com".match EmailAddress::Host::CANONICAL_HOST_REGEX
85
+ assert "xn--5ca.com".match EmailAddress::Host::CANONICAL_HOST_REGEX
86
+ assert "[127.0.0.1]".match EmailAddress::Host::STANDARD_HOST_REGEX
87
+ assert "[IPv6:2001:dead::1]".match EmailAddress::Host::STANDARD_HOST_REGEX
88
+ assert_equal nil, "[256.0.0.1]".match(EmailAddress::Host::STANDARD_HOST_REGEX)
89
+ end
49
90
  end
@@ -2,30 +2,94 @@
2
2
  require_relative '../test_helper'
3
3
 
4
4
  class TestLocal < MiniTest::Test
5
- def test_local
6
- a = EmailAddress::Local.new("TestMonkey")
7
- assert_equal "testmonkey", a.to_s
5
+
6
+ def test_valid_standard
7
+ [ # Via https://en.wikipedia.org/wiki/Email_address
8
+ %Q{prettyandsimple},
9
+ %Q{very.common},
10
+ %Q{disposable.style.email.with+symbol},
11
+ %Q{other.email-with-dash},
12
+ %Q{"much.more unusual"},
13
+ %Q{"(comment)very.unusual.@.unusual.com"},
14
+ %Q{#!$%&'*+-/=?^_`{}|~},
15
+ %Q{" "},
16
+ %Q{"very.(),:;<>[]\\".VERY.\\"very@\\ \\"very\\".unusual"},
17
+ %Q{"()<>[]:,;@\\\"!#$%&'*+-/=?^_`{}| ~.a"},
18
+ %Q{token." ".token},
19
+ %Q{abc."defghi".xyz},
20
+ ].each do |local|
21
+ assert EmailAddress::Local.new(local, local_fix: false).standard?, local
22
+ end
23
+ end
24
+
25
+ def test_invalid_standard
26
+ [ # Via https://en.wikipedia.org/wiki/Email_address
27
+ %Q{A@b@c},
28
+ %Q{a"b(c)d,e:f;g<h>i[j\k]l},
29
+ %Q{just"not"right},
30
+ %Q{this is"not\allowed},
31
+ %Q{this\ still\"not\\allowed},
32
+ %Q{john..doe},
33
+ %Q{ invalid},
34
+ %Q{invalid },
35
+ %Q{abc"defghi"xyz},
36
+ ].each do |local|
37
+ assert_equal false, EmailAddress::Local.new(local, local_fix: false).standard?, local
38
+ end
39
+ end
40
+
41
+ def test_relaxed
42
+ assert EmailAddress::Local.new("first..last", local_format: :relaxed).valid?, "relax.."
43
+ assert EmailAddress::Local.new("first.-last", local_format: :relaxed).valid?, "relax.-"
44
+ assert EmailAddress::Local.new("a", local_format: :relaxed).valid?, "relax single"
45
+ assert ! EmailAddress::Local.new("firstlast_", local_format: :relaxed).valid?, "last_"
46
+ end
47
+
48
+ def test_unicode
49
+ assert ! EmailAddress::Local.new("üñîçøðé1", local_encoding: :ascii).standard?, "not üñîçøðé1"
50
+ assert EmailAddress::Local.new("üñîçøðé2", local_encoding: :unicode).standard?, "üñîçøðé2"
51
+ assert ! EmailAddress::Local.new("üñîçøðé3").valid?, "üñîçøðé3 valid"
8
52
  end
9
53
 
10
- def test_tag_comment
11
- a = EmailAddress::Local.new("User+tag(comment!)")
12
- assert_equal "user", a.mailbox
13
- assert_equal "comment!", a.comment
14
- assert_equal "tag", a.tag
54
+
55
+ def test_valid_conventional
56
+ %w( first.last first First+Tag o'brien).each do |local|
57
+ assert EmailAddress::Local.new(local).conventional?, local
58
+ end
59
+ end
60
+
61
+ def test_invalid_conventional
62
+ (%w( first;.last +leading trailing+ o%brien) + ["first space"]).each do |local|
63
+ assert ! EmailAddress::Local.new(local, local_fix:false).conventional?, local
64
+ end
65
+ end
66
+
67
+ def test_valid
68
+ assert_equal false, EmailAddress::Local.new("first(comment)", local_format: :conventional).valid?
69
+ assert_equal true, EmailAddress::Local.new("first(comment)", local_format: :standard).valid?
15
70
  end
16
71
 
17
72
  def test_format
18
- a = EmailAddress::Local.new("(Comment!)First Last+tag")
19
- assert_equal 'firstlast+tag', a.normalize
73
+ assert_equal :conventional, EmailAddress::Local.new("can1").format?
74
+ assert_equal :standard, EmailAddress::Local.new(%Q{"can1"}).format?
75
+ assert_equal "can1", EmailAddress::Local.new(%Q{"can1(commment)"}).format(:conventional)
20
76
  end
21
77
 
22
- def test_gmail
23
- a = EmailAddress::Local.new("first.last", EmailAddress::Host.new('gmail.com'))
24
- assert_equal "firstlast", a.canonical
78
+ def test_redacted
79
+ l = "{bea3f3560a757f8142d38d212a931237b218eb5e}"
80
+ assert EmailAddress::Local.redacted?(l), "redacted? #{l}"
81
+ assert_equal :redacted, EmailAddress::Local.new(l).format?
25
82
  end
26
83
 
27
- def test_root_name
28
- a = EmailAddress::Local.new("superman123", EmailAddress::Host.new('gmail.com'))
29
- assert_equal "superman", a.root_name
84
+ def test_matches
85
+ a = EmailAddress.new("User+tag@gmail.com")
86
+ assert_equal false, a.matches?('user')
87
+ assert_equal false, a.matches?('user@')
88
+ assert_equal 'user*@', a.matches?('user*@')
30
89
  end
90
+
91
+ def test_munge
92
+ assert_equal "us*****", EmailAddress::Local.new("User+tag").munge
93
+ end
94
+
31
95
  end