thorero-mailer 0.9.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,104 @@
1
+ begin
2
+ require 'mailfactory'
3
+ require 'net/smtp'
4
+ rescue LoadError
5
+ Merb.logger.warn "You need to install the mailfactory gem to use Merb::Mailer"
6
+ end
7
+
8
+ class MailFactory
9
+ attr_reader :html, :text
10
+ end
11
+
12
+ module Merb
13
+
14
+ # You'll need a simple config like this in init.rb if you want
15
+ # to actually send mail:
16
+ #
17
+ # Merb::Mailer.config = {
18
+ # :host => 'smtp.yourserver.com',
19
+ # :port => '25',
20
+ # :user => 'user',
21
+ # :pass => 'pass',
22
+ # :auth => :plain # :plain, :login, :cram_md5, the default is no auth
23
+ # :domain => "localhost.localdomain" # the HELO domain provided by the client to the server
24
+ # }
25
+ #
26
+ # or
27
+ #
28
+ # Merb::Mailer.config = {:sendmail_path => '/somewhere/odd'}
29
+ # Merb::Mailer.delivery_method = :sendmail
30
+ #
31
+ # You could send mail manually like this (but it's better to use
32
+ # a MailController instead).
33
+ #
34
+ # m = Merb::Mailer.new :to => 'foo@bar.com',
35
+ # :from => 'bar@foo.com',
36
+ # :subject => 'Welcome to whatever!',
37
+ # :body => partial(:sometemplate)
38
+ # m.deliver!
39
+
40
+ class Mailer
41
+
42
+ class_inheritable_accessor :config, :delivery_method, :deliveries
43
+ attr_accessor :mail
44
+ self.deliveries = []
45
+
46
+ # Sends the mail using sendmail.
47
+ def sendmail
48
+ sendmail = IO.popen("#{config[:sendmail_path]} #{@mail.to}", 'w+')
49
+ sendmail.puts @mail.to_s
50
+ sendmail.close
51
+ end
52
+
53
+ # Sends the mail using SMTP.
54
+ def net_smtp
55
+ Net::SMTP.start(config[:host], config[:port].to_i, config[:domain],
56
+ config[:user], config[:pass], config[:auth]) { |smtp|
57
+ smtp.send_message(@mail.to_s, @mail.from.first, @mail.to.to_s.split(/[,;]/))
58
+ }
59
+ end
60
+
61
+ # Tests mail sending by adding the mail to deliveries.
62
+ def test_send
63
+ deliveries << @mail
64
+ end
65
+
66
+ # Delivers the mail with the specified delivery method, defaulting to
67
+ # net_smtp.
68
+ def deliver!
69
+ send(delivery_method || :net_smtp)
70
+ end
71
+
72
+ # ==== Parameters
73
+ # file_or_files<File, Array[File]>:: File(s) to attach.
74
+ # filename<String>::
75
+ # type<~to_s>::
76
+ # The attachment MIME type. If left out, it will be determined from
77
+ # file_or_files.
78
+ # headers<String, Array>:: Additional attachment headers.
79
+ #
80
+ # ==== Raises
81
+ # ArgumentError::
82
+ # file_or_files was not a File or an Array of File instances.
83
+ def attach(file_or_files, filename = file_or_files.is_a?(File) ? File.basename(file_or_files.path) : nil,
84
+ type = nil, headers = nil)
85
+ if file_or_files.is_a?(Array)
86
+ file_or_files.each {|k,v| @mail.add_attachment_as k, *v}
87
+ else
88
+ raise ArgumentError, "You did not pass in a file. Instead, you sent a #{file_or_files.class}" if !file_or_files.is_a?(File)
89
+ @mail.add_attachment_as(file_or_files, filename, type, headers)
90
+ end
91
+ end
92
+
93
+ # ==== Parameters
94
+ # o<Hash{~to_s => Object}>:: Configuration commands to send to MailFactory.
95
+ def initialize(o={})
96
+ self.config = {:sendmail_path => '/usr/sbin/sendmail'} if config.nil?
97
+ o[:rawhtml] = o.delete(:html)
98
+ m = MailFactory.new()
99
+ o.each { |k,v| m.send "#{k}=", v }
100
+ @mail = m
101
+ end
102
+
103
+ end
104
+ end
@@ -0,0 +1,25 @@
1
+ module Merb
2
+ module MailerMixin
3
+
4
+ # Sends mail via a MailController (a tutorial can be found in the
5
+ # MailController docs).
6
+ #
7
+ # ==== Parameters
8
+ # klass<Class>:: The mailer class.
9
+ # method<~to_s>:: The method to call on the mailer.
10
+ # mail_params<Hash>::
11
+ # Mailing parameters, e.g. :to and :cc. See
12
+ # Merb::MailController#dispatch_and_deliver for details.
13
+ # send_params<Hash>::
14
+ # Params to send to the mailer. Defaults to the params of the current
15
+ # controller.
16
+ #
17
+ # ==== Examples
18
+ # # Send an email via the FooMailer's bar method.
19
+ # send_mail FooMailer, :bar, :from => "foo@bar.com", :to => "baz@bat.com"
20
+ def send_mail(klass, method, mail_params, send_params = nil)
21
+ klass.new(send_params || params, self).dispatch_and_deliver(method, mail_params)
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1 @@
1
+ merb-gen mail_controller <name> <meth1> <meth2>
@@ -0,0 +1,59 @@
1
+ require "merb-gen/helpers"
2
+ require "merb-gen/base"
3
+
4
+ class MailControllerGenerator < Merb::GeneratorBase
5
+
6
+ attr_reader :controller_class_name,
7
+ :controller_file_name,
8
+ :controller_base_path,
9
+ :controller_modules,
10
+ :full_controller_const
11
+
12
+ def initialize(args, runtime_args = {})
13
+ @base = File.dirname(__FILE__)
14
+ super
15
+ name = args.shift
16
+ @controller_file_name = name.snake_case.gsub("::", "/")
17
+
18
+ # Need to setup the directories
19
+ unless @controller_file_name == File.basename(@controller_file_name)
20
+ @controller_base_path = controller_file_name.split("/")[0..-2].join("/")
21
+ end
22
+
23
+ @controller_modules = @controller_file_name.to_const_string.split("::")[0..-2]
24
+ @controller_class_name = @controller_file_name.to_const_string.split("::").last
25
+
26
+ @full_controller_const = ((@controller_modules.dup || []) << @controller_class_name).join("::")
27
+ end
28
+
29
+ def manifest
30
+ record do |m|
31
+ @m = m
32
+
33
+ # Create the controller directory
34
+ m.directory File.join("app/mailers", controller_base_path) if controller_base_path
35
+
36
+ @assigns = {
37
+ :controller_modules => controller_modules,
38
+ :controller_class_name => controller_class_name,
39
+ :controller_file_name => controller_file_name,
40
+ :controller_base_path => controller_base_path,
41
+ :full_controller_const => full_controller_const
42
+ }
43
+
44
+ copy_dirs
45
+ copy_files
46
+
47
+ end
48
+ end
49
+
50
+ protected
51
+ def banner
52
+ <<-EOS.split("\n").map{|x| x.strip}.join("\n")
53
+ Creates a Merb mail controller stub.
54
+
55
+ USAGE: #{spec.name} mail_controller_name"
56
+ EOS
57
+ end
58
+
59
+ end
@@ -0,0 +1,20 @@
1
+ <% counter = 0 -%>
2
+ <% controller_modules.each_with_index do |mod, i| -%>
3
+ <%= " " * i %>module <%= mod %>
4
+ <% counter = i -%>
5
+ <% end -%>
6
+ <% counter = counter == 0 ? 0 : (counter + 1) -%>
7
+ <%= " " * counter %>class <%= controller_class_name %>Mailer < Merb::MailController
8
+
9
+ <%= " " * counter %> def notify_on_event
10
+ <%= " " * counter %> # use params[] passed to this controller to get data
11
+ <%= " " * counter %> # read more at http://wiki.merbivore.com/pages/mailers
12
+ <%= " " * counter %> render_mail
13
+ <%= " " * counter %> end
14
+
15
+ <%= " " * counter %>end
16
+ <% counter = counter == 0 ? 0 : (counter - 1) -%>
17
+ <% controller_modules.reverse.each_with_index do |mod, i| -%>
18
+ <%= " " * counter %>end # <%= mod %>
19
+ <% counter = counter - 1 -%>
20
+ <% end -%>
@@ -0,0 +1,39 @@
1
+ require File.join(File.dirname(__FILE__), "..", "spec_helper")
2
+
3
+ # Move this to your spec_helper.rb.
4
+ module MailControllerTestHelper
5
+ # Helper to clear mail deliveries.
6
+ def clear_mail_deliveries
7
+ Merb::Mailer.deliveries.clear
8
+ end
9
+
10
+ # Helper to access last delivered mail.
11
+ # In test mode merb-mailer puts email to
12
+ # collection accessible as Merb::Mailer.deliveries.
13
+ def last_delivered_mail
14
+ Merb::Mailer.deliveries.last
15
+ end
16
+
17
+ # Helper to deliver
18
+ def deliver(action, mail_params = {}, send_params = {})
19
+ <%= controller_class_name %>Mailer.dispatch_and_deliver(action, { :from => "no-reply@webapp.com", :to => "recepient@person.com" }.merge(mail_params), send_params)
20
+ @delivery = last_delivered_mail
21
+ end
22
+ end
23
+
24
+ describe <%= controller_class_name %>Mailer, "#notify_on_event email template" do
25
+ include MailControllerTestHelper
26
+
27
+ before :each do
28
+ clear_mail_deliveries
29
+
30
+ # instantiate some fixture objects
31
+ end
32
+
33
+ it "includes welcome phrase in email text" do
34
+ voilated "Mailer controller deserves to have specs, too."
35
+
36
+ # <%= controller_class_name %>Mailer.dispatch_and_deliver(:notify_on_event, {}, { :name => "merb-mailer user" })
37
+ # last_delivered_mail.text.should =~ /Hello, merb-mailer user!/
38
+ end
39
+ end
@@ -0,0 +1,174 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ Spec::Runner.configure do |config|
4
+ config.include Merb::Test::RequestHelper
5
+ end
6
+
7
+ class Merb::Mailer
8
+ self.delivery_method = :test_send
9
+ end
10
+
11
+ Merb.push_path(:mailer, File.join(File.dirname(__FILE__), "mailers"))
12
+
13
+ class TestMailController < Merb::MailController
14
+
15
+ def first
16
+ render_mail
17
+ end
18
+
19
+ def second
20
+ render_mail
21
+ end
22
+
23
+ def third
24
+ render_mail :text => :first, :html => :third
25
+ end
26
+
27
+ def fourth
28
+ render_mail :text => "FOURTH_TEXT", :html => "FOURTH_HTML", :layout => :none
29
+ end
30
+
31
+ def fifth
32
+ render_mail :action => {:text => :first, :html => :third}
33
+ end
34
+
35
+ def sixth
36
+ render_mail :action => {:text => :first}, :html => "SIXTH_HTML"
37
+ end
38
+
39
+ def seventh
40
+ render_mail :text => :first, :html => "SEVENTH_HTML"
41
+ end
42
+
43
+ def eighth
44
+ @testing = "TEST"
45
+ render_mail
46
+ end
47
+
48
+ def ninth
49
+ render_mail
50
+ end
51
+
52
+ def tenth
53
+ render_mail
54
+ end
55
+
56
+ end
57
+
58
+ class TestController < Merb::Controller
59
+
60
+ def one
61
+ send_mail TestMailController, :ninth, {:from => "foo@bar.com", :to => "foo@bar.com"}, {:x => "ONE_CONTROLLER"}
62
+ end
63
+
64
+ end
65
+
66
+ describe "A Merb Mail controller" do
67
+
68
+ def deliver(action)
69
+ TestMailController.dispatch_and_deliver action, :from => "foo@bar.com", :to => "foo@bar.com"
70
+ @delivery = Merb::Mailer.deliveries.last
71
+ end
72
+
73
+ undef :call_action if defined?(call_action)
74
+ def call_action(action)
75
+ dispatch_to(TestController, action)
76
+ @delivery = Merb::Mailer.deliveries.last
77
+ end
78
+
79
+ it "should render files in its directory by default" do
80
+ deliver :first
81
+ @delivery.text.should == "TEXT\nFIRST\nENDTEXT"
82
+ end
83
+
84
+ it "should render files in its directory without a mimetype extension by default" do
85
+ deliver :second
86
+ @delivery.text.should == "TEXT\nSECOND\nENDTEXT"
87
+ end
88
+
89
+ it "should be able to accept a :text => :sym, :html => :sym render_mail" do
90
+ deliver :third
91
+ @delivery.text.should == "TEXT\nFIRST\nENDTEXT"
92
+ @delivery.html.should == "BASIC\nTHIRDHTML\nLAYOUT"
93
+ end
94
+
95
+ it "should be able to accept a :text => STRING, :html => STRING render_mail" do
96
+ deliver :fourth
97
+ $DEBUGGER = true
98
+ @delivery.text.should == "FOURTH_TEXT"
99
+ @delivery.html.should == "FOURTH_HTML"
100
+ $DEBUGGER = false
101
+ end
102
+
103
+ it "should be able to accept an :action => {:text => :sym, :html => :sym}" do
104
+ deliver :fifth
105
+ @delivery.text.should == "TEXT\nFIRST\nENDTEXT"
106
+ @delivery.html.should == "BASIC\nTHIRDHTML\nLAYOUT"
107
+ end
108
+
109
+ it "should be able to accept a mix of action and :html => STRING" do
110
+ deliver :sixth
111
+ @delivery.text.should == "TEXT\nFIRST\nENDTEXT"
112
+ @delivery.html.should == "SIXTH_HTML"
113
+ end
114
+
115
+ it "should be able to accept a mix of :text => :sym and :html => STRING" do
116
+ deliver :seventh
117
+ @delivery.text.should == "TEXT\nFIRST\nENDTEXT"
118
+ @delivery.html.should == "SEVENTH_HTML"
119
+ end
120
+
121
+ it "should hold onto instance variables" do
122
+ deliver :eighth
123
+ @delivery.html.should == "BASIC\nTEST\nLAYOUT"
124
+ end
125
+
126
+ it "should have access to the params sent by the calling controller" do
127
+ call_action :one
128
+ @delivery.html.should == "BASIC\nONE_CONTROLLER\nLAYOUT"
129
+ end
130
+
131
+ it "should not raise an error if there are no templates" do
132
+ lambda do
133
+ deliver :tenth
134
+ end.should_not raise_error
135
+ end
136
+
137
+ it "should log an error if there are no templates available" do
138
+ Merb.logger.should_receive(:error).once
139
+ deliver :tenth
140
+ end
141
+
142
+ end
143
+
144
+ # describe "Merb::MailController with url generation" do
145
+ #
146
+ # it_should_behave_like "class with general url generation"
147
+ # it_should_behave_like "non routeable controller with url mixin"
148
+ #
149
+ # def new_url_controller(route, params = {:action => 'show', :controller => 'Test'})
150
+ # request = OpenStruct.new
151
+ # request.route = route
152
+ # request.params = params
153
+ # response = OpenStruct.new
154
+ # response.read = ""
155
+ #
156
+ # @controller = Merb::Controller.build(request, response)
157
+ # TestMailController.new(params, @controller)
158
+ # end
159
+ #
160
+ # it "should raise an error if no controller is specified and the base controller is not set" do
161
+ # c = new_url_controller(@default_route, {})
162
+ # lambda do
163
+ # the_url = c.url(:action => "bar")
164
+ # end.should raise_error
165
+ # end
166
+ #
167
+ # it "should use the base controller when it is set to generate a url when no :controller option is specified" do
168
+ # c = new_url_controller(@defualt_route, :controller => "foo")
169
+ # lambda do
170
+ # the_url = c.url(:action => "bar")
171
+ # the_url.should == "/foo/bar"
172
+ # end.should_not raise_error
173
+ # end
174
+ # end
@@ -0,0 +1,87 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ class TestMailer < Merb::Mailer
4
+ self.delivery_method = :test_send
5
+ end
6
+
7
+ class TestSMTPMailer < Merb::Mailer
8
+ self.delivery_method = :net_smtp
9
+ self.config = { :host => 'smtp.yourserver.com',
10
+ :port => '25',
11
+ :user => 'user',
12
+ :pass => 'pass',
13
+ :auth => :plain }
14
+
15
+ end
16
+
17
+ class TestSendmailMailer < Merb::Mailer
18
+ self.delivery_method = :sendmail
19
+ end
20
+
21
+ def setup_test_mailer klass = TestMailer
22
+ @m = klass.new :to => "test@test.com",
23
+ :from => "foo@bar.com",
24
+ :subject => "Test Subject",
25
+ :body => "Test"
26
+ end
27
+
28
+ describe "a merb mailer" do
29
+
30
+ it "should be able to send test emails" do
31
+ setup_test_mailer
32
+ @m.deliver!
33
+ TestMailer.deliveries.size.should == 1
34
+ delivery = TestMailer.deliveries.last
35
+ delivery.to.should include("test@test.com")
36
+ delivery.from.should include("foo@bar.com")
37
+ delivery.subject.should include("=?utf-8?Q?Test_Subject=?=")
38
+ delivery.body.should include("Test")
39
+ end
40
+
41
+ it "should be able to accept attachments" do
42
+ setup_test_mailer
43
+ @m.attach File.open("README")
44
+ @m.deliver!
45
+ delivery = TestMailer.deliveries.last
46
+ delivery.instance_variable_get("@attachments").size.should == 1
47
+ end
48
+
49
+ it "should be able to accept multiple attachments" do
50
+ setup_test_mailer
51
+ @m.attach [[File.open("README")], [File.open("LICENSE")]]
52
+ @m.deliver!
53
+ delivery = TestMailer.deliveries.last
54
+ delivery.instance_variable_get("@attachments").size.should == 2
55
+ end
56
+
57
+ it "should be able to send mails via SMTP" do
58
+ setup_test_mailer TestSMTPMailer
59
+ Net::SMTP.stub!(:start).and_return(true)
60
+ Net::SMTP.should_receive(:start).with("smtp.yourserver.com", 25, nil, "user", "pass", :plain)
61
+ @m.deliver!
62
+ end
63
+
64
+ it "should send mails via SMTP with no auth" do
65
+ setup_test_mailer TestSMTPMailer
66
+ @m.config[:auth] = nil
67
+ Net::SMTP.stub!(:start).and_return(true)
68
+ Net::SMTP.should_receive(:start).with("smtp.yourserver.com", 25, nil, "user", "pass", nil)
69
+ @m.deliver!
70
+ end
71
+
72
+ it "should be able to send mails via sendmail" do
73
+ sendmail = mock("/usr/sbin/sendmail", :null_object => true)
74
+ setup_test_mailer TestSendmailMailer
75
+ IO.should_receive(:popen).with("/usr/sbin/sendmail #{@m.mail.to}", "w+").and_return(sendmail)
76
+ @m.deliver!
77
+ end
78
+
79
+ it "should be able to use a different sendmail path" do
80
+ sendmail = mock("/somewhere/sendmail", :null_object => true)
81
+ setup_test_mailer TestSendmailMailer
82
+ @m.config[:sendmail_path] = '/somewhere/sendmail'
83
+ IO.should_receive(:popen).with("/somewhere/sendmail #{@m.mail.to}", "w+").and_return(sendmail)
84
+ @m.deliver!
85
+ end
86
+
87
+ end