josevalim-inherited_resources 0.6.2 → 0.6.3

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/CHANGELOG CHANGED
@@ -1,5 +1,18 @@
1
1
  # Version 0.6
2
2
 
3
+ * Ensure that the default template is not rendered if the default_template_format
4
+ is not accepted. This is somehow related with the security breach report:
5
+
6
+ http://www.rorsecurity.info/journal/2009/4/24/hidden-actions-render-templates.html
7
+
8
+ IR forbids based on mime types. For example: respond_to :html, :except => :index
9
+ ensures that the index.html.erb view is not rendered, making your IR controllers
10
+ safer.
11
+
12
+ * Fixed a bug that happens only when format.xml is given to blocks and then it
13
+ acts as default, instead of format.html.
14
+ * Fixed a strange bug where when you have create.html.erb or update.html.erb,
15
+ it makes IE6 and IE7 return unprocessable entity (because they send Mime::ALL).
3
16
  * Stop rescueing any error when constantizing the resource class and allow
4
17
  route_prefix to be nil.
5
18
  * Cleaned up tests and responder structure. Whenever you pass a block to aliases
data/README CHANGED
@@ -1,6 +1,6 @@
1
1
  Inherited Resources
2
2
  License: MIT
3
- Version: 0.6.2
3
+ Version: 0.6.3
4
4
 
5
5
  You can also read this README in pretty html at the GitHub project Wiki page:
6
6
 
@@ -37,7 +37,7 @@ rspec-rails <= 1.1.12 known bug
37
37
  -------------------------------
38
38
 
39
39
  InheritedResources has a known bug with rspec-rails when using blocks inside
40
- actions. This will be fixed in the next rspec release, but until it comes out,
40
+ actions. This is fixed in Rspec >= 1.2.0. But if you have to use 1.1.12, you
41
41
  InheritedResources ships with a patch. To apply it, just put the line below on
42
42
  your spec_helper.rb after loading rspec and rspec-rails:
43
43
 
@@ -245,7 +245,7 @@ module InheritedResources #:nodoc:
245
245
  responder.respond_except_any
246
246
  end
247
247
 
248
- respond_to(options.merge(:responder => responder), &block) unless performed?
248
+ respond_to(options.merge!(:responder => responder, :prioritize => :html), &block) unless performed?
249
249
  end
250
250
 
251
251
  end
@@ -118,14 +118,15 @@ module ActionController #:nodoc:
118
118
  def respond_with(object, options = {})
119
119
  attempt_to_respond = false
120
120
 
121
- responder = options.delete(:responder) || Responder.new(self)
122
- skip_not_acceptable = options.delete(:skip_not_acceptable)
121
+ responder = options.delete(:responder) || Responder.new(self)
122
+ skip_not_acceptable = options.delete(:skip_not_acceptable)
123
+ skip_default_template = options.delete(:skip_default_template)
123
124
 
124
125
  mime_types = Array(options.delete(:to))
125
126
  mime_types.map!{ |mime| mime.to_sym }
126
127
 
127
128
  for priority in responder.mime_type_priority
128
- if priority == Mime::ALL && template_exists?
129
+ if !skip_default_template && priority == Mime::ALL && respond_to_default_template?(responder)
129
130
  render options.merge(:action => action_name)
130
131
  return true
131
132
 
@@ -195,11 +196,16 @@ module ActionController #:nodoc:
195
196
  # format.html { render :template => 'new' }
196
197
  # end
197
198
  #
199
+ # It also accepts an option called prioritize. It allows you to put a
200
+ # format as first, and then when Mime::ALL is sent, it will be the one
201
+ # used as response.
202
+ #
198
203
  def respond_to(*types, &block)
199
204
  options = types.extract_options!
200
205
 
201
- object = options.delete(:with)
202
- responder = options.delete(:responder) || Responder.new(self)
206
+ object = options.delete(:with)
207
+ responder = options.delete(:responder) || Responder.new(self)
208
+ prioritize = options.delete(:prioritize)
203
209
 
204
210
  if object.nil?
205
211
  block ||= lambda { |responder| types.each { |type| responder.send(type) } }
@@ -215,11 +221,15 @@ module ActionController #:nodoc:
215
221
  return true if responder.respond_except_any
216
222
  end
217
223
 
