truemail 2.1.0 → 2.3.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.
@@ -24,13 +24,23 @@ module Truemail
24
24
 
25
25
  private
26
26
 
27
- def request
28
- smtp_results.last
27
+ def fail_fast?
28
+ configuration.smtp_fail_fast
29
+ end
30
+
31
+ def filtered_mail_servers_by_fail_fast_scenario
32
+ fail_fast? ? mail_servers.first(1) : mail_servers
29
33
  end
30
34
 
31
35
  def attempts
32
- @attempts ||=
33
- mail_servers.one? ? { attempts: configuration.connection_attempts } : {}
36
+ @attempts ||= begin
37
+ return {} if fail_fast? || !mail_servers.one?
38
+ { attempts: configuration.connection_attempts }
39
+ end
40
+ end
41
+
42
+ def request
43
+ smtp_results.last
34
44
  end
35
45
 
36
46
  def rcptto_error
@@ -38,7 +48,7 @@ module Truemail
38
48
  end
39
49
 
40
50
  def establish_smtp_connection
41
- mail_servers.each do |mail_server|
51
+ filtered_mail_servers_by_fail_fast_scenario.each do |mail_server|
42
52
  smtp_results << Truemail::Validate::Smtp::Request.new(
43
53
  configuration: configuration, host: mail_server, email: result.punycode_email, **attempts
44
54
  )
@@ -13,20 +13,24 @@ module Truemail
13
13
 
14
14
  attr_reader :configuration, :host, :email, :response
15
15
 
16
- def initialize(configuration:, host:, email:, attempts: nil)
16
+ def initialize(configuration:, host:, email:, attempts: nil, port_open_status: proc { true })
17
17
  @configuration = Truemail::Validate::Smtp::Request::Configuration.new(configuration)
18
18
  @response = Truemail::Validate::Smtp::Response.new
19
19
  @host = host
20
20
  @email = email
21
21
  @attempts = attempts
22
+ @port_open_status = port_open_status
22
23
  end
23
24
 
24
25
  def check_port
25
- Timeout.timeout(configuration.connection_timeout) do
26
- return response.port_opened = !TCPSocket.new(host, Truemail::Validate::Smtp::Request::SMTP_PORT).close
27
- end
26
+ response.port_opened = ::Socket.tcp(
27
+ host,
28
+ Truemail::Validate::Smtp::Request::SMTP_PORT,
29
+ connect_timeout: configuration.connection_timeout,
30
+ &port_open_status
31
+ )
28
32
  rescue => error
29
- retry if attempts_exist? && error.is_a?(Timeout::Error)
33
+ retry if attempts_exist? && error.is_a?(::Errno::ETIMEDOUT)
30
34
  response.port_opened = false
31
35
  end
32
36
 
@@ -53,7 +57,7 @@ module Truemail
53
57
  end
54
58
  end
55
59
 
56
- attr_reader :attempts
60
+ attr_reader :attempts, :port_open_status
57
61
 
58
62
  def attempts_exist?
59
63
  return false unless attempts
@@ -61,7 +65,7 @@ module Truemail
61
65
  end
62
66
 
63
67
  def session
64
- Net::SMTP.new(host, Truemail::Validate::Smtp::Request::SMTP_PORT).tap do |settings|
68
+ ::Net::SMTP.new(host, Truemail::Validate::Smtp::Request::SMTP_PORT).tap do |settings|
65
69
  settings.open_timeout = configuration.connection_timeout
66
70
  settings.read_timeout = configuration.response_timeout
67
71
  end
@@ -5,7 +5,7 @@ module Truemail
5
5
  class Smtp
6
6
  RESPONSE_ATTRS = %i[port_opened connection helo mailfrom rcptto errors].freeze
7
7
 
8
- Response = Struct.new(*RESPONSE_ATTRS, keyword_init: true) do
8
+ Response = ::Struct.new(*RESPONSE_ATTRS, keyword_init: true) do
9
9
  def initialize(errors: {}, **args)
10
10
  super
11
11
  end
@@ -5,13 +5,13 @@ module Truemail
5
5
  RESULT_ATTRS = %i[success email domain mail_servers errors smtp_debug configuration].freeze
6
6
  VALIDATION_TYPES = %i[regex mx smtp].freeze
7
7
 
8
- Result = Struct.new(*RESULT_ATTRS, keyword_init: true) do
8
+ Result = ::Struct.new(*RESULT_ATTRS, keyword_init: true) do
9
9
  def initialize(mail_servers: [], errors: {}, **args)
10
10
  super
11
11
  end
12
12
 
13
13
  def punycode_email
14
- @punycode_email ||= Truemail::PunycodeRepresenter.call(email)
14
+ @punycode_email ||= Truemail::Dns::PunycodeRepresenter.call(email)
15
15
  end
16
16
  alias_method :valid?, :success
17
17
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Truemail
4
- VERSION = '2.1.0'
4
+ VERSION = '2.3.0'
5
5
  end
@@ -15,10 +15,10 @@ module Truemail
15
15
  end
16
16
 
17
17
  def call(&block)
