public
Description: Merb More: The Full Stack. Take what you need; leave what you don't.
Homepage: http://www.merbivore.com
Clone URL: git://github.com/wycats/merb-more.git
Make url generation work properly in mail controllers.

* Add 2 spec examples for absolute and relative urls generation.
* Implement url and absolute_url that really mimic AbstractController behavior.
Thu Sep 25 03:50:29 -0700 2008
commit  caa348607393a55ffd586ab880f49d91acb1c772
tree    614036efa1781d5be6302543bdbcc5307446bc7f
parent  6a480e81ca9dc765cf90506abd607ff3c0e6e6c2
...
6
7
8
9
 
10
11
12
13
14
 
15
16
17
18
19
 
20
21
22
23
 
 
24
25
26
...
28
29
30
31
 
32
33
34
 
35
36
37
...
47
48
49
50
 
51
52
53
54
55
56
 
 
 
57
58
59
...
91
92
93
94
95
96
 
 
 
97
98
99
100
 
101
102
 
103
104
105
...
126
127
128
129
 
130
131
132
...
172
173
174
175
 
176
177
178
...
213
214
215
216
 
217
218
219
220
221
222
 
223
224
225
...
228
229
230
231
 
232
233
234
...
252
253
254
255
256
257
 
 
 
 
 
 
 
 
 
 
258
259
260
261
262
 
263
264
265
...
271
272
273
274
 
275
276
277
 
278
279
280
 
281
282
283
284
 
285
286
287
...
305
306
307
308
 
309
310
311
...
6
7
8
 
9
10
11
12
13
 
14
15
16
17
18
 
19
20
21
 
 
22
23
24
25
26
...
28
29
30
 
31
32
33
 
34
35
36
37
...
47
48
49
 
50
51
52
53
 
 
 
54
55
56
57
58
59
...
91
92
93
 
 
 
94
95
96
97
98
99
 
100
101
 
102
103
104
105
...
126
127
128
 
129
130
131
132
...
172
173
174
 
175
176
177
178
...
213
214
215
 
216
217
218
219
220
221
 
222
223
224
225
...
228
229
230
 
231
232
233
234
...
252
253
254
 
 
 
255
256
257
258
259
260
261
262
263
264
265
266
267
268
 
269
270
271
272
...
278
279
280
 
281
282
283
 
284
285
286
 
287
288
289
290
 
291
292
293
294
...
312
313
314
 
315
316
317
318
0
@@ -6,21 +6,21 @@ module Merb
0
   # * Create a MailController subclass with actions and templates.
0
   # * Call the MailController from another Controller via the send_mail method.
0
   #
0
-  # First, create a file in app/mailers that subclasses Merb::MailController. 
0
+  # First, create a file in app/mailers that subclasses Merb::MailController.
0
   # The actions in this controller will do nothing but render mail.
0
   #
0
   #   # app/mailers/article_mailer.rb
0
   #   class ArticleMailer < Merb::MailController
0
-  # 
0
+  #
0
   #     def notify
0
   #       @user = params[:user]
0
   #       render_mail
0
   #     end
0
-  # 
0
+  #
0
   #   end
0
   #
0
-  # You also can access the params hash for values passed with the 
0
-  # Controller.send_mail method. See also the documentation for 
0
+  # You also can access the params hash for values passed with the
0
+  # Controller.send_mail method. See also the documentation for
0
   # render_mail to see all the ways it can be called.
0
   #
0
   # Create a template in a subdirectory of app/mailers/views that corresponds
0
@@ -28,10 +28,10 @@ module Merb
0
   #
0
   #   # app/mailers/views/article_mailer/notify.text.erb
0
   #   Hey, <%= @user.name %>,
0
-  #   
0
+  #
0
   #   We're running a sale on dog bones!
0
   #
0
-  # Finally, call the Controller.send_mail method from a standard 
0
+  # Finally, call the Controller.send_mail method from a standard
0
   # Merb controller.
0
   #
0
   #   class Articles < Application
0
@@ -47,13 +47,13 @@ module Merb
0
   #       render
0
   #     end
0
   #
0
-  #   end  
0
+  #   end
0
   #
0
   # Note: If you don't pass a fourth argument to Controller.send_mail,
0
   # the controller's params will be sent to the MailController subclass
0
-  # as params. However, you can explicitly send a hash of objects that 
0
-  # will populate the params hash instead. In either case, you must 
0
-  # set instance variables in the MailController's actions if you 
0
+  # as params. However, you can explicitly send a hash of objects that
0
+  # will populate the params hash instead. In either case, you must
0
+  # set instance variables in the MailController's actions if you
0
   # want to use them in the MailController's views.