218
- options.merge!(:to => types, :responder => responder, :skip_not_acceptable => true)
224
+ # If the block includes the default template format, we don't render
225
+ # the default template (which uses the default_template_format).
226
+ options.merge!(:to => types, :responder => responder, :skip_not_acceptable => true,
227
+ :skip_default_template => responder.order.include?(default_template_format))
219
228
 
220
229
  if respond_with(object, options)
221
230
  return true
222
231
  elsif block_given?
232
+ responder.prioritize(prioritize) if prioritize
223
233
  return true if responder.respond_any
224
234
  end
225
235
  end
@@ -229,6 +239,7 @@ module ActionController #:nodoc:
229
239
  end
230
240
 
231
241
  private
242
+
232
243
  # Define template_exists? for Rails 2.3
233
244
  unless ActionController::Base.private_instance_methods.include?('template_exists?') ||
234
245
  ActionController::Base.private_instance_methods.include?(:template_exists?)
@@ -240,20 +251,27 @@ module ActionController #:nodoc:
240
251
  end
241
252
  end
242
253
 
243
- # If ApplicationController is already defined around here, we should call
244
- # inherited_with_inheritable_attributes to insert formats_for_respond_to.
245
- # This usually happens only on Rails 2.3.
246
- #
247
- if defined?(ApplicationController)
248
- self.send(:inherited_with_inheritable_attributes, ApplicationController)
249
- end
254
+ # We respond to the default template if it's a valid format AND the template
255
+ # exists.
256
+ #
257
+ def respond_to_default_template?(responder)
258
+ responder.action_respond_to_format?(default_template_format) && template_exists?
259
+ end
260
+
261
+ # If ApplicationController is already defined around here, we should call
262
+ # inherited_with_inheritable_attributes to insert formats_for_respond_to.
263
+ # This usually happens only on Rails 2.3.
264
+ #
265
+ if defined?(ApplicationController)
266
+ self.send(:inherited_with_inheritable_attributes, ApplicationController)
267
+ end
250
268
 
251
269
  end
252
270
 
253
271
  module MimeResponds #:nodoc:
254
272
  class Responder #:nodoc:
255
273
 
256
- attr_reader :mime_type_priority
274
+ attr_reader :mime_type_priority, :order
257
275
 
258
276
  # Similar as respond but if we can't find a valid mime type, we do not
259
277
  # send :not_acceptable message as head and it does not respond to
@@ -304,6 +322,15 @@ module ActionController #:nodoc:
304
322
  end
305
323
  end
306
324
 
325
+ # Makes a given format the first in the @order array.
326
+ #
327
+ def prioritize(format)
328
+ if index = @order.index(format)
329
+ @order.unshift(@order.delete_at(index))
330
+ end
331
+ @order
332
+ end
333
+
307
334
  end
308
335
  end
309
336
  end
data/test/aliases_test.rb CHANGED
@@ -20,6 +20,7 @@ class StudentsController < InheritedResources::Base
20
20
  def create
21
21
  create! do |success, failure|
22
22
  success.html { render :text => "I won't redirect!" }
23
+ failure.xml { render :text => "I shouldn't be rendered" }
23
24
  end
24
25
  end
25
26
 
@@ -86,11 +87,21 @@ class AliasesTest < ActionController::TestCase
86
87
  end
87
88
 
88
89
  def test_dumb_responder_quietly_receives_everything_on_failure
90
+ @request.accept = 'text/html'
89
91
  Student.stubs(:new).returns(mock_student(:save => false, :errors => []))
90
92
  @controller.stubs(:resource_url).returns('http://test.host/')
91
93
  post :create
92
94
  assert_response :success
93
- assert_template :edit
95
+ assert_equal "New HTML", @response.body.strip
96
+ end
97
+
98
+ def test_html_is_the_default_when_only_xml_is_overwriten
99
+ @request.accept = '*/*'
100
+ Student.stubs(:new).returns(mock_student(:save => false, :errors => []))
101
+ @controller.stubs(:resource_url).returns('http://test.host/')
102
+ post :create
103
+ assert_response :success
104
+ assert_equal "New HTML", @response.body.strip
94
105
  end
95
106
 
96
107
  def test_wont_render_edit_template_on_update_with_failure_if_failure_block_is_given
