sinatra_more 0.2.7 → 0.2.8
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.
- data/README.rdoc +80 -4
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/lib/sinatra_more/mailer_plugin/mail_object.rb +37 -0
- data/lib/sinatra_more/mailer_plugin/mailer_base.rb +73 -0
- data/lib/sinatra_more/mailer_plugin.rb +12 -0
- data/lib/sinatra_more.rb +1 -0
- data/sinatra_more.gemspec +23 -3
- data/test/fixtures/mailer_app/app.rb +51 -0
- data/test/fixtures/mailer_app/views/demo_mailer/sample_mail.erb +1 -0
- data/test/fixtures/mailer_app/views/sample_mailer/anniversary_message.erb +2 -0
- data/test/fixtures/mailer_app/views/sample_mailer/birthday_message.erb +2 -0
- data/test/mailer_plugin/test_mail_object.rb +24 -0
- data/test/mailer_plugin/test_mailer_base.rb +81 -0
- data/test/test_mailer_plugin.rb +33 -0
- data/vendor/pony/lib/pony.rb +90 -0
- data/vendor/pony/spec/base.rb +4 -0
- data/vendor/pony/spec/pony_spec.rb +147 -0
- metadata +29 -2
data/README.rdoc
CHANGED
@@ -49,8 +49,8 @@ Here is a small list of what sinatra_more contains:
|
|
49
49
|
* Asset tag helpers (<tt>link_to</tt>, <tt>image_tag</tt>, <tt>javascript_include_tag</tt>, ...)
|
50
50
|
* Full form helpers and builders support (<tt>form_tag</tt>, <tt>form_for</tt>, <tt>field_set_tag</tt>, <tt>text_field</tt>, ...)
|
51
51
|
* Generally useful formatting extensions (<tt>relative_time_ago</tt>, <tt>js_escape_html</tt>, <tt>sanitize_html</tt>)
|
52
|
+
* Simple 'mailer' support for sinatra (akin to <tt>ActionMailer</tt> but simpler and powered by <tt>pony</tt>)
|
52
53
|
* Plug and play setup for the excellent Warden authentication system
|
53
|
-
* Robust 'mailer' support for sinatra (akin to <tt>ActionMailer</tt> but simpler and powered by <tt>pony</tt>) (COMING SOON)
|
54
54
|
* Code generators for creating a new sinatra application (COMING SOON)
|
55
55
|
|
56
56
|
Keep in mind, the user will be able to pull in these components seperately and leave out those that are not required.
|
@@ -75,12 +75,13 @@ different components based on which pieces are useful for your particular applic
|
|
75
75
|
|
76
76
|
# app.rb
|
77
77
|
require 'sinatra/base'
|
78
|
-
require 'sinatra_more'
|
78
|
+
require 'sinatra_more' # or require 'sinatra_more/markup_plugin' for precise inclusion
|
79
79
|
|
80
80
|
class Application < Sinatra::Base
|
81
81
|
register SinatraMore::MarkupPlugin
|
82
82
|
register SinatraMore::RenderPlugin
|
83
83
|
register SinatraMore::WardenPlugin
|
84
|
+
register SinatraMore::MailerPlugin
|
84
85
|
end
|
85
86
|
|
86
87
|
This will then allow you to use the components that have been registered. A breakdown of components is below:
|
@@ -467,10 +468,85 @@ Eventually I plan to vendor that gem or just remove support for this piece of my
|
|
467
468
|
If anybody has any thoughts on this or the warden integration in general, please let me know.
|
468
469
|
Nonetheless, there is a certain convenience for me having access to a plug-and-play warden solution directly from this gem.
|
469
470
|
|
471
|
+
=== MailerPlugin
|
472
|
+
|
473
|
+
This component uses an enhanced version of the excellent <tt>pony</tt> library (vendored) for a powerful but simple
|
474
|
+
mailer system within Sinatra. There is full support for using an html content type as well as for file attachments.
|
475
|
+
The MailerPlugin has many similarities to ActionMailer but is much lighterweight and (arguably) easier to use.
|
476
|
+
|
477
|
+
Let's take a look at using the MailerPlugin in an application. By default, MailerPlugin uses the built-in sendmail
|
478
|
+
functionality on the server. However, smtp is also supported using the following configuration:
|
479
|
+
|
480
|
+
SinatraMore::MailerBase.smtp_settings = {
|
481
|
+
:host => 'smtp.gmail.com',
|
482
|
+
:port => '587',
|
483
|
+
:tls => true,
|
484
|
+
:user => 'user',
|
485
|
+
:pass => 'pass',
|
486
|
+
:auth => :plain
|
487
|
+
}
|
488
|
+
|
489
|
+
Once those have been defined, the default will become smtp delivery unless overwritten in an individual mail definition.
|
490
|
+
Next, we should define a custom mailer extended from <tt>SinatraMore::MailerBase</tt>.
|
491
|
+
|
492
|
+
class SampleMailer < SinatraMore::MailerBase
|
493
|
+
def registration_email(name, user_email_address)
|
494
|
+
from 'admin@site.com'
|
495
|
+
to user_email_address
|
496
|
+
subject 'Welcome to the site!'
|
497
|
+
body :name => name
|
498
|
+
type 'html' # optional, defaults to plain/text
|
499
|
+
charset 'windows-1252' # optional, defaults to utf-8
|
500
|
+
via :sendmail # optional, to smtp if defined otherwise sendmail
|
501
|
+
end
|
502
|
+
end
|
503
|
+
|
504
|
+
This defines a mail called '<tt>registration_mail</tt>' with the specified attributes for delivery. The <tt>body</tt> method
|
505
|
+
is passing the <tt>name</tt> attribute to the body message template which should be defined in
|
506
|
+
<tt>[views_path]/sample_mailer/registration_email.erb</tt> as shown below:
|
507
|
+
|
508
|
+
# ./views/sample_mailer/registration_email.erb
|
509
|
+
This is the body of the email and can access the <%= name %> that was passed in from the mailer definition
|
510
|
+
That's all there is to defining the body of the email which can be plain text or email
|
511
|
+
|
512
|
+
Once the mailer definition has been completed and the template has been defined, the email can be sent using:
|
513
|
+
|
514
|
+
SampleMailer.deliver(:registration_email, "Bob", "bob@bobby.com")
|
515
|
+
|
516
|
+
or if you like the method_missing approach:
|
517
|
+
|
518
|
+
SampleMailer.deliver_registration_email "Bob", 'bob@bobby.com'
|
519
|
+
|
520
|
+
And that will then deliver the email according the the configured options. This is really all you need to send emails.
|
521
|
+
A few variations are shown below for completeness.
|
522
|
+
|
523
|
+
If we want to attach files to our email:
|
524
|
+
|
525
|
+
class SampleMailer < SinatraMore::MailerBase
|
526
|
+
def attachment_email(name, user_email_address)
|
527
|
+
from 'admin@site.com'
|
528
|
+
to user_email_address
|
529
|
+
# ...
|
530
|
+
attachments { "foo.zip" => File.read("path/to/foo.zip"), "file.txt" => "this is a text file!" }
|
531
|
+
end
|
532
|
+
end
|
533
|
+
|
534
|
+
or perhaps we want to have a short body without the need for a template file:
|
535
|
+
|
536
|
+
class SampleMailer < SinatraMore::MailerBase
|
537
|
+
def short_email(name, user_email_address)
|
538
|
+
from 'admin@site.com'
|
539
|
+
to user_email_address
|
540
|
+
subject 'Welcome to the site!'
|
541
|
+
body "This is a short body defined right in the mailer itself"
|
542
|
+
end
|
543
|
+
end
|
544
|
+
|
470
545
|
== Acknowledgements
|
471
546
|
|
472
|
-
* Thanks to keldredd for the sinatra_helpers code that helped me to create erb capture and concat methods.
|
473
|
-
* Thanks to sbfaulkner for the sinatra-helpers code that I browsed through many times while starting this library.
|
547
|
+
* Thanks to keldredd for the <tt>sinatra_helpers</tt> code that helped me to create erb capture and concat methods.
|
548
|
+
* Thanks to sbfaulkner for the <tt>sinatra-helpers</tt> code that I browsed through many times while starting this library.
|
549
|
+
* Thanks to vestel for the excellent modified <tt>pony</tt> fork which in part powers the mailer_plugin (http://github.com/vestel/pony)
|
474
550
|
|
475
551
|
== Contributors
|
476
552
|
|
data/Rakefile
CHANGED
@@ -12,6 +12,7 @@ begin
|
|
12
12
|
gem.email = "nesquena@gmail.com"
|
13
13
|
gem.homepage = "http://github.com/nesquena/sinatra_more"
|
14
14
|
gem.authors = ["Nathan Esquenazi"]
|
15
|
+
gem.add_runtime_dependency "tilt", ">= 0.2"
|
15
16
|
gem.add_runtime_dependency "sinatra", ">= 0.9.2"
|
16
17
|
gem.add_runtime_dependency "activesupport", ">= 2.2.2"
|
17
18
|
gem.add_development_dependency "haml", ">= 2.2.1"
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.8
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# This represents a particular mail object which will need to be sent
|
2
|
+
# A mail_object requires the mail attributes and the delivery_settings
|
3
|
+
|
4
|
+
module SinatraMore
|
5
|
+
class MailObject
|
6
|
+
def initialize(mail_attributes={}, smtp_settings={})
|
7
|
+
@mail_attributes = mail_attributes.dup
|
8
|
+
@smtp_settings = smtp_settings.dup if smtp_settings.present?
|
9
|
+
end
|
10
|
+
|
11
|
+
# Constructs the delivery attributes for the message and then sends the mail
|
12
|
+
# @mail_object.deliver
|
13
|
+
def deliver
|
14
|
+
@mail_attributes.reverse_merge!(:via => self.delivery_method.to_sym)
|
15
|
+
@mail_attributes.reverse_merge!(:smtp => @smtp_settings) if using_smtp?
|
16
|
+
self.send_mail(@mail_attributes)
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
# Returns the delivery method to use for this mail object
|
22
|
+
# @mo.delivery_method => :smtp || :sendmail
|
23
|
+
def delivery_method
|
24
|
+
@mail_attributes[:via] || (@smtp_settings.present? ? :smtp : :sendmail)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Returns true if the mail object is going to be delivered using smtp
|
28
|
+
def using_smtp?
|
29
|
+
delivery_method.to_s =~ /smtp/
|
30
|
+
end
|
31
|
+
|
32
|
+
# Performs the actual email sending using a third-party library
|
33
|
+
def send_mail(delivery_attributes)
|
34
|
+
Pony.mail(delivery_attributes) && true
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
This is the abstract class that other mailers will inherit from in order to send mail
|
4
|
+
|
5
|
+
You can set the default delivery settings through:
|
6
|
+
|
7
|
+
SinatraMore::MailerBase.smtp_settings = {
|
8
|
+
:host => 'smtp.yourserver.com',
|
9
|
+
:port => '25',
|
10
|
+
:user => 'user',
|
11
|
+
:pass => 'pass',
|
12
|
+
:auth => :plain # :plain, :login, :cram_md5, no auth by default
|
13
|
+
:domain => "localhost.localdomain" # the HELO domain provided by the client to the server
|
14
|
+
}
|
15
|
+
|
16
|
+
and then all delivered mail will use these settings unless otherwise specified.
|
17
|
+
|
18
|
+
=end
|
19
|
+
|
20
|
+
module SinatraMore
|
21
|
+
class MailerBase
|
22
|
+
# Returns the available mail fields when composing a message
|
23
|
+
def self.mail_fields
|
24
|
+
[:to, :from, :subject, :type, :charset, :via, :attachments]
|
25
|
+
end
|
26
|
+
|
27
|
+
attr_accessor :mail_attributes
|
28
|
+
|
29
|
+
def initialize(mail_name=nil)
|
30
|
+
@mail_name = mail_name
|
31
|
+
@mail_attributes = {}
|
32
|
+
end
|
33
|
+
|
34
|
+
# Defines a method allowing mail attributes to be set into a hash for use when delivering
|
35
|
+
self.mail_fields.each do |field|
|
36
|
+
define_method(field) { |value| @mail_attributes[field] = value }
|
37
|
+
end
|
38
|
+
|
39
|
+
# Assigns the body key to the mail attributes either with the rendered body from a template or the given string value
|
40
|
+
def body(body_value)
|
41
|
+
@mail_attributes[:body] = Tilt.new(template_path).render(self, body_value.symbolize_keys) if body_value.is_a?(Hash)
|
42
|
+
@mail_attributes[:body] = body_value if body_value.is_a?(String)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Returns the path to the email template searched for using glob pattern
|
46
|
+
def template_path
|
47
|
+
Dir[File.join(self.views_path, self.class.name.underscore.split("/").last, "#{@mail_name}.*")].first
|
48
|
+
end
|
49
|
+
|
50
|
+
cattr_accessor :smtp_settings
|
51
|
+
cattr_accessor :views_path
|
52
|
+
|
53
|
+
# Delivers the specified message for mail_name to the intended recipients
|
54
|
+
# mail_name corresponds to the name of a defined method within the mailer class
|
55
|
+
# SampleMailer.deliver(:birthday_message)
|
56
|
+
def self.deliver(mail_name, *args)
|
57
|
+
mail_object = self.new(mail_name)
|
58
|
+
mail_object.method(mail_name).call(*args)
|
59
|
+
MailObject.new(mail_object.mail_attributes, self.smtp_settings).deliver
|
60
|
+
end
|
61
|
+
|
62
|
+
# Returns true if a mail exists with the name being delivered
|
63
|
+
def self.respond_to?(method_sym, include_private = false)
|
64
|
+
method_sym.to_s =~ /deliver_(.*)/ ? self.method_defined?($1) : super
|
65
|
+
end
|
66
|
+
|
67
|
+
# Handles method missing for a mailer class. Delivers a message based on the method
|
68
|
+
# being called i.e #deliver_birthday_message(22) invokes #birthday_message(22) to setup mail object
|
69
|
+
def self.method_missing(method_sym, *arguments, &block)
|
70
|
+
method_sym.to_s =~ /deliver_(.*)/ ? self.deliver($1, *arguments) : super
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'tilt'
|
2
|
+
require File.dirname(__FILE__) + '/support_lite'
|
3
|
+
require File.dirname(__FILE__) + '/../../vendor/pony/lib/pony'
|
4
|
+
Dir[File.dirname(__FILE__) + '/mailer_plugin/**/*.rb'].each { |file| load file }
|
5
|
+
|
6
|
+
module SinatraMore
|
7
|
+
module MailerPlugin
|
8
|
+
def self.registered(app)
|
9
|
+
MailerBase::views_path = app.views
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/lib/sinatra_more.rb
CHANGED
@@ -3,3 +3,4 @@ require 'sinatra/base'
|
|
3
3
|
require File.join(File.dirname(__FILE__) + '/sinatra_more/markup_plugin')
|
4
4
|
require File.join(File.dirname(__FILE__) + '/sinatra_more/render_plugin')
|
5
5
|
require File.join(File.dirname(__FILE__) + '/sinatra_more/warden_plugin')
|
6
|
+
require File.join(File.dirname(__FILE__) + '/sinatra_more/mailer_plugin')
|
data/sinatra_more.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{sinatra_more}
|
8
|
-
s.version = "0.2.
|
8
|
+
s.version = "0.2.8"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Nathan Esquenazi"]
|
12
|
-
s.date = %q{2009-
|
12
|
+
s.date = %q{2009-11-03}
|
13
13
|
s.description = %q{Expands sinatra with standard helpers and tools to allow for complex applications}
|
14
14
|
s.email = %q{nesquena@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -25,6 +25,9 @@ Gem::Specification.new do |s|
|
|
25
25
|
"TODO",
|
26
26
|
"VERSION",
|
27
27
|
"lib/sinatra_more.rb",
|
28
|
+
"lib/sinatra_more/mailer_plugin.rb",
|
29
|
+
"lib/sinatra_more/mailer_plugin/mail_object.rb",
|
30
|
+
"lib/sinatra_more/mailer_plugin/mailer_base.rb",
|
28
31
|
"lib/sinatra_more/markup_plugin.rb",
|
29
32
|
"lib/sinatra_more/markup_plugin/asset_tag_helpers.rb",
|
30
33
|
"lib/sinatra_more/markup_plugin/form_builder/abstract_form_builder.rb",
|
@@ -40,6 +43,10 @@ Gem::Specification.new do |s|
|
|
40
43
|
"lib/sinatra_more/warden_plugin/warden_helpers.rb",
|
41
44
|
"sinatra_more.gemspec",
|
42
45
|
"test/active_support_helpers.rb",
|
46
|
+
"test/fixtures/mailer_app/app.rb",
|
47
|
+
"test/fixtures/mailer_app/views/demo_mailer/sample_mail.erb",
|
48
|
+
"test/fixtures/mailer_app/views/sample_mailer/anniversary_message.erb",
|
49
|
+
"test/fixtures/mailer_app/views/sample_mailer/birthday_message.erb",
|
43
50
|
"test/fixtures/markup_app/app.rb",
|
44
51
|
"test/fixtures/markup_app/views/capture_concat.erb",
|
45
52
|
"test/fixtures/markup_app/views/capture_concat.haml",
|
@@ -60,14 +67,20 @@ Gem::Specification.new do |s|
|
|
60
67
|
"test/fixtures/warden_app/app.rb",
|
61
68
|
"test/fixtures/warden_app/views/dashboard.haml",
|
62
69
|
"test/helper.rb",
|
70
|
+
"test/mailer_plugin/test_mail_object.rb",
|
71
|
+
"test/mailer_plugin/test_mailer_base.rb",
|
63
72
|
"test/markup_plugin/test_asset_tag_helpers.rb",
|
64
73
|
"test/markup_plugin/test_form_builder.rb",
|
65
74
|
"test/markup_plugin/test_form_helpers.rb",
|
66
75
|
"test/markup_plugin/test_format_helpers.rb",
|
67
76
|
"test/markup_plugin/test_output_helpers.rb",
|
68
77
|
"test/markup_plugin/test_tag_helpers.rb",
|
78
|
+
"test/test_mailer_plugin.rb",
|
69
79
|
"test/test_render_plugin.rb",
|
70
|
-
"test/test_warden_plugin.rb"
|
80
|
+
"test/test_warden_plugin.rb",
|
81
|
+
"vendor/pony/lib/pony.rb",
|
82
|
+
"vendor/pony/spec/base.rb",
|
83
|
+
"vendor/pony/spec/pony_spec.rb"
|
71
84
|
]
|
72
85
|
s.homepage = %q{http://github.com/nesquena/sinatra_more}
|
73
86
|
s.rdoc_options = ["--charset=UTF-8"]
|
@@ -76,16 +89,20 @@ Gem::Specification.new do |s|
|
|
76
89
|
s.summary = %q{Expands sinatra to allow for complex applications}
|
77
90
|
s.test_files = [
|
78
91
|
"test/active_support_helpers.rb",
|
92
|
+
"test/fixtures/mailer_app/app.rb",
|
79
93
|
"test/fixtures/markup_app/app.rb",
|
80
94
|
"test/fixtures/render_app/app.rb",
|
81
95
|
"test/fixtures/warden_app/app.rb",
|
82
96
|
"test/helper.rb",
|
97
|
+
"test/mailer_plugin/test_mail_object.rb",
|
98
|
+
"test/mailer_plugin/test_mailer_base.rb",
|
83
99
|
"test/markup_plugin/test_asset_tag_helpers.rb",
|
84
100
|
"test/markup_plugin/test_form_builder.rb",
|
85
101
|
"test/markup_plugin/test_form_helpers.rb",
|
86
102
|
"test/markup_plugin/test_format_helpers.rb",
|
87
103
|
"test/markup_plugin/test_output_helpers.rb",
|
88
104
|
"test/markup_plugin/test_tag_helpers.rb",
|
105
|
+
"test/test_mailer_plugin.rb",
|
89
106
|
"test/test_render_plugin.rb",
|
90
107
|
"test/test_warden_plugin.rb"
|
91
108
|
]
|
@@ -95,6 +112,7 @@ Gem::Specification.new do |s|
|
|
95
112
|
s.specification_version = 3
|
96
113
|
|
97
114
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
115
|
+
s.add_runtime_dependency(%q<tilt>, [">= 0.2"])
|
98
116
|
s.add_runtime_dependency(%q<sinatra>, [">= 0.9.2"])
|
99
117
|
s.add_runtime_dependency(%q<activesupport>, [">= 2.2.2"])
|
100
118
|
s.add_development_dependency(%q<haml>, [">= 2.2.1"])
|
@@ -103,6 +121,7 @@ Gem::Specification.new do |s|
|
|
103
121
|
s.add_development_dependency(%q<rack-test>, [">= 0.5.0"])
|
104
122
|
s.add_development_dependency(%q<webrat>, [">= 0.5.1"])
|
105
123
|
else
|
124
|
+
s.add_dependency(%q<tilt>, [">= 0.2"])
|
106
125
|
s.add_dependency(%q<sinatra>, [">= 0.9.2"])
|
107
126
|
s.add_dependency(%q<activesupport>, [">= 2.2.2"])
|
108
127
|
s.add_dependency(%q<haml>, [">= 2.2.1"])
|
@@ -112,6 +131,7 @@ Gem::Specification.new do |s|
|
|
112
131
|
s.add_dependency(%q<webrat>, [">= 0.5.1"])
|
113
132
|
end
|
114
133
|
else
|
134
|
+
s.add_dependency(%q<tilt>, [">= 0.2"])
|
115
135
|
s.add_dependency(%q<sinatra>, [">= 0.9.2"])
|
116
136
|
s.add_dependency(%q<activesupport>, [">= 2.2.2"])
|
117
137
|
s.add_dependency(%q<haml>, [">= 2.2.1"])
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
require 'sinatra_more'
|
3
|
+
require 'haml'
|
4
|
+
|
5
|
+
class MailerDemo < Sinatra::Base
|
6
|
+
configure do
|
7
|
+
set :root, File.dirname(__FILE__)
|
8
|
+
set :smtp_settings, {
|
9
|
+
:host => 'smtp.gmail.com',
|
10
|
+
:port => '587',
|
11
|
+
:tls => true,
|
12
|
+
:user => 'user',
|
13
|
+
:pass => 'pass',
|
14
|
+
:auth => :plain
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
register SinatraMore::MailerPlugin
|
19
|
+
|
20
|
+
class SampleMailer < SinatraMore::MailerBase
|
21
|
+
def birthday_message(name, age)
|
22
|
+
subject "Happy Birthday!"
|
23
|
+
to 'john@fake.com'
|
24
|
+
from 'noreply@birthday.com'
|
25
|
+
body 'name' => name, 'age' => age
|
26
|
+
via :smtp
|
27
|
+
end
|
28
|
+
|
29
|
+
def anniversary_message(names, years_married)
|
30
|
+
subject "Happy anniversary!"
|
31
|
+
to 'julie@fake.com'
|
32
|
+
from 'noreply@anniversary.com'
|
33
|
+
body 'names' => names, 'years_married' => years_married
|
34
|
+
type 'html'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
post "/deliver/plain" do
|
39
|
+
result = SampleMailer.deliver_birthday_message("Joey", 21)
|
40
|
+
result ? "mail delivered" : 'mail not delivered'
|
41
|
+
end
|
42
|
+
|
43
|
+
post "/deliver/html" do
|
44
|
+
result = SampleMailer.deliver_anniversary_message("Joey & Charlotte", 16)
|
45
|
+
result ? "mail delivered" : 'mail not delivered'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class MailerUser
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
This is a sample message
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'sinatra_more'
|
3
|
+
|
4
|
+
class TestMailObject < Test::Unit::TestCase
|
5
|
+
context 'for #deliver method' do
|
6
|
+
should "send mail with attributes default to sendmail no smtp" do
|
7
|
+
mail_object = SinatraMore::MailObject.new({:to => "test@john.com", :from => "sender@sent.com", :body => "Hello"}, {})
|
8
|
+
Pony.expects(:mail).with(:to => "test@john.com", :from => "sender@sent.com", :body => "Hello", :via => :sendmail)
|
9
|
+
mail_object.deliver
|
10
|
+
end
|
11
|
+
|
12
|
+
should "send mail with attributes default to smtp if set" do
|
13
|
+
mail_object = SinatraMore::MailObject.new({:to => "test@john.com", :body => "Hello"}, { :host => 'smtp.gmail.com' })
|
14
|
+
Pony.expects(:mail).with(:to => "test@john.com", :body => "Hello", :via => :smtp, :smtp => { :host => 'smtp.gmail.com' })
|
15
|
+
mail_object.deliver
|
16
|
+
end
|
17
|
+
|
18
|
+
should "send mail with attributes use sendmail if explicit" do
|
19
|
+
mail_object = SinatraMore::MailObject.new({:to => "test@john.com", :via => :sendmail }, { :host => 'smtp.gmail.com' })
|
20
|
+
Pony.expects(:mail).with(:to => "test@john.com", :via => :sendmail)
|
21
|
+
mail_object.deliver
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'sinatra_more'
|
3
|
+
|
4
|
+
class DemoMailer < SinatraMore::MailerBase
|
5
|
+
def sample_mail
|
6
|
+
from 'test@default.com'
|
7
|
+
to 'test@test.com'
|
8
|
+
body "Hello world!"
|
9
|
+
via :sendmail
|
10
|
+
end
|
11
|
+
|
12
|
+
def sample_mail_smtp
|
13
|
+
from 'test@default.com'
|
14
|
+
to 'test@test.com'
|
15
|
+
body "SMTP Hello world!"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class TestMailerBase < Test::Unit::TestCase
|
20
|
+
context 'for defining email attributes' do
|
21
|
+
DemoMailer.mail_fields.each do |field|
|
22
|
+
should "support setting '#{field}' attribute" do
|
23
|
+
demo_mailer = DemoMailer.new(:sample_mail)
|
24
|
+
demo_mailer.send(field, "some_value")
|
25
|
+
assert_equal({ field => "some_value" }, demo_mailer.mail_attributes)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
should "allow defining text body" do
|
30
|
+
demo_mailer = DemoMailer.new(:sample_mail)
|
31
|
+
demo_mailer.body("Hello world!")
|
32
|
+
assert_equal({ :body => "Hello world!" }, demo_mailer.mail_attributes)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'for retrieving template path' do
|
37
|
+
should "return correct path" do
|
38
|
+
demo_mailer = DemoMailer.new(:sample_mail)
|
39
|
+
assert_match %r{demo_mailer/sample_mail.erb}, demo_mailer.template_path
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'for #deliver class method' do
|
44
|
+
should "perform the email delivery for sendmail" do
|
45
|
+
Pony.expects(:mail).with(:from => 'test@default.com', :to => 'test@test.com', :body => "Hello world!", :via => :sendmail)
|
46
|
+
DemoMailer.deliver(:sample_mail)
|
47
|
+
end
|
48
|
+
|
49
|
+
should "perform the email delivery for smtp" do
|
50
|
+
DemoMailer.smtp_settings = { :host => 'smtp.arcadic.com' }
|
51
|
+
Pony.expects(:mail).with(:from => 'test@default.com', :to => 'test@test.com',
|
52
|
+
:body => "SMTP Hello world!", :via => :smtp, :smtp => { :host => 'smtp.arcadic.com' })
|
53
|
+
DemoMailer.deliver(:sample_mail_smtp)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'for #respond_to? class method' do
|
58
|
+
should "respond as true for any delivery method calls for mails that exist" do
|
59
|
+
assert DemoMailer.respond_to?(:deliver_sample_mail)
|
60
|
+
end
|
61
|
+
|
62
|
+
should "respond as false for any delivery method calls for mails that don't exist" do
|
63
|
+
assert_equal false, DemoMailer.respond_to?(:deliver_faker_mail)
|
64
|
+
end
|
65
|
+
|
66
|
+
should "respond as true for any non-delivery methods that exist" do
|
67
|
+
assert DemoMailer.respond_to?(:inspect)
|
68
|
+
end
|
69
|
+
|
70
|
+
should "respond as false for any non-delivery methods that don't exist" do
|
71
|
+
assert_equal false, DemoMailer.respond_to?(:fake_method)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'for #method_missing dynamic delivery' do
|
76
|
+
should 'invoke deliver method with appropriate parameters' do
|
77
|
+
DemoMailer.expects(:deliver).with("example_name", "test", 5)
|
78
|
+
DemoMailer.deliver_example_name("test", 5)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'fixtures/mailer_app/app'
|
3
|
+
|
4
|
+
class TestMailerPlugin < Test::Unit::TestCase
|
5
|
+
def app
|
6
|
+
MailerDemo.tap { |app| app.set :environment, :test }
|
7
|
+
end
|
8
|
+
|
9
|
+
context 'for mail delivery in sample application' do
|
10
|
+
setup { MailerDemo::SampleMailer.smtp_settings = MailerDemo.smtp_settings }
|
11
|
+
|
12
|
+
should 'be able to deliver plain text emails' do
|
13
|
+
assert_email_sent(:to => 'john@fake.com', :from => 'noreply@birthday.com', :via => :smtp,
|
14
|
+
:subject => "Happy Birthday!", :body => "Happy Birthday Joey! \nYou are turning 21")
|
15
|
+
visit '/deliver/plain', :post
|
16
|
+
assert_equal 'mail delivered', last_response.body
|
17
|
+
end
|
18
|
+
|
19
|
+
should 'be able to deliver html emails' do
|
20
|
+
assert_email_sent(:to => 'julie@fake.com', :from => 'noreply@anniversary.com', :type => 'html', :via => :smtp,
|
21
|
+
:subject => "Happy anniversary!", :body => "<p>Yay Joey & Charlotte!</p>\n<p>You have been married 16 years</p>")
|
22
|
+
visit '/deliver/html', :post
|
23
|
+
assert_equal 'mail delivered', last_response.body
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
protected
|
28
|
+
|
29
|
+
def assert_email_sent(mail_attributes)
|
30
|
+
delivery_attributes = mail_attributes.merge(:smtp => MailerDemo.smtp_settings)
|
31
|
+
SinatraMore::MailObject.any_instance.expects(:send_mail).with(delivery_attributes).once.returns(true)
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'net/smtp'
|
3
|
+
begin
|
4
|
+
require 'smtp_tls'
|
5
|
+
rescue LoadError
|
6
|
+
end
|
7
|
+
require 'base64'
|
8
|
+
begin
|
9
|
+
require 'tmail'
|
10
|
+
rescue LoadError
|
11
|
+
require 'actionmailer'
|
12
|
+
end
|
13
|
+
|
14
|
+
module Pony
|
15
|
+
def self.mail(options)
|
16
|
+
raise(ArgumentError, ":to is required") unless options[:to]
|
17
|
+
|
18
|
+
via = options.delete(:via)
|
19
|
+
if via.nil?
|
20
|
+
transport build_tmail(options)
|
21
|
+
else
|
22
|
+
if via_options.include?(via.to_s)
|
23
|
+
send("transport_via_#{via}", build_tmail(options), options)
|
24
|
+
else
|
25
|
+
raise(ArgumentError, ":via must be either smtp or sendmail")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.build_tmail(options)
|
31
|
+
mail = TMail::Mail.new
|
32
|
+
mail.to = options[:to]
|
33
|
+
mail.from = options[:from] || 'pony@unknown'
|
34
|
+
mail.subject = options[:subject]
|
35
|
+
mail.body = options[:body] || ""
|
36
|
+
mail.set_content_type 'text', options[:type] || 'plain', {'charset'=> options[:charset] || 'utf-8'}
|
37
|
+
(options[:attachments] || []).each do |name, body|
|
38
|
+
attachment = TMail::Mail.new
|
39
|
+
attachment.transfer_encoding = "base64"
|
40
|
+
attachment.body = Base64.encode64(body)
|
41
|
+
# attachment.set_content_type # TODO: if necessary
|
42
|
+
attachment.set_content_disposition "attachment", "filename" => name
|
43
|
+
mail.parts.push attachment
|
44
|
+
end
|
45
|
+
mail
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.sendmail_binary
|
49
|
+
@sendmail_binary ||= `which sendmail`.chomp
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.transport(tmail)
|
53
|
+
if File.executable? sendmail_binary
|
54
|
+
transport_via_sendmail(tmail)
|
55
|
+
else
|
56
|
+
transport_via_smtp(tmail)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.via_options
|
61
|
+
%w(sendmail smtp)
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.transport_via_sendmail(tmail, options={})
|
65
|
+
IO.popen('-', 'w+') do |pipe|
|
66
|
+
if pipe
|
67
|
+
pipe.write(tmail.to_s)
|
68
|
+
else
|
69
|
+
exec(sendmail_binary, *tmail.to)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.transport_via_smtp(tmail, options={:smtp => {}})
|
75
|
+
default_options = {:smtp => { :host => 'localhost', :port => '25', :domain => 'localhost.localdomain' }}
|
76
|
+
o = default_options[:smtp].merge(options[:smtp])
|
77
|
+
smtp = Net::SMTP.new(o[:host], o[:port])
|
78
|
+
if o[:tls]
|
79
|
+
raise "You may need: gem install smtp_tls" unless smtp.respond_to?(:enable_starttls)
|
80
|
+
smtp.enable_starttls
|
81
|
+
end
|
82
|
+
if o.include?(:auth)
|
83
|
+
smtp.start(o[:domain], o[:user], o[:password], o[:auth])
|
84
|
+
else
|
85
|
+
smtp.start(o[:domain])
|
86
|
+
end
|
87
|
+
smtp.send_message tmail.to_s, tmail.from, tmail.to
|
88
|
+
smtp.finish
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/base'
|
2
|
+
|
3
|
+
describe Pony do
|
4
|
+
it "sends mail" do
|
5
|
+
Pony.should_receive(:transport) do |tmail|
|
6
|
+
tmail.to.should == [ 'joe@example.com' ]
|
7
|
+
tmail.from.should == [ 'sender@example.com' ]
|
8
|
+
tmail.subject.should == 'hi'
|
9
|
+
tmail.body.should == 'Hello, Joe.'
|
10
|
+
end
|
11
|
+
Pony.mail(:to => 'joe@example.com', :from => 'sender@example.com', :subject => 'hi', :body => 'Hello, Joe.')
|
12
|
+
end
|
13
|
+
|
14
|
+
it "requires :to param" do
|
15
|
+
Pony.stub!(:transport)
|
16
|
+
lambda { Pony.mail({}) }.should raise_error(ArgumentError)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "doesn't require any other param" do
|
20
|
+
Pony.stub!(:transport)
|
21
|
+
lambda { Pony.mail(:to => 'joe@example.com') }.should_not raise_error
|
22
|
+
end
|
23
|
+
|
24
|
+
####################
|
25
|
+
|
26
|
+
describe "builds a TMail object with field:" do
|
27
|
+
it "to" do
|
28
|
+
Pony.build_tmail(:to => 'joe@example.com').to.should == [ 'joe@example.com' ]
|
29
|
+
end
|
30
|
+
|
31
|
+
it "from" do
|
32
|
+
Pony.build_tmail(:from => 'joe@example.com').from.should == [ 'joe@example.com' ]
|
33
|
+
end
|
34
|
+
|
35
|
+
it "from (default)" do
|
36
|
+
Pony.build_tmail({}).from.should == [ 'pony@unknown' ]
|
37
|
+
end
|
38
|
+
|
39
|
+
it "subject" do
|
40
|
+
Pony.build_tmail(:subject => 'hello').subject.should == 'hello'
|
41
|
+
end
|
42
|
+
|
43
|
+
it "body" do
|
44
|
+
Pony.build_tmail(:body => 'What do you know, Joe?').body.should == 'What do you know, Joe?'
|
45
|
+
end
|
46
|
+
|
47
|
+
it "type" do
|
48
|
+
Pony.build_tmail(:type => 'html').content_type.should == 'text/html'
|
49
|
+
end
|
50
|
+
|
51
|
+
it "charset" do
|
52
|
+
Pony.build_tmail(:charset => 'windows-1252').charset.should == 'windows-1252'
|
53
|
+
end
|
54
|
+
|
55
|
+
it "attachments" do
|
56
|
+
tmail = Pony.build_tmail(:attachments => {"foo.txt" => "content of foo.txt"})
|
57
|
+
tmail.should have(1).parts
|
58
|
+
tmail.parts.first.to_s.should == <<-PART
|
59
|
+
Content-Transfer-Encoding: Base64
|
60
|
+
Content-Disposition: attachment; filename=foo.txt
|
61
|
+
|
62
|
+
Y29udGVudCBvZiBmb28udHh0
|
63
|
+
PART
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "transport" do
|
68
|
+
it "transports via the sendmail binary if it exists" do
|
69
|
+
File.stub!(:executable?).and_return(true)
|
70
|
+
Pony.should_receive(:transport_via_sendmail).with(:tmail)
|
71
|
+
Pony.transport(:tmail)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "transports via smtp if no sendmail binary" do
|
75
|
+
Pony.stub!(:sendmail_binary).and_return('/does/not/exist')
|
76
|
+
Pony.should_receive(:transport_via_smtp).with(:tmail)
|
77
|
+
Pony.transport(:tmail)
|
78
|
+
end
|
79
|
+
|
80
|
+
it "transports mail via /usr/sbin/sendmail binary" do
|
81
|
+
pipe = mock('sendmail pipe')
|
82
|
+
IO.should_receive(:popen).with('-',"w+").and_yield(pipe)
|
83
|
+
pipe.should_receive(:write).with('message')
|
84
|
+
Pony.transport_via_sendmail(mock('tmail', :to => 'to', :from => 'from', :to_s => 'message'))
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "SMTP transport" do
|
88
|
+
before do
|
89
|
+
@smtp = mock('net::smtp object')
|
90
|
+
@smtp.stub!(:start)
|
91
|
+
@smtp.stub!(:send_message)
|
92
|
+
@smtp.stub!(:finish)
|
93
|
+
Net::SMTP.stub!(:new).and_return(@smtp)
|
94
|
+
end
|
95
|
+
|
96
|
+
it "defaults to localhost as the SMTP server" do
|
97
|
+
Net::SMTP.should_receive(:new).with('localhost', '25').and_return(@smtp)
|
98
|
+
Pony.transport_via_smtp(mock('tmail', :to => 'to', :from => 'from', :to_s => 'message'))
|
99
|
+
end
|
100
|
+
|
101
|
+
it "uses SMTP authorization when auth key is provided" do
|
102
|
+
o = { :smtp => { :user => 'user', :password => 'password', :auth => 'plain'}}
|
103
|
+
@smtp.should_receive(:start).with('localhost.localdomain', 'user', 'password', 'plain')
|
104
|
+
Pony.transport_via_smtp(mock('tmail', :to => 'to', :from => 'from', :to_s => 'message'), o)
|
105
|
+
end
|
106
|
+
|
107
|
+
it "enable starttls when tls option is true" do
|
108
|
+
o = { :smtp => { :user => 'user', :password => 'password', :auth => 'plain', :tls => true}}
|
109
|
+
@smtp.should_receive(:enable_starttls)
|
110
|
+
Pony.transport_via_smtp(mock('tmail', :to => 'to', :from => 'from', :to_s => 'message'), o)
|
111
|
+
end
|
112
|
+
|
113
|
+
it "starts the job" do
|
114
|
+
@smtp.should_receive(:start)
|
115
|
+
Pony.transport_via_smtp(mock('tmail', :to => 'to', :from => 'from', :to_s => 'message'))
|
116
|
+
end
|
117
|
+
|
118
|
+
it "sends a tmail message" do
|
119
|
+
@smtp.should_receive(:send_message)
|
120
|
+
Pony.transport_via_smtp(mock('tmail', :to => 'to', :from => 'from', :to_s => 'message'))
|
121
|
+
end
|
122
|
+
|
123
|
+
it "finishes the job" do
|
124
|
+
@smtp.should_receive(:finish)
|
125
|
+
Pony.transport_via_smtp(mock('tmail', :to => 'to', :from => 'from', :to_s => 'message'))
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe ":via option should over-ride the default transport mechanism" do
|
132
|
+
it "should send via sendmail if :via => sendmail" do
|
133
|
+
Pony.should_receive(:transport_via_sendmail)
|
134
|
+
Pony.mail(:to => 'joe@example.com', :via => :sendmail)
|
135
|
+
end
|
136
|
+
|
137
|
+
it "should send via smtp if :via => smtp" do
|
138
|
+
Pony.should_receive(:transport_via_smtp)
|
139
|
+
Pony.mail(:to => 'joe@example.com', :via => :smtp)
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should raise an error if via is neither smtp nor sendmail" do
|
143
|
+
lambda { Pony.mail(:to => 'joe@plumber.com', :via => :pigeon) }.should raise_error(ArgumentError)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sinatra_more
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nathan Esquenazi
|
@@ -9,9 +9,19 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-11-03 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: tilt
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0.2"
|
24
|
+
version:
|
15
25
|
- !ruby/object:Gem::Dependency
|
16
26
|
name: sinatra
|
17
27
|
type: :runtime
|
@@ -100,6 +110,9 @@ files:
|
|
100
110
|
- TODO
|
101
111
|
- VERSION
|
102
112
|
- lib/sinatra_more.rb
|
113
|
+
- lib/sinatra_more/mailer_plugin.rb
|
114
|
+
- lib/sinatra_more/mailer_plugin/mail_object.rb
|
115
|
+
- lib/sinatra_more/mailer_plugin/mailer_base.rb
|
103
116
|
- lib/sinatra_more/markup_plugin.rb
|
104
117
|
- lib/sinatra_more/markup_plugin/asset_tag_helpers.rb
|
105
118
|
- lib/sinatra_more/markup_plugin/form_builder/abstract_form_builder.rb
|
@@ -115,6 +128,10 @@ files:
|
|
115
128
|
- lib/sinatra_more/warden_plugin/warden_helpers.rb
|
116
129
|
- sinatra_more.gemspec
|
117
130
|
- test/active_support_helpers.rb
|
131
|
+
- test/fixtures/mailer_app/app.rb
|
132
|
+
- test/fixtures/mailer_app/views/demo_mailer/sample_mail.erb
|
133
|
+
- test/fixtures/mailer_app/views/sample_mailer/anniversary_message.erb
|
134
|
+
- test/fixtures/mailer_app/views/sample_mailer/birthday_message.erb
|
118
135
|
- test/fixtures/markup_app/app.rb
|
119
136
|
- test/fixtures/markup_app/views/capture_concat.erb
|
120
137
|
- test/fixtures/markup_app/views/capture_concat.haml
|
@@ -135,14 +152,20 @@ files:
|
|
135
152
|
- test/fixtures/warden_app/app.rb
|
136
153
|
- test/fixtures/warden_app/views/dashboard.haml
|
137
154
|
- test/helper.rb
|
155
|
+
- test/mailer_plugin/test_mail_object.rb
|
156
|
+
- test/mailer_plugin/test_mailer_base.rb
|
138
157
|
- test/markup_plugin/test_asset_tag_helpers.rb
|
139
158
|
- test/markup_plugin/test_form_builder.rb
|
140
159
|
- test/markup_plugin/test_form_helpers.rb
|
141
160
|
- test/markup_plugin/test_format_helpers.rb
|
142
161
|
- test/markup_plugin/test_output_helpers.rb
|
143
162
|
- test/markup_plugin/test_tag_helpers.rb
|
163
|
+
- test/test_mailer_plugin.rb
|
144
164
|
- test/test_render_plugin.rb
|
145
165
|
- test/test_warden_plugin.rb
|
166
|
+
- vendor/pony/lib/pony.rb
|
167
|
+
- vendor/pony/spec/base.rb
|
168
|
+
- vendor/pony/spec/pony_spec.rb
|
146
169
|
has_rdoc: true
|
147
170
|
homepage: http://github.com/nesquena/sinatra_more
|
148
171
|
licenses: []
|
@@ -173,15 +196,19 @@ specification_version: 3
|
|
173
196
|
summary: Expands sinatra to allow for complex applications
|
174
197
|
test_files:
|
175
198
|
- test/active_support_helpers.rb
|
199
|
+
- test/fixtures/mailer_app/app.rb
|
176
200
|
- test/fixtures/markup_app/app.rb
|
177
201
|
- test/fixtures/render_app/app.rb
|
178
202
|
- test/fixtures/warden_app/app.rb
|
179
203
|
- test/helper.rb
|
204
|
+
- test/mailer_plugin/test_mail_object.rb
|
205
|
+
- test/mailer_plugin/test_mailer_base.rb
|
180
206
|
- test/markup_plugin/test_asset_tag_helpers.rb
|
181
207
|
- test/markup_plugin/test_form_builder.rb
|
182
208
|
- test/markup_plugin/test_form_helpers.rb
|
183
209
|
- test/markup_plugin/test_format_helpers.rb
|
184
210
|
- test/markup_plugin/test_output_helpers.rb
|
185
211
|
- test/markup_plugin/test_tag_helpers.rb
|
212
|
+
- test/test_mailer_plugin.rb
|
186
213
|
- test/test_render_plugin.rb
|
187
214
|
- test/test_warden_plugin.rb
|