0
   #
0
   # The MailController class is very powerful. You can:
0
@@ -91,15 +91,15 @@ module Merb
0
     def _template_location(action, type = nil, controller = controller_name)
0
       "#{controller}/#{action}.#{type}"
0
     end
0
-    
0
-    # The location to look for a template and mime-type. This is overridden 
0
-    # from AbstractController, which defines a version of this that does not 
0
+
0
+    # The location to look for a template and mime-type. This is overridden
0
+    # from AbstractController, which defines a version of this that does not
0
     # involve mime-types.
0
     #
0
     # ==== Parameters
0
-    # template<String>:: 
0
+    # template<String>::
0
     #    The absolute path to a template - without mime and template extension.
0
-    #    The mime-type extension is optional - it will be appended from the 
0
+    #    The mime-type extension is optional - it will be appended from the
0
     #    current content type if it hasn't been added already.
0
     # type<~to_s>::
0
     #    The mime-type of the template that will be rendered. Defaults to nil.
0
@@ -126,7 +126,7 @@ module Merb
0
     #
0
     # ==== Parameters
0
     # klass<Class>::
0
-    #   The Merb::MailController inheriting from the base class.  
0
+    #   The Merb::MailController inheriting from the base class.
0
     def self.inherited(klass)
0
       super
0
       klass._template_root = Merb.dir_for(:mailer) / "views" unless self._template_root
0
@@ -172,7 +172,7 @@ module Merb
0
     # "foo", this is identical to render_mail :foo.
0
     #
0
     #   render_mail :foo
0
-    # 
0
+    #
0
     # checks for foo.html.ext and foo.text.ext and applies them as appropriate.
0
     #
0
     #   render_mail :action => {:html => :foo, :text => :bar}
0
@@ -213,13 +213,13 @@ module Merb
0
       @_missing_templates = false # used to make sure that at least one template was found
0
       # If the options are not a hash, normalize to an action hash
0
       options = {:action => {:html => options, :text => options}} if !options.is_a?(Hash)
0
-  
0
+
0
       # Take care of the options
0
       opts_hash = {}
0
       opts = options.dup
0
       actions = opts.delete(:action) if opts[:action].is_a?(Hash)
0
       templates = opts.delete(:template) if opts[:template].is_a?(Hash)
0
-  
0
+
0
       # Prepare the options hash for each format
0
       # We need to delete anything relating to the other format here
0
       # before we try to render the template.
0
@@ -228,7 +228,7 @@ module Merb
0
         opts_hash[fmt] ||= actions[fmt] if actions && actions[fmt]
0
         opts_hash[:template] = templates[fmt] if templates && templates[fmt]
0
       end
0
-        
0
+
0
       # Send the result to the mailer
0
       { :html => "rawhtml=", :text => "text="}.each do |fmt,meth|
0
         begin
0
@@ -252,14 +252,21 @@ module Merb
0
 
0
     # Mimic the behavior of absolute_url in AbstractController
0
     # but use @base_controller.request
0
-    def absolute_url(name, rparams={})
0
-      req = @base_controller.request
0
-      uri =  req.protocol + req.host + url(name, rparams)
0
+    def url(name, *args)
0
+      self.base_controller.request.generate_url(name, *args)
0
+    end
0
+
0
+    alias_method :relative_url, :url
0
+
0
+    # Mimic the behavior of absolute_url in AbstractController
0
+    # but use @base_controller.request
0
+    def absolute_url(name, *args)
0
+      self.base_controller.request.generate_absolute_url(name, *args)
0
     end
0
 
0
     # Attaches a file or multiple files to an email. You call this from a
0
     # method in your MailController (including a before filter).
0
-    # 
0
+    #
0
     # ==== Parameters
0
     # file_or_files<File, Array[File]>:: File(s) to attach.
0
     # filename<String>::
0
@@ -271,17 +278,17 @@ module Merb
0
     # ==== Examples
0
     #   attach File.open("foo")
0
     #   attach [File.open("foo"), File.open("bar")]
0
-    # 
0
+    #
0
     # If you are passing an array of files, you should use an array of the
0
     # allowed parameters:
0
-    # 
0
+    #
0
     #   attach [[File.open("foo"), "bar", "text/html"], [File.open("baz"),
0
     #     "bat", "text/css"]
0
-    # 
0
+    #
0
     #  which would attach two files ("foo" and "baz" in the filesystem) as
0
     # "bar" and "bat" respectively. It would also set the mime-type as
0
     # "text/html" and "text/css" respectively.
