josevalim-inherited_resources 0.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.
Files changed (57) hide show
  1. data/CHANGELOG +4 -0
  2. data/MIT-LICENSE +21 -0
  3. data/README +362 -0
  4. data/Rakefile +19 -0
  5. data/init.rb +1 -0
  6. data/lib/inherited_resources.rb +4 -0
  7. data/lib/inherited_resources/base.rb +272 -0
  8. data/lib/inherited_resources/base_helpers.rb +199 -0
  9. data/lib/inherited_resources/belongs_to.rb +227 -0
  10. data/lib/inherited_resources/belongs_to_helpers.rb +89 -0
  11. data/lib/inherited_resources/class_methods.rb +155 -0
  12. data/lib/inherited_resources/polymorphic_helpers.rb +19 -0
  13. data/lib/inherited_resources/respond_to.rb +324 -0
  14. data/lib/inherited_resources/singleton_helpers.rb +53 -0
  15. data/lib/inherited_resources/url_helpers.rb +147 -0
  16. data/test/aliases_test.rb +71 -0
  17. data/test/base_helpers_test.rb +130 -0
  18. data/test/base_test.rb +219 -0
  19. data/test/belongs_to_base_test.rb +268 -0
  20. data/test/belongs_to_test.rb +109 -0
  21. data/test/class_methods_test.rb +73 -0
  22. data/test/fixtures/en.yml +9 -0
  23. data/test/nested_belongs_to_test.rb +138 -0
  24. data/test/polymorphic_base_test.rb +282 -0
  25. data/test/respond_to_test.rb +282 -0
  26. data/test/singleton_base_test.rb +226 -0
  27. data/test/test_helper.rb +37 -0
  28. data/test/url_helpers_test.rb +284 -0
  29. data/test/views/cities/edit.html.erb +1 -0
  30. data/test/views/cities/index.html.erb +1 -0
  31. data/test/views/cities/new.html.erb +1 -0
  32. data/test/views/cities/show.html.erb +1 -0
  33. data/test/views/comments/edit.html.erb +1 -0
  34. data/test/views/comments/index.html.erb +1 -0
  35. data/test/views/comments/new.html.erb +1 -0
  36. data/test/views/comments/show.html.erb +1 -0
  37. data/test/views/employees/edit.html.erb +1 -0
  38. data/test/views/employees/index.html.erb +1 -0
  39. data/test/views/employees/new.html.erb +1 -0
  40. data/test/views/employees/show.html.erb +1 -0
  41. data/test/views/managers/edit.html.erb +1 -0
  42. data/test/views/managers/new.html.erb +1 -0
  43. data/test/views/managers/show.html.erb +1 -0
  44. data/test/views/pets/edit.html.erb +1 -0
  45. data/test/views/professors/edit.html.erb +1 -0
  46. data/test/views/professors/index.html.erb +1 -0
  47. data/test/views/professors/new.html.erb +1 -0
  48. data/test/views/professors/show.html.erb +1 -0
  49. data/test/views/projects/index.html.erb +1 -0
  50. data/test/views/projects/respond_to_with_resource.html.erb +1 -0
  51. data/test/views/students/edit.html.erb +1 -0
  52. data/test/views/students/new.html.erb +1 -0
  53. data/test/views/users/edit.html.erb +1 -0
  54. data/test/views/users/index.html.erb +1 -0
  55. data/test/views/users/new.html.erb +1 -0
  56. data/test/views/users/show.html.erb +1 -0
  57. metadata +108 -0
