email_validator 2.0.1 → 2.2.3
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 +4 -4
- data/CHANGELOG.md +106 -0
- data/README.md +181 -20
- data/lib/email_validator.rb +153 -18
- data/lib/email_validator/rfc.rb +4 -0
- data/lib/email_validator/strict.rb +2 -7
- data/spec/email_validator_spec.rb +989 -91
- data/spec/spec_helper.rb +12 -2
- metadata +18 -45
- data/.document +0 -5
- data/.gitignore +0 -22
- data/.travis.yml +0 -12
- data/Changes.md +0 -20
- data/Gemfile +0 -3
- data/Rakefile +0 -10
- data/email_validator.gemspec +0 -23
@@ -1,9 +1,4 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
ActiveSupport::Deprecation.warn(
|
4
|
-
'Strict mode has been deprecated in email_validator 2.0. You are receiving '\
|
5
|
-
'this warning because your project is requiring "email_validator/strict", '\
|
6
|
-
'most likely in your Gemfile.'
|
7
|
-
)
|
1
|
+
# require this file to enable `:strict` mode by default
|
8
2
|
|
9
3
|
require 'email_validator'
|
4
|
+
EmailValidator.default_options[:mode] = :strict
|
@@ -1,153 +1,1051 @@
|
|
1
|
-
# encoding: UTF-8
|
2
1
|
require 'spec_helper'
|
3
2
|
|
4
|
-
class
|
3
|
+
class DefaultUser < TestModel
|
5
4
|
validates :email, :email => true
|
6
5
|
end
|
7
6
|
|
8
|
-
class
|
9
|
-
validates :email, :email => {:
|
7
|
+
class StrictUser < TestModel
|
8
|
+
validates :email, :email => { :mode => :strict }
|
10
9
|
end
|
11
10
|
|
12
|
-
class
|
13
|
-
validates :email, :email => {:
|
11
|
+
class RfcUser < TestModel
|
12
|
+
validates :email, :email => { :mode => :rfc }
|
14
13
|
end
|
15
14
|
|
16
|
-
class
|
17
|
-
validates :
|
15
|
+
class AllowNilDefaultUser < TestModel
|
16
|
+
validates :email, :email => { :allow_nil => true }
|
18
17
|
end
|
19
18
|
|
20
|
-
|
19
|
+
class AllowNilStrictUser < TestModel
|
20
|
+
validates :email, :email => { :allow_nil => true, :mode => :strict }
|
21
|
+
end
|
22
|
+
|
23
|
+
class AllowNilRfcUser < TestModel
|
24
|
+
validates :email, :email => { :allow_nil => true, :mode => :rfc }
|
25
|
+
end
|
26
|
+
|
27
|
+
class DisallowNilDefaultUser < TestModel
|
28
|
+
validates :email, :email => { :allow_nil => false }
|
29
|
+
end
|
30
|
+
|
31
|
+
class DisallowNilStrictUser < TestModel
|
32
|
+
validates :email, :email => { :allow_nil => false, :mode => :strict }
|
33
|
+
end
|
34
|
+
|
35
|
+
class DisallowNilRfcUser < TestModel
|
36
|
+
validates :email, :email => { :allow_nil => false, :mode => :rfc }
|
37
|
+
end
|
38
|
+
|
39
|
+
class DomainStrictUser < TestModel
|
40
|
+
validates :email, :email => { :domain => 'example.com', :mode => :strict }
|
41
|
+
end
|
42
|
+
|
43
|
+
class DomainRfcUser < TestModel
|
44
|
+
validates :email, :email => { :domain => 'example.com', :mode => :rfc }
|
45
|
+
end
|
46
|
+
|
47
|
+
class NonFqdnStrictUser < TestModel
|
48
|
+
validates :email, :email => { :require_fqdn => false, :mode => :strict }
|
49
|
+
end
|
50
|
+
|
51
|
+
class NonFqdnRfcUser < TestModel
|
52
|
+
validates :email, :email => { :require_fqdn => false, :mode => :rfc }
|
53
|
+
end
|
54
|
+
|
55
|
+
class DefaultUserWithMessage < TestModel
|
56
|
+
validates :email_address, :email => { :message => 'is not looking very good!' }
|
57
|
+
end
|
58
|
+
|
59
|
+
RSpec.describe EmailValidator do
|
60
|
+
describe 'validation' do
|
61
|
+
valid_special_chars = {
|
62
|
+
:ampersand => '&',
|
63
|
+
:asterisk => '*',
|
64
|
+
:backtick => '`',
|
65
|
+
:braceleft => '{',
|
66
|
+
:braceright => '}',
|
67
|
+
:caret => '^',
|
68
|
+
:dollar => '$',
|
69
|
+
:equals => '=',
|
70
|
+
:exclaim => '!',
|
71
|
+
:hash => '#',
|
72
|
+
:hyphen => '-',
|
73
|
+
:percent => '%',
|
74
|
+
:plus => '+',
|
75
|
+
:pipe => '|',
|
76
|
+
:question => '?',
|
77
|
+
:quotedouble => '"',
|
78
|
+
:quotesingle => "'",
|
79
|
+
:slash => '/',
|
80
|
+
:tilde => '~',
|
81
|
+
:underscore => '_'
|
82
|
+
}
|
83
|
+
|
84
|
+
invalid_special_chars = {
|
85
|
+
:backslash => '\\',
|
86
|
+
:braketleft => '[',
|
87
|
+
:braketright => ']',
|
88
|
+
:colon => ':',
|
89
|
+
:comma => ',',
|
90
|
+
:greater => '>',
|
91
|
+
:lesser => '<',
|
92
|
+
:parenleft => '(',
|
93
|
+
:parenright => ')',
|
94
|
+
:semicolon => ';'
|
95
|
+
}
|
96
|
+
|
97
|
+
valid_includable = valid_special_chars.merge({ :dot => '.' })
|
98
|
+
valid_beginable = valid_special_chars
|
99
|
+
valid_endable = valid_special_chars
|
100
|
+
invalid_includable = { :at => '@' }
|
101
|
+
whitespace = { :newline => "\n", :tab => "\t", :carriage_return => "\r", :space => ' ' }
|
102
|
+
strictly_invalid_includable = invalid_special_chars
|
103
|
+
strictly_invalid_beginable = strictly_invalid_includable.merge({ :dot => '.' })
|
104
|
+
strictly_invalid_endable = strictly_invalid_beginable
|
105
|
+
domain_invalid_beginable = invalid_special_chars.merge(valid_special_chars)
|
106
|
+
domain_invalid_endable = domain_invalid_beginable
|
107
|
+
domain_invalid_includable = domain_invalid_beginable.reject { |k, _v| k == :hyphen }
|
108
|
+
|
109
|
+
# rubocop:disable Layout/BlockEndNewline, Layout/MultilineBlockLayout, Layout/MultilineMethodCallBraceLayout, Style/BlockDelimiters, Style/MultilineBlockChain
|
110
|
+
context 'when given the valid email' do
|
111
|
+
valid_includable.map { |k, v| [
|
112
|
+
"include-#{v}-#{k}@valid-characters-in-local.dev"
|
113
|
+
]}.concat(valid_beginable.map { |k, v| [
|
114
|
+
"#{v}start-with-#{k}@valid-characters-in-local.dev"
|
115
|
+
]}).concat(valid_endable.map { |k, v| [
|
116
|
+
"end-with-#{k}-#{v}@valid-characters-in-local.dev"
|
117
|
+
]}).concat([
|
118
|
+
'a+b@plus-in-local.com',
|
119
|
+
'a_b@underscore-in-local.com',
|
120
|
+
'user@example.com',
|
121
|
+
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@letters-in-local.dev',
|
122
|
+
'01234567890@numbers-in-local.dev',
|
123
|
+
'a@single-character-in-local.dev',
|
124
|
+
'one-character-third-level@a.example.com',
|
125
|
+
'single-character-in-sld@x.dev',
|
126
|
+
'local@dash-in-sld.com',
|
127
|
+
'numbers-in-sld@s123.com',
|
128
|
+
'one-letter-sld@x.dev',
|
129
|
+
'uncommon-tld@sld.museum',
|
130
|
+
'uncommon-tld@sld.travel',
|
131
|
+
'uncommon-tld@sld.mobi',
|
132
|
+
'country-code-tld@sld.uk',
|
133
|
+
'country-code-tld@sld.rw',
|
134
|
+
'local@sld.newTLD',
|
135
|
+
'local@sub.domains.com',
|
136
|
+
'aaa@bbb.co.jp',
|
137
|
+
'nigel.worthington@big.co.uk',
|
138
|
+
'f@c.com',
|
139
|
+
'f@s.c',
|
140
|
+
'someuser@somehost.somedomain',
|
141
|
+
'mixed-1234-in-{+^}-local@sld.dev',
|
142
|
+
'partially."quoted"@sld.com',
|
143
|
+
'areallylongnameaasdfasdfasdfasdf@asdfasdfasdfasdfasdf.ab.cd.ef.gh.co.ca',
|
144
|
+
'john.doe@2020.example.com',
|
145
|
+
'john.doe@2a.com',
|
146
|
+
'john.doe@a2.com',
|
147
|
+
'john.doe@2020.a-z.com',
|
148
|
+
'john.doe@2020.a2z.com',
|
149
|
+
'john.doe@2020.12345a6789.com',
|
150
|
+
'jonh.doe@163.com'
|
151
|
+
]).flatten.each do |email|
|
152
|
+
context 'when using defaults' do
|
153
|
+
it "'#{email}' should be valid" do
|
154
|
+
expect(DefaultUser.new(:email => email)).to be_valid
|
155
|
+
end
|
156
|
+
|
157
|
+
it "'#{email}' should be valid using EmailValidator.valid?" do
|
158
|
+
expect(described_class).to be_valid(email)
|
159
|
+
end
|
160
|
+
|
161
|
+
it "'#{email}' should not be invalid using EmailValidator.invalid?" do
|
162
|
+
expect(described_class).not_to be_invalid(email)
|
163
|
+
end
|
164
|
+
|
165
|
+
it "'#{email}' should match the regexp" do
|
166
|
+
expect(!!(email.strip =~ described_class.regexp)).to be(true)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
context 'when in `:strict` mode' do
|
171
|
+
it "'#{email}' should be valid" do
|
172
|
+
expect(StrictUser.new(:email => email)).to be_valid
|
173
|
+
end
|
174
|
+
|
175
|
+
it "'#{email}' should be valid using EmailValidator.valid?" do
|
176
|
+
expect(described_class).to be_valid(email, :mode => :strict)
|
177
|
+
end
|
178
|
+
|
179
|
+
it "'#{email}' should not be invalid using EmailValidator.valid?" do
|
180
|
+
expect(described_class).not_to be_invalid(email, :mode => :strict)
|
181
|
+
end
|
182
|
+
|
183
|
+
it "'#{email}' should match the regexp" do
|
184
|
+
expect(!!(email.strip =~ described_class.regexp(:mode => :strict))).to be(true)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
context 'when in `:rfc` mode' do
|
189
|
+
it "'#{email}' should be valid" do
|
190
|
+
expect(RfcUser.new(:email => email)).to be_valid
|
191
|
+
end
|
192
|
+
|
193
|
+
it "'#{email}' should be valid using EmailValidator.valid?" do
|
194
|
+
expect(described_class).to be_valid(email, :mode => :rfc)
|
195
|
+
end
|
196
|
+
|
197
|
+
it "'#{email}' should not be invalid using EmailValidator.invalid?" do
|
198
|
+
expect(described_class).not_to be_invalid(email, :mode => :rfc)
|
199
|
+
end
|
200
|
+
|
201
|
+
it "'#{email}' should match the regexp" do
|
202
|
+
expect(!!(email.strip =~ described_class.regexp(:mode => :rfc))).to be(true)
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
context 'when given the valid host-only email' do
|
209
|
+
[
|
210
|
+
'f@s',
|
211
|
+
'user@localhost',
|
212
|
+
'someuser@somehost'
|
213
|
+
].each do |email|
|
214
|
+
context 'when using defaults' do
|
215
|
+
it "'#{email}' should be valid" do
|
216
|
+
expect(DefaultUser.new(:email => email)).to be_valid
|
217
|
+
end
|
218
|
+
|
219
|
+
it "'#{email}' should be valid using EmailValidator.valid?" do
|
220
|
+
expect(described_class).to be_valid(email)
|
221
|
+
end
|
222
|
+
|
223
|
+
it "'#{email}' should not be invalid using EmailValidator.invalid?" do
|
224
|
+
expect(described_class).not_to be_invalid(email)
|
225
|
+
end
|
226
|
+
|
227
|
+
it "'#{email}' should match the regexp" do
|
228
|
+
expect(!!(email.strip =~ described_class.regexp)).to be(true)
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
context 'when in `:strict` mode' do
|
233
|
+
it "'#{email}' should not be valid" do
|
234
|
+
expect(StrictUser.new(:email => email)).not_to be_valid
|
235
|
+
end
|
236
|
+
|
237
|
+
it "'#{email}' should not be valid using EmailValidator.valid?" do
|
238
|
+
expect(described_class).not_to be_valid(email, :mode => :strict)
|
239
|
+
end
|
240
|
+
|
241
|
+
it "'#{email}' should be invalid using EmailValidator.invalid?" do
|
242
|
+
expect(described_class).to be_invalid(email, :mode => :strict)
|
243
|
+
end
|
244
|
+
|
245
|
+
it "'#{email}' should not match the regexp" do
|
246
|
+
expect(!!(email.strip =~ described_class.regexp(:mode => :strict))).to be(false)
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
context 'when in `:rfc` mode' do
|
251
|
+
it "'#{email}' should be valid" do
|
252
|
+
expect(RfcUser.new(:email => email)).to be_valid
|
253
|
+
end
|
254
|
+
|
255
|
+
it "'#{email}' should be valid using EmailValidator.valid?" do
|
256
|
+
expect(described_class).to be_valid(email, :mode => :rfc)
|
257
|
+
end
|
258
|
+
|
259
|
+
it "'#{email}' should not be invalid using EmailValidator.invalid?" do
|
260
|
+
expect(described_class).not_to be_invalid(email, :mode => :rfc)
|
261
|
+
end
|
262
|
+
|
263
|
+
it "'#{email}' should match the regexp" do
|
264
|
+
expect(!!(email.strip =~ described_class.regexp(:mode => :rfc))).to be(true)
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
context 'when given the numeric domain' do
|
271
|
+
[
|
272
|
+
'only-numbers-in-domain-label@sub.123.custom'
|
273
|
+
].each do |email|
|
274
|
+
context 'when using defaults' do
|
275
|
+
it "'#{email}' should be valid" do
|
276
|
+
expect(DefaultUser.new(:email => email)).to be_valid
|
277
|
+
end
|
278
|
+
|
279
|
+
it "'#{email}' should be valid using EmailValidator.valid?" do
|
280
|
+
expect(described_class).to be_valid(email)
|
281
|
+
end
|
21
282
|
|
22
|
-
|
23
|
-
|
283
|
+
it "'#{email}' should not be invalid using EmailValidator.invalid?" do
|
284
|
+
expect(described_class).not_to be_invalid(email)
|
285
|
+
end
|
286
|
+
|
287
|
+
it "'#{email}' should match the regexp" do
|
288
|
+
expect(!!(email.strip =~ described_class.regexp)).to be(true)
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
context 'when in `:strict` mode' do
|
293
|
+
it "'#{email}' should be valid" do
|
294
|
+
expect(StrictUser.new(:email => email)).to be_valid
|
295
|
+
end
|
296
|
+
|
297
|
+
it "'#{email}' should be valid using EmailValidator.valid?" do
|
298
|
+
expect(described_class).to be_valid(email, :mode => :strict)
|
299
|
+
end
|
300
|
+
|
301
|
+
it "'#{email}' should be not invalid using EmailValidator.invalid?" do
|
302
|
+
expect(described_class).not_to be_invalid(email, :mode => :strict)
|
303
|
+
end
|
304
|
+
|
305
|
+
it "'#{email}' should match the regexp" do
|
306
|
+
expect(!!(email.strip =~ described_class.regexp(:mode => :strict))).to be(true)
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
context 'when in `:rfc` mode' do
|
311
|
+
it "'#{email}' should be valid" do
|
312
|
+
expect(RfcUser.new(:email => email)).to be_valid
|
313
|
+
end
|
314
|
+
|
315
|
+
it "'#{email}' should be valid using EmailValidator.valid?" do
|
316
|
+
expect(described_class).to be_valid(email, :mode => :rfc)
|
317
|
+
end
|
318
|
+
|
319
|
+
it "'#{email}' should not be invalid using EmailValidator.invalid?" do
|
320
|
+
expect(described_class).not_to be_invalid(email, :mode => :rfc)
|
321
|
+
end
|
322
|
+
|
323
|
+
it "'#{email}' should match the regexp" do
|
324
|
+
expect(!!(email.strip =~ described_class.regexp(:mode => :rfc))).to be(true)
|
325
|
+
end
|
326
|
+
end
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
context 'when given the valid mailbox-only email' do
|
331
|
+
valid_includable.map { |k, v| [
|
332
|
+
"user-#{v}-#{k}-name"
|
333
|
+
]}.concat(valid_beginable.map { |k, v| [
|
334
|
+
"#{v}-start-with-#{k}-user"
|
335
|
+
]}).concat(valid_endable.map { |k, v| [
|
336
|
+
"end-with-#{k}-#{v}"
|
337
|
+
]}).concat([
|
338
|
+
'user'
|
339
|
+
]).flatten.each do |email|
|
340
|
+
context 'when using defaults' do
|
341
|
+
it "'#{email}' should not be valid" do
|
342
|
+
expect(DefaultUser.new(:email => email)).not_to be_valid
|
343
|
+
end
|
344
|
+
|
345
|
+
it "'#{email}' should not be valid using EmailValidator.valid?" do
|
346
|
+
expect(described_class).not_to be_valid(email)
|
347
|
+
end
|
348
|
+
|
349
|
+
it "'#{email}' should be invalid using EmailValidator.invalid?" do
|
350
|
+
expect(described_class).to be_invalid(email)
|
351
|
+
end
|
352
|
+
|
353
|
+
it "'#{email}' should not match the regexp" do
|
354
|
+
expect(!!(email.strip =~ described_class.regexp)).to be(false)
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
context 'when in `:strict` mode' do
|
359
|
+
it "'#{email}' should not be valid" do
|
360
|
+
expect(StrictUser.new(:email => email)).not_to be_valid
|
361
|
+
end
|
362
|
+
|
363
|
+
it "'#{email}' should not be valid using EmailValidator.valid?" do
|
364
|
+
expect(described_class).not_to be_valid(email, :mode => :strict)
|
365
|
+
end
|
366
|
+
|
367
|
+
it "'#{email}' should be invalid using EmailValidator.invalid?" do
|
368
|
+
expect(described_class).to be_invalid(email, :mode => :strict)
|
369
|
+
end
|
370
|
+
|
371
|
+
it "'#{email}' should not match the regexp" do
|
372
|
+
expect(!!(email.strip =~ described_class.regexp(:mode => :strict))).to be(false)
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
context 'when in `:rfc` mode' do
|
377
|
+
it "'#{email}' should be valid" do
|
378
|
+
expect(RfcUser.new(:email => email)).to be_valid
|
379
|
+
end
|
380
|
+
|
381
|
+
it "'#{email}' should be valid using EmailValidator.valid?" do
|
382
|
+
expect(described_class).to be_valid(email, :mode => :rfc)
|
383
|
+
end
|
384
|
+
|
385
|
+
it "'#{email}' should not be invalid using EmailValidator.invalid?" do
|
386
|
+
expect(described_class).not_to be_invalid(email, :mode => :rfc)
|
387
|
+
end
|
388
|
+
|
389
|
+
it "'#{email}' should match the regexp" do
|
390
|
+
expect(!!(email.strip =~ described_class.regexp(:mode => :rfc))).to be(true)
|
391
|
+
end
|
392
|
+
end
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
396
|
+
context 'when given the valid IP address email' do
|
24
397
|
[
|
25
|
-
|
26
|
-
|
27
|
-
"user@example.com",
|
28
|
-
" user@example.com ",
|
29
|
-
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@letters-in-local.org",
|
30
|
-
"01234567890@numbers-in-local.net",
|
31
|
-
"a@single-character-in-local.org",
|
32
|
-
"one-character-third-level@a.example.com",
|
33
|
-
"single-character-in-sld@x.org",
|
34
|
-
"local@dash-in-sld.com",
|
35
|
-
"letters-in-sld@123.com",
|
36
|
-
"one-letter-sld@x.org",
|
37
|
-
"uncommon-tld@sld.museum",
|
38
|
-
"uncommon-tld@sld.travel",
|
39
|
-
"uncommon-tld@sld.mobi",
|
40
|
-
"country-code-tld@sld.uk",
|
41
|
-
"country-code-tld@sld.rw",
|
42
|
-
"local@sld.newTLD",
|
43
|
-
"local@sub.domains.com",
|
44
|
-
"aaa@bbb.co.jp",
|
45
|
-
"nigel.worthington@big.co.uk",
|
46
|
-
"f@c.com",
|
47
|
-
"areallylongnameaasdfasdfasdfasdf@asdfasdfasdfasdfasdf.ab.cd.ef.gh.co.ca",
|
48
|
-
"ящик@яндекс.рф",
|
49
|
-
"test@test.testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttes",
|
50
|
-
"hans,peter@example.com",
|
51
|
-
"hans(peter@example.com",
|
52
|
-
"hans)peter@example.com",
|
53
|
-
"partially.\"quoted\"@sld.com",
|
54
|
-
"&'*+-./=?^_{}~@other-valid-characters-in-local.net",
|
55
|
-
"mixed-1234-in-{+^}-local@sld.net",
|
56
|
-
"user@domain.рф",
|
57
|
-
"寿司@example.com"
|
398
|
+
'bracketed-IP@[127.0.0.1]',
|
399
|
+
'bracketed-and-labeled-IPv6@[IPv6:abcd:ef01:1234:5678:9abc:def0:1234:5678]'
|
58
400
|
].each do |email|
|
401
|
+
context 'when using defaults' do
|
402
|
+
it "'#{email}' should be valid" do
|
403
|
+
expect(DefaultUser.new(:email => email)).to be_valid
|
404
|
+
end
|
405
|
+
|
406
|
+
it "'#{email}' should be valid using EmailValidator.valid?" do
|
407
|
+
expect(described_class).to be_valid(email)
|
408
|
+
end
|
59
409
|
|
60
|
-
|
61
|
-
|
410
|
+
it "'#{email}' should not be invalid using EmailValidator.invalid?" do
|
411
|
+
expect(described_class).not_to be_invalid(email)
|
412
|
+
end
|
413
|
+
|
414
|
+
it "'#{email}' should match the regexp" do
|
415
|
+
expect(!!(email.strip =~ described_class.regexp)).to be(true)
|
416
|
+
end
|
62
417
|
end
|
63
418
|
|
64
|
-
|
65
|
-
|
419
|
+
context 'when in `:strict` mode' do
|
420
|
+
it "'#{email}' should not be valid" do
|
421
|
+
expect(StrictUser.new(:email => email)).not_to be_valid
|
422
|
+
end
|
423
|
+
|
424
|
+
it "'#{email}' should not be valid using EmailValidator.valid?" do
|
425
|
+
expect(described_class).not_to be_valid(email, :mode => :strict)
|
426
|
+
end
|
427
|
+
|
428
|
+
it "'#{email}' should be invalid using EmailValidator.invalid?" do
|
429
|
+
expect(described_class).to be_invalid(email, :mode => :strict)
|
430
|
+
end
|
431
|
+
|
432
|
+
it "'#{email}' should not match the regexp" do
|
433
|
+
expect(!!(email.strip =~ described_class.regexp(:mode => :strict))).to be(false)
|
434
|
+
end
|
66
435
|
end
|
67
436
|
|
68
|
-
|
69
|
-
|
437
|
+
context 'when in `:rfc` mode' do
|
438
|
+
it "'#{email}' should be valid" do
|
439
|
+
expect(RfcUser.new(:email => email)).to be_valid
|
440
|
+
end
|
441
|
+
|
442
|
+
it "'#{email}' should be valid using EmailValidator.valid?" do
|
443
|
+
expect(described_class).to be_valid(email, :mode => :rfc)
|
444
|
+
end
|
445
|
+
|
446
|
+
it "'#{email}' should not be invalid using EmailValidator.invalid?" do
|
447
|
+
expect(described_class).not_to be_invalid(email, :mode => :rfc)
|
448
|
+
end
|
449
|
+
|
450
|
+
it "'#{email}' should match the regexp" do
|
451
|
+
expect(!!(email.strip =~ described_class.regexp(:mode => :rfc))).to be(true)
|
452
|
+
end
|
70
453
|
end
|
454
|
+
end
|
455
|
+
end
|
456
|
+
|
457
|
+
context 'when given the invalid email' do
|
458
|
+
invalid_includable.map { |k, v| [
|
459
|
+
"include-#{v}-#{k}@invalid-characters-in-local.dev"
|
460
|
+
]}.concat(domain_invalid_beginable.map { |k, v| [
|
461
|
+
"start-with-#{k}@#{v}invalid-characters-in-domain.dev"
|
462
|
+
]}).concat(domain_invalid_endable.map { |k, v| [
|
463
|
+
"end-with-#{k}@invalid-characters-in-domain#{v}.dev"
|
464
|
+
]}).concat(domain_invalid_includable.map { |k, v| [
|
465
|
+
"include-#{k}@invalid-characters-#{v}-in-domain.dev"
|
466
|
+
]}).concat([
|
467
|
+
'test@example.com@example.com',
|
468
|
+
'missing-sld@.com',
|
469
|
+
'missing-tld@sld.',
|
470
|
+
'unbracketed-IPv6@abcd:ef01:1234:5678:9abc:def0:1234:5678',
|
471
|
+
'unbracketed-and-labled-IPv6@IPv6:abcd:ef01:1234:5678:9abc:def0:1234:5678',
|
472
|
+
'bracketed-and-unlabeled-IPv6@[abcd:ef01:1234:5678:9abc:def0:1234:5678]',
|
473
|
+
'unbracketed-IPv4@127.0.0.1',
|
474
|
+
'invalid-IPv4@127.0.0.1.26',
|
475
|
+
'another-invalid-IPv4@127.0.0.256',
|
476
|
+
'IPv4-and-port@127.0.0.1:25',
|
477
|
+
'host-beginning-with-dot@.example.com',
|
478
|
+
'domain-beginning-with-dash@-example.com',
|
479
|
+
'domain-ending-with-dash@example-.com',
|
480
|
+
'domain-contains-double-dash@foo--example.com',
|
481
|
+
'the-local-part-is-invalid-if-it-is-longer-than-sixty-four-characters@sld.dev',
|
482
|
+
"domain-too-long@t#{".#{'o' * 63}" * 5}.long",
|
483
|
+
"user@example.com<script>alert('hello')</script>"
|
484
|
+
]).flatten.each do |email|
|
485
|
+
context 'when using defaults' do
|
486
|
+
it "'#{email}' should be valid" do
|
487
|
+
expect(DefaultUser.new(:email => email)).to be_valid
|
488
|
+
end
|
71
489
|
|
72
|
-
|
73
|
-
|
490
|
+
it "'#{email}' should be valid using EmailValidator.valid?" do
|
491
|
+
expect(described_class).to be_valid(email)
|
492
|
+
end
|
493
|
+
|
494
|
+
it "'#{email}' should not be invalid using EmailValidator.invalid?" do
|
495
|
+
expect(described_class).not_to be_invalid(email)
|
496
|
+
end
|
497
|
+
|
498
|
+
it "'#{email}' should match the regexp" do
|
499
|
+
expect(!!(email.strip =~ described_class.regexp)).to be(true)
|
500
|
+
end
|
74
501
|
end
|
75
502
|
|
503
|
+
context 'when in `:strict` mode' do
|
504
|
+
it "'#{email}' should not be valid" do
|
505
|
+
expect(StrictUser.new(:email => email)).not_to be_valid
|
506
|
+
end
|
507
|
+
|
508
|
+
it "'#{email}' should not be valid using EmailValidator.valid?" do
|
509
|
+
expect(described_class).not_to be_valid(email, :mode => :strict)
|
510
|
+
end
|
511
|
+
|
512
|
+
it "'#{email}' should be invalid using EmailValidator.invalid?" do
|
513
|
+
expect(described_class).to be_invalid(email, :mode => :strict)
|
514
|
+
end
|
515
|
+
|
516
|
+
it "'#{email}' should not match the regexp" do
|
517
|
+
expect(!!(email.strip =~ described_class.regexp(:mode => :strict))).to be(false)
|
518
|
+
end
|
519
|
+
end
|
520
|
+
|
521
|
+
context 'when in `:rfc` mode' do
|
522
|
+
it "'#{email}' should not be valid" do
|
523
|
+
expect(RfcUser.new(:email => email)).not_to be_valid
|
524
|
+
end
|
525
|
+
|
526
|
+
it "'#{email}' should not be valid using EmailValidator.valid?" do
|
527
|
+
expect(described_class).not_to be_valid(email, :mode => :rfc)
|
528
|
+
end
|
529
|
+
|
530
|
+
it "'#{email}' should be invalid using EmailValidator.invalid?" do
|
531
|
+
expect(described_class).to be_invalid(email, :mode => :rfc)
|
532
|
+
end
|
533
|
+
|
534
|
+
it "'#{email}' should not match the regexp" do
|
535
|
+
expect(!!(email.strip =~ described_class.regexp(:mode => :rfc))).to be(false)
|
536
|
+
end
|
537
|
+
end
|
76
538
|
end
|
539
|
+
end
|
540
|
+
|
541
|
+
context 'when given the invalid email with whitespace in parts' do
|
542
|
+
whitespace.map { |k, v| [
|
543
|
+
"include-#{v}-#{k}@invalid-characters-in-local.dev"
|
544
|
+
]}.concat([
|
545
|
+
'foo @bar.com',
|
546
|
+
"foo\t@bar.com",
|
547
|
+
"foo\n@bar.com",
|
548
|
+
"foo\r@bar.com",
|
549
|
+
'test@ example.com',
|
550
|
+
'user@example .com',
|
551
|
+
"user@example\t.com",
|
552
|
+
"user@example\n.com",
|
553
|
+
"user@example\r.com",
|
554
|
+
'user@exam ple.com',
|
555
|
+
"user@exam\tple.com",
|
556
|
+
"user@exam\nple.com",
|
557
|
+
"user@exam\rple.com",
|
558
|
+
'us er@example.com',
|
559
|
+
"us\ter@example.com",
|
560
|
+
"us\ner@example.com",
|
561
|
+
"us\rer@example.com",
|
562
|
+
"user@example.com\n<script>alert('hello')</script>",
|
563
|
+
"user@example.com\t<script>alert('hello')</script>",
|
564
|
+
"user@example.com\r<script>alert('hello')</script>",
|
565
|
+
"user@example.com <script>alert('hello')</script>",
|
566
|
+
' leading-whitespace@example.com',
|
567
|
+
'trailing-whitespace@example.com ',
|
568
|
+
' leading-and-trailing-whitespace@example.com ',
|
569
|
+
' user-with-leading-whitespace-space@example.com',
|
570
|
+
"\tuser-with-leading-whitespace-tab@example.com",
|
571
|
+
"
|
572
|
+
user-with-leading-whitespace-newline@example.com",
|
573
|
+
'domain-with-trailing-whitespace-space@example.com ',
|
574
|
+
"domain-with-trailing-whitespace-tab@example.com\t",
|
575
|
+
"domain-with-trailing-whitespace-newline@example.com
|
576
|
+
"
|
577
|
+
]).flatten.each do |email|
|
578
|
+
context 'when using defaults' do
|
579
|
+
it "'#{email}' should not be valid" do
|
580
|
+
expect(DefaultUser.new(:email => email)).not_to be_valid
|
581
|
+
end
|
582
|
+
|
583
|
+
it "'#{email}' should not be valid using EmailValidator.valid?" do
|
584
|
+
expect(described_class).not_to be_valid(email)
|
585
|
+
end
|
586
|
+
|
587
|
+
it "'#{email}' should be invalid using EmailValidator.invalid?" do
|
588
|
+
expect(described_class).to be_invalid(email)
|
589
|
+
end
|
590
|
+
|
591
|
+
it "'#{email}' should not match the regexp" do
|
592
|
+
expect(!!(email =~ described_class.regexp)).to be(false)
|
593
|
+
end
|
594
|
+
end
|
595
|
+
|
596
|
+
context 'when in `:strict` mode' do
|
597
|
+
it "'#{email}' should not be valid" do
|
598
|
+
expect(StrictUser.new(:email => email)).not_to be_valid
|
599
|
+
end
|
600
|
+
|
601
|
+
it "'#{email}' should not be valid using EmailValidator.valid?" do
|
602
|
+
expect(described_class).not_to be_valid(email, :mode => :strict)
|
603
|
+
end
|
77
604
|
|
605
|
+
it "'#{email}' should be invalid using EmailValidator.invalid?" do
|
606
|
+
expect(described_class).to be_invalid(email, :mode => :strict)
|
607
|
+
end
|
608
|
+
|
609
|
+
it "'#{email}' should not match the regexp" do
|
610
|
+
expect(!!(email =~ described_class.regexp(:mode => :strict))).to be(false)
|
611
|
+
end
|
612
|
+
end
|
613
|
+
|
614
|
+
context 'when in `:rfc` mode' do
|
615
|
+
it "'#{email}' should not be valid" do
|
616
|
+
expect(RfcUser.new(:email => email)).not_to be_valid
|
617
|
+
end
|
618
|
+
|
619
|
+
it "'#{email}' should not be valid using EmailValidator.valid?" do
|
620
|
+
expect(described_class).not_to be_valid(email, :mode => :rfc)
|
621
|
+
end
|
622
|
+
|
623
|
+
it "'#{email}' should be invalid using EmailValidator.invalid?" do
|
624
|
+
expect(described_class).to be_invalid(email, :mode => :rfc)
|
625
|
+
end
|
626
|
+
|
627
|
+
it "'#{email}' should not match the regexp" do
|
628
|
+
expect(!!(email =~ described_class.regexp(:mode => :rfc))).to be(false)
|
629
|
+
end
|
630
|
+
end
|
631
|
+
end
|
78
632
|
end
|
79
633
|
|
80
|
-
context
|
634
|
+
context 'when given the invalid email with missing parts' do
|
81
635
|
[
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
" ",
|
88
|
-
"missing-at-sign.net",
|
636
|
+
'',
|
637
|
+
'@bar.com',
|
638
|
+
'test@',
|
639
|
+
'@missing-local.dev',
|
640
|
+
' '
|
89
641
|
].each do |email|
|
642
|
+
context 'when using defaults' do
|
643
|
+
it "'#{email}' should not be valid" do
|
644
|
+
expect(DefaultUser.new(:email => email)).not_to be_valid
|
645
|
+
end
|
646
|
+
|
647
|
+
it "'#{email}' should not be valid using EmailValidator.valid?" do
|
648
|
+
expect(described_class).not_to be_valid(email)
|
649
|
+
end
|
650
|
+
|
651
|
+
it "'#{email}' should be invalid using EmailValidator.invalid?" do
|
652
|
+
expect(described_class).to be_invalid(email)
|
653
|
+
end
|
654
|
+
|
655
|
+
it "'#{email}' should not match the regexp" do
|
656
|
+
expect(!!(email.strip =~ described_class.regexp)).to be(false)
|
657
|
+
end
|
658
|
+
end
|
659
|
+
|
660
|
+
context 'when in `:strict` mode' do
|
661
|
+
it "'#{email}' should not be valid" do
|
662
|
+
expect(StrictUser.new(:email => email)).not_to be_valid
|
663
|
+
end
|
664
|
+
|
665
|
+
it "'#{email}' should not be valid using EmailValidator.valid?" do
|
666
|
+
expect(described_class).not_to be_valid(email, :mode => :strict)
|
667
|
+
end
|
668
|
+
|
669
|
+
it "'#{email}' should be invalid using EmailValidator.invalid?" do
|
670
|
+
expect(described_class).to be_invalid(email, :mode => :strict)
|
671
|
+
end
|
672
|
+
|
673
|
+
it "'#{email}' should not match the regexp" do
|
674
|
+
expect(!!(email.strip =~ described_class.regexp(:mode => :strict))).to be(false)
|
675
|
+
end
|
676
|
+
end
|
677
|
+
|
678
|
+
context 'when in `:rfc` mode' do
|
679
|
+
it "'#{email}' should not be valid" do
|
680
|
+
expect(RfcUser.new(:email => email)).not_to be_valid
|
681
|
+
end
|
682
|
+
|
683
|
+
it "'#{email}' should not be valid using EmailValidator.valid?" do
|
684
|
+
expect(described_class).not_to be_valid(email, :mode => :rfc)
|
685
|
+
end
|
686
|
+
|
687
|
+
it "'#{email}' should be invalid using EmailValidator.invalid?" do
|
688
|
+
expect(described_class).to be_invalid(email, :mode => :rfc)
|
689
|
+
end
|
690
|
+
|
691
|
+
it "'#{email}' should not match the regexp" do
|
692
|
+
expect(!!(email.strip =~ described_class.regexp(:mode => :rfc))).to be(false)
|
693
|
+
end
|
694
|
+
end
|
695
|
+
end
|
696
|
+
end
|
697
|
+
|
698
|
+
context 'when given the strictly invalid email' do
|
699
|
+
strictly_invalid_includable.map { |k, v| [
|
700
|
+
"include-#{v}-#{k}@invalid-characters-in-local.dev"
|
701
|
+
]}.concat(strictly_invalid_beginable.map { |k, v| [
|
702
|
+
"#{v}start-with-#{k}@invalid-characters-in-local.dev"
|
703
|
+
]}).concat(strictly_invalid_endable.map { |k, v| [
|
704
|
+
"end-with-#{k}#{v}@invalid-characters-in-local.dev"
|
705
|
+
]}).concat([
|
706
|
+
'user..-with-double-dots@example.com',
|
707
|
+
'.user-beginning-with-dot@example.com',
|
708
|
+
'user-ending-with-dot.@example.com',
|
709
|
+
'fully-numeric-tld@example.123'
|
710
|
+
]).flatten.each do |email|
|
711
|
+
context 'when using defaults' do
|
712
|
+
it "#{email.strip} in a model should be valid" do
|
713
|
+
expect(DefaultUser.new(:email => email)).to be_valid
|
714
|
+
end
|
715
|
+
|
716
|
+
it "#{email.strip} should be valid using EmailValidator.valid?" do
|
717
|
+
expect(described_class).to be_valid(email)
|
718
|
+
end
|
719
|
+
|
720
|
+
it "#{email.strip} should not be invalid using EmailValidator.invalid?" do
|
721
|
+
expect(described_class).not_to be_invalid(email)
|
722
|
+
end
|
723
|
+
|
724
|
+
it "#{email.strip} should match the regexp" do
|
725
|
+
expect(!!(email =~ described_class.regexp)).to be(true)
|
726
|
+
end
|
727
|
+
end
|
728
|
+
|
729
|
+
context 'when in `:strict` mode' do
|
730
|
+
it "#{email.strip} in a model should be valid" do
|
731
|
+
expect(StrictUser.new(:email => email)).not_to be_valid
|
732
|
+
end
|
733
|
+
|
734
|
+
it "#{email.strip} should not be valid using EmailValidator.valid?" do
|
735
|
+
expect(described_class).not_to be_valid(email, :mode => :strict)
|
736
|
+
end
|
737
|
+
|
738
|
+
it "#{email.strip} should be invalid using EmailValidator.invalid?" do
|
739
|
+
expect(described_class).to be_invalid(email, :mode => :strict)
|
740
|
+
end
|
741
|
+
|
742
|
+
it "#{email.strip} should not match the regexp" do
|
743
|
+
expect(!!(email =~ described_class.regexp(:mode => :strict))).to be(false)
|
744
|
+
end
|
745
|
+
end
|
746
|
+
|
747
|
+
context 'when in `:rfc` mode' do
|
748
|
+
it "#{email.strip} in a model should not be valid" do
|
749
|
+
expect(RfcUser.new(:email => email)).not_to be_valid
|
750
|
+
end
|
751
|
+
|
752
|
+
it "#{email.strip} should not be valid using EmailValidator.valid?" do
|
753
|
+
expect(described_class).not_to be_valid(email, :mode => :rfc)
|
754
|
+
end
|
755
|
+
|
756
|
+
it "#{email.strip} should be invalid using EmailValidator.invalid?" do
|
757
|
+
expect(described_class).to be_invalid(email, :mode => :rfc)
|
758
|
+
end
|
759
|
+
|
760
|
+
it "#{email.strip} should not match the regexp" do
|
761
|
+
expect(!!(email =~ described_class.regexp(:mode => :rfc))).to be(false)
|
762
|
+
end
|
763
|
+
end
|
764
|
+
end
|
765
|
+
end
|
766
|
+
|
767
|
+
context 'when `require_fqdn` is explicitly disabled' do
|
768
|
+
let(:opts) { { :require_fqdn => false } }
|
769
|
+
|
770
|
+
context 'when given a valid hostname-only email' do
|
771
|
+
let(:email) { 'someuser@somehost' }
|
772
|
+
|
773
|
+
context 'when using defaults' do
|
774
|
+
it 'is valid using EmailValidator.valid?' do
|
775
|
+
expect(described_class).to be_valid(email, opts)
|
776
|
+
end
|
777
|
+
|
778
|
+
it 'is not invalid using EmailValidator.invalid?' do
|
779
|
+
expect(described_class).not_to be_invalid(email, opts)
|
780
|
+
end
|
781
|
+
|
782
|
+
it 'matches the regexp' do
|
783
|
+
expect(!!(email =~ described_class.regexp(opts))).to be(true)
|
784
|
+
end
|
785
|
+
end
|
786
|
+
|
787
|
+
# Strict mode enables `require_fqdn` anyway
|
788
|
+
context 'when in `:strict` mode' do
|
789
|
+
let(:opts) { { :require_fqdn => false, :mode => :strict } }
|
790
|
+
|
791
|
+
it 'is not valid' do
|
792
|
+
expect(NonFqdnStrictUser.new(:email => email)).not_to be_valid
|
793
|
+
end
|
794
|
+
|
795
|
+
it 'is not valid using EmailValidator.valid?' do
|
796
|
+
expect(described_class).not_to be_valid(email, opts)
|
797
|
+
end
|
798
|
+
|
799
|
+
it 'is invalid using EmailValidator.invalid?' do
|
800
|
+
expect(described_class).to be_invalid(email, opts)
|
801
|
+
end
|
802
|
+
|
803
|
+
it 'matches the regexp' do
|
804
|
+
expect(!!(email =~ described_class.regexp(opts))).to be(false)
|
805
|
+
end
|
806
|
+
end
|
807
|
+
|
808
|
+
context 'when in `:rfc` mode' do
|
809
|
+
let(:opts) { { :require_fqdn => false, :mode => :rfc } }
|
810
|
+
|
811
|
+
it 'is valid' do
|
812
|
+
expect(NonFqdnRfcUser.new(:email => email)).to be_valid
|
813
|
+
end
|
814
|
+
|
815
|
+
it 'is valid using EmailValidator.valid?' do
|
816
|
+
expect(described_class).to be_valid(email, opts)
|
817
|
+
end
|
818
|
+
|
819
|
+
it 'is not invalid using EmailValidator.invalid?' do
|
820
|
+
expect(described_class).not_to be_invalid(email, opts)
|
821
|
+
end
|
822
|
+
|
823
|
+
it 'matches the regexp' do
|
824
|
+
expect(!!(email =~ described_class.regexp(opts))).to be(true)
|
825
|
+
end
|
826
|
+
end
|
827
|
+
end
|
828
|
+
|
829
|
+
context 'when given a valid email using an FQDN' do
|
830
|
+
let(:email) { 'someuser@somehost.somedomain' }
|
831
|
+
|
832
|
+
it 'is valid' do
|
833
|
+
expect(NonFqdnStrictUser.new(:email => email)).to be_valid
|
834
|
+
end
|
90
835
|
|
91
|
-
|
92
|
-
|
836
|
+
# rubocop:disable RSpec/PredicateMatcher
|
837
|
+
it 'is valid using EmailValidator.valid?' do
|
838
|
+
expect(described_class.valid?(email, opts)).to be(true)
|
93
839
|
end
|
94
840
|
|
95
|
-
it
|
96
|
-
expect(
|
841
|
+
it 'is not invalid using EmailValidator.invalid?' do
|
842
|
+
expect(described_class.invalid?(email, opts)).to be(false)
|
97
843
|
end
|
844
|
+
# rubocop:enable RSpec/PredicateMatcher
|
98
845
|
|
99
|
-
it
|
100
|
-
expect(email =~
|
846
|
+
it 'matches the regexp' do
|
847
|
+
expect(!!(email =~ described_class.regexp(opts))).to be(true)
|
101
848
|
end
|
102
849
|
|
103
|
-
|
104
|
-
|
850
|
+
context 'when in `:rfc` mode' do
|
851
|
+
let(:opts) { { :require_fqdn => false, :mode => :rfc } }
|
852
|
+
|
853
|
+
# rubocop:disable RSpec/PredicateMatcher
|
854
|
+
it 'is valid using EmailValidator.valid?' do
|
855
|
+
expect(described_class.valid?(email, opts)).to be(true)
|
856
|
+
end
|
857
|
+
|
858
|
+
it 'is not invalid using EmailValidator.invalid?' do
|
859
|
+
expect(described_class.invalid?(email, opts)).to be(false)
|
860
|
+
end
|
861
|
+
# rubocop:enable RSpec/PredicateMatcher
|
862
|
+
|
863
|
+
it 'is valid' do
|
864
|
+
expect(NonFqdnRfcUser.new(:email => email)).to be_valid
|
865
|
+
end
|
866
|
+
|
867
|
+
it 'matches the regexp' do
|
868
|
+
expect(!!(email =~ described_class.regexp(opts))).to be(true)
|
869
|
+
end
|
105
870
|
end
|
106
871
|
|
872
|
+
context 'when requiring a non-matching domain' do
|
873
|
+
let(:domain) { 'example.com' }
|
874
|
+
let(:opts) { { :domain => domain } }
|
875
|
+
|
876
|
+
it 'is not valid' do
|
877
|
+
expect(DomainStrictUser.new(:email => email)).not_to be_valid
|
878
|
+
end
|
879
|
+
|
880
|
+
it 'is not valid using EmailValidator.valid?' do
|
881
|
+
expect(described_class).not_to be_valid(email, opts)
|
882
|
+
end
|
883
|
+
|
884
|
+
it 'is invalid using EmailValidator.invalid?' do
|
885
|
+
expect(described_class).to be_invalid(email, opts)
|
886
|
+
end
|
887
|
+
|
888
|
+
it 'does not matches the regexp' do
|
889
|
+
expect(!!(email =~ described_class.regexp(opts))).to be(false)
|
890
|
+
end
|
891
|
+
|
892
|
+
context 'when in `:rfc` mode' do
|
893
|
+
let(:opts) { { :domain => domain, :require_fqdn => false, :mode => :rfc } }
|
894
|
+
|
895
|
+
it 'is not valid using EmailValidator.valid?' do
|
896
|
+
expect(described_class).not_to be_valid(email, opts)
|
897
|
+
end
|
898
|
+
|
899
|
+
it 'is invalid using EmailValidator.invalid?' do
|
900
|
+
expect(described_class).to be_invalid(email, opts)
|
901
|
+
end
|
902
|
+
|
903
|
+
it 'is not valid' do
|
904
|
+
expect(DomainRfcUser.new(:email => email)).not_to be_valid
|
905
|
+
end
|
906
|
+
|
907
|
+
it 'does not match the regexp' do
|
908
|
+
expect(!!(email =~ described_class.regexp(opts))).to be(false)
|
909
|
+
end
|
910
|
+
end
|
911
|
+
end
|
107
912
|
end
|
108
913
|
end
|
109
914
|
end
|
915
|
+
# rubocop:enable Layout/BlockEndNewline, Layout/MultilineBlockLayout, Layout/MultilineMethodCallBraceLayout, Style/BlockDelimiters, Style/MultilineBlockChain
|
916
|
+
|
917
|
+
describe 'error messages' do
|
918
|
+
context 'when the message is not defined' do
|
919
|
+
let(:model) { DefaultUser.new :email => 'invalidemail@' }
|
920
|
+
|
921
|
+
before { model.valid? }
|
922
|
+
|
923
|
+
it 'adds the default message' do
|
924
|
+
expect(model.errors[:email]).to include 'is invalid'
|
925
|
+
end
|
926
|
+
end
|
927
|
+
|
928
|
+
context 'when the message is defined' do
|
929
|
+
let(:model) { DefaultUserWithMessage.new :email_address => 'invalidemail@' }
|
930
|
+
|
931
|
+
before { model.valid? }
|
932
|
+
|
933
|
+
it 'adds the customized message' do
|
934
|
+
expect(model.errors[:email_address]).to include 'is not looking very good!'
|
935
|
+
end
|
936
|
+
end
|
937
|
+
end
|
938
|
+
|
939
|
+
describe 'nil email' do
|
940
|
+
it 'is not valid when :allow_nil option is missing' do
|
941
|
+
expect(DefaultUser.new(:email => nil)).not_to be_valid
|
942
|
+
end
|
943
|
+
|
944
|
+
it 'is valid when :allow_nil options is set to true' do
|
945
|
+
expect(AllowNilDefaultUser.new(:email => nil)).to be_valid
|
946
|
+
end
|
947
|
+
|
948
|
+
it 'is not valid when :allow_nil option is set to false' do
|
949
|
+
expect(DisallowNilDefaultUser.new(:email => nil)).not_to be_valid
|
950
|
+
end
|
951
|
+
end
|
952
|
+
|
953
|
+
describe 'limited to a domain' do
|
954
|
+
context 'when in `:strict` mode' do
|
955
|
+
it 'is not valid with mismatched domain' do
|
956
|
+
expect(DomainStrictUser.new(:email => 'user@not-matching.io')).not_to be_valid
|
957
|
+
end
|
110
958
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
before { subject.valid? }
|
959
|
+
it 'is valid with matching domain' do
|
960
|
+
expect(DomainStrictUser.new(:email => 'user@example.com')).to be_valid
|
961
|
+
end
|
115
962
|
|
116
|
-
it
|
117
|
-
expect(
|
963
|
+
it 'does not interpret the dot as any character' do
|
964
|
+
expect(DomainStrictUser.new(:email => 'user@example-com')).not_to be_valid
|
118
965
|
end
|
119
966
|
end
|
120
967
|
|
121
|
-
context
|
122
|
-
|
123
|
-
|
968
|
+
context 'when in `:rfc` mode' do
|
969
|
+
it 'does not interpret the dot as any character' do
|
970
|
+
expect(DomainRfcUser.new(:email => 'user@example-com')).not_to be_valid
|
971
|
+
end
|
972
|
+
|
973
|
+
it 'is valid with matching domain' do
|
974
|
+
expect(DomainRfcUser.new(:email => 'user@example.com')).to be_valid
|
975
|
+
end
|
124
976
|
|
125
|
-
it
|
126
|
-
expect(
|
977
|
+
it 'is not valid with mismatched domain' do
|
978
|
+
expect(DomainRfcUser.new(:email => 'user@not-matching.io')).not_to be_valid
|
127
979
|
end
|
128
980
|
end
|
129
981
|
end
|
130
982
|
|
131
|
-
describe
|
132
|
-
|
133
|
-
|
983
|
+
describe 'default_options' do
|
984
|
+
let(:valid_email) { 'valid-email@localhost.localdomain' }
|
985
|
+
let(:invalid_email) { 'invalid email@localhost.localdomain' }
|
134
986
|
|
135
|
-
it
|
136
|
-
expect(
|
987
|
+
it 'validates valid using `:loose` mode' do
|
988
|
+
expect(DefaultUser.new(:email => valid_email)).to be_valid
|
989
|
+
end
|
990
|
+
|
991
|
+
it 'invalidates invalid using `:loose` mode' do
|
992
|
+
expect(DefaultUser.new(:email => invalid_email)).to be_invalid
|
993
|
+
end
|
994
|
+
|
995
|
+
context 'when `email_validator/strict` has been required' do
|
996
|
+
before { require 'email_validator/strict' }
|
997
|
+
|
998
|
+
it 'validates valid using `:strict` mode' do
|
999
|
+
expect(DefaultUser.new(:email => valid_email)).to be_valid
|
1000
|
+
end
|
1001
|
+
|
1002
|
+
it 'invalidates invalid using `:strict` mode' do
|
1003
|
+
expect(DefaultUser.new(:email => invalid_email)).to be_invalid
|
1004
|
+
end
|
1005
|
+
end
|
1006
|
+
|
1007
|
+
context 'when `email_validator/rfc` has been required' do
|
1008
|
+
before { require 'email_validator/rfc' }
|
1009
|
+
|
1010
|
+
it 'validates valid using `:rfc` mode' do
|
1011
|
+
expect(DefaultUser.new(:email => valid_email)).to be_valid
|
1012
|
+
end
|
1013
|
+
|
1014
|
+
it 'invalidates invalid using `:rfc` mode' do
|
1015
|
+
expect(DefaultUser.new(:email => invalid_email)).to be_invalid
|
1016
|
+
end
|
137
1017
|
end
|
138
1018
|
end
|
139
1019
|
|
140
|
-
|
141
|
-
it
|
142
|
-
expect(
|
1020
|
+
context 'with regexp' do
|
1021
|
+
it 'returns a regexp when asked' do
|
1022
|
+
expect(described_class.regexp).to be_a(Regexp)
|
1023
|
+
end
|
1024
|
+
|
1025
|
+
it 'returns a strict regexp when asked' do
|
1026
|
+
expect(described_class.regexp(:mode => :strict)).to be_a(Regexp)
|
143
1027
|
end
|
144
1028
|
|
145
|
-
it
|
146
|
-
expect(
|
1029
|
+
it 'returns a RFC regexp when asked' do
|
1030
|
+
expect(described_class.regexp(:mode => :rfc)).to be_a(Regexp)
|
147
1031
|
end
|
148
1032
|
|
149
|
-
it
|
150
|
-
expect(
|
1033
|
+
it 'has different regexp for strict and loose' do
|
1034
|
+
expect(described_class.regexp(:mode => :strict)).not_to eq(described_class.regexp(:mode => :loose))
|
1035
|
+
end
|
1036
|
+
|
1037
|
+
it 'has different regexp for RFC and loose' do
|
1038
|
+
expect(described_class.regexp(:mode => :rfc)).not_to eq(described_class.regexp(:mode => :loose))
|
1039
|
+
end
|
1040
|
+
|
1041
|
+
it 'has different regexp for RFC and strict' do
|
1042
|
+
expect(described_class.regexp(:mode => :rfc)).not_to eq(described_class.regexp(:mode => :strict))
|
1043
|
+
end
|
1044
|
+
end
|
1045
|
+
|
1046
|
+
context 'with invalid `:mode`' do
|
1047
|
+
it 'raises an error' do
|
1048
|
+
expect { described_class.regexp(:mode => :invalid) }.to raise_error(EmailValidator::Error)
|
151
1049
|
end
|
152
1050
|
end
|
153
1051
|
end
|