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,162 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class Car
4
+ def self.human_name; 'Car'; end
5
+ end
6
+
7
+ class CarsController < InheritedResources::Base
8
+ respond_to :html
9
+
10
+ protected
11
+
12
+ def collection
13
+ @cars ||= Car.get_all
14
+ end
15
+
16
+ def build_resource
17
+ @car ||= Car.create_new(params[:car])
18
+ end
19
+
20
+ def resource
21
+ @car ||= Car.get(params[:id])
22
+ end
23
+
24
+ def create_resource(resource)
25
+ resource.save_successfully
26
+ end
27
+
28
+ def update_resource(resource, attributes)
29
+ resource.update_successfully(attributes)
30
+ end
31
+
32
+ def destroy_resource(resource)
33
+ resource.destroy_successfully
34
+ end
35
+ end
36
+
37
+ module CarTestHelper
38
+ def setup
39
+ @controller = CarsController.new
40
+ @controller.request = @request = ActionController::TestRequest.new
41
+ @controller.response = @response = ActionController::TestResponse.new
42
+ end
43
+
44
+ protected
45
+ def mock_car(stubs={})
46
+ @mock_car ||= mock(stubs)
47
+ end
48
+ end
49
+
50
+ class IndexActionCustomizedBaseTest < ActionController::TestCase
51
+ include CarTestHelper
52
+
53
+ def test_expose_all_users_as_instance_variable
54
+ Car.expects(:get_all).returns([mock_car])
55
+ get :index
56
+ assert_equal [mock_car], assigns(:cars)
57
+ end
58
+ end
59
+
60
+ class ShowActionCustomizedBaseTest < ActionController::TestCase
61
+ include CarTestHelper
62
+
63
+ def test_expose_the_resquested_user
64
+ Car.expects(:get).with('42').returns(mock_car)
65
+ get :show, :id => '42'
66
+ assert_equal mock_car, assigns(:car)
67
+ end
68
+ end
69
+
70
+ class NewActionCustomizedBaseTest < ActionController::TestCase
71
+ include CarTestHelper
72
+
73
+ def test_expose_a_new_user
74
+ Car.expects(:create_new).returns(mock_car)
75
+ get :new
76
+ assert_equal mock_car, assigns(:car)
77
+ end
78
+ end
79
+
80
+ class EditActionCustomizedBaseTest < ActionController::TestCase
81
+ include CarTestHelper
82
+
83
+ def test_expose_the_resquested_user
84
+ Car.expects(:get).with('42').returns(mock_car)
85
+ get :edit, :id => '42'
86
+ assert_response :success
87
+ assert_equal mock_car, assigns(:car)
88
+ end
89
+ end
90
+
91
+ class CreateActionCustomizedBaseTest < ActionController::TestCase
92
+ include CarTestHelper
93
+
94
+ def test_expose_a_newly_create_user_when_saved_with_success
95
+ Car.expects(:create_new).with({'these' => 'params'}).returns(mock_car(:save_successfully => true))
96
+ post :create, :car => {:these => 'params'}
97
+ assert_equal mock_car, assigns(:car)
98
+ end
99
+
100
+ def test_redirect_to_the_created_user
101
+ Car.stubs(:create_new).returns(mock_car(:save_successfully => true))
102
+ @controller.expects(:resource_url).returns('http://test.host/')
103
+ post :create
104
+ assert_redirected_to 'http://test.host/'
105
+ end
106
+
107
+ def test_render_new_template_when_user_cannot_be_saved
108
+ Car.stubs(:create_new).returns(mock_car(:save_successfully => false, :errors => {:some => :error}))
109
+ post :create
110
+ assert_response :success
111
+ assert_equal "New HTML", @response.body.strip
112
+ end
113
+ end
114
+
115
+ class UpdateActionCustomizedBaseTest < ActionController::TestCase
116
+ include CarTestHelper
117
+
118
+ def test_update_the_requested_object
119
+ Car.expects(:get).with('42').returns(mock_car)
120
+ mock_car.expects(:update_successfully).with({'these' => 'params'}).returns(true)
121
+ put :update, :id => '42', :car => {:these => 'params'}
122
+ assert_equal mock_car, assigns(:car)
123
+ end
124
+
125
+ def test_redirect_to_the_created_user
126
+ Car.stubs(:get).returns(mock_car(:update_successfully => true))
127
+ @controller.expects(:resource_url).returns('http://test.host/')
128
+ put :update
129
+ assert_redirected_to 'http://test.host/'
130
+ end
131
+
132
+ def test_render_edit_template_when_user_cannot_be_saved
133
+ Car.stubs(:get).returns(mock_car(:update_successfully => false, :errors => {:some => :error}))
134
+ put :update
135
+ assert_response :success
136
+ assert_equal "Edit HTML", @response.body.strip
137
+ end
138
+ end
139
+
140
+ class DestroyActionCustomizedBaseTest < ActionController::TestCase
141
+ include CarTestHelper
142
+
143
+ def test_the_requested_user_is_destroyed
144
+ Car.expects(:get).with('42').returns(mock_car)
145
+ mock_car.expects(:destroy_successfully)
146
+ delete :destroy, :id => '42'
147
+ assert_equal mock_car, assigns(:car)
148
+ end
149
+
150
+ def test_show_flash_message_when_user_can_be_deleted
151
+ Car.stubs(:get).returns(mock_car(:destroy_successfully => true))
152
+ delete :destroy
153
+ assert_equal flash[:notice], 'Car was successfully destroyed.'
154
+ end
155
+
156
+ def test_show_flash_message_when_cannot_be_deleted
157
+ Car.stubs(:get).returns(mock_car(:destroy_successfully => false))
158
+ delete :destroy
159
+ assert_equal flash[:error], 'Car could not be destroyed.'
160
+ end
161
+ end
162
+
@@ -0,0 +1,76 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class GreatSchool
4
+ end
5
+
6
+ class Professor
7
+ def self.human_name; 'Professor'; end
8
+ end
9
+
10
+ class ProfessorsController < InheritedResources::Base
11
+ belongs_to :school, :parent_class => GreatSchool, :instance_name => :great_school,
12
+ :finder => :find_by_title!, :param => :school_title
13
+ end
14
+
15
+ class CustomizedBelongsToTest < ActionController::TestCase
16
+ tests ProfessorsController
17
+
18
+ def setup
19
+ GreatSchool.expects(:find_by_title!).with('nice').returns(mock_school(:professors => Professor))
20
+ @controller.stubs(:resource_url).returns('/')
21
+ @controller.stubs(:collection_url).returns('/')
22
+ end
23
+
24
+ def test_expose_the_resquested_school_with_chosen_instance_variable_on_index
25
+ Professor.stubs(:find).returns([mock_professor])
26
+ get :index, :school_title => 'nice'
27
+ assert_equal mock_school, assigns(:great_school)
28
+ end
29
+
30
+ def test_expose_the_resquested_school_with_chosen_instance_variable_on_show
31
+ Professor.stubs(:find).returns(mock_professor)
32
+ get :show, :school_title => 'nice'
33
+ assert_equal mock_school, assigns(:great_school)
34
+ end
35
+
36
+ def test_expose_the_resquested_school_with_chosen_instance_variable_on_new
37
+ Professor.stubs(:build).returns(mock_professor)
38
+ get :new, :school_title => 'nice'
39
+ assert_equal mock_school, assigns(:great_school)
40
+ end
41
+
42
+ def test_expose_the_resquested_school_with_chosen_instance_variable_on_edit
43
+ Professor.stubs(:find).returns(mock_professor)
44
+ get :edit, :school_title => 'nice'
45
+ assert_equal mock_school, assigns(:great_school)
46
+ end
47
+
48
+ def test_expose_the_resquested_school_with_chosen_instance_variable_on_create
49
+ Professor.stubs(:build).returns(mock_professor(:save => true))
50
+ post :create, :school_title => 'nice'
51
+ assert_equal mock_school, assigns(:great_school)
52
+ end
53
+
54
+ def test_expose_the_resquested_school_with_chosen_instance_variable_on_update
55
+ Professor.stubs(:find).returns(mock_professor(:update_attributes => true))
56
+ put :update, :school_title => 'nice'
57
+ assert_equal mock_school, assigns(:great_school)
58
+ end
59
+
60
+ def test_expose_the_resquested_school_with_chosen_instance_variable_on_destroy
61
+ Professor.stubs(:find).returns(mock_professor(:destroy => true))
62
+ delete :destroy, :school_title => 'nice'
63
+ assert_equal mock_school, assigns(:great_school)
64
+ end
65
+
66
+ protected
67
+
68
+ def mock_school(stubs={})
69
+ @mock_school ||= mock(stubs)
70
+ end
71
+
72
+ def mock_professor(stubs={})
73
+ @mock_professor ||= mock(stubs)
74
+ end
75
+ end
76
+
@@ -0,0 +1,70 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class Malarz
4
+ def self.human_name; 'Painter'; end
5
+ end
6
+
7
+ class PaintersController < InheritedResources::Base
8
+ defaults :instance_name => 'malarz', :collection_name => 'malarze',
9
+ :resource_class => Malarz, :route_prefix => nil
10
+ end
11
+
12
+ class DefaultsTest < ActionController::TestCase
13
+ tests PaintersController
14
+
15
+ def setup
16
+ @controller.stubs(:resource_url).returns('/')
17
+ @controller.stubs(:collection_url).returns('/')
18
+ end
19
+
20
+ def test_expose_all_painters_as_instance_variable
21
+ Malarz.expects(:find).with(:all).returns([mock_painter])
22
+ get :index
23
+ assert_equal [mock_painter], assigns(:malarze)
24
+ end
25
+
26
+ def test_expose_the_resquested_painter_on_show
27
+ Malarz.expects(:find).with('42').returns(mock_painter)
28
+ get :show, :id => '42'
29
+ assert_equal mock_painter, assigns(:malarz)
30
+ end
31
+
32
+ def test_expose_a_new_painter
33
+ Malarz.expects(:new).returns(mock_painter)
34
+ get :new
35
+ assert_equal mock_painter, assigns(:malarz)
36
+ end
37
+
38
+ def test_expose_the_resquested_painter_on_edit
39
+ Malarz.expects(:find).with('42').returns(mock_painter)
40
+ get :edit, :id => '42'
41
+ assert_response :success
42
+ assert_equal mock_painter, assigns(:malarz)
43
+ end
44
+
45
+ def test_expose_a_newly_create_painter_when_saved_with_success
46
+ Malarz.expects(:new).with({'these' => 'params'}).returns(mock_painter(:save => true))
47
+ post :create, :malarz => {:these => 'params'}
48
+ assert_equal mock_painter, assigns(:malarz)
49
+ end
50
+
51
+ def test_update_the_requested_object
52
+ Malarz.expects(:find).with('42').returns(mock_painter)
53
+ mock_painter.expects(:update_attributes).with({'these' => 'params'}).returns(true)
54
+ put :update, :id => '42', :malarz => {:these => 'params'}
55
+ assert_equal mock_painter, assigns(:malarz)
56
+ end
57
+
58
+ def test_the_resquested_painter_is_destroyed
59
+ Malarz.expects(:find).with('42').returns(mock_painter)
60
+ mock_painter.expects(:destroy)
61
+ delete :destroy, :id => '42'
62
+ assert_equal mock_painter, assigns(:malarz)
63
+ end
64
+
65
+ protected
66
+ def mock_painter(stubs={})
67
+ @mock_painter ||= mock(stubs)
68
+ end
69
+ end
70
+
@@ -0,0 +1,88 @@
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
+ respond_to :xml
9
+ protected
10
+ def interpolation_options
11
+ { :reference => 'Ocean Avenue' }
12
+ end
13
+ end
14
+
15
+ module Admin; end
16
+ class Admin::AddressesController < InheritedResources::Base
17
+ respond_to :xml
18
+ protected
19
+ def interpolation_options
20
+ { :reference => 'Ocean Avenue' }
21
+ end
22
+ end
23
+
24
+ class FlashBaseHelpersTest < ActionController::TestCase
25
+ tests AddressesController
26
+
27
+ def setup
28
+ super
29
+ @request.accept = 'application/xml'
30
+ @controller.stubs(:resource_url).returns("http://test.host/")
31
+ @controller.stubs(:collection_url).returns("http://test.host/")
32
+ end
33
+
34
+ def test_success_flash_message_on_create_with_yml
35
+ Address.stubs(:new).returns(mock_address(:save => true))
36
+ post :create
37
+ assert_equal 'You created a new address close to <b>Ocean Avenue</b>.', flash[:notice]
38
+ end
39
+
40
+ def test_success_flash_message_on_create_with_namespaced_controller
41
+ @controller = Admin::AddressesController.new
42
+ @controller.stubs(:resource_url).returns("http://test.host/")
43
+ Address.stubs(:new).returns(mock_address(:save => true))
44
+ post :create
45
+ assert_equal 'Admin, you created a new address close to <b>Ocean Avenue</b>.', flash[:notice]
46
+ end
47
+
48
+ def test_failure_flash_message_on_create_with_namespaced_controller_actions
49
+ @controller = Admin::AddressesController.new
50
+ @controller.stubs(:resource_url).returns("http://test.host/")
51
+ Address.stubs(:new).returns(mock_address(:save => false))
52
+ post :create
53
+ assert_equal 'Admin error message.', flash[:error]
54
+ end
55
+
56
+ def test_inherited_success_flash_message_on_update_on_namespaced_controllers
57
+ @controller = Admin::AddressesController.new
58
+ @controller.stubs(:resource_url).returns("http://test.host/")
59
+ Address.stubs(:find).returns(mock_address(:update_attributes => true))
60
+ put :update
61
+ assert_response :success
62
+ assert_equal 'Nice! Address was updated with success!', flash[:notice]
63
+ end
64
+
65
+ def test_success_flash_message_on_update
66
+ Address.stubs(:find).returns(mock_address(:update_attributes => true))
67
+ put :update
68
+ assert_response :success
69
+ assert_equal 'Nice! Address was updated with success!', flash[:notice]
70
+ end
71
+
72
+ def test_failure_flash_message_on_update
73
+ Address.stubs(:find).returns(mock_address(:update_attributes => false, :errors => {:some => :error}))
74
+ put :update
75
+ assert_equal 'Oh no! We could not update your address!', flash[:error]
76
+ end
77
+
78
+ def test_success_flash_message_on_destroy
79
+ Address.stubs(:find).returns(mock_address(:destroy => true))
80
+ delete :destroy
81
+ assert_equal 'Address was successfully destroyed.', flash[:notice]
82
+ end
83
+
84
+ protected
85
+ def mock_address(stubs={})
86
+ @mock_address ||= stub(stubs.merge(:to_xml => "xml"))
87
+ end
88
+ end
@@ -0,0 +1,139 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class Tree
4
+ def self.human_name; 'Tree'; end
5
+ end
6
+
7
+ class TreesController < InheritedResources::Base
8
+ has_scope :color, :unless => :show_all_colors?
9
+ has_scope :only_tall, :boolean => true, :only => :index, :if => :restrict_to_only_tall_trees?
10
+ has_scope :shadown_range, :default => 10, :except => [ :index, :show, :destroy, :new ]
11
+ has_scope :root_type, :as => :root
12
+ has_scope :calculate_height, :default => proc {|c| c.session[:height] || 20 }, :only => :new
13
+
14
+ protected
15
+ def restrict_to_only_tall_trees?
16
+ true
17
+ end
18
+
19
+ def show_all_colors?
20
+ false
21
+ end
22
+ end
23
+
24
+ class HasScopeTest < ActionController::TestCase
25
+ tests TreesController
26
+
27
+ def setup
28
+ @controller.stubs(:resource_url).returns('/')
29
+ @controller.stubs(:collection_url).returns('/')
30
+ end
31
+
32
+ def test_boolean_scope_is_called_when_boolean_param_is_true
33
+ Tree.expects(:only_tall).with().returns(Tree).in_sequence
34
+ Tree.expects(:find).with(:all).returns([mock_tree]).in_sequence
35
+ get :index, :only_tall => 'true'
36
+ assert_equal([mock_tree], assigns(:trees))
37
+ assert_equal({ :only_tall => 'true' }, assigns(:current_scopes))
38
+ end
39
+
40
+ def test_boolean_scope_is_called_when_boolean_param_is_false
41
+ Tree.expects(:only_tall).never
42
+ Tree.expects(:find).with(:all).returns([mock_tree])
43
+ get :index, :only_tall => 'false'
44
+ assert_equal([mock_tree], assigns(:trees))
45
+ assert_equal({ :only_tall => 'false' }, assigns(:current_scopes))
46
+ end
47
+
48
+ def test_scope_is_called_only_on_index
49
+ Tree.expects(:only_tall).never
50
+ Tree.expects(:find).with('42').returns(mock_tree)
51
+ get :show, :only_tall => 'true', :id => '42'
52
+ assert_equal(mock_tree, assigns(:tree))
53
+ assert_equal({ }, assigns(:current_scopes))
54
+ end
55
+
56
+ def test_scope_is_skipped_when_if_option_is_false
57
+ @controller.stubs(:restrict_to_only_tall_trees?).returns(false)
58
+ Tree.expects(:only_tall).never
59
+ Tree.expects(:find).with(:all).returns([mock_tree])
60
+ get :index, :only_tall => 'true'
61
+ assert_equal([mock_tree], assigns(:trees))
62
+ assert_equal({ }, assigns(:current_scopes))
63
+ end
64
+
65
+ def test_scope_is_skipped_when_unless_option_is_true
66
+ @controller.stubs(:show_all_colors?).returns(true)
67
+ Tree.expects(:color).never
68
+ Tree.expects(:find).with(:all).returns([mock_tree])
69
+ get :index, :color => 'blue'
70
+ assert_equal([mock_tree], assigns(:trees))
71
+ assert_equal({ }, assigns(:current_scopes))
72
+ end
73
+
74
+ def test_scope_is_called_except_on_index
75
+ Tree.expects(:shadown_range).with().never
76
+ Tree.expects(:find).with(:all).returns([mock_tree])
77
+ get :index, :shadown_range => 20
78
+ assert_equal([mock_tree], assigns(:trees))
79
+ assert_equal({ }, assigns(:current_scopes))
80
+ end
81
+
82
+ def test_scope_is_called_with_arguments
83
+ Tree.expects(:color).with('blue').returns(Tree).in_sequence
84
+ Tree.expects(:find).with(:all).returns([mock_tree]).in_sequence
85
+ get :index, :color => 'blue'
86
+ assert_equal([mock_tree], assigns(:trees))
87
+ assert_equal({ :color => 'blue' }, assigns(:current_scopes))
88
+ end
89
+
90
+ def test_multiple_scopes_are_called
91
+ Tree.expects(:only_tall).with().returns(Tree)
92
+ Tree.expects(:color).with('blue').returns(Tree)
93
+ Tree.expects(:find).with(:all).returns([mock_tree])
94
+ get :index, :color => 'blue', :only_tall => 'true'
95
+ assert_equal([mock_tree], assigns(:trees))
96
+ assert_equal({ :color => 'blue', :only_tall => 'true' }, assigns(:current_scopes))
97
+ end
98
+
99
+ def test_scope_is_called_with_default_value
100
+ Tree.expects(:shadown_range).with(10).returns(Tree).in_sequence
101
+ Tree.expects(:find).with('42').returns(mock_tree).in_sequence
102
+ get :edit, :id => '42'
103
+ assert_equal(mock_tree, assigns(:tree))
104
+ assert_equal({ :shadown_range => 10 }, assigns(:current_scopes))
105
+ end
106
+
107
+ def test_default_scope_value_can_be_overwritten
108
+ Tree.expects(:shadown_range).with('20').returns(Tree).in_sequence
109
+ Tree.expects(:find).with('42').returns(mock_tree).in_sequence
110
+ get :edit, :id => '42', :shadown_range => '20'
111
+ assert_equal(mock_tree, assigns(:tree))
112
+ assert_equal({ :shadown_range => '20' }, assigns(:current_scopes))
113
+ end
114
+
115
+ def test_scope_with_different_key
116
+ Tree.expects(:root_type).with('outside').returns(Tree).in_sequence
117
+ Tree.expects(:find).with('42').returns(mock_tree).in_sequence
118
+ get :show, :id => '42', :root => 'outside'
119
+ assert_equal(mock_tree, assigns(:tree))
120
+ assert_equal({ :root => 'outside' }, assigns(:current_scopes))
121
+ end
122
+
123
+ def test_scope_with_default_value_as_proc
124
+ session[:height] = 100
125
+ Tree.expects(:calculate_height).with(100).returns(Tree).in_sequence
126
+ Tree.expects(:new).returns(mock_tree).in_sequence
127
+ get :new
128
+ assert_equal(mock_tree, assigns(:tree))
129
+ assert_equal({ :calculate_height => 100 }, assigns(:current_scopes))
130
+ end
131
+
132
+ protected
133
+
134
+ def mock_tree(stubs={})
135
+ @mock_tree ||= mock(stubs)
136
+ end
137
+
138
+ end
139
+