sinatra_more 0.2.7 → 0.2.8
Sign up to get free protection for your applications and to get access to all the features.
- 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
|