@@ -0,0 +1,53 @@
1
+ module InheritedResources #:nodoc:
2
+ module SingletonHelpers #:nodoc:
3
+
4
+ # Protected helpers. You might want to overwrite some of them.
5
+ protected
6
+ # Singleton methods does not deal with collections.
7
+ #
8
+ def collection
9
+ nil
10
+ end
11
+
12
+ # Overwrites how singleton deals with resource.
13
+ # If you are going to overwrite it, you should notice that the
14
+ # end_of_association_chain here is not the same as in default belongs_to.
15
+ #
16
+ # class TasksController < InheritedResources::Base
17
+ # belongs_to :project
18
+ # end
19
+ #
20
+ # In this case, the association chain would be:
21
+ #
22
+ # Project.find(params[:project_id]).tasks
23
+ #
24
+ # So you would just have to call find(:all) at the end of association
25
+ # chain. And this is what happened.
26
+ #
27
+ # In singleton controllers:
28
+ #
29
+ # class ManagersController < InheritedResources::Base
30
+ # belongs_to :project, :singleton => true
31
+ # end
32
+ #
33
+ # The association chain will be:
34
+ #
35
+ # Project.find(params[:project_id])
36
+ #
37
+ # So we have to call manager on it. And again, this is what happens.
38
+ #
39
+ def resource
40
+ get_resource_ivar || set_resource_ivar(end_of_association_chain.send(resource_instance_name))
41
+ end
42
+
43
+ # Private helpers, you probably don't have to worry with them.
44
+ private
45
+
46
+ # Returns the appropriated method to build the resource.
47
+ #
48
+ def method_for_build
49
+ "build_#{resource_instance_name}"
50
+ end
51
+
52
+ end
53
+ end
@@ -0,0 +1,147 @@
1
+ # = URLHelpers
2
+ #
3
+ # When you use InheritedResources it creates some UrlHelpers for you.
4
+ # And they handle everything for you.
5
+ #
6
+ # # /posts/1/comments
7
+ # resource_url # => /posts/1/comments/#{@comment.to_param}
8
+ # resource_url(comment) # => /posts/1/comments/#{comment.to_param}
9
+ # new_resource_url # => /posts/1/comments/new
10
+ # edit_resource_url # => /posts/1/comments/#{@comment.to_param}/edit
11
+ # collection_url # => /posts/1/comments
12
+ #
13
+ # # /projects/1/tasks
14
+ # resource_url # => /products/1/tasks/#{@task.to_param}
15
+ # resource_url(task) # => /products/1/tasks/#{task.to_param}
16
+ # new_resource_url # => /products/1/tasks/new
17
+ # edit_resource_url # => /products/1/tasks/#{@task.to_param}/edit
18
+ # collection_url # => /products/1/tasks
19
+ #
20
+ # # /users
21
+ # resource_url # => /users/#{@user.to_param}
22
+ # resource_url(user) # => /users/#{user.to_param}
23
+ # new_resource_url # => /users/new
24
+ # edit_resource_url # => /users/#{@user.to_param}/edit
25
+ # collection_url # => /users
26
+ #
27
+ # The nice thing is that those urls are not guessed during runtime. They are
28
+ # all created when you inherit.
29
+ #
30
+ module InheritedResources #:nodoc:
31
+ module UrlHelpers #:nodoc:
32
+
33
+ # This method hard code url helpers in the class.
34
+ #
35
+ # We are doing this because is cheaper than guessing them when our action
36
+ # is being processed (and even more cheaper when we are using nested
37
+ # resources).
38
+ #
39
+ # When we are using polymorphic associations, those helpers rely on
40
+ # polymorphic_url Rails helper.
41
+ #
42
+ def self.create_resources_url_helpers!(base)
43
+ resource_segments, resource_ivars = [], []
44
+ resource_config = base.resources_configuration[:self]
45
+ polymorphic = false
46
+
47
+ # Deal with belongs_to associations.
48
+ #
49
+ # If we find a :polymorphic symbol, it means that we should not add
50
+ # :route_name to resource_segments (which will be useless anyway).
51
+ #
52
+ base.parents_symbols.map do |symbol|
53
+ if symbol == :polymorphic
54
+ polymorphic = true
55
+ resource_ivars << :parent_instance
56
+ else
57
+ config = base.resources_configuration[symbol]
58
+ resource_segments << config[:route_name]
59
+ resource_ivars << config[:instance_name]
60
+ end
61
+ end
62
+
63
+ # Deals with singleton.
64
+ # We define collection_url to singletons just for compatibility mode.
65
+ #
66
+ # The collection_url for singleton is the parent show url. For example,
67
+ # if we have ProjectsController with ManagerController, where the second
68
+ # is the singleton, the collection url would be: project_url.
69
+ #
70
+ # This is where you are going to be redirected after destroing the manager.
71
+ #
72
+ unless base.singleton
73
+ resource_segments << resource_config[:collection_name]
74
+ generate_url_and_path_helpers(base, nil, :collection, resource_segments, resource_ivars, polymorphic)
75
+ resource_segments.pop
76
+ else
77
+ generate_url_and_path_helpers(base, nil, :collection, resource_segments, resource_ivars, polymorphic)
78
+ end
79
+
80
+ # Prepare and add new_resource_url
81
+ resource_segments << resource_config[:instance_name]
82
+ generate_url_and_path_helpers(base, :new, :resource, resource_segments, resource_ivars, polymorphic)
83
+
84
+ # We don't add the resource ivar to edit and resource url if singleton
85
+ resource_ivars << resource_config[:instance_name] unless base.singleton
86
+
87
+ # Prepare and add resource_url and edit_resource_url
88
+ generate_url_and_path_helpers(base, nil, :resource, resource_segments, resource_ivars, polymorphic)
89
+ generate_url_and_path_helpers(base, :edit, :resource, resource_segments, resource_ivars, polymorphic)
90
+ end
91
+
92
+ def self.generate_url_and_path_helpers(base, prefix, name, resource_segments, resource_ivars, polymorphic=false)
93
+ ivars = resource_ivars.map{|i| i == :parent_instance ? :parent_instance : "@#{i}" }
94
+
95
+ # If it's not a singleton, ivars are not empty, not a collection or
96
+ # not a new hew helper, we can add args to the method.
97
+ #
98
+ arg = unless base.singleton || ivars.empty? || name == :collection || prefix == :new
99
+ ivars.push("(given_arg || #{ivars.pop})")
100
+ 'given_arg=nil'
101
+ else
102
+ ''
103
+ end
104
+
105
+ # When polymorphic is true, the segments must be replace by :polymorphic
106
+ # and ivars should be gathered into an array.
107
+ #
108
+ if polymorphic
109
+ segments = :polymorphic
110
+
111
+ # Customization to allow polymorphic with singletons.
112
+ #
113
+ # In such cases, we must send a string with the resource instance name
114
+ # to polymorphic_url.
115
+ #
116
+ # When not a singleton, but a collection or new url, we should add
117
+ # resource_class.new to instance ivars to allow polymorphic_url to
118
+ # deal with it properly.
119
+ #
120
+ if base.singleton
121
+ ivars << base.resources_configuration[:self][:instance_name].inspect unless name == :collection
122
+ elsif name == :collection || prefix == :new
123
+ ivars << 'resource_class.new'
124
+ end
125
+
126
+ ivars = "[#{ivars.join(', ')}]"
127
+ else
128
+ segments = resource_segments.join('_')
129
+ ivars = ivars.join(', ')
130
+ end
131
+
132
+ prefix = prefix ? "#{prefix}_" : ''
133
+
134
+ base.class_eval <<URL_HELPERS, __FILE__, __LINE__
135
+ protected
136
+ def #{prefix}#{name}_path(#{arg})
137
+ #{prefix}#{segments}_path(#{ivars})
138
+ end
139
+
140
+ def #{prefix}#{name}_url(#{arg})
141
+ #{prefix}#{segments}_url(#{ivars})
142
+ end
143
+ URL_HELPERS
144
+ end
145
+
146
+ end
147
+ end
@@ -0,0 +1,71 @@
1
+ # Now we are going to test aliases defined in base.rb and if overwriting
2
+ # methods works properly.
3
+ require File.dirname(__FILE__) + '/test_helper'
4
+
5
+ class Student; end
6
+
7
+ class StudentsController < InheritedResources::Base
8
+
9
+ def edit
10
+ edit! do |format|
11
+ format.xml { render :text => 'Render XML' }
12
+ end
13
+ end
14
+
15
+ def new
16
+ @something = 'magical'
17
+ new!
18
+ end
19
+
20
+ end
21
+
22
+ class AliasesBaseTest < Test::Unit::TestCase
23
+
24
+ def setup
25
+ @controller = StudentsController.new
26
+ @controller.request = @request = ActionController::TestRequest.new
27
+ @controller.response = @response = ActionController::TestResponse.new
28
+ end
29
+
30
+ def test_assignments_before_calling_alias
31
+ Student.stubs(:new).returns(mock_student)
32
+ get :new
33
+ assert_response :success
34
+ assert_equal 'magical', assigns(:something)
35
+ end
36
+
37
+ def test_controller_should_render_new
38
+ Student.stubs(:new).returns(mock_student)
39
+ get :new
40
+ assert_response :success
41
+ assert_equal 'New HTML', @response.body.strip
42
+ end
43
+
44
+ def test_expose_the_resquested_user
45
+ Student.expects(:find).with('42').returns(mock_student)
46
+ get :edit, :id => '42'
47
+ assert_equal mock_student, assigns(:student)
48
+ assert_response :success
49
+ end
50
+
51
+ def test_controller_should_render_edit
52
+ Student.stubs(:find).returns(mock_student)
53
+ get :edit
54
+ assert_response :success
55
+ assert_equal 'Edit HTML', @response.body.strip
56
+ end
57
+
58
+ def test_render_xml_when_it_is_given_as_a_block
59
+ @request.accept = 'application/xml'
60
+ Student.stubs(:find).returns(mock_student)
61
+ get :edit
62
+ assert_response :success
63
+ assert_equal 'Render XML', @response.body
64
+ end
65
+
66
+ protected
67
+ def mock_student(stubs={})
68
+ @mock_student ||= mock(stubs)
69
+ end
70
+ end
71
+
@@ -0,0 +1,130 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
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
+ class FlashBaseHelpersTest < Test::Unit::TestCase
15
+
16
+ def setup
17
+ @controller = AddressesController.new
18
+ @controller.request = @request = ActionController::TestRequest.new
19
+ @controller.response = @response = ActionController::TestResponse.new
20
+ @request.accept = 'application/xml'
21
+ end
22
+
23
+ def test_default_success_flash_message_on_create
24
+ Address.stubs(:new).returns(mock_address(:save => true))
25
+ @controller.stubs(:address_url)
26
+ post :create
27
+ assert_equal 'You created a new address close to <b>Ocean Avenue</b>.', flash[:notice]
28
+ end
29
+
30
+ def test_set_success_flash_message_on_update
31
+ Address.stubs(:find).returns(mock_address(:update_attributes => true))
32
+ put :update
33
+ assert_response :success
34
+ assert_equal 'Nice! Address was updated with success!', flash[:notice]
35
+ end
36
+
37
+ def test_set_failure_flash_message_on_update
38
+ Address.stubs(:find).returns(mock_address(:update_attributes => false, :errors => []))
39
+ put :update
40
+ assert_equal 'Oh no! We could not update your address!', flash[:error]
41
+ end
42
+
43
+ def test_default_success_flash_message_on_destroy
44
+ Address.stubs(:find).returns(mock_address(:destroy => true))
45
+ delete :destroy
46
+ assert_equal 'Address was successfully destroyed.', flash[:notice]
47
+ end
48
+
49
+ protected
50
+ def mock_address(stubs={})
51
+ @mock_address ||= mock(stubs)
52
+ end
53
+
54
+ end
55
+
56
+ class Pet
57
+ def self.human_name; 'Pet'; end
58
+ end
59
+
60
+ class PetsController < InheritedResources::Base
61
+ attr_accessor :current_user
62
+
63
+ def edit
64
+ @pet = 'new pet'
65
+ edit!
66
+ end
67
+
68
+ protected
69
+ def collection
70
+ @pets ||= end_of_association_chain.all
71
+ end
72
+
73
+ def begin_of_association_chain
74
+ @current_user
75
+ end
76
+ end
77
+
78
+ class AssociationChainBaseHelpersTest < Test::Unit::TestCase
79
+
80
+ def setup
81
+ @controller = PetsController.new
82
+ @controller.request = @request = ActionController::TestRequest.new
83
+ @controller.response = @response = ActionController::TestResponse.new
84
+ @controller.current_user = mock()
85
+ @request.accept = 'application/xml'
86
+ end
87
+
88
+ def test_begin_of_association_chain_is_called_on_index
89
+ @controller.current_user.expects(:pets).returns(Pet)
90
+ Pet.expects(:all).returns(mock_pet)
91
+ mock_pet.expects(:to_xml).returns('Generated XML')
92
+ get :index
93
+ assert_response :success
94
+ assert 'Generated XML', @response.body.strip
95
+ end
96
+
97
+ def test_begin_of_association_chain_is_called_on_new
98
+ @controller.current_user.expects(:pets).returns(Pet)
99
+ Pet.expects(:build).returns(mock_pet)
100
+ mock_pet.expects(:to_xml).returns('Generated XML')
101
+ get :new
102
+ assert_response :success
103
+ assert 'Generated XML', @response.body.strip
104
+ end
105
+
106
+ def test_begin_of_association_chain_is_called_on_show
107
+ @controller.current_user.expects(:pets).returns(Pet)
108
+ Pet.expects(:find).with('47').returns(mock_pet)
109
+ mock_pet.expects(:to_xml).returns('Generated XML')
110
+ get :show, :id => '47'
111
+ assert_response :success
112
+ assert 'Generated XML', @response.body.strip
113
+ end
114
+
115
+ def test_instance_variable_should_not_be_set_if_already_defined
116
+ @request.accept = 'text/html'
117
+ @controller.current_user.expects(:pets).never
118
+ Pet.expects(:find).never
119
+ get :edit
120
+ assert_response :success
121
+ assert_equal 'new pet', assigns(:pet)
122
+ end
123
+
124
+ protected
125
+ def mock_pet(stubs={})
126
+ @mock_pet ||= mock(stubs)
127
+ end
128
+
129
+ end
130
+
data/test/base_test.rb ADDED
@@ -0,0 +1,219 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ # This test file is instead to test the how controller flow and actions.
4
+ # This is done using mocks a la rspec.
5
+ #
6
+ class User
7
+ def self.human_name; 'User'; end
8
+ end
9
+
10
+ class UsersController < InheritedResources::Base
11
+ end
12
+
13
+ # Create a TestHelper module with some helpers
14
+ module UserTestHelper
15
+ def setup
16
+ @controller = UsersController.new
17
+ @controller.request = @request = ActionController::TestRequest.new
18
+ @controller.response = @response = ActionController::TestResponse.new
19
+ end
20
+
21
+ protected
22
+ def mock_user(stubs={})
23
+ @mock_user ||= mock(stubs)
24
+ end
25
+ end
26
+
27
+ class IndexActionBaseTest < Test::Unit::TestCase
28
+ include UserTestHelper
29
+
30
+ def test_expose_all_users_as_instance_variable
31
+ User.expects(:find).with(:all).returns([mock_user])
32
+ get :index
33
+ assert_equal [mock_user], assigns(:users)
34
+ end
35
+
36
+ def test_controller_should_render_index
37
+ User.stubs(:find).returns([mock_user])
38
+ get :index
39
+ assert_response :success
40
+ assert_equal 'Index HTML', @response.body.strip
41
+ end
42
+
43
+ def test_render_all_users_as_xml_when_mime_type_is_xml
44
+ @request.accept = 'application/xml'
45
+ User.expects(:find).with(:all).returns(mock_user)
46
+ mock_user.expects(:to_xml).returns('Generated XML')
47
+ get :index
48
+ assert_response :success
49
+ assert_equal 'Generated XML', @response.body
50
+ end
51
+ end
52
+
53
+ class ShowActionBaseTest < Test::Unit::TestCase
54
+ include UserTestHelper
55
+
56
+ def test_expose_the_resquested_user
57
+ User.expects(:find).with('42').returns(mock_user)
58
+ get :show, :id => '42'
59
+ assert_equal mock_user, assigns(:user)
60
+ end
61
+
62
+ def test_controller_should_render_show
63
+ User.stubs(:find).returns(mock_user)
64
+ get :show
65
+ assert_response :success
66
+ assert_equal 'Show HTML', @response.body.strip
67
+ end
68
+
69
+ def test_render_exposed_user_as_xml_when_mime_type_is_xml
70
+ @request.accept = 'application/xml'
71
+ User.expects(:find).with('42').returns(mock_user)
72
+ mock_user.expects(:to_xml).returns("Generated XML")
73
+ get :show, :id => '42'
74
+ assert_response :success
75
+ assert_equal 'Generated XML', @response.body
76
+ end
77
+ end
78
+
79
+ class NewActionBaseTest < Test::Unit::TestCase
80
+ include UserTestHelper
81
+
82
+ def test_expose_a_new_user
83
+ User.expects(:new).returns(mock_user)
84
+ get :new
85
+ assert_equal mock_user, assigns(:user)
86
+ end
87
+
88
+ def test_controller_should_render_new
89
+ User.stubs(:new).returns(mock_user)
90
+ get :new
91
+ assert_response :success
92
+ assert_equal 'New HTML', @response.body.strip
93
+ end
94
+
95
+ def test_render_exposed_a_new_user_as_xml_when_mime_type_is_xml
96
+ @request.accept = 'application/xml'
97
+ User.expects(:new).returns(mock_user)
98
+ mock_user.expects(:to_xml).returns("Generated XML")
99
+ get :new
100
+ assert_response :success
101
+ assert_equal 'Generated XML', @response.body
102
+ end
103
+ end
104
+
105
+ class EditActionBaseTest < Test::Unit::TestCase
106
+ include UserTestHelper
107
+
108
+ def test_expose_the_resquested_user
109
+ User.expects(:find).with('42').returns(mock_user)
110
+ get :edit, :id => '42'
111
+ assert_response :success
112
+ assert_equal mock_user, assigns(:user)
113
+ end
114
+
115
+ def test_controller_should_render_edit
116
+ User.stubs(:find).returns(mock_user)
117
+ get :edit
118
+ assert_response :success
119
+ assert_equal 'Edit HTML', @response.body.strip
120
+ end
121
+ end
122
+
123
+ class CreateActionBaseTest < Test::Unit::TestCase
124
+ include UserTestHelper
125
+
126
+ def test_expose_a_newly_create_user_when_saved_with_success
127
+ User.expects(:new).with({'these' => 'params'}).returns(mock_user(:save => true))
128
+ post :create, :user => {:these => 'params'}
129
+ assert_equal mock_user, assigns(:user)
130
+ end
131
+
132
+ def test_redirect_to_the_created_user
133
+ User.stubs(:new).returns(mock_user(:save => true))
134
+ @controller.expects(:resource_url).returns('http://test.host/').times(2)
135
+ post :create
136
+ assert_redirected_to 'http://test.host/'
137
+ end
138
+
139
+ def test_show_flash_message_when_success
140
+ User.stubs(:new).returns(mock_user(:save => true))
141
+ post :create
142
+ assert_equal flash[:notice], 'User was successfully created.'
143
+ end
144
+
145
+ def test_render_new_template_when_user_cannot_be_saved
146
+ User.stubs(:new).returns(mock_user(:save => false, :errors => []))
147
+ post :create
148
+ assert_response :success
149
+ assert_template 'new'
150
+ end
151
+
152
+ def test_dont_show_flash_message_when_user_cannot_be_saved
153
+ User.stubs(:new).returns(mock_user(:save => false, :errors => []))
154
+ post :create
155
+ assert flash.empty?
156
+ end
157
+ end
158
+
159
+ class UpdateActionBaseTest < Test::Unit::TestCase
160
+ include UserTestHelper
161
+
162
+ def test_update_the_requested_object
163
+ User.expects(:find).with('42').returns(mock_user)
164
+ mock_user.expects(:update_attributes).with({'these' => 'params'}).returns(true)
165
+ put :update, :id => '42', :user => {:these => 'params'}
166
+ assert_equal mock_user, assigns(:user)
167
+ end
168
+
169
+ def test_redirect_to_the_created_user
170
+ User.stubs(:find).returns(mock_user(:update_attributes => true))
171
+ @controller.expects(:resource_url).returns('http://test.host/')
172
+ put :update
173
+ assert_redirected_to 'http://test.host/'
174
+ end
175
+
176
+ def test_show_flash_message_when_success
177
+ User.stubs(:find).returns(mock_user(:update_attributes => true))
178
+ put :update
179
+ assert_equal flash[:notice], 'User was successfully updated.'
180
+ end
181
+
182
+ def test_render_edit_template_when_user_cannot_be_saved
183
+ User.stubs(:find).returns(mock_user(:update_attributes => false, :errors => []))
184
+ put :update
185
+ assert_response :success
186
+ assert_template 'edit'
187
+ end
188
+
189
+ def test_dont_show_flash_message_when_user_cannot_be_saved
190
+ User.stubs(:find).returns(mock_user(:update_attributes => false, :errors => []))
191
+ put :update
192
+ assert flash.empty?
193
+ end
194
+ end
195
+
196
+ class DestroyActionBaseTest < Test::Unit::TestCase
197
+ include UserTestHelper
198
+
199
+ def test_the_resquested_user_is_destroyed
200
+ User.expects(:find).with('42').returns(mock_user)
201
+ mock_user.expects(:destroy)
202
+ delete :destroy, :id => '42'
203
+ assert_equal mock_user, assigns(:user)
204
+ end
205
+
206
+ def test_show_flash_message
207
+ User.stubs(:find).returns(mock_user(:destroy => true))
208
+ delete :destroy
209
+ assert_equal flash[:notice], 'User was successfully destroyed.'
210
+ end
211
+
212
+ def test_redirects_to_users_list
213
+ User.stubs(:find).returns(mock_user(:destroy => true))
214
+ @controller.expects(:collection_url).returns('http://test.host/')
215
+ delete :destroy
216
+ assert_redirected_to 'http://test.host/'
217
+ end
218
+ end
219
+