karsthammer-inherited_resources 1.1.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 (36) hide show
  1. data/CHANGELOG +119 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +516 -0
  4. data/Rakefile +43 -0
  5. data/lib/generators/rails/USAGE +10 -0
  6. data/lib/generators/rails/inherited_resources_controller_generator.rb +11 -0
  7. data/lib/generators/rails/templates/controller.rb +5 -0
  8. data/lib/inherited_resources.rb +37 -0
  9. data/lib/inherited_resources/actions.rb +67 -0
  10. data/lib/inherited_resources/base.rb +44 -0
  11. data/lib/inherited_resources/base_helpers.rb +270 -0
  12. data/lib/inherited_resources/belongs_to_helpers.rb +97 -0
  13. data/lib/inherited_resources/blank_slate.rb +12 -0
  14. data/lib/inherited_resources/class_methods.rb +267 -0
  15. data/lib/inherited_resources/dsl.rb +26 -0
  16. data/lib/inherited_resources/polymorphic_helpers.rb +155 -0
  17. data/lib/inherited_resources/responder.rb +6 -0
  18. data/lib/inherited_resources/singleton_helpers.rb +95 -0
  19. data/lib/inherited_resources/url_helpers.rb +188 -0
  20. data/lib/inherited_resources/version.rb +3 -0
  21. data/test/aliases_test.rb +144 -0
  22. data/test/association_chain_test.rb +125 -0
  23. data/test/base_test.rb +278 -0
  24. data/test/belongs_to_test.rb +105 -0
  25. data/test/class_methods_test.rb +132 -0
  26. data/test/customized_base_test.rb +168 -0
  27. data/test/customized_belongs_to_test.rb +76 -0
  28. data/test/defaults_test.rb +70 -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/singleton_test.rb +83 -0
  34. data/test/test_helper.rb +40 -0
  35. data/test/url_helpers_test.rb +665 -0
  36. metadata +142 -0
