dvdplm-ar_mailer 2.0.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.
@@ -0,0 +1,665 @@
1
+ require 'test/unit'
2
+ require 'action_mailer'
3
+ require 'action_mailer/ar_sendmail'
4
+ require 'rubygems'
5
+ require 'minitest/autorun'
6
+ require 'mocha'
7
+
8
+ class ActionMailer::ARSendmail
9
+ attr_accessor :slept
10
+ def sleep(secs)
11
+ @slept ||= []
12
+ @slept << secs
13
+ end
14
+ end
15
+
16
+ class TestARSendmail < MiniTest::Unit::TestCase
17
+
18
+ def setup
19
+ ActionMailer::Base.reset
20
+ Email.reset
21
+ Net::SMTP.reset
22
+
23
+ @sm = ActionMailer::ARSendmail.new
24
+ @sm.verbose = true
25
+
26
+ Net::SMTP.clear_on_start
27
+
28
+ @include_c_e = ! $".grep(/config\/environment.rb/).empty?
29
+ $" << 'config/environment.rb' unless @include_c_e
30
+ end
31
+
32
+ def teardown
33
+ $".delete 'config/environment.rb' unless @include_c_e
34
+ end
35
+
36
+ def test_class_create_migration
37
+ out, = capture_io do
38
+ ActionMailer::ARSendmail.create_migration 'Mail'
39
+ end
40
+
41
+ expected = <<-EOF
42
+ class CreateMail < ActiveRecord::Migration
43
+ def self.up
44
+ create_table :mail do |t|
45
+ t.column :from, :string
46
+ t.column :to, :string
47
+ t.column :last_send_attempt, :integer, :default => 0
48
+ t.column :mail, :text
49
+ t.column :created_on, :datetime
50
+ end
51
+ end
52
+
53
+ def self.down
54
+ drop_table :mail
55
+ end
56
+ end
57
+ EOF
58
+
59
+ assert_equal expected, out
60
+ end
61
+
62
+ def test_class_create_model
63
+ out, = capture_io do
64
+ ActionMailer::ARSendmail.create_model 'Mail'
65
+ end
66
+
67
+ expected = <<-EOF
68
+ class Mail < ActiveRecord::Base
69
+ end
70
+ EOF
71
+
72
+ assert_equal expected, out
73
+ end
74
+
75
+ def test_class_mailq
76
+ Email.create :from => nobody, :to => 'recip@h1.example.com',
77
+ :mail => 'body0'
78
+ Email.create :from => nobody, :to => 'recip@h1.example.com',
79
+ :mail => 'body1'
80
+ last = Email.create :from => nobody, :to => 'recip@h2.example.com',
81
+ :mail => 'body2'
82
+ last_attempt_time = Time.parse('Thu Aug 10 2006 11:40:05')
83
+ last.last_send_attempt = last_attempt_time.to_i
84
+
85
+ out, err = capture_io do
86
+ ActionMailer::ARSendmail.mailq 'Email'
87
+ end
88
+
89
+ expected = <<-EOF
90
+ -Queue ID- --Size-- ----Arrival Time---- -Sender/Recipient-------
91
+ 1 5 Thu Aug 10 11:19:49 nobody@example.com
92
+ recip@h1.example.com
93
+
94
+ 2 5 Thu Aug 10 11:19:50 nobody@example.com
95
+ recip@h1.example.com
96
+
97
+ 3 5 Thu Aug 10 11:19:51 nobody@example.com
98
+ Last send attempt: Thu Aug 10 11:40:05 %s 2006
99
+ recip@h2.example.com
100
+
101
+ -- 0 Kbytes in 3 Requests.
102
+ EOF
103
+
104
+ expected = expected % last_attempt_time.strftime('%z')
105
+ assert_equal expected, out
106
+ end
107
+
108
+ def test_class_mailq_empty
109
+ out, err = capture_io do
110
+ ActionMailer::ARSendmail.mailq 'Email'
111
+ end
112
+
113
+ assert_equal "Mail queue is empty\n", out
114
+ end
115
+
116
+ def test_class_new
117
+ @sm = ActionMailer::ARSendmail.new
118
+
119
+ assert_equal 60, @sm.delay
120
+ assert_equal Email, @sm.email_class
121
+ assert_equal nil, @sm.once
122
+ assert_equal nil, @sm.verbose
123
+ assert_equal nil, @sm.batch_size
124
+
125
+ @sm = ActionMailer::ARSendmail.new :Delay => 75, :Verbose => true,
126
+ :TableName => 'Object', :Once => true,
127
+ :BatchSize => 1000
128
+
129
+ assert_equal 75, @sm.delay
130
+ assert_equal Object, @sm.email_class
131
+ assert_equal true, @sm.once
132
+ assert_equal true, @sm.verbose
133
+ assert_equal 1000, @sm.batch_size
134
+ end
135
+
136
+ def test_class_parse_args_batch_size
137
+ options = ActionMailer::ARSendmail.process_args %w[-b 500]
138
+
139
+ assert_equal 500, options[:BatchSize]
140
+
141
+ options = ActionMailer::ARSendmail.process_args %w[--batch-size 500]
142
+
143
+ assert_equal 500, options[:BatchSize]
144
+ end
145
+
146
+ def test_class_parse_args_chdir
147
+ argv = %w[-c /tmp]
148
+
149
+ options = ActionMailer::ARSendmail.process_args argv
150
+
151
+ assert_equal '/tmp', options[:Chdir]
152
+
153
+ argv = %w[--chdir /tmp]
154
+
155
+ options = ActionMailer::ARSendmail.process_args argv
156
+
157
+ assert_equal '/tmp', options[:Chdir]
158
+
159
+ argv = %w[-c /nonexistent]
160
+
161
+ out, err = capture_io do
162
+ assert_raises SystemExit do
163
+ ActionMailer::ARSendmail.process_args argv
164
+ end
165
+ end
166
+ end
167
+
168
+ def test_class_parse_args_daemon
169
+ argv = %w[-d]
170
+
171
+ options = ActionMailer::ARSendmail.process_args argv
172
+
173
+ assert_equal true, options[:Daemon]
174
+
175
+ argv = %w[--daemon]
176
+
177
+ options = ActionMailer::ARSendmail.process_args argv
178
+
179
+ assert_equal true, options[:Daemon]
180
+ end
181
+
182
+ def test_class_parse_args_pidfile
183
+ argv = %w[-p ./log/ar_sendmail.pid]
184
+
185
+ options = ActionMailer::ARSendmail.process_args argv
186
+
187
+ assert_equal './log/ar_sendmail.pid', options[:Pidfile]
188
+
189
+ argv = %w[--pidfile ./log/ar_sendmail.pid]
190
+
191
+ options = ActionMailer::ARSendmail.process_args argv
192
+
193
+ assert_equal './log/ar_sendmail.pid', options[:Pidfile]
194
+ end
195
+
196
+ def test_class_parse_args_delay
197
+ argv = %w[--delay 75]
198
+
199
+ options = ActionMailer::ARSendmail.process_args argv
200
+
201
+ assert_equal 75, options[:Delay]
202
+ end
203
+
204
+ def test_class_parse_args_environment
205
+ assert_equal nil, ENV['RAILS_ENV']
206
+
207
+ argv = %w[-e production]
208
+
209
+ options = ActionMailer::ARSendmail.process_args argv
210
+
211
+ assert_equal 'production', options[:RailsEnv]
212
+
213
+ assert_equal 'production', ENV['RAILS_ENV']
214
+
215
+ argv = %w[--environment production]
216
+
217
+ options = ActionMailer::ARSendmail.process_args argv
218
+
219
+ assert_equal 'production', options[:RailsEnv]
220
+ end
221
+
222
+ def test_class_parse_args_mailq
223
+ options = ActionMailer::ARSendmail.process_args []
224
+ refute_includes options, :MailQ
225
+
226
+ argv = %w[--mailq]
227
+
228
+ options = ActionMailer::ARSendmail.process_args argv
229
+
230
+ assert_equal true, options[:MailQ]
231
+ end
232
+
233
+ def test_class_parse_args_max_age
234
+ options = ActionMailer::ARSendmail.process_args []
235
+ assert_equal 86400 * 7, options[:MaxAge]
236
+
237
+ argv = %w[--max-age 86400]
238
+
239
+ options = ActionMailer::ARSendmail.process_args argv
240
+
241
+ assert_equal 86400, options[:MaxAge]
242
+ end
243
+
244
+ def test_class_parse_args_migration
245
+ options = ActionMailer::ARSendmail.process_args []
246
+ refute_includes options, :Migration
247
+
248
+ argv = %w[--create-migration]
249
+
250
+ options = ActionMailer::ARSendmail.process_args argv
251
+
252
+ assert_equal true, options[:Migrate]
253
+ end
254
+
255
+ def test_class_parse_args_model
256
+ options = ActionMailer::ARSendmail.process_args []
257
+ refute_includes options, :Model
258
+
259
+ argv = %w[--create-model]
260
+
261
+ options = ActionMailer::ARSendmail.process_args argv
262
+
263
+ assert_equal true, options[:Model]
264
+ end
265
+
266
+ def test_class_parse_args_no_config_environment
267
+ $".delete 'config/environment.rb'
268
+
269
+ out, err = capture_io do
270
+ assert_raises SystemExit do
271
+ ActionMailer::ARSendmail.process_args []
272
+ end
273
+ end
274
+
275
+ ensure
276
+ $" << 'config/environment.rb' if @include_c_e
277
+ end
278
+
279
+ def test_class_parse_args_no_config_environment_migrate
280
+ $".delete 'config/environment.rb'
281
+
282
+ out, err = capture_io do
283
+ ActionMailer::ARSendmail.process_args %w[--create-migration]
284
+ end
285
+
286
+ assert true # count
287
+
288
+ ensure
289
+ $" << 'config/environment.rb' if @include_c_e
290
+ end
291
+
292
+ def test_class_parse_args_no_config_environment_model
293
+ $".delete 'config/environment.rb'
294
+
295
+ out, err = capture_io do
296
+ ActionMailer::ARSendmail.process_args %w[--create-model]
297
+ end
298
+
299
+ assert true # count
300
+
301
+ rescue SystemExit
302
+ flunk 'Should not exit'
303
+
304
+ ensure
305
+ $" << 'config/environment.rb' if @include_c_e
306
+ end
307
+
308
+ def test_class_parse_args_once
309
+ argv = %w[-o]
310
+
311
+ options = ActionMailer::ARSendmail.process_args argv
312
+
313
+ assert_equal true, options[:Once]
314
+
315
+ argv = %w[--once]
316
+
317
+ options = ActionMailer::ARSendmail.process_args argv
318
+
319
+ assert_equal true, options[:Once]
320
+ end
321
+
322
+ def test_class_parse_args_table_name
323
+ argv = %w[-t Email]
324
+
325
+ options = ActionMailer::ARSendmail.process_args argv
326
+
327
+ assert_equal 'Email', options[:TableName]
328
+
329
+ argv = %w[--table-name=Email]
330
+
331
+ options = ActionMailer::ARSendmail.process_args argv
332
+
333
+ assert_equal 'Email', options[:TableName]
334
+ end
335
+
336
+ def test_class_usage
337
+ out, err = capture_io do
338
+ assert_raises SystemExit do
339
+ ActionMailer::ARSendmail.usage 'opts'
340
+ end
341
+ end
342
+
343
+ assert_equal '', out
344
+ assert_equal "opts\n", err
345
+
346
+ out, err = capture_io do
347
+ assert_raises SystemExit do
348
+ ActionMailer::ARSendmail.usage 'opts', 'hi'
349
+ end
350
+ end
351
+
352
+ assert_equal '', out
353
+ assert_equal "hi\n\nopts\n", err
354
+ end
355
+
356
+ def test_cleanup
357
+ e1 = Email.create :mail => 'body', :to => 'to', :from => 'from'
358
+ e1.created_on = Time.now
359
+ e2 = Email.create :mail => 'body', :to => 'to', :from => 'from'
360
+ e3 = Email.create :mail => 'body', :to => 'to', :from => 'from'
361
+ e3.last_send_attempt = Time.now
362
+
363
+ out, err = capture_io do
364
+ @sm.cleanup
365
+ end
366
+
367
+ assert_equal '', out
368
+ assert_equal "expired 1 emails from the queue\n", err
369
+ assert_equal 2, Email.records.length
370
+
371
+ assert_equal [e1, e2], Email.records
372
+ end
373
+
374
+ def test_cleanup_disabled
375
+ e1 = Email.create :mail => 'body', :to => 'to', :from => 'from'
376
+ e1.created_on = Time.now
377
+ e2 = Email.create :mail => 'body', :to => 'to', :from => 'from'
378
+
379
+ @sm.max_age = 0
380
+
381
+ out, err = capture_io do
382
+ @sm.cleanup
383
+ end
384
+
385
+ assert_equal '', out
386
+ assert_equal 2, Email.records.length
387
+ end
388
+
389
+ def test_deliver
390
+ email = Email.create :mail => 'body', :to => 'to', :from => 'from'
391
+
392
+ out, err = capture_io do
393
+ @sm.deliver [email]
394
+ end
395
+
396
+ assert_equal 1, Net::SMTP.deliveries.length
397
+ assert_equal ['body', 'from', 'to'], Net::SMTP.deliveries.first
398
+ assert_equal 0, Email.records.length
399
+ assert_equal 0, Net::SMTP.reset_called, 'Reset connection on SyntaxError'
400
+
401
+ assert_equal '', out
402
+ assert_equal "sent email 00000000001 from from to to: \"queued\"\n", err
403
+ end
404
+
405
+ def test_deliver_not_called_when_no_emails
406
+ sm = ActionMailer::ARSendmail.new({:Once => true})
407
+ sm.expects(:deliver).never
408
+ sm.run
409
+ end
410
+
411
+ def test_deliver_auth_error
412
+ Net::SMTP.on_start do
413
+ e = Net::SMTPAuthenticationError.new 'try again'
414
+ e.set_backtrace %w[one two three]
415
+ raise e
416
+ end
417
+
418
+ now = Time.now.to_i
419
+
420
+ email = Email.create :mail => 'body', :to => 'to', :from => 'from'
421
+
422
+ out, err = capture_io do
423
+ @sm.deliver [email]
424
+ end
425
+
426
+ assert_equal 0, Net::SMTP.deliveries.length
427
+ assert_equal 1, Email.records.length
428
+ assert_equal 0, Email.records.first.last_send_attempt
429
+ assert_equal 0, Net::SMTP.reset_called
430
+ assert_equal 1, @sm.failed_auth_count
431
+ assert_equal [60], @sm.slept
432
+
433
+ assert_equal '', out
434
+ assert_equal "authentication error, retrying: try again\n", err
435
+ end
436
+
437
+ def test_deliver_auth_error_recover
438
+ email = Email.create :mail => 'body', :to => 'to', :from => 'from'
439
+ @sm.failed_auth_count = 1
440
+
441
+ out, err = capture_io do @sm.deliver [email] end
442
+
443
+ assert_equal 0, @sm.failed_auth_count
444
+ assert_equal 1, Net::SMTP.deliveries.length
445
+ end
446
+
447
+ def test_deliver_auth_error_twice
448
+ Net::SMTP.on_start do
449
+ e = Net::SMTPAuthenticationError.new 'try again'
450
+ e.set_backtrace %w[one two three]
451
+ raise e
452
+ end
453
+
454
+ @sm.failed_auth_count = 1
455
+
456
+ out, err = capture_io do
457
+ assert_raises Net::SMTPAuthenticationError do
458
+ @sm.deliver []
459
+ end
460
+ end
461
+
462
+ assert_equal 2, @sm.failed_auth_count
463
+ assert_equal "authentication error, giving up: try again\n", err
464
+ end
465
+
466
+ def test_deliver_4xx_error
467
+ Net::SMTP.on_send_message do
468
+ e = Net::SMTPSyntaxError.new 'try again'
469
+ e.set_backtrace %w[one two three]
470
+ raise e
471
+ end
472
+
473
+ now = Time.now.to_i
474
+
475
+ email = Email.create :mail => 'body', :to => 'to', :from => 'from'
476
+
477
+ out, err = capture_io do
478
+ @sm.deliver [email]
479
+ end
480
+
481
+ assert_equal 0, Net::SMTP.deliveries.length
482
+ assert_equal 1, Email.records.length
483
+ assert_operator now, :<=, Email.records.first.last_send_attempt
484
+ assert_equal 1, Net::SMTP.reset_called, 'Reset connection on SyntaxError'
485
+
486
+ assert_equal '', out
487
+ assert_equal "error sending email 1: \"try again\"(Net::SMTPSyntaxError):\n\tone\n\ttwo\n\tthree\n", err
488
+ end
489
+
490
+ def test_deliver_5xx_error
491
+ Net::SMTP.on_send_message do
492
+ e = Net::SMTPFatalError.new 'unknown recipient'
493
+ e.set_backtrace %w[one two three]
494
+ raise e
495
+ end
496
+
497
+ now = Time.now.to_i
498
+
499
+ email = Email.create :mail => 'body', :to => 'to', :from => 'from'
500
+
501
+ out, err = capture_io do
502
+ @sm.deliver [email]
503
+ end
504
+
505
+ assert_equal 0, Net::SMTP.deliveries.length
506
+ assert_equal 0, Email.records.length
507
+ assert_equal 1, Net::SMTP.reset_called, 'Reset connection on SyntaxError'
508
+
509
+ assert_equal '', out
510
+ assert_equal "5xx error sending email 1, removing from queue: \"unknown recipient\"(Net::SMTPFatalError):\n\tone\n\ttwo\n\tthree\n", err
511
+ end
512
+
513
+ def test_deliver_errno_epipe
514
+ Net::SMTP.on_send_message do
515
+ raise Errno::EPIPE
516
+ end
517
+
518
+ now = Time.now.to_i
519
+
520
+ email = Email.create :mail => 'body', :to => 'to', :from => 'from'
521
+
522
+ out, err = capture_io do
523
+ @sm.deliver [email]
524
+ end
525
+
526
+ assert_equal 0, Net::SMTP.deliveries.length
527
+ assert_equal 1, Email.records.length
528
+ assert_operator now, :>=, Email.records.first.last_send_attempt
529
+ assert_equal 0, Net::SMTP.reset_called, 'Reset connection on SyntaxError'
530
+
531
+ assert_equal '', out
532
+ assert_equal '', err
533
+ end
534
+
535
+ def test_deliver_server_busy
536
+ Net::SMTP.on_send_message do
537
+ e = Net::SMTPServerBusy.new 'try again'
538
+ e.set_backtrace %w[one two three]
539
+ raise e
540
+ end
541
+
542
+ now = Time.now.to_i
543
+
544
+ email = Email.create :mail => 'body', :to => 'to', :from => 'from'
545
+
546
+ out, err = capture_io do
547
+ @sm.deliver [email]
548
+ end
549
+
550
+ assert_equal 0, Net::SMTP.deliveries.length
551
+ assert_equal 1, Email.records.length
552
+ assert_operator now, :>=, Email.records.first.last_send_attempt
553
+ assert_equal 0, Net::SMTP.reset_called, 'Reset connection on SyntaxError'
554
+ assert_equal [60], @sm.slept
555
+
556
+ assert_equal '', out
557
+ assert_equal "server too busy, sleeping 60 seconds\n", err
558
+ end
559
+
560
+ def test_deliver_syntax_error
561
+ Net::SMTP.on_send_message do
562
+ Net::SMTP.on_send_message # clear
563
+ e = Net::SMTPSyntaxError.new 'blah blah blah'
564
+ e.set_backtrace %w[one two three]
565
+ raise e
566
+ end
567
+
568
+ now = Time.now.to_i
569
+
570
+ email1 = Email.create :mail => 'body', :to => 'to', :from => 'from'
571
+ email2 = Email.create :mail => 'body', :to => 'to', :from => 'from'
572
+
573
+ out, err = capture_io do
574
+ @sm.deliver [email1, email2]
575
+ end
576
+
577
+ assert_equal 1, Net::SMTP.deliveries.length, 'delivery count'
578
+ assert_equal 1, Email.records.length
579
+ assert_equal 1, Net::SMTP.reset_called, 'Reset connection on SyntaxError'
580
+ assert_operator now, :<=, Email.records.first.last_send_attempt
581
+
582
+ assert_equal '', out
583
+ assert_equal "error sending email 1: \"blah blah blah\"(Net::SMTPSyntaxError):\n\tone\n\ttwo\n\tthree\nsent email 00000000002 from from to to: \"queued\"\n", err
584
+ end
585
+
586
+ def test_deliver_timeout
587
+ Net::SMTP.on_send_message do
588
+ e = Timeout::Error.new 'timed out'
589
+ e.set_backtrace %w[one two three]
590
+ raise e
591
+ end
592
+
593
+ now = Time.now.to_i
594
+
595
+ email = Email.create :mail => 'body', :to => 'to', :from => 'from'
596
+
597
+ out, err = capture_io do
598
+ @sm.deliver [email]
599
+ end
600
+
601
+ assert_equal 0, Net::SMTP.deliveries.length
602
+ assert_equal 1, Email.records.length
603
+ assert_operator now, :>=, Email.records.first.last_send_attempt
604
+ assert_equal 1, Net::SMTP.reset_called, 'Reset connection on Timeout'
605
+
606
+ assert_equal '', out
607
+ assert_equal "error sending email 1: \"timed out\"(Timeout::Error):\n\tone\n\ttwo\n\tthree\n", err
608
+ end
609
+
610
+ def test_do_exit
611
+ out, err = capture_io do
612
+ assert_raises SystemExit do
613
+ @sm.do_exit
614
+ end
615
+ end
616
+
617
+ assert_equal '', out
618
+ assert_equal "caught signal, shutting down\n", err
619
+ end
620
+
621
+ def test_log
622
+ out, err = capture_io do
623
+ @sm.log 'hi'
624
+ end
625
+
626
+ assert_equal "hi\n", err
627
+ end
628
+
629
+ def test_find_emails
630
+ email_data = [
631
+ { :mail => 'body0', :to => 'recip@h1.example.com', :from => nobody },
632
+ { :mail => 'body1', :to => 'recip@h1.example.com', :from => nobody },
633
+ { :mail => 'body2', :to => 'recip@h2.example.com', :from => nobody },
634
+ ]
635
+
636
+ emails = email_data.map do |email_data| Email.create email_data end
637
+
638
+ tried = Email.create :mail => 'body3', :to => 'recip@h3.example.com',
639
+ :from => nobody
640
+
641
+ tried.last_send_attempt = Time.now.to_i - 258
642
+
643
+ found_emails = []
644
+
645
+ out, err = capture_io do
646
+ found_emails = @sm.find_emails
647
+ end
648
+
649
+ assert_equal emails, found_emails
650
+
651
+ assert_equal '', out
652
+ assert_equal "found 3 emails to send\n", err
653
+ end
654
+
655
+ def test_smtp_settings
656
+ ActionMailer::Base.server_settings[:address] = 'localhost'
657
+
658
+ assert_equal 'localhost', @sm.smtp_settings[:address]
659
+ end
660
+
661
+ def nobody
662
+ 'nobody@example.com'
663
+ end
664
+
665
+ end