18
- Timeout.timeout(timeout, &block)
19
- rescue Resolv::ResolvError, IPAddr::InvalidAddressError
18
+ ::Timeout.timeout(timeout, &block)
19
+ rescue ::Resolv::ResolvError, ::IPAddr::InvalidAddressError
20
20
  false
21
- rescue Timeout::Error
21
+ rescue ::Timeout::Error
22
22
  retry unless (self.attempts -= 1).zero?
23
23
  false
24
24
  end
data/truemail.gemspec CHANGED
@@ -31,21 +31,23 @@ Gem::Specification.new do |spec|
31
31
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
32
32
  spec.require_paths = ['lib']
33
33
 
34
- spec.add_runtime_dependency 'simpleidn', '~> 0.1.1'
34
+ spec.add_runtime_dependency 'simpleidn', '~> 0.2.1'
35
35
 
36
36
  spec.add_development_dependency 'bundler', '~> 1.16'
37
37
  spec.add_development_dependency 'bundler-audit', '~> 0.7.0.1'
38
+ spec.add_development_dependency 'dns_mock', '~> 1.2'
39
+ spec.add_development_dependency 'faker', '~> 2.15', '>= 2.15.1'
38
40
  spec.add_development_dependency 'fasterer', '~> 0.8.3'
39
- spec.add_development_dependency 'ffaker', '~> 2.17'
40
41
  spec.add_development_dependency 'json_matchers', '~> 0.11.1'
41
42
  spec.add_development_dependency 'overcommit', '~> 0.57.0'
42
43
  spec.add_development_dependency 'pry-byebug', '~> 3.9'
43
- spec.add_development_dependency 'rake', '~> 13.0', '>= 13.0.1'
44
- spec.add_development_dependency 'reek', '~> 6.0', '>= 6.0.2'
44
+ spec.add_development_dependency 'rake', '~> 13.0', '>= 13.0.3'
45
+ spec.add_development_dependency 'reek', '~> 6.0', '>= 6.0.3'
45
46
  spec.add_development_dependency 'rspec', '~> 3.10'
46
- spec.add_development_dependency 'rubocop', '~> 1.3'
47
- spec.add_development_dependency 'rubocop-performance', '~> 1.8', '>= 1.8.1'
48
- spec.add_development_dependency 'rubocop-rspec', '~> 2.0'
47
+ spec.add_development_dependency 'rubocop', '~> 1.9', '>= 1.9.1'
48
+ spec.add_development_dependency 'rubocop-performance', '~> 1.9', '>= 1.9.2'
49
+ spec.add_development_dependency 'rubocop-rspec', '~> 2.2'
49
50
  spec.add_development_dependency 'simplecov', '~> 0.17.1'
50
- spec.add_development_dependency 'truemail-rspec', '~> 0.2.1'
51
+ spec.add_development_dependency 'truemail-rspec', '~> 0.3.3'
52
+ spec.add_development_dependency 'webmock', '~> 3.11', '>= 3.11.2'
51
53
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: truemail
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladislav Trotsenko
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-11-21 00:00:00.000000000 Z
11
+ date: 2021-02-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: simpleidn
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.1.1
19
+ version: 0.2.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.1.1
26
+ version: 0.2.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -53,33 +53,53 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: 0.7.0.1
55
55
  - !ruby/object:Gem::Dependency
56
- name: fasterer
56
+ name: dns_mock
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 0.8.3
61
+ version: '1.2'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 0.8.3
68
+ version: '1.2'
69
+ - !ruby/object:Gem::Dependency
70
+ name: faker
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '2.15'
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: 2.15.1
79
+ type: :development
80
+ prerelease: false
81
+ version_requirements: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - "~>"
84
+ - !ruby/object:Gem::Version
85
+ version: '2.15'
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: 2.15.1
69
89
  - !ruby/object:Gem::Dependency
70
- name: ffaker
90
+ name: fasterer
71
91
  requirement: !ruby/object:Gem::Requirement
72
92
  requirements:
73
93
  - - "~>"
74
94
  - !ruby/object:Gem::Version
75
- version: '2.17'
95
+ version: 0.8.3
76
96
  type: :development
77
97
  prerelease: false
78
98
  version_requirements: !ruby/object:Gem::Requirement
79
99
  requirements:
80
100
  - - "~>"
81
101
  - !ruby/object:Gem::Version
82
- version: '2.17'
102
+ version: 0.8.3
83
103
  - !ruby/object:Gem::Dependency
84
104
  name: json_matchers
85
105
  requirement: !ruby/object:Gem::Requirement
@@ -131,7 +151,7 @@ dependencies:
131
151
  version: '13.0'
132
152
  - - ">="
133
153
  - !ruby/object:Gem::Version
134
- version: 13.0.1
154
+ version: 13.0.3
135
155
  type: :development
136
156
  prerelease: false
137
157
  version_requirements: !ruby/object:Gem::Requirement
@@ -141,7 +161,7 @@ dependencies:
141
161
  version: '13.0'
142
162
  - - ">="
143
163
  - !ruby/object:Gem::Version
