josevalim-inherited_resources 0.6.3 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +9 -0
- data/README +132 -105
- data/lib/inherited_resources/base.rb +15 -189
- data/lib/inherited_resources/base_helpers.rb +75 -39
- data/lib/inherited_resources/belongs_to_helpers.rb +62 -40
- data/lib/inherited_resources/class_methods.rb +268 -272
- data/lib/inherited_resources/dumb_responder.rb +7 -6
- data/lib/inherited_resources/has_scope_helpers.rb +65 -0
- data/lib/inherited_resources/polymorphic_helpers.rb +96 -5
- data/lib/inherited_resources/respond_to.rb +7 -7
- data/lib/inherited_resources/singleton_helpers.rb +48 -6
- data/lib/inherited_resources/url_helpers.rb +37 -36
- data/lib/inherited_resources.rb +4 -2
- data/test/base_helpers_test.rb +3 -92
- data/test/class_methods_test.rb +116 -75
- data/test/customized_belongs_to_test.rb +76 -0
- data/test/defaults_test.rb +2 -1
- data/test/flash_test.rb +83 -0
- data/test/has_scope_test.rb +171 -0
- data/test/test_helper.rb +4 -8
- data/test/url_helpers_test.rb +3 -3
- data/test/views/branches/edit.html.erb +1 -0
- data/test/views/branches/index.html.erb +1 -0
- data/test/views/branches/new.html.erb +1 -0
- data/test/views/branches/show.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/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
- metadata +17 -2
@@ -0,0 +1,65 @@
|
|
1
|
+
module InheritedResources
|
2
|
+
|
3
|
+
# = has_scopes
|
4
|
+
#
|
5
|
+
# This module in included in your controller when has_scope is called for the
|
6
|
+
# first time.
|
7
|
+
#
|
8
|
+
module HasScopeHelpers
|
9
|
+
TRUE_VALUES = ["true", true, "1", 1] unless self.const_defined?(:TRUE_VALUES)
|
10
|
+
|
11
|
+
protected
|
12
|
+
|
13
|
+
# Overwrites apply to scope to implement default scope logic.
|
14
|
+
#
|
15
|
+
def apply_scope_to(target_object, target_name) #:nodoc:
|
16
|
+
@current_scopes ||= {}
|
17
|
+
scope_config = self.scopes_configuration[target_name] || {}
|
18
|
+
|
19
|
+
scope_config.each do |scope, options|
|
20
|
+
next unless apply_scope_to_action?(options)
|
21
|
+
key = options[:key]
|
22
|
+
|
23
|
+
if params.key?(key)
|
24
|
+
value, call_scope = params[key], true
|
25
|
+
elsif options.key?(:default)
|
26
|
+
value, call_scope = options[:default], true
|
27
|
+
end
|
28
|
+
|
29
|
+
if call_scope
|
30
|
+
@current_scopes[key] = value
|
31
|
+
|
32
|
+
if options[:boolean]
|
33
|
+
target_object = target_object.send(scope) if TRUE_VALUES.include?(value)
|
34
|
+
else
|
35
|
+
target_object = target_object.send(scope, value)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
target_object
|
41
|
+
end
|
42
|
+
|
43
|
+
# Given an options with :only and :except arrays, check if the scope
|
44
|
+
# can be performed in the current action.
|
45
|
+
#
|
46
|
+
def apply_scope_to_action?(options) #:nodoc:
|
47
|
+
if options[:only].empty?
|
48
|
+
if options[:except].empty?
|
49
|
+
true
|
50
|
+
else
|
51
|
+
!options[:except].include?(action_name.to_sym)
|
52
|
+
end
|
53
|
+
else
|
54
|
+
options[:only].include?(action_name.to_sym)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Returns the scopes used in this action.
|
59
|
+
#
|
60
|
+
def current_scopes
|
61
|
+
@current_scopes || {}
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
@@ -1,8 +1,94 @@
|
|
1
|
-
module InheritedResources
|
2
|
-
|
1
|
+
module InheritedResources
|
2
|
+
|
3
|
+
# = polymorphic associations
|
4
|
+
#
|
5
|
+
# In some cases you have a resource that belongs to two different resources
|
6
|
+
# but not at the same time. For example, let's suppose you have File, Message
|
7
|
+
# and Task as resources and they are all commentable.
|
8
|
+
#
|
9
|
+
# Polymorphic associations allows you to create just one controller that will
|
10
|
+
# deal with each case.
|
11
|
+
#
|
12
|
+
# class Comment < InheritedResources::Base
|
13
|
+
# belongs_to :file, :message, :task, :polymorphic => true
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# Your routes should be something like:
|
17
|
+
#
|
18
|
+
# m.resources :files, :has_many => :comments #=> /files/13/comments
|
19
|
+
# m.resources :tasks, :has_many => :comments #=> /tasks/17/comments
|
20
|
+
# m.resources :messages, :has_many => :comments #=> /messages/11/comments
|
21
|
+
#
|
22
|
+
# When using polymorphic associations, you get some free helpers:
|
23
|
+
#
|
24
|
+
# parent? #=> true
|
25
|
+
# parent_type #=> :task
|
26
|
+
# parent_class #=> Task
|
27
|
+
# parent #=> @task
|
28
|
+
#
|
29
|
+
# This polymorphic controllers thing is a great idea by James Golick and he
|
30
|
+
# built it in resource_controller. Here is just a re-implementation.
|
31
|
+
#
|
32
|
+
# = optional polymorphic associations
|
33
|
+
#
|
34
|
+
# Let's take another break from ProjectsController. Let's suppose we are
|
35
|
+
# building a store, which sell products.
|
36
|
+
#
|
37
|
+
# On the website, we can show all products, but also products scoped to
|
38
|
+
# categories, brands, users. In this case case, the association is optional, and
|
39
|
+
# we deal with it in the following way:
|
40
|
+
#
|
41
|
+
# class ProductsController < InheritedResources::Base
|
42
|
+
# belongs_to :category, :brand, :user, :polymorphic => true, :optional => true
|
43
|
+
# end
|
44
|
+
#
|
45
|
+
# This will handle all those urls properly:
|
46
|
+
#
|
47
|
+
# /products/1
|
48
|
+
# /categories/2/products/5
|
49
|
+
# /brands/10/products/3
|
50
|
+
# /user/13/products/11
|
51
|
+
#
|
52
|
+
# = nested polymorphic associations
|
53
|
+
#
|
54
|
+
# You can have polymorphic associations with nested resources. Let's suppose
|
55
|
+
# that our File, Task and Message resources in the previous example belongs to
|
56
|
+
# a project.
|
57
|
+
#
|
58
|
+
# This way we can have:
|
59
|
+
#
|
60
|
+
# class CommentsController < InheritedResources::Base
|
61
|
+
# belongs_to :project {
|
62
|
+
# belongs_to :file, :message, :task, :polymorphic => true
|
63
|
+
# }
|
64
|
+
# end
|
65
|
+
#
|
66
|
+
# Or:
|
67
|
+
#
|
68
|
+
# class CommentsController < InheritedResources::Base
|
69
|
+
# nested_belongs_to :project
|
70
|
+
# nested_belongs_to :file, :message, :task, :polymorphic => true
|
71
|
+
# end
|
72
|
+
#
|
73
|
+
# Choose the syntax that makes more sense to you. :)
|
74
|
+
#
|
75
|
+
# Finally your routes should be something like:
|
76
|
+
#
|
77
|
+
# map.resources :projects do |m|
|
78
|
+
# m.resources :files, :has_many => :comments #=> /projects/1/files/13/comments
|
79
|
+
# m.resources :tasks, :has_many => :comments #=> /projects/1/tasks/17/comments
|
80
|
+
# m.resources :messages, :has_many => :comments #=> /projects/1/messages/11/comments
|
81
|
+
# end
|
82
|
+
#
|
83
|
+
# The helpers work in the same way as above.
|
84
|
+
#
|
85
|
+
module PolymorphicHelpers
|
3
86
|
|
4
87
|
protected
|
5
88
|
|
89
|
+
# Returns the parent type. A Comments class can have :task, :file, :note
|
90
|
+
# as parent types.
|
91
|
+
#
|
6
92
|
def parent_type
|
7
93
|
@parent_type
|
8
94
|
end
|
@@ -11,12 +97,15 @@ module InheritedResources #:nodoc:
|
|
11
97
|
parent.class if @parent_type
|
12
98
|
end
|
13
99
|
|
100
|
+
# Returns the parent object. They are also available with the instance
|
101
|
+
# variable name: @task, @file, @note...
|
102
|
+
#
|
14
103
|
def parent
|
15
104
|
instance_variable_get("@#{@parent_type}") if @parent_type
|
16
105
|
end
|
17
106
|
|
18
|
-
|
19
|
-
|
107
|
+
# If the polymorphic association is optional, we might not have a parent.
|
108
|
+
#
|
20
109
|
def parent?
|
21
110
|
if resources_configuration[:polymorphic][:optional]
|
22
111
|
parents_symbols.size > 1 || !@parent_type.nil?
|
@@ -25,6 +114,8 @@ module InheritedResources #:nodoc:
|
|
25
114
|
end
|
26
115
|
end
|
27
116
|
|
117
|
+
private
|
118
|
+
|
28
119
|
# Maps parents_symbols to build association chain.
|
29
120
|
#
|
30
121
|
# If the parents_symbols find :polymorphic, it goes through the
|
@@ -33,7 +124,7 @@ module InheritedResources #:nodoc:
|
|
33
124
|
# When optional is given, it does not raise errors if the polymorphic
|
34
125
|
# params are missing.
|
35
126
|
#
|
36
|
-
def
|
127
|
+
def symbols_for_association_chain #:nodoc:
|
37
128
|
polymorphic_config = resources_configuration[:polymorphic]
|
38
129
|
|
39
130
|
parents_symbols.map do |symbol|
|
@@ -1,8 +1,8 @@
|
|
1
|
-
|
2
|
-
#
|
3
|
-
#
|
4
|
-
|
5
|
-
class Base
|
1
|
+
module ActionController
|
2
|
+
# Provides an extension for Rails respond_to by expading MimeResponds::Responder
|
3
|
+
# and adding respond_to class method and respond_with instance method.
|
4
|
+
#
|
5
|
+
class Base
|
6
6
|
|
7
7
|
protected
|
8
8
|
# Defines respond_to method to store formats that are rendered by default.
|
@@ -240,10 +240,10 @@ module ActionController #:nodoc:
|
|
240
240
|
|
241
241
|
private
|
242
242
|
|
243
|
-
# Define template_exists? for Rails 2.3
|
244
243
|
unless ActionController::Base.private_instance_methods.include?('template_exists?') ||
|
245
244
|
ActionController::Base.private_instance_methods.include?(:template_exists?)
|
246
245
|
|
246
|
+
# Define template_exists? for Rails 2.3
|
247
247
|
def template_exists?
|
248
248
|
default_template ? true : false
|
249
249
|
rescue ActionView::MissingTemplate
|
@@ -254,7 +254,7 @@ module ActionController #:nodoc:
|
|
254
254
|
# We respond to the default template if it's a valid format AND the template
|
255
255
|
# exists.
|
256
256
|
#
|
257
|
-
def respond_to_default_template?(responder)
|
257
|
+
def respond_to_default_template?(responder) #:nodoc:
|
258
258
|
responder.action_respond_to_format?(default_template_format) && template_exists?
|
259
259
|
end
|
260
260
|
|
@@ -1,8 +1,43 @@
|
|
1
|
-
module InheritedResources
|
2
|
-
|
1
|
+
module InheritedResources
|
2
|
+
|
3
|
+
# = singleton
|
4
|
+
#
|
5
|
+
# Singletons are usually used in associations which are related through has_one
|
6
|
+
# and belongs_to. You declare those associations like this:
|
7
|
+
#
|
8
|
+
# class ManagersController < InheritedResources::Base
|
9
|
+
# belongs_to :project, :singleton => true
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# But in some cases, like an AccountsController, you have a singleton object
|
13
|
+
# that is not necessarily associated with another:
|
14
|
+
#
|
15
|
+
# class AccountsController < InheritedResources::Base
|
16
|
+
# defaults :singleton => true
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# Besides that, you should overwrite the methods :resource and :build_resource
|
20
|
+
# to make it work properly:
|
21
|
+
#
|
22
|
+
# class AccountsController < InheritedResources::Base
|
23
|
+
# defaults :singleton => true
|
24
|
+
#
|
25
|
+
# protected
|
26
|
+
# def resource
|
27
|
+
# @current_user.account
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# def build_resource(attributes = {})
|
31
|
+
# Account.new(attributes)
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# When you have a singleton controller, the action index is removed.
|
36
|
+
#
|
37
|
+
module SingletonHelpers
|
3
38
|
|
4
|
-
# Protected helpers. You might want to overwrite some of them.
|
5
39
|
protected
|
40
|
+
|
6
41
|
# Singleton methods does not deal with collections.
|
7
42
|
#
|
8
43
|
def collection
|
@@ -10,6 +45,7 @@ module InheritedResources #:nodoc:
|
|
10
45
|
end
|
11
46
|
|
12
47
|
# Overwrites how singleton deals with resource.
|
48
|
+
#
|
13
49
|
# If you are going to overwrite it, you should notice that the
|
14
50
|
# end_of_association_chain here is not the same as in default belongs_to.
|
15
51
|
#
|
@@ -34,20 +70,26 @@ module InheritedResources #:nodoc:
|
|
34
70
|
#
|
35
71
|
# Project.find(params[:project_id])
|
36
72
|
#
|
37
|
-
# So we have to call manager on it
|
73
|
+
# So we have to call manager on it, not find.
|
38
74
|
#
|
39
75
|
def resource
|
40
76
|
get_resource_ivar || set_resource_ivar(end_of_association_chain.send(resource_instance_name))
|
41
77
|
end
|
42
78
|
|
43
|
-
# Private helpers, you probably don't have to worry with them.
|
44
79
|
private
|
45
80
|
|
46
81
|
# Returns the appropriated method to build the resource.
|
47
82
|
#
|
48
|
-
def method_for_build
|
83
|
+
def method_for_build #:nodoc:
|
49
84
|
"build_#{resource_instance_name}"
|
50
85
|
end
|
51
86
|
|
87
|
+
# Sets the method_for_association_chain to nil. See <tt>resource</tt>
|
88
|
+
# above for more information.
|
89
|
+
#
|
90
|
+
def method_for_association_chain #:nodoc:
|
91
|
+
nil
|
92
|
+
end
|
93
|
+
|
52
94
|
end
|
53
95
|
end
|
@@ -1,34 +1,34 @@
|
|
1
|
-
|
2
|
-
#
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
|
7
|
-
#
|
8
|
-
# resource_url
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
|
14
|
-
#
|
15
|
-
# resource_url
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
|
21
|
-
#
|
22
|
-
# resource_url
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
|
31
|
-
module UrlHelpers
|
1
|
+
module InheritedResources
|
2
|
+
# = URLHelpers
|
3
|
+
#
|
4
|
+
# When you use InheritedResources it creates some UrlHelpers for you.
|
5
|
+
# And they handle everything for you.
|
6
|
+
#
|
7
|
+
# # /posts/1/comments
|
8
|
+
# resource_url # => /posts/1/comments/#{@comment.to_param}
|
9
|
+
# resource_url(comment) # => /posts/1/comments/#{comment.to_param}
|
10
|
+
# new_resource_url # => /posts/1/comments/new
|
11
|
+
# edit_resource_url # => /posts/1/comments/#{@comment.to_param}/edit
|
12
|
+
# collection_url # => /posts/1/comments
|
13
|
+
#
|
14
|
+
# # /projects/1/tasks
|
15
|
+
# resource_url # => /products/1/tasks/#{@task.to_param}
|
16
|
+
# resource_url(task) # => /products/1/tasks/#{task.to_param}
|
17
|
+
# new_resource_url # => /products/1/tasks/new
|
18
|
+
# edit_resource_url # => /products/1/tasks/#{@task.to_param}/edit
|
19
|
+
# collection_url # => /products/1/tasks
|
20
|
+
#
|
21
|
+
# # /users
|
22
|
+
# resource_url # => /users/#{@user.to_param}
|
23
|
+
# resource_url(user) # => /users/#{user.to_param}
|
24
|
+
# new_resource_url # => /users/new
|
25
|
+
# edit_resource_url # => /users/#{@user.to_param}/edit
|
26
|
+
# collection_url # => /users
|
27
|
+
#
|
28
|
+
# The nice thing is that those urls are not guessed during runtime. They are
|
29
|
+
# all created when you inherit.
|
30
|
+
#
|
31
|
+
module UrlHelpers
|
32
32
|
|
33
33
|
# This method hard code url helpers in the class.
|
34
34
|
#
|
@@ -76,7 +76,7 @@ module InheritedResources #:nodoc:
|
|
76
76
|
#
|
77
77
|
# This is where you are going to be redirected after destroying the manager.
|
78
78
|
#
|
79
|
-
unless base.singleton
|
79
|
+
unless base.resources_configuration[:self][:singleton]
|
80
80
|
resource_segments << resource_config[:route_collection_name]
|
81
81
|
generate_url_and_path_helpers(base, nil, :collection, resource_segments, resource_ivars, polymorphic)
|
82
82
|
resource_segments.pop
|
@@ -97,20 +97,21 @@ module InheritedResources #:nodoc:
|
|
97
97
|
#
|
98
98
|
# edit_project_manager_url(@project, @manager)
|
99
99
|
#
|
100
|
-
resource_ivars << resource_config[:instance_name] unless base.singleton
|
100
|
+
resource_ivars << resource_config[:instance_name] unless base.resources_configuration[:self][:singleton]
|
101
101
|
|
102
102
|
# Prepare and add resource_url and edit_resource_url
|
103
103
|
generate_url_and_path_helpers(base, nil, :resource, resource_segments, resource_ivars, polymorphic)
|
104
104
|
generate_url_and_path_helpers(base, :edit, :resource, resource_segments, resource_ivars, polymorphic)
|
105
105
|
end
|
106
106
|
|
107
|
-
def self.generate_url_and_path_helpers(base, prefix, name, resource_segments, resource_ivars, polymorphic=false)
|
107
|
+
def self.generate_url_and_path_helpers(base, prefix, name, resource_segments, resource_ivars, polymorphic=false) #:nodoc:
|
108
108
|
ivars = resource_ivars.map{|i| i == :parent ? :parent : "@#{i}" }
|
109
109
|
|
110
110
|
# If it's not a singleton, ivars are not empty, not a collection or
|
111
111
|
# not a "new" named route, we can pass a resource as argument.
|
112
112
|
#
|
113
|
-
unless base.singleton || ivars.empty? ||
|
113
|
+
unless base.resources_configuration[:self][:singleton] || ivars.empty? ||
|
114
|
+
name == :collection || prefix == :new
|
114
115
|
ivars.push "(given_args.first || #{ivars.pop})"
|
115
116
|
end
|
116
117
|
|
@@ -159,7 +160,7 @@ module InheritedResources #:nodoc:
|
|
159
160
|
# polymorphic_url(@project, Task.new)
|
160
161
|
# new_polymorphic_url(@project, Task.new)
|
161
162
|
#
|
162
|
-
if base.singleton
|
163
|
+
if base.resources_configuration[:self][:singleton]
|
163
164
|
ivars << base.resources_configuration[:self][:instance_name].inspect unless name == :collection
|
164
165
|
elsif name == :collection || prefix == :new
|
165
166
|
ivars << 'resource_class.new'
|
data/lib/inherited_resources.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# respond_to is the only file that should be loaded before hand. All others
|
2
|
+
# are loaded on demand.
|
3
|
+
#
|
4
|
+
require File.join(File.dirname(__FILE__), 'inherited_resources', 'respond_to')
|
3
5
|
|
4
6
|
module InheritedResources; end
|
data/test/base_helpers_test.rb
CHANGED
@@ -1,94 +1,10 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/test_helper'
|
2
2
|
|
3
|
-
class Address
|
4
|
-
def self.human_name; 'Address'; end
|
5
|
-
end
|
6
|
-
|
7
|
-
class AddressesController < InheritedResources::Base
|
8
|
-
protected
|
9
|
-
def interpolation_options
|
10
|
-
{ :reference => 'Ocean Avenue' }
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
module Admin; end
|
15
|
-
class Admin::AddressesController < InheritedResources::Base
|
16
|
-
protected
|
17
|
-
def interpolation_options
|
18
|
-
{ :reference => 'Ocean Avenue' }
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
class FlashBaseHelpersTest < ActionController::TestCase
|
23
|
-
tests AddressesController
|
24
|
-
|
25
|
-
def setup
|
26
|
-
@request.accept = 'application/xml'
|
27
|
-
end
|
28
|
-
|
29
|
-
def test_success_flash_message_on_create_with_yml
|
30
|
-
Address.stubs(:new).returns(mock_address(:save => true))
|
31
|
-
@controller.stubs(:address_url)
|
32
|
-
post :create
|
33
|
-
assert_equal 'You created a new address close to <b>Ocean Avenue</b>.', flash[:notice]
|
34
|
-
end
|
35
|
-
|
36
|
-
def test_success_flash_message_on_create_with_namespaced_controller
|
37
|
-
@controller = Admin::AddressesController.new
|
38
|
-
Address.stubs(:new).returns(mock_address(:save => true))
|
39
|
-
@controller.stubs(:address_url)
|
40
|
-
post :create
|
41
|
-
assert_equal 'Admin, you created a new address close to <b>Ocean Avenue</b>.', flash[:notice]
|
42
|
-
end
|
43
|
-
|
44
|
-
def test_failure_flash_message_on_create_with_namespaced_controller_actions
|
45
|
-
@controller = Admin::AddressesController.new
|
46
|
-
Address.stubs(:new).returns(mock_address(:save => false))
|
47
|
-
@controller.stubs(:address_url)
|
48
|
-
post :create
|
49
|
-
assert_equal 'Admin error message.', flash[:error]
|
50
|
-
end
|
51
|
-
|
52
|
-
def test_inherited_success_flash_message_on_update_on_namespaced_controllers
|
53
|
-
@controller = Admin::AddressesController.new
|
54
|
-
Address.stubs(:find).returns(mock_address(:update_attributes => true))
|
55
|
-
put :update
|
56
|
-
assert_response :success
|
57
|
-
assert_equal 'Nice! Address was updated with success!', flash[:notice]
|
58
|
-
end
|
59
|
-
|
60
|
-
def test_success_flash_message_on_update
|
61
|
-
Address.stubs(:find).returns(mock_address(:update_attributes => true))
|
62
|
-
put :update
|
63
|
-
assert_response :success
|
64
|
-
assert_equal 'Nice! Address was updated with success!', flash[:notice]
|
65
|
-
end
|
66
|
-
|
67
|
-
def test_failure_flash_message_on_update
|
68
|
-
Address.stubs(:find).returns(mock_address(:update_attributes => false, :errors => []))
|
69
|
-
put :update
|
70
|
-
assert_equal 'Oh no! We could not update your address!', flash[:error]
|
71
|
-
end
|
72
|
-
|
73
|
-
def test_success_flash_message_on_destroy
|
74
|
-
Address.stubs(:find).returns(mock_address(:destroy => true))
|
75
|
-
delete :destroy
|
76
|
-
assert_equal 'Address was successfully destroyed.', flash[:notice]
|
77
|
-
end
|
78
|
-
|
79
|
-
protected
|
80
|
-
def mock_address(stubs={})
|
81
|
-
@mock_address ||= mock(stubs)
|
82
|
-
end
|
83
|
-
|
84
|
-
end
|
85
|
-
|
86
3
|
class Pet
|
87
4
|
def self.human_name; 'Pet'; end
|
88
5
|
end
|
89
6
|
|
90
7
|
class PetsController < InheritedResources::Base
|
91
|
-
respond_to :xml
|
92
8
|
attr_accessor :current_user
|
93
9
|
|
94
10
|
def edit
|
@@ -111,38 +27,33 @@ class AssociationChainBaseHelpersTest < ActionController::TestCase
|
|
111
27
|
|
112
28
|
def setup
|
113
29
|
@controller.current_user = mock()
|
114
|
-
@request.accept = 'application/xml'
|
115
30
|
end
|
116
31
|
|
117
32
|
def test_begin_of_association_chain_is_called_on_index
|
118
33
|
@controller.current_user.expects(:pets).returns(Pet)
|
119
34
|
Pet.expects(:all).returns(mock_pet)
|
120
|
-
mock_pet.expects(:to_xml).returns('Generated XML')
|
121
35
|
get :index
|
122
36
|
assert_response :success
|
123
|
-
assert '
|
37
|
+
assert 'Index HTML', @response.body.strip
|
124
38
|
end
|
125
39
|
|
126
40
|
def test_begin_of_association_chain_is_called_on_new
|
127
41
|
@controller.current_user.expects(:pets).returns(Pet)
|
128
42
|
Pet.expects(:build).returns(mock_pet)
|
129
|
-
mock_pet.expects(:to_xml).returns('Generated XML')
|
130
43
|
get :new
|
131
44
|
assert_response :success
|
132
|
-
assert '
|
45
|
+
assert 'New HTML', @response.body.strip
|
133
46
|
end
|
134
47
|
|
135
48
|
def test_begin_of_association_chain_is_called_on_show
|
136
49
|
@controller.current_user.expects(:pets).returns(Pet)
|
137
50
|
Pet.expects(:find).with('47').returns(mock_pet)
|
138
|
-
mock_pet.expects(:to_xml).returns('Generated XML')
|
139
51
|
get :show, :id => '47'
|
140
52
|
assert_response :success
|
141
|
-
assert '
|
53
|
+
assert 'Show HTML', @response.body.strip
|
142
54
|
end
|
143
55
|
|
144
56
|
def test_instance_variable_should_not_be_set_if_already_defined
|
145
|
-
@request.accept = 'text/html'
|
146
57
|
@controller.current_user.expects(:pets).never
|
147
58
|
Pet.expects(:find).never
|
148
59
|
get :edit
|