File: network_spec.rb

package info (click to toggle)
ruby-mail 2.6.4%2Bdfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 4,256 kB
  • ctags: 1,327
  • sloc: ruby: 44,678; makefile: 3
file content (372 lines) | stat: -rw-r--r-- 13,791 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
# encoding: utf-8
# frozen_string_literal: true
require 'spec_helper'

class MyDelivery; def initialize(settings); end; end

class MyRetriever; def initialize(settings); end; end

describe "Mail" do

  before(:each) do
    # Reset all defaults back to original state
    Mail.defaults do
      delivery_method :smtp, { :address              => "localhost",
                               :port                 => 25,
                               :domain               => 'localhost.localdomain',
                               :user_name            => nil,
                               :password             => nil,
                               :authentication       => nil,
                               :enable_starttls_auto => true  }

      retriever_method :pop3, { :address             => "localhost",
                                :port                => 110,
                                :user_name           => nil,
                                :password            => nil,
                                :enable_ssl          => true }
    end
  end

  describe "default delivery and retriever methods" do

    it "should set the delivery method" do
      Mail.defaults do
        delivery_method :smtp
      end
      expect(Mail.delivery_method.class).to eq Mail::SMTP
    end

    it "should default to settings for smtp" do
      expect(Mail.delivery_method.class).to eq Mail::SMTP
      expect(Mail.delivery_method.settings).to eql({:address              => "localhost",
                                                :port                 => 25,
                                                :domain               => 'localhost.localdomain',
                                                :user_name            => nil,
                                                :password             => nil,
                                                :authentication       => nil,
                                                :enable_starttls_auto => true,
                                                :openssl_verify_mode  => nil,
                                                :ssl                  => nil,
                                                :tls                  => nil })
    end

    it "should set the retriever method" do
      Mail.defaults do
        retriever_method :pop3
      end
      expect(Mail.retriever_method.class).to eq Mail::POP3
    end

    it "should default to settings for pop3" do
      expect(Mail.retriever_method.class).to eq Mail::POP3
      expect(Mail.retriever_method.settings).to eql({:address              => "localhost",
                                                 :port                 => 110,
                                                 :user_name            => nil,
                                                 :password             => nil,
                                                 :authentication       => nil,
                                                 :enable_ssl           => true  })
    end

    it "should allow us to overwrite anything we need on SMTP" do
      Mail.defaults do
        delivery_method :smtp, :port => 999
      end
      expect(Mail.delivery_method.settings[:address]).to eq 'localhost'
      expect(Mail.delivery_method.settings[:port]).to eq 999
    end

    it "should allow us to overwrite anything we need on POP3" do
      Mail.defaults do
        retriever_method :pop3, :address => 'foo.bar.com'
      end
      expect(Mail.retriever_method.settings[:address]).to eq 'foo.bar.com'
      expect(Mail.retriever_method.settings[:port]).to eq 110
    end

    it "should allow you to pass in your own delivery method" do
      Mail.defaults do
        delivery_method MyDelivery
      end
      expect(Mail.delivery_method.class).to eq MyDelivery
    end

    it "should ask the custom delivery agent for its settings" do
      mock_my_delivery = double(MyDelivery)
      expect(mock_my_delivery).to receive(:settings).and_return({:these_are => :settings})
      expect(MyDelivery).to receive(:new).and_return(mock_my_delivery)
      Mail.defaults do
        delivery_method MyDelivery
      end
      expect(Mail.delivery_method.settings).to eql({:these_are => :settings})
    end

    it "should allow you to pass in your own retriever method" do
      Mail.defaults do
        retriever_method MyRetriever
      end
      expect(Mail.retriever_method.class).to eq MyRetriever
    end

    it "should ask the custom retriever agent for its settings" do
      mock_my_retriever = double(MyRetriever)
      expect(mock_my_retriever).to receive(:settings).and_return({:these_are => :settings})
      expect(MyRetriever).to receive(:new).and_return(mock_my_retriever)
      Mail.defaults do
        retriever_method MyRetriever
      end
      expect(Mail.retriever_method.settings).to eql({:these_are => :settings})
    end

  end

  describe "instance delivery methods" do

    it "should copy the defaults defined by Mail.defaults" do
      mail = Mail.new
      expect(mail.delivery_method.class).to eq Mail::SMTP
    end

    it "should be able to change the delivery_method" do
      mail = Mail.new
      mail.delivery_method :file
      expect(mail.delivery_method.class).to eq Mail::FileDelivery
    end

    it "should be able to change the delivery_method and pass in settings" do
      mail = Mail.new
      tmpdir = File.expand_path('../../../tmp/mail', __FILE__)
      mail.delivery_method :file, :location => tmpdir
      expect(mail.delivery_method.class).to eq Mail::FileDelivery
      expect(mail.delivery_method.settings).to eql({:location => tmpdir})
    end

    it "should not change the default when it changes the delivery_method" do
      mail1 = Mail.new
      mail2 = Mail.new
      mail1.delivery_method :file
      expect(Mail.delivery_method.class).to eq Mail::SMTP
      expect(mail1.delivery_method.class).to eq Mail::FileDelivery
      expect(mail2.delivery_method.class).to eq Mail::SMTP
    end

    it "should not change the default settings when it changes the delivery_method settings" do
      mail1 = Mail.new
      mail2 = Mail.new
      mail1.delivery_method :smtp, :address => 'my.own.address'
      expect(Mail.delivery_method.settings[:address]).to eq 'localhost'
      expect(mail1.delivery_method.settings[:address]).to eq 'my.own.address'
      expect(mail2.delivery_method.settings[:address]).to eq 'localhost'
    end

  end

  describe "retrieving emails via POP3" do
    it "should retrieve all emails via POP3" do
      messages = Mail.all

      expect(messages).not_to be_empty
      for message in messages
        expect(message).to be_instance_of(Mail::Message)
      end
    end
  end

  describe "sending emails via SMTP" do

    before(:each) do
      # Set the delivery method to test as the default
      MockSMTP.clear_deliveries
    end

    it "should deliver a mail message" do
      message = Mail.deliver do
        from 'mikel@test.lindsaar.net'
        to 'ada@test.lindsaar.net'
        subject 'Re: No way!'
        body 'Yeah sure'
        # add_file 'New Header Image', '/somefile.png'
      end

      expect(MockSMTP.deliveries[0][0]).to eq message.encoded
      expect(MockSMTP.deliveries[0][1]).to eq "mikel@test.lindsaar.net"
      expect(MockSMTP.deliveries[0][2]).to eq ["ada@test.lindsaar.net"]
    end

    it "should deliver itself" do
      message = Mail.new do
        from 'mikel@test.lindsaar.net'
        to 'ada@test.lindsaar.net'
        subject 'Re: No way!'
        body 'Yeah sure'
        # add_file 'New Header Image', '/somefile.png'
      end

      message.deliver!

      expect(MockSMTP.deliveries[0][0]).to eq message.encoded
      expect(MockSMTP.deliveries[0][1]).to eq "mikel@test.lindsaar.net"
      expect(MockSMTP.deliveries[0][2]).to eq ["ada@test.lindsaar.net"]
    end

  end

  describe "deliveries" do

    class MyDeliveryMethod
      attr_accessor :settings
      def initialize(values = {}); end
      def deliver!(message); true; end
    end

    class MyObserver
      def self.delivered_email(message); end
    end

    class MyDeliveryHandler
      def deliver_mail(mail)
        postman = MyDeliveryMethod.new
        postman.deliver!(mail)
      end
    end

    class MyYieldingDeliveryHandler
      def deliver_mail(mail)
        yield
      end
    end

    before(:each) do
      @message = Mail.new do
        from 'mikel@test.lindsaar.net'
        to 'ada@test.lindsaar.net'
        subject 'Re: No way!'
        body 'Yeah sure'
      end
      @message.delivery_method :test
    end

    describe "adding to Mail.deliveries" do
      it "should add itself to the deliveries collection on mail on delivery" do
        expect { @message.deliver }.to change(Mail::TestMailer.deliveries, :size).by(1)
      end
    end

    describe "perform_deliveries" do
      it "should call deliver! on the delivery method by default" do
        delivery_agent = MyDeliveryMethod.new
        expect(@message).to receive(:delivery_method).and_return(delivery_agent)
        expect(delivery_agent).to receive(:deliver!).with(@message)
        @message.deliver
      end

      it "should not call deliver if perform deliveries is set to false" do
        @message.perform_deliveries = false
        delivery_agent = MyDeliveryMethod.new
        expect(@message).not_to receive(:delivery_method)
        expect(delivery_agent).not_to receive(:deliver!)
        @message.deliver
      end

      it "should add to the deliveries array if perform_deliveries is true" do
        @message.perform_deliveries = true
        expect { @message.deliver }.to change(Mail::TestMailer.deliveries, :size).by(1)
      end

      it "should not add to the deliveries array if perform_deliveries is false" do
        @message.perform_deliveries = false
        expect { @message.deliver }.not_to change(Mail::TestMailer.deliveries, :size)
      end
    end

    describe "observers" do
      it "should tell its observers that it was told to deliver an email" do
        Mail.register_observer(MyObserver)
        expect(MyObserver).to receive(:delivered_email).with(@message).once
        @message.deliver
      end

      it "should tell its observers that it was told to deliver an email even if perform_deliveries is false" do
        Mail.register_observer(MyObserver)
        @message.perform_deliveries = false
        expect(MyObserver).to receive(:delivered_email).with(@message).once
        @message.deliver
      end

      it "should tell its observers that it was told to deliver an email even if it is using a delivery_handler" do
        Mail.register_observer(MyObserver)
        @message.delivery_handler = MyYieldingDeliveryHandler.new
        @message.perform_deliveries = false
        expect(MyObserver).to receive(:delivered_email).with(@message).once
        @message.deliver
      end

    end

    describe "raise_delivery_errors" do
      it "should pass on delivery errors if raised" do
        delivery_agent = MyDeliveryMethod.new
        allow(@message).to receive(:delivery_method).and_return(delivery_agent)
        allow(delivery_agent).to receive(:deliver!).and_raise(StandardError)
        expect { @message.deliver }.to raise_error(StandardError)
      end

      it "should not pass on delivery errors if raised raise_delivery_errors is set to false" do
        delivery_agent = MyDeliveryMethod.new
        allow(@message).to receive(:delivery_method).and_return(delivery_agent)
        @message.raise_delivery_errors = false
        allow(delivery_agent).to receive(:deliver!).and_raise(StandardError)
        expect { @message.deliver }.not_to raise_error
      end

      it "should pass through Exceptions even when raise_delivery_errors is set to false" do
        delivery_agent = MyDeliveryMethod.new
        allow(@message).to receive(:delivery_method).and_return(delivery_agent)
        @message.raise_delivery_errors = false
        allow(delivery_agent).to receive(:deliver!).and_raise(Exception)
        expect { @message.deliver }.to raise_error(Exception)
      end
    end

    describe "delivery_handler" do

      it "should allow you to hand off performing the actual delivery to another object" do
        delivery_handler = MyYieldingDeliveryHandler.new
        expect(delivery_handler).to receive(:deliver_mail).with(@message).exactly(:once)
        @message.delivery_handler = delivery_handler
        @message.deliver
      end

      it "mail should be told to :deliver once and then :deliver! once by the delivery handler" do
        @message.delivery_handler = MyYieldingDeliveryHandler.new
        expect(@message).to receive(:do_delivery).exactly(:once)
        @message.deliver
      end

      it "mail only call its delivery_method once" do
        @message.delivery_handler = MyYieldingDeliveryHandler.new
        expect(@message).to receive(:delivery_method).exactly(:once).and_return(Mail::TestMailer.new({}))
        @message.deliver
      end

      it "mail should not catch any exceptions when using a delivery_handler" do
        @message.delivery_handler = MyYieldingDeliveryHandler.new
        expect(@message).to receive(:delivery_method).and_raise(Exception)
        expect { @message.deliver }.to raise_error(Exception)
      end

      it "mail should not modify the Mail.deliveries object if using a delivery_handler that does not append to deliveries" do
        @message.delivery_handler = MyDeliveryHandler.new
        expect { @message.deliver }.not_to change(Mail::TestMailer, :deliveries)
      end

      it "should be able to just yield and let mail do its thing" do
        @message.delivery_handler = MyYieldingDeliveryHandler.new
        expect(@message).to receive(:do_delivery).exactly(:once)
        @message.deliver
      end

    end

  end

end