@@ -17,11 +17,12 @@ end
17
17
  class ProjectsController < ActionController::Base
18
18
  # Inherited respond_to definition is:
19
19
  # respond_to :html
20
- respond_to :xml, :except => :edit
21
20
  respond_to :html
21
+ respond_to :xml, :except => :edit
22
22
  respond_to :rjs => :edit
23
23
  respond_to :rss, :only => 'index'
24
24
  respond_to :json, :except => :index
25
+ respond_to :csv, :except => :index
25
26
 
26
27
  def index
27
28
  respond_with(Project.new)
@@ -46,6 +47,16 @@ class ProjectsController < ActionController::Base
46
47
  format.rss { render :text => 'Render RSS' }
47
48
  end
48
49
  end
50
+
51
+ # If the user request Mime::ALL and we have a template called action.html.erb,
52
+ # the html template should be rendered *unless* html is specified inside the
53
+ # block. This tests exactly this case.
54
+ #
55
+ def respond_to_skip_default_template
56
+ respond_to(:with => Project.new) do |format|
57
+ format.html { render :text => 'Render HTML' }
58
+ end
59
+ end
49
60
  end
50
61
 
51
62
  class SuperProjectsController < ProjectsController
@@ -149,6 +160,17 @@ class RespondToUnitTest < ActionController::TestCase
149
160
  @responder.respond_any
150
161
  assert !@performed
151
162
  end
163
+
164
+ def test_responder_prioritize
165
+ prepare_responder_to_respond!
166
+ assert_equal [Mime::HTML, Mime::XML], @responder.order
167
+
168
+ @responder.prioritize(:xml)
169
+ assert_equal [Mime::XML, Mime::HTML], @responder.order
170
+
171
+ @responder.prioritize(:js)
172
+ assert_equal [Mime::XML, Mime::HTML], @responder.order
173
+ end
152
174
 
153
175
  protected
154
176
  def prepare_responder_to_respond!(content_type='*/*')
@@ -195,7 +217,7 @@ class RespondToFunctionalTest < ActionController::TestCase
195
217
  end
196
218
 
197
219
  def test_respond_with_renders_status_not_acceptable_if_mime_type_is_not_registered
198
- @request.accept = 'application/json'
220
+ @request.accept = 'text/csv'
199
221
  get :index
200
222
  assert_equal '406 Not Acceptable', @response.status
201
223
  end
@@ -212,6 +234,13 @@ class RespondToFunctionalTest < ActionController::TestCase
212
234
  assert_equal 'Index HTML', @response.body.strip
213
235
  end
214
236
 
237
+ def test_default_template_is_not_rendered_if_template_format_is_not_accepted
238
+ @controller.stubs(:default_template_format).returns(:json)
239
+ @request.accept = '*/*'
240
+ get :index
241
+ assert_equal '406 Not Acceptable', @response.status
242
+ end
243
+
215
244
  def test_respond_with_sets_content_type_properly
216
245
  @request.accept = 'text/html'
217
246
  get :index
@@ -276,4 +305,10 @@ class RespondToFunctionalTest < ActionController::TestCase
276
305
  get :respond_to_with_resource_and_blocks
277
306
  assert_equal 'Render JSON', @response.body.strip
278
307
  end
308
+
309
+ def test_respond_to_skip_default_template_when_it_is_in_block
310
+ @request.accept = '*/*'
311
+ get :respond_to_skip_default_template
312
+ assert_equal 'Render HTML', @response.body.strip
313
+ end
279
314
  end
@@ -0,0 +1 @@
1
+ Index JSON
@@ -0,0 +1 @@
1
+ DefaultTemplate HTML
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: josevalim-inherited_resources
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.2
4
+ version: 0.6.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - "Jos\xC3\xA9 Valim"
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-04-19 00:00:00 -07:00
12
+ date: 2009-04-24 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -110,6 +110,8 @@ test_files:
110
110
  - test/views/professors/new.html.erb
111
111
  - test/views/professors/show.html.erb
112
112
  - test/views/projects/index.html.erb
113
+ - test/views/projects/index.json.erb
114
+ - test/views/projects/respond_to_skip_default_template.html.erb
113
115
  - test/views/projects/respond_to_with_resource.html.erb
114
116
  - test/views/students/edit.html.erb
115
117
  - test/views/students/new.html.erb