Skip to content

Commit 63fa0fa

Browse files
committed
feat: detect subdomains 6 levels deep
1 parent 2819f87 commit 63fa0fa

File tree

2 files changed

+55
-4
lines changed

2 files changed

+55
-4
lines changed

lib/valid_email2/address.rb

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,16 @@ def domain_is_in?(domain_list)
117117
address_domain = address.domain.downcase
118118
return true if domain_list.include?(address_domain)
119119

120-
i = address_domain.index('.')
121-
return false unless i
120+
tokens = address_domain.split('.')
121+
return false if tokens.length < 3
122122

123-
domain_list.include?(address_domain[(i + 1)..-1])
123+
# check only 6 elements deep
124+
2.upto(6).each do |depth|
125+
limited_sub_domain_part = tokens.reverse.first(depth).reverse.join('.')
126+
return true if domain_list.include?(limited_sub_domain_part)
127+
end
128+
129+
false
124130
end
125131

126132
def mx_server_is_in?(domain_list)

spec/address_spec.rb

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,52 @@
5555

5656
it "is valid if it contains special scandinavian characters" do
5757
address = described_class.new("jørgen@email.dk")
58-
expect(address.valid?).to eq true
58+
expect(address.valid?).to be_truthy
59+
end
60+
end
61+
end
62+
63+
describe "#disposable_domain?" do
64+
context "when the disposable domain does not have subdomains" do
65+
let(:disposable_domain) { ValidEmail2.disposable_emails.select { |domain| domain.count(".") == 1 }.sample }
66+
67+
it "is true if the domain is in the disposable_emails list" do
68+
address = described_class.new("foo@#{disposable_domain}")
69+
expect(address.disposable_domain?).to be_truthy
70+
end
71+
72+
it "is true if the domain is a subdomain of a disposable domain" do
73+
address = described_class.new("foo@sub.#{disposable_domain}")
74+
expect(address.disposable_domain?).to be_truthy
75+
end
76+
77+
it "is true if the domain is a deeply nested subdomain of a disposable domain" do
78+
address = described_class.new("foo@sub3.sub2.sub1.#{disposable_domain}")
79+
expect(address.disposable_domain?).to be_truthy
80+
end
81+
82+
it "is false if the domain is not in the disposable_emails list" do
83+
address = described_class.new("foo@example.com")
84+
expect(address.disposable_domain?).to eq false
85+
end
86+
end
87+
88+
context "when the disposable domain has subdomains" do
89+
let(:disposable_domain) { ValidEmail2.disposable_emails.select { |domain| domain.count(".") > 1 }.sample }
90+
91+
it "is true if the domain is in the disposable_emails list" do
92+
address = described_class.new("foo@#{disposable_domain}")
93+
expect(address.disposable_domain?).to be_truthy
94+
end
95+
96+
it "is true if the domain is a subdomain of a disposable domain" do
97+
address = described_class.new("foo@sub.#{disposable_domain}")
98+
expect(address.disposable_domain?).to be_truthy
99+
end
100+
101+
it "is true if the domain is a deeply nested subdomain of a disposable domain" do
102+
address = described_class.new("foo@sub3.sub2.sub1.#{disposable_domain}")
103+
expect(address.disposable_domain?).to be_truthy
59104
end
60105
end
61106
end

0 commit comments

Comments
 (0)