inherited_resources 0.9.2

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 (37) hide show
  1. data/CHANGELOG +103 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +524 -0
  4. data/Rakefile +40 -0
  5. data/lib/inherited_resources.rb +23 -0
  6. data/lib/inherited_resources/actions.rb +79 -0
  7. data/lib/inherited_resources/base.rb +42 -0
  8. data/lib/inherited_resources/base_helpers.rb +363 -0
  9. data/lib/inherited_resources/belongs_to_helpers.rb +89 -0
  10. data/lib/inherited_resources/class_methods.rb +338 -0
  11. data/lib/inherited_resources/dsl.rb +26 -0
  12. data/lib/inherited_resources/dumb_responder.rb +20 -0
  13. data/lib/inherited_resources/has_scope_helpers.rb +83 -0
  14. data/lib/inherited_resources/legacy/respond_to.rb +156 -0
  15. data/lib/inherited_resources/legacy/responder.rb +200 -0
  16. data/lib/inherited_resources/polymorphic_helpers.rb +155 -0
  17. data/lib/inherited_resources/singleton_helpers.rb +95 -0
  18. data/lib/inherited_resources/url_helpers.rb +179 -0
  19. data/test/aliases_test.rb +139 -0
  20. data/test/association_chain_test.rb +125 -0
  21. data/test/base_test.rb +225 -0
  22. data/test/belongs_to_test.rb +87 -0
  23. data/test/class_methods_test.rb +138 -0
  24. data/test/customized_base_test.rb +162 -0
  25. data/test/customized_belongs_to_test.rb +76 -0
  26. data/test/defaults_test.rb +70 -0
  27. data/test/flash_test.rb +88 -0
  28. data/test/has_scope_test.rb +139 -0
  29. data/test/nested_belongs_to_test.rb +108 -0
  30. data/test/optional_belongs_to_test.rb +164 -0
  31. data/test/polymorphic_test.rb +186 -0
  32. data/test/redirect_to_test.rb +51 -0
  33. data/test/respond_to_test.rb +155 -0
  34. data/test/singleton_test.rb +83 -0
  35. data/test/test_helper.rb +38 -0
  36. data/test/url_helpers_test.rb +537 -0
  37. metadata +89 -0
