actionpack 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionpack might be problematic. Click here for more details.

Files changed (40) hide show
  1. data/CHANGELOG +78 -0
  2. data/README +1 -1
  3. data/install.rb +4 -2
  4. data/lib/action_controller.rb +3 -0
  5. data/lib/action_controller/base.rb +16 -8
  6. data/lib/action_controller/caching.rb +401 -0
  7. data/lib/action_controller/cgi_process.rb +2 -1
  8. data/lib/action_controller/cookies.rb +3 -3
  9. data/lib/action_controller/filters.rb +94 -24
  10. data/lib/action_controller/layout.rb +63 -21
  11. data/lib/action_controller/session/mem_cache_store.rb +1 -1
  12. data/lib/action_controller/support/binding_of_caller.rb +72 -68
  13. data/lib/action_controller/support/breakpoint.rb +526 -524
  14. data/lib/action_controller/support/class_inheritable_attributes.rb +105 -29
  15. data/lib/action_controller/support/core_ext.rb +1 -0
  16. data/lib/action_controller/support/core_ext/hash.rb +5 -0
  17. data/lib/action_controller/support/core_ext/hash/keys.rb +35 -0
  18. data/lib/action_controller/support/core_ext/numeric.rb +7 -0
  19. data/lib/action_controller/support/core_ext/numeric/bytes.rb +33 -0
  20. data/lib/action_controller/support/core_ext/numeric/time.rb +59 -0
  21. data/lib/action_controller/support/core_ext/string.rb +5 -0
  22. data/lib/action_controller/support/core_ext/string/inflections.rb +41 -0
  23. data/lib/action_controller/support/dependencies.rb +1 -14
  24. data/lib/action_controller/support/inflector.rb +6 -6
  25. data/lib/action_controller/support/misc.rb +0 -24
  26. data/lib/action_controller/templates/rescues/_request_and_response.rhtml +7 -4
  27. data/lib/action_controller/test_process.rb +9 -0
  28. data/lib/action_controller/url_rewriter.rb +13 -5
  29. data/lib/action_view/helpers/active_record_helper.rb +10 -3
  30. data/lib/action_view/helpers/cache_helper.rb +10 -0
  31. data/lib/action_view/helpers/form_helper.rb +25 -2
  32. data/lib/action_view/helpers/form_options_helper.rb +1 -2
  33. data/lib/action_view/helpers/url_helper.rb +8 -5
  34. data/lib/action_view/partials.rb +2 -2
  35. data/rakefile +6 -3
  36. data/test/controller/filters_test.rb +118 -3
  37. data/test/controller/render_test.rb +5 -0
  38. data/test/controller/send_file_test.rb +24 -0
  39. data/test/controller/url_test.rb +47 -2
  40. metadata +16 -2
@@ -1,10 +1,13 @@
1
1
  <% if defined?(Breakpoint) %>
2
2
  <br /><br />
3
- <%= form_tag({}, "method" => @request.method) %>
3
+ <%= form_tag({:params => {}, :only_path => true}, "method" => @request.method) %>
4
4
  <input type="hidden" name="BP-RETRY" value="1" />
5
-
6
- <% for key, value in @request.params %>
7
- <input type="hidden" name="<%= key %>" value="<%= value %>" />
5
+
6
+ <% for key, values in @params %>
7
+ <% next if key == "BP-RETRY" %>
8
+ <% for value in Array(values) %>
9
+ <input type="hidden" name="<%= key %>" value="<%= value %>" />
10
+ <% end %>
8
11
  <% end %>
9
12
 
10
13
  <input type="submit" value="Retry with Breakpoint" />
@@ -182,6 +182,15 @@ module ActionController #:nodoc:
182
182
  def has_template_object?(name=nil)
183
183
  !template_objects[name].nil?
184
184
  end
185
+
186
+ # Returns the response cookies, converted to a Hash of (name => CGI::Cookie) pairs
187
+ # Example:
188
+ #
189
+ # assert_equal ['AuthorOfNewPage'], r.cookies['author'].value
190
+ def cookies
191
+ headers['cookie'].inject({}) { |hash, cookie| hash[cookie.name] = cookie; hash }
192
+ end
193
+
185
194
  end
186
195
 
187
196
  class TestSession #:nodoc:
@@ -49,7 +49,7 @@ module ActionController
49
49
 
50
50
  def rewrite_path(path, options)
51
51
  include_id_in_path_params(options)