144
- version: 13.0.1
164
+ version: 13.0.3
145
165
  - !ruby/object:Gem::Dependency
146
166
  name: reek
147
167
  requirement: !ruby/object:Gem::Requirement
@@ -151,7 +171,7 @@ dependencies:
151
171
  version: '6.0'
152
172
  - - ">="
153
173
  - !ruby/object:Gem::Version
154
- version: 6.0.2
174
+ version: 6.0.3
155
175
  type: :development
156
176
  prerelease: false
157
177
  version_requirements: !ruby/object:Gem::Requirement
@@ -161,7 +181,7 @@ dependencies:
161
181
  version: '6.0'
162
182
  - - ">="
163
183
  - !ruby/object:Gem::Version
164
- version: 6.0.2
184
+ version: 6.0.3
165
185
  - !ruby/object:Gem::Dependency
166
186
  name: rspec
167
187
  requirement: !ruby/object:Gem::Requirement
@@ -182,48 +202,54 @@ dependencies:
182
202
  requirements:
183
203
  - - "~>"
184
204
  - !ruby/object:Gem::Version
185
- version: '1.3'
205
+ version: '1.9'
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: 1.9.1
186
209
  type: :development
187
210
  prerelease: false
188
211
  version_requirements: !ruby/object:Gem::Requirement
189
212
  requirements:
190
213
  - - "~>"
191
214
  - !ruby/object:Gem::Version
192
- version: '1.3'
215
+ version: '1.9'
216
+ - - ">="
217
+ - !ruby/object:Gem::Version
218
+ version: 1.9.1
193
219
  - !ruby/object:Gem::Dependency
194
220
  name: rubocop-performance
195
221
  requirement: !ruby/object:Gem::Requirement
196
222
  requirements:
197
223
  - - "~>"
198
224
  - !ruby/object:Gem::Version
199
- version: '1.8'
225
+ version: '1.9'
200
226
  - - ">="
201
227
  - !ruby/object:Gem::Version
202
- version: 1.8.1
228
+ version: 1.9.2
203
229
  type: :development
204
230
  prerelease: false
205
231
  version_requirements: !ruby/object:Gem::Requirement
206
232
  requirements:
207
233
  - - "~>"
208
234
  - !ruby/object:Gem::Version
209
- version: '1.8'
235
+ version: '1.9'
210
236
  - - ">="
211
237
  - !ruby/object:Gem::Version
212
- version: 1.8.1
238
+ version: 1.9.2
213
239
  - !ruby/object:Gem::Dependency
214
240
  name: rubocop-rspec
215
241
  requirement: !ruby/object:Gem::Requirement
216
242
  requirements:
217
243
  - - "~>"
218
244
  - !ruby/object:Gem::Version
219
- version: '2.0'
245
+ version: '2.2'
220
246
  type: :development
221
247
  prerelease: false
222
248
  version_requirements: !ruby/object:Gem::Requirement
223
249
  requirements:
224
250
  - - "~>"
225
251
  - !ruby/object:Gem::Version
226
- version: '2.0'
252
+ version: '2.2'
227
253
  - !ruby/object:Gem::Dependency
228
254
  name: simplecov
229
255
  requirement: !ruby/object:Gem::Requirement
@@ -244,14 +270,34 @@ dependencies:
244
270
  requirements:
245
271
  - - "~>"
246
272
  - !ruby/object:Gem::Version
247
- version: 0.2.1
273
+ version: 0.3.3
248
274
  type: :development
249
275
  prerelease: false
250
276
  version_requirements: !ruby/object:Gem::Requirement
251
277
  requirements:
252
278
  - - "~>"
253
279
  - !ruby/object:Gem::Version
254
- version: 0.2.1
280
+ version: 0.3.3
281
+ - !ruby/object:Gem::Dependency
282
+ name: webmock
283
+ requirement: !ruby/object:Gem::Requirement
284
+ requirements:
285
+ - - "~>"
286
+ - !ruby/object:Gem::Version
287
+ version: '3.11'
288
+ - - ">="
289
+ - !ruby/object:Gem::Version
290
+ version: 3.11.2
291
+ type: :development
292
+ prerelease: false
293
+ version_requirements: !ruby/object:Gem::Requirement
294
+ requirements:
295
+ - - "~>"
296
+ - !ruby/object:Gem::Version
297
+ version: '3.11'
298
+ - - ">="
299
+ - !ruby/object:Gem::Version
300
+ version: 3.11.2
255
301
  description: Configurable framework agnostic plain Ruby email validator. Verify email
256
302
  via Regex, DNS and SMTP.
257
303
  email:
@@ -293,6 +339,9 @@ files:
293
339
  - lib/truemail/auditor.rb
294
340
  - lib/truemail/configuration.rb
295
341
  - lib/truemail/core.rb
342
+ - lib/truemail/dns/punycode_representer.rb
343
+ - lib/truemail/dns/resolver.rb
344
+ - lib/truemail/dns/worker.rb
296
345
  - lib/truemail/executor.rb
297
346
  - lib/truemail/log/event.rb
298
347
  - lib/truemail/log/serializer/auditor_json.rb