0
-    def attach( file_or_files, filename = file_or_files.is_a?(File) ? File.basename(file_or_files.path) : nil, 
0
+    def attach( file_or_files, filename = file_or_files.is_a?(File) ? File.basename(file_or_files.path) : nil,
0
       type = nil, headers = nil)
0
       @mailer.attach(file_or_files, filename, type, headers)
0
     end
0
@@ -305,7 +312,7 @@ module Merb
0
       @mailer         = self.class._mailer_klass.new(mail_params)
0
       @mail           = @mailer.mail
0
       @method         = method
0
-  
0
+
0
       # dispatch and render use params[:action], so set it
0
       self.action_name = method
0
 
...
1
2
3
4
 
 
5
6
7
...
48
49
50
51
 
52
53
54
55
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
57
 
58
59
60
61
62
63
64
65
66
...
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
...
1
2
3
 
4
5
6
7
8
...
49
50
51
 
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
 
75
76
77
 
78
79
80
...
152
153
154
 
 
155
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
0
@@ -1,7 +1,8 @@
0
 require File.dirname(__FILE__) + '/spec_helper'
0
 
0
 Spec::Runner.configure do |config|
0
-  config.include Merb::Test::RequestHelper  
0
+  config.include Merb::Test::RequestHelper
0
+  config.include Merb::Test::ControllerHelper
0
 end
0
 
0
 class Merb::Mailer
0
@@ -48,19 +49,32 @@ class TestMailController < Merb::MailController
0
   def ninth
0
     render_mail
0
   end
0
-  
0
+
0
   def tenth
0
     render_mail
0
   end
0
   
0
+  def generates_relative_url
0
+    render_mail
0
+  end
0
+
0
+  def generates_absolute_url
0
+    render_mail
0
+  end
0
+end
0
+
0
+
0
+Merb::Router.prepare do
0
+  match("/subprojects/:subproject").
0
+    to(:controller => "test_controller", :action => "whatever").
0
+    name(:merb_subproject)
0
 end
0
 
0
+
0
 class TestController < Merb::Controller
0
-  
0
   def one
0
     send_mail TestMailController, :ninth, {:from => "foo@bar.com", :to => "foo@bar.com"}, {:x => "ONE_CONTROLLER"}
0
   end
0
-  
0
 end
0
 
0
 describe "A Merb Mail controller" do
0
@@ -138,37 +152,20 @@ describe "A Merb Mail controller" do
0
     Merb.logger.should_receive(:error).once
0
     deliver :tenth
0
   end
0
-  
0
-end
0
 
0
-# describe "Merb::MailController with url generation" do
0
-#   
0
-#   it_should_behave_like "class with general url generation"
0
-#   it_should_behave_like "non routeable controller with url mixin"
0
-#   
0
-#   def new_url_controller(route, params = {:action => 'show', :controller => 'Test'})
0
-#     request = OpenStruct.new
0
-#     request.route = route
0
-#     request.params = params
0
-#     response = OpenStruct.new
0
-#     response.read = ""
0
-#     
0
-#     @controller = Merb::Controller.build(request, response)
0
-#     TestMailController.new(params, @controller)
0
-#   end
0
-#   
0
-#   it "should raise an error if no controller is specified and the base controller is not set" do
0
-#     c = new_url_controller(@default_route, {})    
0
-#     lambda do
0
-#       the_url = c.url(:action => "bar")
0
-#     end.should raise_error
0
-#   end
0
-#   
0
-#   it "should use the base controller when it is set to generate a url when no :controller option is specified" do
0
-#     c = new_url_controller(@defualt_route, :controller => "foo")
0
-#     lambda do
0
-#       the_url = c.url(:action => "bar")
0
-#       the_url.should == "/foo/bar"
0
-#     end.should_not raise_error    
0
-#   end
0
-# end
0
+  it "delegates relative url generation to base controller" do
0
+    controller = TestController.new(fake_request)
0
+    TestMailController.new({ :subproject => "core" }, controller).
0
+      dispatch_and_deliver :generates_relative_url, :from => "foo@bar.com", :to => "foo@bar.com"
0
+    
0
+    Merb::Mailer.deliveries.last.text.should == "TEXT\n/subprojects/core\nENDTEXT"
0
+  end
0
+
0
+  it "delegates relative url generation to base controller" do
0
+    controller = TestController.new(fake_request)
0
+    TestMailController.new({ :subproject => "extlib" }, controller).
0
+      dispatch_and_deliver :generates_absolute_url, :from => "foo@bar.com", :to => "foo@bar.com"
0
+    
0
+    Merb::Mailer.deliveries.last.text.should == "TEXT\nhttp://merbivore.com/subprojects/extlib\nENDTEXT"
0
+  end
0
+end

Comments