thorero-mailer 0.9.4

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,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