52
-
52
+
53
53
  path = rewrite_action(path, options) if options[:action] || options[:action_prefix]
54
54
  path = rewrite_path_params(path, options) if options[:path_params]
55
55
  path = rewrite_controller(path, options) if options[:controller] || options[:controller_prefix]
@@ -86,12 +86,15 @@ module ActionController
86
86
  # don't tell action_name about our little boo-boo
87
87
  path = path.sub(action_prefix, action_name(options, nil))
88
88
  elsif action_prefix && !action_prefix.empty?
89
- path = path.sub(action_prefix, action_name(options, action_prefix))
89
+ path = path.sub(%r(/#{action_prefix}/?), "/" + action_name(options, action_prefix))
90
90
  else
91
- path = path.sub(%r(#{@controller}/?), @controller + "/" + action_name(options)) # " ruby-mode
91
+ path = path.sub(%r(#{@controller}/?$), @controller + "/" + action_name(options)) # " ruby-mode
92
92
  end
93
93
  else
94
- path = path.sub(@controller + "/" + (action_prefix || "") + @action + (action_suffix || ""), @controller + "/" + action_name(options, action_prefix))
94
+ path = path.sub(
95
+ @controller + "/" + (action_prefix || "") + @action + (action_suffix || ""),
96
+ @controller + "/" + action_name(options, action_prefix)
97
+ )
95
98
  end
96
99
 
97
100
  if options[:controller_prefix] && !options[:controller]
@@ -171,7 +174,12 @@ module ActionController
171
174
  elements = []
172
175
  query_string = ""
173
176
 
174
- hash.each { |key, value| elements << "#{CGI.escape(key)}=#{CGI.escape(value.to_s)}" }
177
+ hash.each do |key, value|
178
+ key = CGI.escape key
179
+ key += '[]' if value.class == Array
180
+ value = [ value ] unless value.class == Array
181
+ value.each { |val| elements << "#{key}=#{CGI.escape(val.to_s)}" }
182
+ end
175
183
  unless elements.empty? then query_string << ("?" + elements.join("&")) end
176
184
 
177
185
  return query_string
@@ -49,6 +49,13 @@ module ActionView
49
49
  # <input id="post_title" name="post[title]" size="30" type="text" value="Hello World" /><br />
50
50
  # <input type='submit' value='Sign' />
51
51
  # </form>
52
+ #
53
+ # It's also possible to add additional content to the form by giving it a block, such as:
54
+ #
55
+ # form("entry", :action => "sign") do |form|
56
+ # form << content_tag("b", "Department")
57
+ # form << collection_select("department", "id", @departments, "id", "name")
58
+ # end
52
59
  def form(record_name, options = {})
53
60
  record = instance_eval("@#{record_name}")
54
61
 
@@ -59,9 +66,9 @@ module ActionView
59
66
 
60
67
  id_field = record.new_record? ? "" : InstanceTag.new(record_name, "id", self).to_input_field_tag("hidden")
61
68
 
62
- %(<form action="#{action}" method="post">#{id_field}) +
63
- all_input_tags(record, record_name, options) +
64
- %(<input type="submit" value="#{submit_value}" /></form>)
69
+ formtag = %(<form action="#{action}" method="post">#{id_field}) + all_input_tags(record, record_name, options)
70
+ yield formtag if block_given?
71
+ formtag + %(<input type="submit" value="#{submit_value}" /></form>)
65
72
  end
66
73
 
67
74
  # Returns a string containing the error message attached to the +method+ on the +object+, if one exists.
@@ -0,0 +1,10 @@
1
+ module ActionView
2
+ module Helpers
3
+ # See ActionController::Caching::Fragments for usage instructions.
4
+ module CacheHelper
5
+ def cache(binding, name = {})
6
+ @controller.cache_erb_fragment(binding, name) { yield }
7
+ end
8
+ end
9
+ end
10
+ end
@@ -45,6 +45,15 @@ module ActionView
45
45
  # <input type="submit" value="Save">
46
46
  # </form>
47
47
  #
48
+ # If the helper is being used to generate a repetitive sequence of similar form elements, for example in a partial
49
+ # used by render_collection_of_partials, the "index" option may come in handy. Example:
50
+ #
51
+ # <%= text_field "person", "name", "index" => 1 %>
52
+ #
53
+ # becomes
54
+ #
55
+ # <input type="text" id="person_1_name" name="person[1][name]" value="<%= @person.name %>" />
56
+ #
48
57
  # There's also methods for helping to build form tags in link:classes/ActionView/Helpers/FormOptionsHelper.html,
49
58
  # link:classes/ActionView/Helpers/DateHelper.html, and link:classes/ActionView/Helpers/ActiveRecordHelper.html
50
59
  module FormHelper
@@ -201,17 +210,31 @@ module ActionView
201
210
 
202
211
  private
203
212
  def add_default_name_and_id(options)
204
- options['name'] = tag_name unless options.has_key? "name"
205
- options['id'] = tag_id unless options.has_key? "id"
213
+ if options.has_key? "index"
214
+ options['name'] = tag_name_with_index(options["index"]) unless options.has_key? "name"
215
+ options['id'] = tag_id_with_index(options["index"]) unless options.has_key? "id"
216
+ options.delete("index")
217
+ else
218
+ options['name'] = tag_name unless options.has_key? "name"
219
+ options['id'] = tag_id unless options.has_key? "id"
220
+ end
206
221
  end
207
222
 
208
223
  def tag_name
209
224
  "#{@object_name}[#{@method_name}]"
210
225
  end
226
+
227
+ def tag_name_with_index(index)
228
+ "#{@object_name}[#{index}][#{@method_name}]"
229
+ end
211
230
 
212
231
  def tag_id
213
232
  "#{@object_name}_#{@method_name}"
214
233
  end
234
+
235
+ def tag_id_with_index(index)
236
+ "#{@object_name}_#{index}_#{@method_name}"
237
+ end
215
238
  end
216
239
  end
217
240
  end
@@ -4,8 +4,7 @@ require File.dirname(__FILE__) + '/form_helper'
4
4
 
5
5
  module ActionView
6
6
  module Helpers
7
- # Provides a number of methods for turning different kinds of containers into a set of option tags. Neither of the methods provide
8
- # the actual select tag, so you'll need to construct that in HTML manually.
7
+ # Provides a number of methods for turning different kinds of containers into a set of option tags.
9
8
  module FormOptionsHelper
10
9
  include ERB::Util
11
10
 
@@ -13,15 +13,18 @@ module ActionView
13
13
 
14
14
  # Creates a link tag of the given +name+ using an URL created by the set of +options+. See the valid options in
15
15
  # link:classes/ActionController/Base.html#M000021. It's also possible to pass a string instead of an options hash to
16
- # get a link tag that just points without consideration. The html_options have a special feature for creating javascript
17
- # confirm alerts where if you pass :confirm => 'Are you sure?', the link will be guarded with a JS popup asking that question.
18
- # If the user accepts, the link is processed, otherwise not.
16
+ # get a link tag that just points without consideration. If nil is passed as a name, the link itself will become the name.
17
+ # The html_options have a special feature for creating javascript confirm alerts where if you pass :confirm => 'Are you sure?',
18
+ # the link will be guarded with a JS popup asking that question. If the user accepts, the link is processed, otherwise not.
19
19
  def link_to(name, options = {}, html_options = {}, *parameters_for_method_reference)
20
20
  convert_confirm_option_to_javascript!(html_options) unless html_options.nil?
21
21
  if options.is_a?(String)
22
- content_tag "a", name, (html_options || {}).merge({ "href" => options })
22
+ content_tag "a", name || options, (html_options || {}).merge({ "href" => options })
23
23
  else
24
- content_tag("a", name, (html_options || {}).merge({ "href" => url_for(options, *parameters_for_method_reference) }))
24
+ content_tag(
25
+ "a", name || url_for(options, *parameters_for_method_reference),
26
+ (html_options || {}).merge({ "href" => url_for(options, *parameters_for_method_reference) })
27
+ )
25
28
  end
26
29
  end
27
30
 
@@ -39,11 +39,11 @@ module ActionView
39
39
  render("#{path}/_#{partial_name}", { partial_name => object }.merge(local_assigns))
40
40
  end
41
41
 
42
- def render_collection_of_partials(partial_name, collection, partial_spacer_template = nil)
42
+ def render_collection_of_partials(partial_name, collection, partial_spacer_template = nil, local_assigns = {})
43
43
  collection_of_partials = Array.new
44
44
  counter_name = partial_counter_name(partial_name)
45
45
  collection.each_with_index do |element, counter|
46
- collection_of_partials.push(render_partial(partial_name, element, counter_name => counter))
46
+ collection_of_partials.push(render_partial(partial_name, element, { counter_name => counter }.merge(local_assigns)))
47
47
  end
48
48
 
49
49
  return nil if collection_of_partials.empty?
data/rakefile CHANGED
@@ -8,7 +8,7 @@ require 'rake/contrib/rubyforgepublisher'
8
8
 
9
9
  PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
10
10
  PKG_NAME = 'actionpack'
11
- PKG_VERSION = '1.2.0' + PKG_BUILD
11
+ PKG_VERSION = '1.3.0' + PKG_BUILD
12
12
  PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
13
13
 
14
14
  desc "Default Task"
@@ -18,7 +18,10 @@ task :default => [ :test ]
18
18
 
19
19
  Rake::TestTask.new { |t|
20
20
  t.libs << "test"
21
- t.pattern = 'test/*/*_test.rb'
21
+ # make sure we include the controller tests (c*) first as on some systems
22
+ # this will not happen automatically and the tests (as a whole) will error
23
+ t.test_files=Dir.glob( "test/c*/*_test.rb" ) + Dir.glob( "test/[ft]*/*_test.rb" )
24
+ # t.pattern = 'test/*/*_test.rb'
22
25
  t.verbose = true
23
26
  }
24
27
 
@@ -102,4 +105,4 @@ task :lines do
102
105
  end
103
106
  }
104
107
  puts "Lines #{lines}, LOC #{codelines}"
105
- end
108
+ end
@@ -15,6 +15,74 @@ class FilterTest < Test::Unit::TestCase
15
15
  end
16
16
  end
17
17
 
18
+ class ConditionalFilterController < ActionController::Base
19
+ def show
20
+ render_text "ran action"
21
+ end
22
+
23
+ def another_action
24
+ render_text "ran action"
25
+ end
26
+
27
+ def show_without_filter
28
+ render_text "ran action without filter"
29
+ end
30
+
31
+ private
32
+ def ensure_login
33
+ @ran_filter ||= []
34
+ @ran_filter << "ensure_login"
35
+ end
36
+
37
+ def clean_up_tmp
38
+ @ran_filter ||= []
39
+ @ran_filter << "clean_up_tmp"
40
+ end
41
+
42
+ def rescue_action(e) raise(e) end
43
+ end
44
+
45
+ class ConditionalCollectionFilterController < ConditionalFilterController
46
+ before_filter :ensure_login, :except => [ :show_without_filter, :another_action ]
47
+ end
48
+
49
+ class OnlyConditionSymController < ConditionalFilterController
50
+ before_filter :ensure_login, :only => :show
51
+ end
52
+
53
+ class ExceptConditionSymController < ConditionalFilterController
54
+ before_filter :ensure_login, :except => :show_without_filter
55
+ end
56
+
57
+ class BeforeAndAfterConditionController < ConditionalFilterController
58
+ before_filter :ensure_login, :only => :show
59
+ after_filter :clean_up_tmp, :only => :show
60
+ end
61
+
62
+ class OnlyConditionProcController < ConditionalFilterController
63
+ before_filter(:only => :show) {|c| c.assigns["ran_proc_filter"] = true }
64
+ end
65
+
66
+ class ExceptConditionProcController < ConditionalFilterController
67
+ before_filter(:except => :show_without_filter) {|c| c.assigns["ran_proc_filter"] = true }
68
+ end
69
+
70
+ class ConditionalClassFilter
71
+ def self.filter(controller) controller.assigns["ran_class_filter"] = true end
72
+ end
73
+
74
+ class OnlyConditionClassController < ConditionalFilterController
75
+ before_filter ConditionalClassFilter, :only => :show
76
+ end
77
+
78
+ class ExceptConditionClassController < ConditionalFilterController
79
+ before_filter ConditionalClassFilter, :except => :show_without_filter
80
+ end
81
+
82
+ class AnomolousYetValidConditionController < ConditionalFilterController
83
+ before_filter(ConditionalClassFilter, :ensure_login, Proc.new {|c| c.assigns["ran_proc_filter1"] = true }, :except => :show_without_filter) { |c| c.assigns["ran_proc_filter2"] = true}
84
+ end
85
+
18
86
  class PrependingController < TestController
19
87
  prepend_before_filter :wonderful_life
20
88
 
@@ -125,6 +193,53 @@ class FilterTest < Test::Unit::TestCase
125
193
  def test_running_filters_with_class
126
194
  assert test_process(AuditController).template.assigns["was_audited"]
127
195
  end
196
+
197
+ def test_running_anomolous_yet_valid_condition_filters
198
+ response = test_process(AnomolousYetValidConditionController)
199
+ assert_equal %w( ensure_login ), response.template.assigns["ran_filter"]
200
+ assert response.template.assigns["ran_class_filter"]
201
+ assert response.template.assigns["ran_proc_filter1"]
202
+ assert response.template.assigns["ran_proc_filter2"]
203
+
204
+ response = test_process(AnomolousYetValidConditionController, "show_without_filter")
205
+ assert_equal nil, response.template.assigns["ran_filter"]
206
+ assert !response.template.assigns["ran_class_filter"]
207
+ assert !response.template.assigns["ran_proc_filter1"]
208
+ assert !response.template.assigns["ran_proc_filter2"]
209
+ end
210
+
211
+ def test_running_collection_condition_filters
212
+ assert_equal %w( ensure_login ), test_process(ConditionalCollectionFilterController).template.assigns["ran_filter"]
213
+ assert_equal nil, test_process(ConditionalCollectionFilterController, "show_without_filter").template.assigns["ran_filter"]
214
+ assert_equal nil, test_process(ConditionalCollectionFilterController, "another_action").template.assigns["ran_filter"]
215
+ end
216
+
217
+ def test_running_only_condition_filters
218
+ assert_equal %w( ensure_login ), test_process(OnlyConditionSymController).template.assigns["ran_filter"]
219
+ assert_equal nil, test_process(OnlyConditionSymController, "show_without_filter").template.assigns["ran_filter"]
220
+
221
+ assert test_process(OnlyConditionProcController).template.assigns["ran_proc_filter"]
222
+ assert !test_process(OnlyConditionProcController, "show_without_filter").template.assigns["ran_proc_filter"]
223
+
224
+ assert test_process(OnlyConditionClassController).template.assigns["ran_class_filter"]
225
+ assert !test_process(OnlyConditionClassController, "show_without_filter").template.assigns["ran_class_filter"]
226
+ end
227
+
228
+ def test_running_except_condition_filters
229
+ assert_equal %w( ensure_login ), test_process(ExceptConditionSymController).template.assigns["ran_filter"]
230
+ assert_equal nil, test_process(ExceptConditionSymController, "show_without_filter").template.assigns["ran_filter"]
231
+
232
+ assert test_process(ExceptConditionProcController).template.assigns["ran_proc_filter"]
233
+ assert !test_process(ExceptConditionProcController, "show_without_filter").template.assigns["ran_proc_filter"]
234
+
235
+ assert test_process(ExceptConditionClassController).template.assigns["ran_class_filter"]
236
+ assert !test_process(ExceptConditionClassController, "show_without_filter").template.assigns["ran_class_filter"]
237
+ end
238
+
239
+ def test_running_before_and_after_condition_filters
240
+ assert_equal %w( ensure_login clean_up_tmp), test_process(BeforeAndAfterConditionController).template.assigns["ran_filter"]
241
+ assert_equal nil, test_process(BeforeAndAfterConditionController, "show_without_filter").template.assigns["ran_filter"]
242
+ end
128
243
 
129
244
  def test_bad_filter
130
245
  assert_raises(ActionController::ActionControllerError) {
@@ -151,9 +266,9 @@ class FilterTest < Test::Unit::TestCase
151
266
  end
152
267
 
153
268
  private
154
- def test_process(controller)
269
+ def test_process(controller, action = "show")
155
270
  request = ActionController::TestRequest.new
156
- request.action = "show"
271
+ request.action = action
157
272
  controller.process(request, ActionController::TestResponse.new)
158
273
  end
159
- end
274
+ end
@@ -126,6 +126,11 @@ class RenderTest < Test::Unit::TestCase
126
126
  assert_raises(ActionController::UnknownAction, "No action responded to [clone]") { process_request }
127
127
  end
128
128
 
129
+ def test_private_methods
130
+ @request.action = "determine_layout"
131
+ assert_raises(ActionController::UnknownAction, "No action responded to [determine_layout]") { process_request }
132
+ end
133
+
129
134
  def test_access_to_request_in_view
130
135
  ActionController::Base.view_controller_internals = false
131
136
 
@@ -65,4 +65,28 @@ class SendFileTest < Test::Unit::TestCase
65
65
  assert_kind_of String, response.body
66
66
  assert_equal file_data, response.body
67
67
  end
68
+
69
+ # Test that send_file_headers! is setting the correct HTTP headers.
70
+ def test_send_file_headers!
71
+ options = {
72
+ :length => 1,
73
+ :type => 'type',
74
+ :disposition => 'disposition',
75
+ :filename => 'filename'
76
+ }
77
+
78
+ # Do it a few times: the resulting headers should be identical
79
+ # no matter how many times you send with the same options.
80
+ # Test resolving Ticket #458.
81
+ @controller.headers = {}
82
+ @controller.send(:send_file_headers!, options)
83
+ @controller.send(:send_file_headers!, options)
84
+ @controller.send(:send_file_headers!, options)
85
+
86
+ h = @controller.headers
87
+ assert_equal 1, h['Content-Length']
88
+ assert_equal 'type', h['Content-Type']
89
+ assert_equal 'disposition; filename="filename"', h['Content-Disposition']
90
+ assert_equal 'binary', h['Content-Transfer-Encoding']
91
+ end
68
92
  end
@@ -12,6 +12,15 @@ class MockRequest
12
12
  end
13
13
  end
14
14
 
15
+ class UrlMockFactory
16
+ def self.create(path, parameters)
17
+ ActionController::UrlRewriter.new(
18
+ MockRequest.new("http://", "example.com", 80, path, parameters),
19
+ parameters["controller"], parameters["action"]
20
+ )
21
+ end
22
+ end
23
+
15
24
  class UrlTest < Test::Unit::TestCase
16
25
  def setup
17
26
  @library_url = ActionController::UrlRewriter.new(MockRequest.new(
@@ -191,7 +200,6 @@ class UrlTest < Test::Unit::TestCase
191
200
  assert_equal "http://www.singlefile.com/login/logout", @clean_url_with_same_action_and_controller_name.rewrite(:action => "logout")
192
201
  end
193
202
 
194
- # FIXME
195
203
  def xtest_same_module_and_controller_and_action_names
196
204
  assert_equal "http://www.singlefile.com/login/login/logout", @clean_url_with_same_action_and_controller_and_module_name.rewrite(:action => "logout")
197
205
  end
@@ -238,7 +246,18 @@ class UrlTest < Test::Unit::TestCase
238
246
  )
239
247
  end
240
248
  end
241
-
249
+
250
+ def test_parameters_with_array
251
+ @clean_urls.each do |url|
252
+ assert_equal(
253
+ "http://www.singlefile.com/identity/show?id[]=3&id[]=5&id[]=10",
254
+ url.rewrite(
255
+ :action => "show",
256
+ :params => { 'id' => [ 3, 5, 10 ] } )
257
+ )
258
+ end
259
+ end
260
+
242
261
  def test_action_with_id
243
262
  assert_equal(
244
263
  "http://www.singlefile.com/identity/show/7",
@@ -408,4 +427,30 @@ class UrlTest < Test::Unit::TestCase
408
427
  assert_equal("http://example.com/controller/foo", url.rewrite(:action => 'foo'))
409
428
  end
410
429
 
430
+ def test_rewriting_on_similar_fragments
431
+ url = UrlMockFactory.create("/advertisements/advert/", {"controller"=>"advert", "action"=>"index"})
432
+ assert_equal("http://example.com/advertisements/advert/news", url.rewrite(:action => 'news'))
433
+ end
434
+
435
+ def test_rewriting_on_similar_fragments_with_action_prefixes
436
+ url = UrlMockFactory.create(
437
+ "/clients/prall/1/msg/all/",
438
+ { "category_name"=>"all", "client_name"=>"prall", "action"=>"index", "controller"=>"msg", "project_name"=>"1"}
439
+ )
440
+
441
+ assert_equal(
442
+ "http://example.com/clients/prall/1/msg/all/new",
443
+ url.rewrite({ :controller => "msg", :action_prefix => "all", :action => "new" })
444
+ )
445
+
446
+ url = UrlMockFactory.create(
447
+ "/clients/prall/1/msg/all/",
448
+ { "category_name"=>"all", "client_name"=>"prall", "action"=>"index", "controller"=>"msg", "project_name"=>"1"}
449
+ )
450
+
451
+ assert_equal(
452
+ "http://example.com/clients/prall/1/msg/allous/new",
453
+ url.rewrite({ :controller => "msg", :action_prefix => "allous", :action => "new" })
454
+ )
455
+ end
411
456
  end