karsthammer-inherited_resources 1.1.2.1 → 1.2.1
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/.gitignore +1 -0
- data/CHANGELOG +11 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +86 -0
- data/README.rdoc +78 -50
- data/Rakefile +0 -22
- data/karsthammer-inherited_resources.gemspec +24 -0
- data/lib/inherited_resources/actions.rb +4 -4
- data/lib/inherited_resources/base.rb +11 -10
- data/lib/inherited_resources/base_helpers.rb +40 -3
- data/lib/inherited_resources/class_methods.rb +100 -9
- data/lib/inherited_resources/shallow_helpers.rb +87 -0
- data/lib/inherited_resources/url_helpers.rb +44 -4
- data/lib/inherited_resources/version.rb +1 -1
- data/lib/karsthammer-inherited_resources.rb +7 -2
- data/test/base_test.rb +33 -13
- data/test/belongs_to_test.rb +29 -4
- data/test/belongs_to_with_shallow_test.rb +93 -0
- data/test/class_methods_test.rb +13 -11
- data/test/customized_belongs_to_test.rb +1 -1
- data/test/customized_redirect_to_test.rb +32 -0
- data/test/defaults_test.rb +137 -10
- data/test/locales/en.yml +17 -0
- data/test/nested_belongs_to_with_shallow_test.rb +123 -0
- data/test/nested_model_with_shallow_test.rb +147 -0
- data/test/optional_belongs_to_test.rb +3 -3
- data/test/polymorphic_test.rb +4 -4
- data/test/singleton_test.rb +4 -1
- data/test/test_helper.rb +4 -3
- data/test/url_helpers_test.rb +146 -2
- data/test/views/cars/edit.html.erb +1 -0
- data/test/views/cars/index.html.erb +1 -0
- data/test/views/cars/new.html.erb +1 -0
- data/test/views/cars/show.html.erb +1 -0
- data/test/views/cities/edit.html.erb +1 -0
- data/test/views/cities/index.html.erb +1 -0
- data/test/views/cities/new.html.erb +1 -0
- data/test/views/cities/show.html.erb +1 -0
- data/test/views/comments/edit.html.erb +1 -0
- data/test/views/comments/index.html.erb +1 -0
- data/test/views/comments/new.html.erb +1 -0
- data/test/views/comments/show.html.erb +1 -0
- data/test/views/educations/new.html.erb +0 -0
- data/test/views/employees/edit.html.erb +1 -0
- data/test/views/employees/index.html.erb +1 -0
- data/test/views/employees/new.html.erb +1 -0
- data/test/views/employees/show.html.erb +1 -0
- data/test/views/groups/edit.html.erb +0 -0
- data/test/views/managers/edit.html.erb +1 -0
- data/test/views/managers/new.html.erb +1 -0
- data/test/views/managers/show.html.erb +1 -0
- data/test/views/painters/edit.html.erb +1 -0
- data/test/views/painters/index.html.erb +1 -0
- data/test/views/painters/new.html.erb +1 -0
- data/test/views/painters/show.html.erb +1 -0
- data/test/views/pets/edit.html.erb +1 -0
- data/test/views/pets/index.html.erb +1 -0
- data/test/views/pets/new.html.erb +1 -0
- data/test/views/pets/show.html.erb +1 -0
- data/test/views/plates/edit.html.erb +1 -0
- data/test/views/plates/index.html.erb +1 -0
- data/test/views/plates/new.html.erb +1 -0
- data/test/views/plates/show.html.erb +1 -0
- data/test/views/products/edit.html.erb +1 -0
- data/test/views/products/index.html.erb +1 -0
- data/test/views/products/new.html.erb +1 -0
- data/test/views/products/show.html.erb +1 -0
- data/test/views/professors/edit.html.erb +1 -0
- data/test/views/professors/index.html.erb +1 -0
- data/test/views/professors/new.html.erb +1 -0
- data/test/views/professors/show.html.erb +1 -0
- data/test/views/projects/index.html.erb +1 -0
- data/test/views/projects/index.json.erb +1 -0
- data/test/views/projects/respond_to_skip_default_template.html.erb +1 -0
- data/test/views/projects/respond_with_resource.html.erb +1 -0
- data/test/views/students/edit.html.erb +1 -0
- data/test/views/students/new.html.erb +1 -0
- data/test/views/tags/edit.html.erb +1 -0
- data/test/views/tags/index.html.erb +1 -0
- data/test/views/tags/new.html.erb +1 -0
- data/test/views/tags/show.html.erb +1 -0
- data/test/views/trees/edit.html.erb +1 -0
- data/test/views/trees/index.html.erb +1 -0
- data/test/views/trees/new.html.erb +1 -0
- data/test/views/trees/show.html.erb +1 -0
- data/test/views/university/professors/edit.html.erb +1 -0
- data/test/views/university/professors/index.html.erb +1 -0
- data/test/views/university/professors/new.html.erb +1 -0
- data/test/views/university/professors/show.html.erb +1 -0
- data/test/views/users/create.js.erb +1 -0
- data/test/views/users/destroy.js.erb +1 -0
- data/test/views/users/edit.html.erb +1 -0
- data/test/views/users/index.html.erb +1 -0
- data/test/views/users/new.html.erb +1 -0
- data/test/views/users/show.html.erb +1 -0
- data/test/views/users/update.js.erb +1 -0
- metadata +178 -29
@@ -30,22 +30,31 @@ module InheritedResources
|
|
30
30
|
#
|
31
31
|
# * <tt>:singleton</tt> - Tells if this controller is singleton or not.
|
32
32
|
#
|
33
|
+
# * <tt>:finder</tt> - Specifies which method should be called to instantiate the resource.
|
34
|
+
#
|
35
|
+
# defaults :project, :finder => :find_by_slug
|
36
|
+
#
|
33
37
|
def defaults(options)
|
34
38
|
raise ArgumentError, 'Class method :defaults expects a hash of options.' unless options.is_a? Hash
|
35
39
|
|
36
40
|
options.symbolize_keys!
|
37
41
|
options.assert_valid_keys(:resource_class, :collection_name, :instance_name,
|
38
42
|
:class_name, :route_prefix, :route_collection_name,
|
39
|
-
:route_instance_name, :singleton)
|
43
|
+
:route_instance_name, :singleton, :finder)
|
40
44
|
|
41
|
-
self.resource_class = options
|
42
|
-
self.resource_class = options
|
45
|
+
self.resource_class = options[:resource_class] if options.key?(:resource_class)
|
46
|
+
self.resource_class = options[:class_name].constantize if options.key?(:class_name)
|
43
47
|
|
44
48
|
acts_as_singleton! if options.delete(:singleton)
|
45
49
|
|
46
50
|
config = self.resources_configuration[:self]
|
47
51
|
config[:route_prefix] = options.delete(:route_prefix) if options.key?(:route_prefix)
|
48
52
|
|
53
|
+
if options.key?(:resource_class) or options.key?(:class_name)
|
54
|
+
config[:request_name] = self.resource_class.to_s.underscore.gsub('/', '_')
|
55
|
+
options.delete(:resource_class) and options.delete(:class_name)
|
56
|
+
end
|
57
|
+
|
49
58
|
options.each do |key, value|
|
50
59
|
config[key] = value.to_sym
|
51
60
|
end
|
@@ -132,9 +141,10 @@ module InheritedResources
|
|
132
141
|
options.symbolize_keys!
|
133
142
|
options.assert_valid_keys(:class_name, :parent_class, :instance_name, :param,
|
134
143
|
:finder, :route_name, :collection_name, :singleton,
|
135
|
-
:polymorphic, :optional)
|
144
|
+
:polymorphic, :optional, :shallow)
|
136
145
|
|
137
146
|
optional = options.delete(:optional)
|
147
|
+
shallow = options.delete(:shallow)
|
138
148
|
singleton = options.delete(:singleton)
|
139
149
|
polymorphic = options.delete(:polymorphic)
|
140
150
|
finder = options.delete(:finder)
|
@@ -143,6 +153,7 @@ module InheritedResources
|
|
143
153
|
|
144
154
|
acts_as_singleton! if singleton
|
145
155
|
acts_as_polymorphic! if polymorphic || optional
|
156
|
+
acts_as_shallow! if shallow
|
146
157
|
|
147
158
|
raise ArgumentError, 'You have to give me at least one association name.' if symbols.empty?
|
148
159
|
raise ArgumentError, 'You cannot define multiple associations with options: #{options.keys.inspect} to belongs to.' unless symbols.size == 1 || options.empty?
|
@@ -158,6 +169,8 @@ module InheritedResources
|
|
158
169
|
self.parents_symbols << symbol
|
159
170
|
end
|
160
171
|
|
172
|
+
self.resources_configuration[:self][:shallow] = true if shallow
|
173
|
+
|
161
174
|
config = self.resources_configuration[symbol] = {}
|
162
175
|
|
163
176
|
config[:parent_class] = options.delete(:parent_class) || begin
|
@@ -208,6 +221,40 @@ module InheritedResources
|
|
208
221
|
belongs_to(*symbols << options, &block)
|
209
222
|
end
|
210
223
|
|
224
|
+
# Defines custom restful actions by resource or collection basis.
|
225
|
+
#
|
226
|
+
# custom_actions :resource => [:delete, :transit], :collection => :search
|
227
|
+
#
|
228
|
+
# == Options
|
229
|
+
#
|
230
|
+
# * <tt>:resource</tt> - Allows you to specify resource actions.
|
231
|
+
# custom_actions :resource => :delete
|
232
|
+
# This macro creates 'delete' method in controller and defines
|
233
|
+
# delete_reource_{path,url} helpers. The body of generated 'delete'
|
234
|
+
# method is same as 'show' method. So you can override it if need
|
235
|
+
#
|
236
|
+
# * <tt>:collection</tt> - Allows you to specify collection actions.
|
237
|
+
# custom_actions :collection => :search
|
238
|
+
# This macro creates 'search' method in controller and defines
|
239
|
+
# search_reources_{path,url} helpers. The body of generated 'search'
|
240
|
+
# method is same as 'index' method. So you can override it if need
|
241
|
+
#
|
242
|
+
def custom_actions(options)
|
243
|
+
self.resources_configuration[:self][:custom_actions] = options
|
244
|
+
options.each do | resource_or_collection, actions |
|
245
|
+
[*actions].each do | action |
|
246
|
+
create_custom_action(resource_or_collection, action)
|
247
|
+
end
|
248
|
+
end
|
249
|
+
create_resources_url_helpers!
|
250
|
+
[*options[:resource]].each do | action |
|
251
|
+
helper_method "#{action}_resource_path", "#{action}_resource_url"
|
252
|
+
end
|
253
|
+
[*options[:collection]].each do | action |
|
254
|
+
helper_method "#{action}_resources_path", "#{action}_resources_url"
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
211
258
|
private
|
212
259
|
|
213
260
|
def acts_as_singleton! #:nodoc:
|
@@ -225,11 +272,31 @@ module InheritedResources
|
|
225
272
|
end
|
226
273
|
end
|
227
274
|
|
275
|
+
def acts_as_shallow! #:nodoc:
|
276
|
+
include ShallowHelpers
|
277
|
+
end
|
278
|
+
|
228
279
|
# Initialize resources class accessors and set their default values.
|
229
280
|
#
|
230
281
|
def initialize_resources_class_accessors! #:nodoc:
|
231
|
-
#
|
282
|
+
# First priority is the namespaced modek, e.g. User::Group
|
232
283
|
self.resource_class = begin
|
284
|
+
namespaced_class = self.name.sub(/Controller/, '').singularize
|
285
|
+
namespaced_class.constantize
|
286
|
+
rescue NameError
|
287
|
+
nil
|
288
|
+
end
|
289
|
+
|
290
|
+
# Second priority the camelcased c, i.e. UserGroup
|
291
|
+
self.resource_class ||= begin
|
292
|
+
camelcased_class = self.name.sub(/Controller/, '').gsub('::', '').singularize
|
293
|
+
camelcased_class.constantize
|
294
|
+
rescue NameError
|
295
|
+
nil
|
296
|
+
end
|
297
|
+
|
298
|
+
# Otherwise use the Group class, or fail
|
299
|
+
self.resource_class ||= begin
|
233
300
|
class_name = self.controller_name.classify
|
234
301
|
class_name.constantize
|
235
302
|
rescue NameError => e
|
@@ -237,9 +304,16 @@ module InheritedResources
|
|
237
304
|
nil
|
238
305
|
end
|
239
306
|
|
307
|
+
self.parents_symbols = self.parents_symbols.try(:dup) || []
|
308
|
+
|
240
309
|
# Initialize resources configuration hash
|
241
|
-
self.resources_configuration
|
242
|
-
|
310
|
+
self.resources_configuration = self.resources_configuration.try(:dup) || {}
|
311
|
+
self.resources_configuration.each do |key, value|
|
312
|
+
next unless value.is_a?(Hash) || value.is_a?(Array)
|
313
|
+
self.resources_configuration[key] = value.dup
|
314
|
+
end
|
315
|
+
|
316
|
+
config = (self.resources_configuration[:self] ||= {})
|
243
317
|
config[:collection_name] = self.controller_name.to_sym
|
244
318
|
config[:instance_name] = self.controller_name.singularize.to_sym
|
245
319
|
|
@@ -250,9 +324,26 @@ module InheritedResources
|
|
250
324
|
namespaces = self.controller_path.split('/')[0..-2]
|
251
325
|
config[:route_prefix] = namespaces.join('_') unless namespaces.empty?
|
252
326
|
|
327
|
+
# Deal with default request parameters in namespaced controllers, e.g.
|
328
|
+
# Forum::Thread#create will properly pick up the request parameter
|
329
|
+
# which will be forum_thread, and not thread
|
330
|
+
# Additionally make this work orthogonally with instance_name
|
331
|
+
config[:request_name] = self.resource_class.to_s.underscore.gsub('/', '_')
|
332
|
+
|
253
333
|
# Initialize polymorphic, singleton, scopes and belongs_to parameters
|
254
|
-
self.
|
255
|
-
|
334
|
+
polymorphic = self.resources_configuration[:polymorphic] || { :symbols => [], :optional => false }
|
335
|
+
polymorphic[:symbols] = polymorphic[:symbols].dup
|
336
|
+
self.resources_configuration[:polymorphic] = polymorphic
|
337
|
+
end
|
338
|
+
|
339
|
+
def create_custom_action(resource_or_collection, action)
|
340
|
+
class_eval <<-CUSTOM_ACTION, __FILE__, __LINE__
|
341
|
+
def #{action}(options={}, &block)
|
342
|
+
respond_with(*(with_chain(#{resource_or_collection}) << options), &block)
|
343
|
+
end
|
344
|
+
alias :#{action}! :#{action}
|
345
|
+
protected :#{action}!
|
346
|
+
CUSTOM_ACTION
|
256
347
|
end
|
257
348
|
|
258
349
|
# Hook called on inheritance.
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module InheritedResources
|
2
|
+
# = belongs_to
|
3
|
+
#
|
4
|
+
# Let's suppose that we have some tasks that belongs to projects. To specify
|
5
|
+
# this assoication in your controllers, just do:
|
6
|
+
#
|
7
|
+
# class TasksController < InheritedResources::Base
|
8
|
+
# belongs_to :project
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# belongs_to accepts several options to be able to configure the association.
|
12
|
+
# For example, if you want urls like /projects/:project_title/tasks, you
|
13
|
+
# can customize how InheritedResources find your projects:
|
14
|
+
#
|
15
|
+
# class TasksController < InheritedResources::Base
|
16
|
+
# belongs_to :project, :finder => :find_by_title!, :param => :project_title
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# It also accepts :route_name, :parent_class and :instance_name as options.
|
20
|
+
# Check the lib/inherited_resources/class_methods.rb for more.
|
21
|
+
#
|
22
|
+
# = nested_belongs_to
|
23
|
+
#
|
24
|
+
# Now, our Tasks get some Comments and you need to nest even deeper. Good
|
25
|
+
# practices says that you should never nest more than two resources, but sometimes
|
26
|
+
# you have to for security reasons. So this is an example of how you can do it:
|
27
|
+
#
|
28
|
+
# class CommentsController < InheritedResources::Base
|
29
|
+
# nested_belongs_to :project, :task
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# If you need to configure any of these belongs to, you can nested them using blocks:
|
33
|
+
#
|
34
|
+
# class CommentsController < InheritedResources::Base
|
35
|
+
# belongs_to :project, :finder => :find_by_title!, :param => :project_title do
|
36
|
+
# belongs_to :task
|
37
|
+
# end
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
# Warning: calling several belongs_to is the same as nesting them:
|
41
|
+
#
|
42
|
+
# class CommentsController < InheritedResources::Base
|
43
|
+
# belongs_to :project
|
44
|
+
# belongs_to :task
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# In other words, the code above is the same as calling nested_belongs_to.
|
48
|
+
#
|
49
|
+
module ShallowHelpers
|
50
|
+
include BelongsToHelpers
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
# Evaluate the parent given. This is used to nest parents in the
|
55
|
+
# association chain.
|
56
|
+
#
|
57
|
+
|
58
|
+
# Maps parents_symbols to build association chain. In this case, it
|
59
|
+
# simply return the parent_symbols, however on polymorphic belongs to,
|
60
|
+
# it has some customization.
|
61
|
+
#
|
62
|
+
def symbols_for_association_chain #:nodoc:
|
63
|
+
parent_symbols = parents_symbols.dup
|
64
|
+
if parents_symbols.size > 1 && !params[:id]
|
65
|
+
inst_class_name = parent_symbols.pop
|
66
|
+
finder_method = resources_configuration[inst_class_name][:finder] || :find
|
67
|
+
instance = resources_configuration[inst_class_name][:parent_class].send(finder_method, params[resources_configuration[inst_class_name][:param]])
|
68
|
+
load_parents(instance, parent_symbols)
|
69
|
+
end
|
70
|
+
if params[:id]
|
71
|
+
finder_method = resources_configuration[:self][:finder] || :find
|
72
|
+
instance = self.resource_class.send(finder_method, params[:id])
|
73
|
+
load_parents(instance, parent_symbols)
|
74
|
+
end
|
75
|
+
parents_symbols
|
76
|
+
end
|
77
|
+
|
78
|
+
def load_parents(instance, parent_symbols)
|
79
|
+
|
80
|
+
parent_symbols.reverse.each do |parent|
|
81
|
+
instance = instance.send(parent)
|
82
|
+
params[resources_configuration[parent][:param]] = instance.to_param
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
@@ -32,6 +32,7 @@ module InheritedResources
|
|
32
32
|
# all created when you inherit.
|
33
33
|
#
|
34
34
|
module UrlHelpers
|
35
|
+
protected
|
35
36
|
|
36
37
|
# This method hard code url helpers in the class.
|
37
38
|
#
|
@@ -39,7 +40,7 @@ module InheritedResources
|
|
39
40
|
# is being processed (and even more cheaper when we are using nested
|
40
41
|
# resources).
|
41
42
|
#
|
42
|
-
# When we are using polymorphic associations, those helpers rely on
|
43
|
+
# When we are using polymorphic associations, those helpers rely on
|
43
44
|
# polymorphic_url Rails helper.
|
44
45
|
#
|
45
46
|
def create_resources_url_helpers!
|
@@ -75,6 +76,7 @@ module InheritedResources
|
|
75
76
|
collection_ivars = resource_ivars.dup
|
76
77
|
collection_segments = resource_segments.dup
|
77
78
|
|
79
|
+
|
78
80
|
# Generate parent url before we add resource instances.
|
79
81
|
unless parents_symbols.empty?
|
80
82
|
generate_url_and_path_helpers nil, :parent, resource_segments, resource_ivars
|
@@ -119,9 +121,9 @@ module InheritedResources
|
|
119
121
|
elsif polymorphic
|
120
122
|
collection_ivars << '(@_resource_class_new ||= resource_class.new)'
|
121
123
|
end
|
122
|
-
|
124
|
+
|
123
125
|
# If route is uncountable then add "_index" suffix to collection index route name
|
124
|
-
#
|
126
|
+
#
|
125
127
|
if !singleton && resource_config[:route_collection_name] == resource_config[:route_instance_name]
|
126
128
|
collection_segments << :index
|
127
129
|
end
|
@@ -130,11 +132,49 @@ module InheritedResources
|
|
130
132
|
generate_url_and_path_helpers :new, :resource, resource_segments, new_ivars || collection_ivars
|
131
133
|
generate_url_and_path_helpers nil, :resource, resource_segments, resource_ivars
|
132
134
|
generate_url_and_path_helpers :edit, :resource, resource_segments, resource_ivars
|
135
|
+
|
136
|
+
if resource_config[:custom_actions]
|
137
|
+
[*resource_config[:custom_actions][:resource]].each do | method |
|
138
|
+
generate_url_and_path_helpers method, :resource, resource_segments, resource_ivars
|
139
|
+
end
|
140
|
+
[*resource_config[:custom_actions][:collection]].each do | method |
|
141
|
+
generate_url_and_path_helpers method, :resources, collection_segments, collection_ivars
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def handle_shallow_resource(prefix, name, segments, ivars) #:nodoc:
|
147
|
+
return segments, ivars unless self.resources_configuration[:self][:shallow]
|
148
|
+
case name
|
149
|
+
when :collection, :resources
|
150
|
+
segments = segments[-2..-1]
|
151
|
+
ivars = [ivars.last]
|
152
|
+
when :resource
|
153
|
+
if prefix == :new
|
154
|
+
segments = segments[-2..-1]
|
155
|
+
ivars = [ivars.last]
|
156
|
+
else
|
157
|
+
segments = [segments.last]
|
158
|
+
ivars = [ivars.last]
|
159
|
+
end
|
160
|
+
when :parent
|
161
|
+
segments = [segments.last]
|
162
|
+
ivars = [ivars.last]
|
163
|
+
end
|
164
|
+
|
165
|
+
segments ||= []
|
166
|
+
|
167
|
+
unless self.resources_configuration[:self][:route_prefix].blank?
|
168
|
+
segments.unshift self.resources_configuration[:self][:route_prefix]
|
169
|
+
end
|
170
|
+
|
171
|
+
return segments, ivars
|
133
172
|
end
|
134
173
|
|
135
174
|
def generate_url_and_path_helpers(prefix, name, resource_segments, resource_ivars) #:nodoc:
|
136
|
-
|
175
|
+
resource_segments, resource_ivars = handle_shallow_resource(prefix, name, resource_segments, resource_ivars)
|
137
176
|
|
177
|
+
ivars = resource_ivars.dup
|
138
178
|
singleton = self.resources_configuration[:self][:singleton]
|
139
179
|
polymorphic = self.parents_symbols.include?(:polymorphic)
|
140
180
|
|
@@ -6,6 +6,7 @@ module InheritedResources
|
|
6
6
|
autoload :Actions, 'inherited_resources/actions'
|
7
7
|
autoload :Base, 'inherited_resources/base'
|
8
8
|
autoload :BaseHelpers, 'inherited_resources/base_helpers'
|
9
|
+
autoload :ShallowHelpers, 'inherited_resources/shallow_helpers'
|
9
10
|
autoload :BelongsToHelpers, 'inherited_resources/belongs_to_helpers'
|
10
11
|
autoload :ClassMethods, 'inherited_resources/class_methods'
|
11
12
|
autoload :DSL, 'inherited_resources/dsl'
|
@@ -21,7 +22,11 @@ module InheritedResources
|
|
21
22
|
|
22
23
|
class Railtie < ::Rails::Railtie
|
23
24
|
config.inherited_resources = InheritedResources
|
24
|
-
config.
|
25
|
+
if config.respond_to?(:app_generators)
|
26
|
+
config.app_generators.scaffold_controller = :inherited_resources_controller
|
27
|
+
else
|
28
|
+
config.generators.scaffold_controller = :inherited_resources_controller
|
29
|
+
end
|
25
30
|
end
|
26
31
|
end
|
27
32
|
|
@@ -34,4 +39,4 @@ class ActionController::Base
|
|
34
39
|
initialize_resources_class_accessors!
|
35
40
|
create_resources_url_helpers!
|
36
41
|
end
|
37
|
-
end
|
42
|
+
end
|
data/test/base_test.rb
CHANGED
@@ -29,34 +29,40 @@ module UserTestHelper
|
|
29
29
|
end
|
30
30
|
|
31
31
|
protected
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
32
|
+
|
33
|
+
def mock_user(expectations={})
|
34
|
+
@mock_user ||= begin
|
35
|
+
user = mock(expectations.except(:errors))
|
36
|
+
user.stubs(:class).returns(User)
|
37
|
+
user.stubs(:errors).returns(expectations.fetch(:errors, {}))
|
38
|
+
user.singleton_class.class_eval do
|
39
|
+
def method_missing(symbol, *arguments, &block)
|
40
|
+
raise NoMethodError.new('this is expected by Array#flatten') if symbol == :to_ary
|
41
|
+
super
|
42
|
+
end
|
39
43
|
end
|
44
|
+
user
|
40
45
|
end
|
46
|
+
end
|
41
47
|
end
|
42
48
|
|
43
49
|
class IndexActionBaseTest < ActionController::TestCase
|
44
50
|
include UserTestHelper
|
45
51
|
|
46
52
|
def test_expose_all_users_as_instance_variable
|
47
|
-
User.expects(:
|
53
|
+
User.expects(:scoped).returns([mock_user])
|
48
54
|
get :index
|
49
55
|
assert_equal [mock_user], assigns(:users)
|
50
56
|
end
|
51
57
|
|
52
58
|
def test_apply_scopes_if_method_is_available
|
53
|
-
User.expects(:
|
59
|
+
User.expects(:scoped).returns([mock_user])
|
54
60
|
get :index
|
55
61
|
assert @controller.scopes_applied
|
56
62
|
end
|
57
63
|
|
58
64
|
def test_controller_should_render_index
|
59
|
-
User.stubs(:
|
65
|
+
User.stubs(:scoped).returns([mock_user])
|
60
66
|
get :index
|
61
67
|
assert_response :success
|
62
68
|
assert_equal 'Index HTML', @response.body.strip
|
@@ -64,12 +70,18 @@ class IndexActionBaseTest < ActionController::TestCase
|
|
64
70
|
|
65
71
|
def test_render_all_users_as_xml_when_mime_type_is_xml
|
66
72
|
@request.accept = 'application/xml'
|
67
|
-
User.expects(:
|
68
|
-
|
73
|
+
User.expects(:scoped).returns(collection = [mock_user])
|
74
|
+
collection.expects(:to_xml).returns('Generated XML')
|
69
75
|
get :index
|
70
76
|
assert_response :success
|
71
77
|
assert_equal 'Generated XML', @response.body
|
72
78
|
end
|
79
|
+
|
80
|
+
def test_scoped_is_called_only_when_available
|
81
|
+
User.stubs(:all).returns([mock_user])
|
82
|
+
get :index
|
83
|
+
assert_equal Array, assigns(:users).class
|
84
|
+
end
|
73
85
|
end
|
74
86
|
|
75
87
|
class ShowActionBaseTest < ActionController::TestCase
|
@@ -201,6 +213,14 @@ class UpdateActionBaseTest < ActionController::TestCase
|
|
201
213
|
assert_redirected_to 'http://test.host/'
|
202
214
|
end
|
203
215
|
|
216
|
+
def test_redirect_to_the_users_list_if_show_undefined
|
217
|
+
@controller.class.send(:actions, :all, :except => :show)
|
218
|
+
User.stubs(:find).returns(mock_user(:update_attributes => true))
|
219
|
+
@controller.expects(:collection_url).returns('http://test.host/')
|
220
|
+
put :update
|
221
|
+
assert_redirected_to 'http://test.host/'
|
222
|
+
end
|
223
|
+
|
204
224
|
def test_show_flash_message_when_success
|
205
225
|
User.stubs(:find).returns(mock_user(:update_attributes => true))
|
206
226
|
put :update
|
@@ -229,7 +249,7 @@ end
|
|
229
249
|
|
230
250
|
class DestroyActionBaseTest < ActionController::TestCase
|
231
251
|
include UserTestHelper
|
232
|
-
|
252
|
+
|
233
253
|
def test_the_requested_user_is_destroyed
|
234
254
|
User.expects(:find).with('42').returns(mock_user)
|
235
255
|
mock_user.expects(:destroy).returns(true)
|