@@ -0,0 +1,125 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class Pet
4
+ def self.human_name; 'Pet'; end
5
+ end
6
+
7
+ class Puppet
8
+ def self.human_name; 'Puppet'; end
9
+ end
10
+
11
+ class PetsController < InheritedResources::Base
12
+ attr_accessor :current_user
13
+
14
+ def edit
15
+ @pet = 'new pet'
16
+ edit!
17
+ end
18
+
19
+ protected
20
+ def collection
21
+ @pets ||= end_of_association_chain.all
22
+ end
23
+
24
+ def begin_of_association_chain
25
+ @current_user
26
+ end
27
+ end
28
+
29
+ class BeginOfAssociationChainTest < ActionController::TestCase
30
+ tests PetsController
31
+
32
+ def setup
33
+ @controller.current_user = mock()
34
+ end
35
+
36
+ def test_begin_of_association_chain_is_called_on_index
37
+ @controller.current_user.expects(:pets).returns(Pet)
38
+ Pet.expects(:all).returns(mock_pet)
39
+ get :index
40
+ assert_response :success
41
+ assert_equal 'Index HTML', @response.body.strip
42
+ end
43
+
44
+ def test_begin_of_association_chain_is_called_on_new
45
+ @controller.current_user.expects(:pets).returns(Pet)
46
+ Pet.expects(:build).returns(mock_pet)
47
+ get :new
48
+ assert_response :success
49
+ assert_equal 'New HTML', @response.body.strip
50
+ end
51
+
52
+ def test_begin_of_association_chain_is_called_on_show
53
+ @controller.current_user.expects(:pets).returns(Pet)
54
+ Pet.expects(:find).with('47').returns(mock_pet)
55
+ get :show, :id => '47'
56
+ assert_response :success
57
+ assert_equal 'Show HTML', @response.body.strip
58
+ end
59
+
60
+ def test_instance_variable_should_not_be_set_if_already_defined
61
+ @controller.current_user.expects(:pets).never
62
+ Pet.expects(:find).never
63
+ get :edit
64
+ assert_response :success
65
+ assert_equal 'new pet', assigns(:pet)
66
+ end
67
+
68
+ def test_model_is_not_initialized_with_nil
69
+ @controller.current_user.expects(:pets).returns(Pet)
70
+ Pet.expects(:build).with({}).returns(mock_pet)
71
+ get :new
72
+ assert_equal mock_pet, assigns(:pet)
73
+ end
74
+
75
+ def test_begin_of_association_chain_is_included_in_chain
76
+ @controller.current_user.expects(:pets).returns(Pet)
77
+ Pet.expects(:build).with({}).returns(mock_pet)
78
+ get :new
79
+ assert_equal [@controller.current_user], @controller.send(:association_chain)
80
+ end
81
+
82
+ protected
83
+ def mock_pet(stubs={})
84
+ @mock_pet ||= mock(stubs)
85
+ end
86
+
87
+ end
88
+
89
+ class PuppetsController < InheritedResources::Base
90
+ optional_belongs_to :pet
91
+ end
92
+
93
+ class AssociationChainTest < ActionController::TestCase
94
+ tests PuppetsController
95
+
96
+ def setup
97
+ @controller.stubs(:resource_url).returns('/')
98
+ @controller.stubs(:collection_url).returns('/')
99
+ end
100
+
101
+ def test_parent_is_added_to_association_chain
102
+ Pet.expects(:find).with('37').returns(mock_pet)
103
+ mock_pet.expects(:puppets).returns(Puppet)
104
+ Puppet.expects(:find).with('42').returns(mock_puppet)
105
+ mock_puppet.expects(:destroy)
106
+ delete :destroy, :id => '42', :pet_id => '37'
107
+ assert_equal [mock_pet], @controller.send(:association_chain)
108
+ end
109
+
110
+ def test_parent_is_added_to_association_chain_if_not_available
111
+ Puppet.expects(:find).with('42').returns(mock_puppet)
112
+ mock_puppet.expects(:destroy)
113
+ delete :destroy, :id => '42'
114
+ assert_equal [], @controller.send(:association_chain)
115
+ end
116
+
117
+ protected
118
+ def mock_pet(stubs={})
119
+ @mock_pet ||= mock(stubs)
120
+ end
121
+
122
+ def mock_puppet(stubs={})
123
+ @mock_puppet ||= mock(stubs)
124
+ end
125
+ end
data/test/base_test.rb ADDED
@@ -0,0 +1,225 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class User
4
+ def self.human_name; 'User'; end
5
+ end
6
+
7
+ class AccountsController < InheritedResources::Base
8
+ end
9
+
10
+ class UsersController < AccountsController
11
+ respond_to :html, :xml
12
+ end
13
+
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 < ActionController::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 < ActionController::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 < ActionController::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 < ActionController::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 < ActionController::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/')
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 => {:some => :error}))
147
+ post :create
148
+ assert_response :success
149
+ assert_equal "New HTML", @response.body.strip
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 => {:some => :error}))
154
+ post :create
155
+ assert flash.empty?
156
+ end
157
+ end
158
+
159
+ class UpdateActionBaseTest < ActionController::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 => {:some => :error}))
184
+ put :update
185
+ assert_response :success
186
+ assert_equal "Edit HTML", @response.body.strip
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 => {:some => :error}))
191
+ put :update
192
+ assert flash.empty?
193
+ end
194
+ end
195
+
196
+ class DestroyActionBaseTest < ActionController::TestCase
197
+ include UserTestHelper
198
+
199
+ def test_the_requested_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_when_user_can_be_deleted
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_show_flash_message_when_cannot_be_deleted
213
+ User.stubs(:find).returns(mock_user(:destroy => false))
214
+ delete :destroy
215
+ assert_equal flash[:error], 'User could not be destroyed.'
216
+ end
217
+
218
+ def test_redirects_to_users_list
219
+ User.stubs(:find).returns(mock_user(:destroy => true))
220
+ @controller.expects(:collection_url).returns('http://test.host/')
221
+ delete :destroy
222
+ assert_redirected_to 'http://test.host/'
223
+ end
224
+ end
225
+
@@ -0,0 +1,87 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class Post
4
+ end
5
+
6
+ class Comment
7
+ def self.human_name; 'Comment'; end
8
+ end
9
+
10
+ class CommentsController < InheritedResources::Base
11
+ belongs_to :post
12
+ end
13
+
14
+ class BelongsToTest < ActionController::TestCase
15
+ tests CommentsController
16
+
17
+ def setup
18
+ Post.expects(:find).with('37').returns(mock_post)
19
+ mock_post.expects(:comments).returns(Comment)
20
+
21
+ @controller.stubs(:resource_url).returns('/')
22
+ @controller.stubs(:collection_url).returns('/')
23
+ end
24
+
25
+ def test_expose_all_comments_as_instance_variable_on_index
26
+ Comment.expects(:find).with(:all).returns([mock_comment])
27
+ get :index, :post_id => '37'
28
+ assert_equal mock_post, assigns(:post)
29
+ assert_equal [mock_comment], assigns(:comments)
30
+ end
31
+
32
+ def test_expose_the_resquested_comment_on_show
33
+ Comment.expects(:find).with('42').returns(mock_comment)
34
+ get :show, :id => '42', :post_id => '37'
35
+ assert_equal mock_post, assigns(:post)
36
+ assert_equal mock_comment, assigns(:comment)
37
+ end
38
+
39
+ def test_expose_a_new_comment_on_new
40
+ Comment.expects(:build).returns(mock_comment)
41
+ get :new, :post_id => '37'
42
+ assert_equal mock_post, assigns(:post)
43
+ assert_equal mock_comment, assigns(:comment)
44
+ end
45
+
46
+ def test_expose_the_resquested_comment_on_edit
47
+ Comment.expects(:find).with('42').returns(mock_comment)
48
+ get :edit, :id => '42', :post_id => '37'
49
+ assert_equal mock_post, assigns(:post)
50
+ assert_equal mock_comment, assigns(:comment)
51
+ end
52
+
53
+ def test_expose_a_newly_create_comment_on_create
54
+ Comment.expects(:build).with({'these' => 'params'}).returns(mock_comment(:save => true))
55
+ post :create, :post_id => '37', :comment => {:these => 'params'}
56
+ assert_equal mock_post, assigns(:post)
57
+ assert_equal mock_comment, assigns(:comment)
58
+ end
59
+
60
+ def test_update_the_requested_object_on_update
61
+ Comment.expects(:find).with('42').returns(mock_comment)
62
+ mock_comment.expects(:update_attributes).with({'these' => 'params'}).returns(true)
63
+ put :update, :id => '42', :post_id => '37', :comment => {:these => 'params'}
64
+ assert_equal mock_post, assigns(:post)
65
+ assert_equal mock_comment, assigns(:comment)
66
+ end
67
+
68
+ def test_the_resquested_comment_is_destroyed_on_destroy
69
+ Comment.expects(:find).with('42').returns(mock_comment)
70
+ mock_comment.expects(:destroy)
71
+ delete :destroy, :id => '42', :post_id => '37'
72
+ assert_equal mock_post, assigns(:post)
73
+ assert_equal mock_comment, assigns(:comment)
74
+ end
75
+
76
+ protected
77
+
78
+ def mock_post(stubs={})
79
+ @mock_post ||= mock(stubs)
80
+ end
81
+
82
+ def mock_comment(stubs={})
83
+ @mock_comment ||= mock(stubs)
84
+ end
85
+
86
+ end
87
+
@@ -0,0 +1,138 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class Book; end
4
+ class Folder; end
5
+
6
+ class BooksController < InheritedResources::Base
7
+ actions :index, :show
8
+ end
9
+
10
+ class ReadersController < InheritedResources::Base
11
+ actions :all, :except => [ :edit, :update ]
12
+ end
13
+
14
+ class FoldersController < InheritedResources::Base
15
+ end
16
+
17
+ class Dean
18
+ def self.human_name; 'Dean'; end
19
+ end
20
+
21
+ class SchoolsController < InheritedResources::Base
22
+ has_scope :by_city
23
+ has_scope :featured, :boolean => true, :only => :index, :as => :by_featured
24
+ end
25
+
26
+ class DeansController < InheritedResources::Base
27
+ belongs_to :school
28
+ end
29
+
30
+
31
+ class ActionsClassMethodTest < ActiveSupport::TestCase
32
+ def test_actions_are_undefined
33
+ action_methods = BooksController.send(:action_methods)
34
+ assert_equal 2, action_methods.size
35
+
36
+ ['index', 'show'].each do |action|
37
+ assert action_methods.include? action
38
+ end
39
+ end
40
+
41
+ def test_actions_are_undefined_when_except_option_is_given
42
+ action_methods = ReadersController.send(:action_methods)
43
+ assert_equal 5, action_methods.size
44
+
45
+ ['index', 'new', 'show', 'create', 'destroy'].each do |action|
46
+ assert action_methods.include? action
47
+ end
48
+ end
49
+ end
50
+
51
+
52
+ class DefaultsClassMethodTest < ActiveSupport::TestCase
53
+ def test_resource_class_is_set_to_nil_when_resource_model_cannot_be_found
54
+ assert_nil ReadersController.send(:resource_class)
55
+ end
56
+
57
+ def test_defaults_are_set
58
+ assert Folder, FoldersController.send(:resource_class)
59
+ assert :folder, FoldersController.send(:resources_configuration)[:self][:instance_name]
60
+ assert :folders, FoldersController.send(:resources_configuration)[:self][:collection_name]
61
+ end
62
+
63
+ def test_defaults_can_be_overwriten
64
+ BooksController.send(:defaults, :resource_class => String, :instance_name => 'string', :collection_name => 'strings')
65
+
66
+ assert String, BooksController.send(:resource_class)
67
+ assert :string, BooksController.send(:resources_configuration)[:self][:instance_name]
68
+ assert :strings, BooksController.send(:resources_configuration)[:self][:collection_name]
69
+
70
+ BooksController.send(:defaults, :class_name => 'Fixnum', :instance_name => :fixnum, :collection_name => :fixnums)
71
+
72
+ assert String, BooksController.send(:resource_class)
73
+ assert :string, BooksController.send(:resources_configuration)[:self][:instance_name]
74
+ assert :strings, BooksController.send(:resources_configuration)[:self][:collection_name]
75
+ end
76
+
77
+ def test_defaults_raises_invalid_key
78
+ assert_raise ArgumentError do
79
+ BooksController.send(:defaults, :boom => String)
80
+ end
81
+ end
82
+
83
+ def test_url_helpers_are_recreated_when_defaults_change
84
+ BooksController.expects(:create_resources_url_helpers!).returns(true).once
85
+ BooksController.send(:defaults, :instance_name => 'string', :collection_name => 'strings')
86
+ end
87
+ end
88
+
89
+ class BelongsToErrorsTest < ActiveSupport::TestCase
90
+ def test_belongs_to_raise_errors_with_invalid_arguments
91
+ assert_raise ArgumentError do
92
+ DeansController.send(:belongs_to)
93
+ end
94
+
95
+ assert_raise ArgumentError do
96
+ DeansController.send(:belongs_to, :nice, :invalid_key => '')
97
+ end
98
+ end
99
+
100
+ def test_belongs_to_raises_an_error_when_multiple_associations_are_given_with_options
101
+ assert_raise ArgumentError do
102
+ DeansController.send(:belongs_to, :arguments, :with_options, :parent_class => Professor)
103
+ end
104
+ end
105
+
106
+ def test_url_helpers_are_recreated_just_once_when_belongs_to_is_called_with_block
107
+ DeansController.expects(:create_resources_url_helpers!).returns(true).once
108
+ DeansController.send(:belongs_to, :school) do
109
+ belongs_to :association
110
+ end
111
+ ensure
112
+ DeansController.send(:parents_symbols=, [:school])
113
+ end
114
+
115
+ def test_url_helpers_are_recreated_just_once_when_belongs_to_is_called_with_multiple_blocks
116
+ DeansController.expects(:create_resources_url_helpers!).returns(true).once
117
+ DeansController.send(:belongs_to, :school) do
118
+ belongs_to :association do
119
+ belongs_to :nested
120
+ end
121
+ end
122
+ ensure
123
+ DeansController.send(:parents_symbols=, [:school])
124
+ end
125
+ end
126
+
127
+ class HasScopeClassMethods < ActiveSupport::TestCase
128
+ def test_scope_configuration_is_stored_as_hashes
129
+ config = SchoolsController.send(:scopes_configuration)
130
+
131
+ assert config.key?(:by_city)
132
+ assert config.key?(:featured)
133
+
134
+ assert_equal config[:by_city], { :as => :by_city, :only => [], :except => [] }
135
+ assert_equal config[:featured], { :as => :by_featured, :only => [ :index ], :except => [], :boolean => true }
136
+ end
137
+ end
138
+