data/test/base_test.rb ADDED
@@ -0,0 +1,278 @@
1
+ require File.expand_path('test_helper', File.dirname(__FILE__))
2
+
3
+ class User
4
+ extend ActiveModel::Naming
5
+ end
6
+
7
+ class AccountsController < InheritedResources::Base
8
+ end
9
+
10
+ class UsersController < AccountsController
11
+ respond_to :html, :xml
12
+ respond_to :js, :only => [:create, :update, :destroy]
13
+ attr_reader :scopes_applied
14
+
15
+ protected
16
+
17
+ def apply_scopes(object)
18
+ @scopes_applied = true
19
+ object
20
+ end
21
+ end
22
+
23
+ module UserTestHelper
24
+ def setup
25
+ @controller = UsersController.new
26
+ @controller.request = @request = ActionController::TestRequest.new
27
+ @controller.response = @response = ActionController::TestResponse.new
28
+ @controller.stubs(:user_url).returns("/")
29
+ end
30
+
31
+ protected
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
39
+ end
40
+ end
41
+ end
42
+
43
+ class IndexActionBaseTest < ActionController::TestCase
44
+ include UserTestHelper
45
+
46
+ def test_expose_all_users_as_instance_variable
47
+ User.expects(:all).returns([mock_user])
48
+ get :index
49
+ assert_equal [mock_user], assigns(:users)
50
+ end
51
+
52
+ def test_apply_scopes_if_method_is_available
53
+ User.expects(:all).returns([mock_user])
54
+ get :index
55
+ assert @controller.scopes_applied
56
+ end
57
+
58
+ def test_controller_should_render_index
59
+ User.stubs(:all).returns([mock_user])
60
+ get :index
61
+ assert_response :success
62
+ assert_equal 'Index HTML', @response.body.strip
63
+ end
64
+
65
+ def test_render_all_users_as_xml_when_mime_type_is_xml
66
+ @request.accept = 'application/xml'
67
+ User.expects(:all).returns(mock_user)
68
+ mock_user.expects(:to_xml).returns('Generated XML')
69
+ get :index
70
+ assert_response :success
71
+ assert_equal 'Generated XML', @response.body
72
+ end
73
+ end
74
+
75
+ class ShowActionBaseTest < ActionController::TestCase
76
+ include UserTestHelper
77
+
78
+ def test_expose_the_requested_user
79
+ User.expects(:find).with('42').returns(mock_user)
80
+ get :show, :id => '42'
81
+ assert_equal mock_user, assigns(:user)
82
+ end
83
+
84
+ def test_controller_should_render_show
85
+ User.stubs(:find).returns(mock_user)
86
+ get :show
87
+ assert_response :success
88
+ assert_equal 'Show HTML', @response.body.strip
89
+ end
90
+
91
+ def test_render_exposed_user_as_xml_when_mime_type_is_xml
92
+ @request.accept = 'application/xml'
93
+ User.expects(:find).with('42').returns(mock_user)
94
+ mock_user.expects(:to_xml).returns("Generated XML")
95
+ get :show, :id => '42'
96
+ assert_response :success
97
+ assert_equal 'Generated XML', @response.body
98
+ end
99
+ end
100
+
101
+ class NewActionBaseTest < ActionController::TestCase
102
+ include UserTestHelper
103
+
104
+ def test_expose_a_new_user
105
+ User.expects(:new).returns(mock_user)
106
+ get :new
107
+ assert_equal mock_user, assigns(:user)
108
+ end
109
+
110
+ def test_controller_should_render_new
111
+ User.stubs(:new).returns(mock_user)
112
+ get :new
113
+ assert_response :success
114
+ assert_equal 'New HTML', @response.body.strip
115
+ end
116
+
117
+ def test_render_exposed_a_new_user_as_xml_when_mime_type_is_xml
118
+ @request.accept = 'application/xml'
119
+ User.expects(:new).returns(mock_user)
120
+ mock_user.expects(:to_xml).returns("Generated XML")
121
+ get :new
122
+ assert_response :success
123
+ assert_equal 'Generated XML', @response.body
124
+ end
125
+ end
126
+
127
+ class EditActionBaseTest < ActionController::TestCase
128
+ include UserTestHelper
129
+
130
+ def test_expose_the_requested_user
131
+ User.expects(:find).with('42').returns(mock_user)
132
+ get :edit, :id => '42'
133
+ assert_response :success
134
+ assert_equal mock_user, assigns(:user)
135
+ end
136
+
137
+ def test_controller_should_render_edit
138
+ User.stubs(:find).returns(mock_user)
139
+ get :edit
140
+ assert_response :success
141
+ assert_equal 'Edit HTML', @response.body.strip
142
+ end
143
+ end
144
+
145
+ class CreateActionBaseTest < ActionController::TestCase
146
+ include UserTestHelper
147
+
148
+ def test_expose_a_newly_create_user_when_saved_with_success
149
+ User.expects(:new).with({'these' => 'params'}).returns(mock_user(:save => true))
150
+ post :create, :user => {:these => 'params'}
151
+ assert_equal mock_user, assigns(:user)
152
+ end
153
+
154
+ def test_redirect_to_the_created_user
155
+ User.stubs(:new).returns(mock_user(:save => true))
156
+ @controller.expects(:resource_url).returns('http://test.host/')
157
+ post :create
158
+ assert_redirected_to 'http://test.host/'
159
+ end
160
+
161
+ def test_show_flash_message_when_success
162
+ User.stubs(:new).returns(mock_user(:save => true))
163
+ post :create
164
+ assert_equal flash[:notice], 'User was successfully created.'
165
+ end
166
+
167
+ def test_show_flash_message_with_javascript_request_when_success
168
+ User.stubs(:new).returns(mock_user(:save => true))
169
+ post :create, :format => :js
170
+ assert_equal flash[:notice], 'User was successfully created.'
171
+ end
172
+
173
+ def test_render_new_template_when_user_cannot_be_saved
174
+ User.stubs(:new).returns(mock_user(:save => false, :errors => {:some => :error}))
175
+ post :create
176
+ assert_response :success
177
+ assert_equal "New HTML", @response.body.strip
178
+ end
179
+
180
+ def test_dont_show_flash_message_when_user_cannot_be_saved
181
+ User.stubs(:new).returns(mock_user(:save => false, :errors => {:some => :error}))
182
+ post :create
183
+ assert flash.empty?
184
+ end
185
+ end
186
+
187
+ class UpdateActionBaseTest < ActionController::TestCase
188
+ include UserTestHelper
189
+
190
+ def test_update_the_requested_object
191
+ User.expects(:find).with('42').returns(mock_user)
192
+ mock_user.expects(:update_attributes).with({'these' => 'params'}).returns(true)
193
+ put :update, :id => '42', :user => {:these => 'params'}
194
+ assert_equal mock_user, assigns(:user)
195
+ end
196
+
197
+ def test_redirect_to_the_created_user
198
+ User.stubs(:find).returns(mock_user(:update_attributes => true))
199
+ @controller.expects(:resource_url).returns('http://test.host/')
200
+ put :update
201
+ assert_redirected_to 'http://test.host/'
202
+ end
203
+
204
+ def test_show_flash_message_when_success
205
+ User.stubs(:find).returns(mock_user(:update_attributes => true))
206
+ put :update
207
+ assert_equal flash[:notice], 'User was successfully updated.'
208
+ end
209
+
210
+ def test_show_flash_message_with_javascript_request_when_success
211
+ User.stubs(:find).returns(mock_user(:update_attributes => true))
212
+ post :update, :format => :js
213
+ assert_equal flash[:notice], 'User was successfully updated.'
214
+ end
215
+
216
+ def test_render_edit_template_when_user_cannot_be_saved
217
+ User.stubs(:find).returns(mock_user(:update_attributes => false, :errors => {:some => :error}))
218
+ put :update
219
+ assert_response :success
220
+ assert_equal "Edit HTML", @response.body.strip
221
+ end
222
+
223
+ def test_dont_show_flash_message_when_user_cannot_be_saved
224
+ User.stubs(:find).returns(mock_user(:update_attributes => false, :errors => {:some => :error}))
225
+ put :update
226
+ assert flash.empty?
227
+ end
228
+ end
229
+
230
+ class DestroyActionBaseTest < ActionController::TestCase
231
+ include UserTestHelper
232
+
233
+ def test_the_requested_user_is_destroyed
234
+ User.expects(:find).with('42').returns(mock_user)
235
+ mock_user.expects(:destroy).returns(true)
236
+ delete :destroy, :id => '42'
237
+ assert_equal mock_user, assigns(:user)
238
+ end
239
+
240
+ def test_show_flash_message_when_user_can_be_deleted
241
+ User.stubs(:find).returns(mock_user(:destroy => true))
242
+ delete :destroy
243
+ assert_equal flash[:notice], 'User was successfully destroyed.'
244
+ end
245
+
246
+ def test_show_flash_message_with_javascript_request_when_user_can_be_deleted
247
+ User.stubs(:find).returns(mock_user(:destroy => true))
248
+ delete :destroy, :format => :js
249
+ assert_equal flash[:notice], 'User was successfully destroyed.'
250
+ end
251
+
252
+ def test_show_flash_message_when_user_cannot_be_deleted
253
+ User.stubs(:find).returns(mock_user(:destroy => false, :errors => { :fail => true }))
254
+ delete :destroy
255
+ assert_equal flash[:alert], 'User could not be destroyed.'
256
+ end
257
+
258
+ def test_show_flash_message_with_javascript_request_when_user_cannot_be_deleted
259
+ User.stubs(:find).returns(mock_user(:destroy => false, :errors => { :fail => true }))
260
+ delete :destroy, :format => :js
261
+ assert_equal flash[:alert], 'User could not be destroyed.'
262
+ end
263
+
264
+ def test_redirects_to_users_list
265
+ User.stubs(:find).returns(mock_user(:destroy => true))
266
+ @controller.expects(:collection_url).returns('http://test.host/')
267
+ delete :destroy
268
+ assert_redirected_to 'http://test.host/'
269
+ end
270
+
271
+ def test_redirects_to_the_resource_if_cannot_be_destroyed
272
+ User.stubs(:find).returns(mock_user(:destroy => false))
273
+ @controller.expects(:collection_url).returns('http://test.host/')
274
+ delete :destroy
275
+ assert_redirected_to 'http://test.host/'
276
+ end
277
+ end
278
+
@@ -0,0 +1,105 @@
1
+ require File.expand_path('test_helper', File.dirname(__FILE__))
2
+
3
+ class Post
4
+ extend ActiveModel::Naming
5
+ end
6
+
7
+ class Comment
8
+ extend ActiveModel::Naming
9
+ end
10
+
11
+ class CommentsController < InheritedResources::Base
12
+ belongs_to :post
13
+ end
14
+
15
+ class BelongsToTest < ActionController::TestCase
16
+ tests CommentsController
17
+
18
+ def setup
19
+ Post.expects(:find).with('37').returns(mock_post)
20
+ mock_post.expects(:comments).returns(Comment)
21
+
22
+ @controller.stubs(:resource_url).returns('/')
23
+ @controller.stubs(:collection_url).returns('/')
24
+ end
25
+
26
+ def test_expose_all_comments_as_instance_variable_on_index
27
+ Comment.expects(:all).returns([mock_comment])
28
+ get :index, :post_id => '37'
29
+ assert_equal mock_post, assigns(:post)
30
+ assert_equal [mock_comment], assigns(:comments)
31
+ end
32
+
33
+ def test_expose_the_requested_comment_on_show
34
+ Comment.expects(:find).with('42').returns(mock_comment)
35
+ get :show, :id => '42', :post_id => '37'
36
+ assert_equal mock_post, assigns(:post)
37
+ assert_equal mock_comment, assigns(:comment)
38
+ end
39
+
40
+ def test_expose_a_new_comment_on_new
41
+ Comment.expects(:build).returns(mock_comment)
42
+ get :new, :post_id => '37'
43
+ assert_equal mock_post, assigns(:post)
44
+ assert_equal mock_comment, assigns(:comment)
45
+ end
46
+
47
+ def test_expose_the_requested_comment_on_edit
48
+ Comment.expects(:find).with('42').returns(mock_comment)
49
+ get :edit, :id => '42', :post_id => '37'
50
+ assert_equal mock_post, assigns(:post)
51
+ assert_equal mock_comment, assigns(:comment)
52
+ end
53
+
54
+ def test_expose_a_newly_create_comment_on_create
55
+ Comment.expects(:build).with({'these' => 'params'}).returns(mock_comment(:save => true))
56
+ post :create, :post_id => '37', :comment => {:these => 'params'}
57
+ assert_equal mock_post, assigns(:post)
58
+ assert_equal mock_comment, assigns(:comment)
59
+ end
60
+
61
+ def test_update_the_requested_object_on_update
62
+ Comment.expects(:find).with('42').returns(mock_comment)
63
+ mock_comment.expects(:update_attributes).with({'these' => 'params'}).returns(true)
64
+ put :update, :id => '42', :post_id => '37', :comment => {:these => 'params'}
65
+ assert_equal mock_post, assigns(:post)
66
+ assert_equal mock_comment, assigns(:comment)
67
+ end
68
+
69
+ def test_the_requested_comment_is_destroyed_on_destroy
70
+ Comment.expects(:find).with('42').returns(mock_comment)
71
+ mock_comment.expects(:destroy)
72
+ delete :destroy, :id => '42', :post_id => '37'
73
+ assert_equal mock_post, assigns(:post)
74
+ assert_equal mock_comment, assigns(:comment)
75
+ end
76
+
77
+ def helper_methods
78
+ @controller.class._helpers.instance_methods.map {|m| m.to_s }
79
+ end
80
+
81
+ def test_helpers
82
+ mock_post.stubs(:class).returns(Post)
83
+
84
+ Comment.expects(:all).returns([mock_comment])
85
+ get :index, :post_id => '37'
86
+
87
+ assert helper_methods.include?('parent?')
88
+ assert @controller.send(:parent?)
89
+ assert_equal mock_post, assigns(:post)
90
+ assert helper_methods.include?('parent')
91
+ assert_equal mock_post, @controller.send(:parent)
92
+ end
93
+
94
+ protected
95
+
96
+ def mock_post(stubs={})
97
+ @mock_post ||= mock(stubs)
98
+ end
99
+
100
+ def mock_comment(stubs={})
101
+ @mock_comment ||= mock(stubs)
102
+ end
103
+
104
+ end
105
+
@@ -0,0 +1,132 @@
1
+ require File.expand_path('test_helper', File.dirname(__FILE__))
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 DeansController < InheritedResources::Base
22
+ belongs_to :school
23
+ end
24
+
25
+ class ActionsClassMethodTest < ActionController::TestCase
26
+ tests BooksController
27
+
28
+ def test_cannot_render_actions
29
+ assert_raise ActionController::UnknownAction do
30
+ get :new
31
+ end
32
+ end
33
+
34
+ def test_actions_are_undefined
35
+ action_methods = BooksController.send(:action_methods).map(&:to_sym)
36
+ assert_equal 2, action_methods.size
37
+
38
+ [:index, :show].each do |action|
39
+ assert action_methods.include?(action)
40
+ end
41
+
42
+ instance_methods = BooksController.send(:instance_methods).map(&:to_sym)
43
+
44
+ [:new, :edit, :create, :update, :destroy].each do |action|
45
+ assert !instance_methods.include?(action)
46
+ end
47
+ end
48
+
49
+ def test_actions_are_undefined_when_except_option_is_given
50
+ action_methods = ReadersController.send(:action_methods)
51
+ assert_equal 5, action_methods.size
52
+
53
+ ['index', 'new', 'show', 'create', 'destroy'].each do |action|
54
+ assert action_methods.include? action
55
+ end
56
+ end
57
+ end
58
+
59
+ class DefaultsClassMethodTest < ActiveSupport::TestCase
60
+ def test_resource_class_is_set_to_nil_when_resource_model_cannot_be_found
61
+ assert_nil ReadersController.send(:resource_class)
62
+ end
63
+
64
+ def test_defaults_are_set
65
+ assert Folder, FoldersController.send(:resource_class)
66
+ assert :folder, FoldersController.send(:resources_configuration)[:self][:instance_name]
67
+ assert :folders, FoldersController.send(:resources_configuration)[:self][:collection_name]
68
+ end
69
+
70
+ def test_defaults_can_be_overwriten
71
+ BooksController.send(:defaults, :resource_class => String, :instance_name => 'string', :collection_name => 'strings')
72
+
73
+ assert String, BooksController.send(:resource_class)
74
+ assert :string, BooksController.send(:resources_configuration)[:self][:instance_name]
75
+ assert :strings, BooksController.send(:resources_configuration)[:self][:collection_name]
76
+
77
+ BooksController.send(:defaults, :class_name => 'Fixnum', :instance_name => :fixnum, :collection_name => :fixnums)
78
+
79
+ assert String, BooksController.send(:resource_class)
80
+ assert :string, BooksController.send(:resources_configuration)[:self][:instance_name]
81
+ assert :strings, BooksController.send(:resources_configuration)[:self][:collection_name]
82
+ end
83
+
84
+ def test_defaults_raises_invalid_key
85
+ assert_raise ArgumentError do
86
+ BooksController.send(:defaults, :boom => String)
87
+ end
88
+ end
89
+
90
+ def test_url_helpers_are_recreated_when_defaults_change
91
+ BooksController.expects(:create_resources_url_helpers!).returns(true).once
92
+ BooksController.send(:defaults, :instance_name => 'string', :collection_name => 'strings')
93
+ end
94
+ end
95
+
96
+ class BelongsToErrorsTest < ActiveSupport::TestCase
97
+ def test_belongs_to_raise_errors_with_invalid_arguments
98
+ assert_raise ArgumentError do
99
+ DeansController.send(:belongs_to)
100
+ end
101
+
102
+ assert_raise ArgumentError do
103
+ DeansController.send(:belongs_to, :nice, :invalid_key => '')
104
+ end
105
+ end
106
+
107
+ def test_belongs_to_raises_an_error_when_multiple_associations_are_given_with_options
108
+ assert_raise ArgumentError do
109
+ DeansController.send(:belongs_to, :arguments, :with_options, :parent_class => Professor)
110
+ end
111
+ end
112
+
113
+ def test_url_helpers_are_recreated_just_once_when_belongs_to_is_called_with_block
114
+ DeansController.expects(:create_resources_url_helpers!).returns(true).once
115
+ DeansController.send(:belongs_to, :school) do
116
+ belongs_to :association
117
+ end
118
+ ensure
119
+ DeansController.send(:parents_symbols=, [:school])
120
+ end
121
+
122
+ def test_url_helpers_are_recreated_just_once_when_belongs_to_is_called_with_multiple_blocks
123
+ DeansController.expects(:create_resources_url_helpers!).returns(true).once
124
+ DeansController.send(:belongs_to, :school) do
125
+ belongs_to :association do
126
+ belongs_to :nested
127
+ end
128
+ end
129
+ ensure
130
+ DeansController.send(:parents_symbols=, [:school])
131
+ end
132
+ end