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
@@ -0,0 +1,168 @@
1
+ require File.expand_path('test_helper', File.dirname(__FILE__))
2
+
3
+ class Car
4
+ extend ActiveModel::Naming
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
+ @controller.stubs(:car_url).returns("/")
43
+ end
44
+
45
+ protected
46
+ def mock_car(expectations={})
47
+ @mock_car ||= begin
48
+ car = mock(expectations.except(:errors))
49
+ car.stubs(:class).returns(Car)
50
+ car.stubs(:errors).returns(expectations.fetch(:errors, {}))
51
+ car
52
+ end
53
+ end
54
+ end
55
+
56
+ class IndexActionCustomizedBaseTest < ActionController::TestCase
57
+ include CarTestHelper
58
+
59
+ def test_expose_all_users_as_instance_variable
60
+ Car.expects(:get_all).returns([mock_car])
61
+ get :index
62
+ assert_equal [mock_car], assigns(:cars)
63
+ end
64
+ end
65
+
66
+ class ShowActionCustomizedBaseTest < ActionController::TestCase
67
+ include CarTestHelper
68
+
69
+ def test_expose_the_requested_user
70
+ Car.expects(:get).with('42').returns(mock_car)
71
+ get :show, :id => '42'
72
+ assert_equal mock_car, assigns(:car)
73
+ end
74
+ end
75
+
76
+ class NewActionCustomizedBaseTest < ActionController::TestCase
77
+ include CarTestHelper
78
+
79
+ def test_expose_a_new_user
80
+ Car.expects(:create_new).returns(mock_car)
81
+ get :new
82
+ assert_equal mock_car, assigns(:car)
83
+ end
84
+ end
85
+
86
+ class EditActionCustomizedBaseTest < ActionController::TestCase
87
+ include CarTestHelper
88
+
89
+ def test_expose_the_requested_user
90
+ Car.expects(:get).with('42').returns(mock_car)
91
+ get :edit, :id => '42'
92
+ assert_response :success
93
+ assert_equal mock_car, assigns(:car)
94
+ end
95
+ end
96
+
97
+ class CreateActionCustomizedBaseTest < ActionController::TestCase
98
+ include CarTestHelper
99
+
100
+ def test_expose_a_newly_create_user_when_saved_with_success
101
+ Car.expects(:create_new).with({'these' => 'params'}).returns(mock_car(:save_successfully => true))
102
+ post :create, :car => {:these => 'params'}
103
+ assert_equal mock_car, assigns(:car)
104
+ end
105
+
106
+ def test_redirect_to_the_created_user
107
+ Car.stubs(:create_new).returns(mock_car(:save_successfully => true))
108
+ @controller.expects(:resource_url).returns('http://test.host/')
109
+ post :create
110
+ assert_redirected_to 'http://test.host/'
111
+ end
112
+
113
+ def test_render_new_template_when_user_cannot_be_saved
114
+ Car.stubs(:create_new).returns(mock_car(:save_successfully => false, :errors => {:some => :error}))
115
+ post :create
116
+ assert_response :success
117
+ assert_equal "New HTML", @response.body.strip
118
+ end
119
+ end
120
+
121
+ class UpdateActionCustomizedBaseTest < ActionController::TestCase
122
+ include CarTestHelper
123
+
124
+ def test_update_the_requested_object
125
+ Car.expects(:get).with('42').returns(mock_car)
126
+ mock_car.expects(:update_successfully).with({'these' => 'params'}).returns(true)
127
+ put :update, :id => '42', :car => {:these => 'params'}
128
+ assert_equal mock_car, assigns(:car)
129
+ end
130
+
131
+ def test_redirect_to_the_created_user
132
+ Car.stubs(:get).returns(mock_car(:update_successfully => true))
133
+ @controller.expects(:resource_url).returns('http://test.host/')
134
+ put :update
135
+ assert_redirected_to 'http://test.host/'
136
+ end
137
+
138
+ def test_render_edit_template_when_user_cannot_be_saved
139
+ Car.stubs(:get).returns(mock_car(:update_successfully => false, :errors => {:some => :error}))
140
+ put :update
141
+ assert_response :success
142
+ assert_equal "Edit HTML", @response.body.strip
143
+ end
144
+ end
145
+
146
+ class DestroyActionCustomizedBaseTest < ActionController::TestCase
147
+ include CarTestHelper
148
+
149
+ def test_the_requested_user_is_destroyed
150
+ Car.expects(:get).with('42').returns(mock_car)
151
+ mock_car.expects(:destroy_successfully)
152
+ delete :destroy, :id => '42'
153
+ assert_equal mock_car, assigns(:car)
154
+ end
155
+
156
+ def test_show_flash_message_when_user_can_be_deleted
157
+ Car.stubs(:get).returns(mock_car(:destroy_successfully => true))
158
+ delete :destroy
159
+ assert_equal flash[:notice], 'Car was successfully destroyed.'
160
+ end
161
+
162
+ def test_show_flash_message_when_cannot_be_deleted
163
+ Car.stubs(:get).returns(mock_car(:destroy_successfully => false, :errors => { :fail => true }))
164
+ delete :destroy
165
+ assert_equal flash[:alert], 'Car could not be destroyed.'
166
+ end
167
+ end
168
+
@@ -0,0 +1,76 @@
1
+ require File.expand_path('test_helper', File.dirname(__FILE__))
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_requested_school_with_chosen_instance_variable_on_index
25
+ Professor.stubs(:all).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_requested_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_requested_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_requested_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_requested_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_requested_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_requested_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.expand_path('test_helper', File.dirname(__FILE__))
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(:all).returns([mock_painter])
22
+ get :index
23
+ assert_equal [mock_painter], assigns(:malarze)
24
+ end
25
+
26
+ def test_expose_the_requested_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_requested_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_requested_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,108 @@
1
+ require File.expand_path('test_helper', File.dirname(__FILE__))
2
+
3
+ class Country
4
+ end
5
+
6
+ class State
7
+ end
8
+
9
+ class City
10
+ def self.human_name; 'City'; end
11
+ end
12
+
13
+ class CitiesController < InheritedResources::Base
14
+ belongs_to :country, :state
15
+ end
16
+
17
+ class NestedBelongsToTest < ActionController::TestCase
18
+ tests CitiesController
19
+
20
+ def setup
21
+ Country.expects(:find).with('13').returns(mock_country)
22
+ mock_country.expects(:states).returns(State)
23
+ State.expects(:find).with('37').returns(mock_state)
24
+ mock_state.expects(:cities).returns(City)
25
+
26
+ @controller.stubs(:resource_url).returns('/')
27
+ @controller.stubs(:collection_url).returns('/')
28
+ end
29
+
30
+ def test_assigns_country_and_state_and_city_on_create
31
+ City.expects(:find).with(:all).returns([mock_city])
32
+ get :index, :state_id => '37', :country_id => '13'
33
+
34
+ assert_equal mock_country, assigns(:country)
35
+ assert_equal mock_state, assigns(:state)
36
+ assert_equal [mock_city], assigns(:cities)
37
+ end
38
+
39
+ def test_assigns_country_and_state_and_city_on_show
40
+ City.expects(:find).with('42').returns(mock_city)
41
+ get :show, :id => '42', :state_id => '37', :country_id => '13'
42
+
43
+ assert_equal mock_country, assigns(:country)
44
+ assert_equal mock_state, assigns(:state)
45
+ assert_equal mock_city, assigns(:city)
46
+ end
47
+
48
+ def test_assigns_country_and_state_and_city_on_new
49
+ City.expects(:build).returns(mock_city)
50
+ get :new, :state_id => '37', :country_id => '13'
51
+
52
+ assert_equal mock_country, assigns(:country)
53
+ assert_equal mock_state, assigns(:state)
54
+ assert_equal mock_city, assigns(:city)
55
+ end
56
+
57
+ def test_assigns_country_and_state_and_city_on_edit
58
+ City.expects(:find).with('42').returns(mock_city)
59
+ get :edit, :id => '42', :state_id => '37', :country_id => '13'
60
+
61
+ assert_equal mock_country, assigns(:country)
62
+ assert_equal mock_state, assigns(:state)
63
+ assert_equal mock_city, assigns(:city)
64
+ end
65
+
66
+ def test_assigns_country_and_state_and_city_on_create
67
+ City.expects(:build).with({'these' => 'params'}).returns(mock_city)
68
+ mock_city.expects(:save).returns(true)
69
+ post :create, :state_id => '37', :country_id => '13', :city => {:these => 'params'}
70
+
71
+ assert_equal mock_country, assigns(:country)
72
+ assert_equal mock_state, assigns(:state)
73
+ assert_equal mock_city, assigns(:city)
74
+ end
75
+
76
+ def test_assigns_country_and_state_and_city_on_update
77
+ City.expects(:find).with('42').returns(mock_city)
78
+ mock_city.expects(:update_attributes).returns(true)
79
+ put :update, :id => '42', :state_id => '37', :country_id => '13', :city => {:these => 'params'}
80
+
81
+ assert_equal mock_country, assigns(:country)
82
+ assert_equal mock_state, assigns(:state)
83
+ assert_equal mock_city, assigns(:city)
84
+ end
85
+
86
+ def test_assigns_country_and_state_and_city_on_destroy
87
+ City.expects(:find).with('42').returns(mock_city)
88
+ mock_city.expects(:destroy)
89
+ delete :destroy, :id => '42', :state_id => '37', :country_id => '13'
90
+
91
+ assert_equal mock_country, assigns(:country)
92
+ assert_equal mock_state, assigns(:state)
93
+ assert_equal mock_city, assigns(:city)
94
+ end
95
+
96
+ protected
97
+ def mock_country(stubs={})
98
+ @mock_country ||= mock(stubs)
99
+ end
100
+
101
+ def mock_state(stubs={})
102
+ @mock_state ||= mock(stubs)
103
+ end
104
+
105
+ def mock_city(stubs={})
106
+ @mock_city ||= mock(stubs)
107
+ end
108
+ end
@@ -0,0 +1,164 @@
1
+ require File.expand_path('test_helper', File.dirname(__FILE__))
2
+
3
+ class Brands; end
4
+ class Category; end
5
+
6
+ class Product
7
+ def self.human_name; 'Product'; end
8
+ end
9
+
10
+ class ProductsController < InheritedResources::Base
11
+ belongs_to :brand, :category, :polymorphic => true, :optional => true
12
+ end
13
+
14
+ class OptionalTest < ActionController::TestCase
15
+ tests ProductsController
16
+
17
+ def setup
18
+ @controller.stubs(:resource_url).returns('/')
19
+ @controller.stubs(:collection_url).returns('/')
20
+ end
21
+
22
+ def test_expose_all_products_as_instance_variable_with_category
23
+ Category.expects(:find).with('37').returns(mock_category)
24
+ mock_category.expects(:products).returns(Product)
25
+ Product.expects(:all).returns([mock_product])
26
+ get :index, :category_id => '37'
27
+ assert_equal mock_category, assigns(:category)
28
+ assert_equal [mock_product], assigns(:products)
29
+ end
30
+
31
+ def test_expose_all_products_as_instance_variable_without_category
32
+ Product.expects(:all).returns([mock_product])
33
+ get :index
34
+ assert_equal nil, assigns(:category)
35
+ assert_equal [mock_product], assigns(:products)
36
+ end
37
+
38
+ def test_expose_the_requested_product_with_category
39
+ Category.expects(:find).with('37').returns(mock_category)
40
+ mock_category.expects(:products).returns(Product)
41
+ Product.expects(:find).with('42').returns(mock_product)
42
+ get :show, :id => '42', :category_id => '37'
43
+ assert_equal mock_category, assigns(:category)
44
+ assert_equal mock_product, assigns(:product)
45
+ end
46
+
47
+ def test_expose_the_requested_product_without_category
48
+ Product.expects(:find).with('42').returns(mock_product)
49
+ get :show, :id => '42'
50
+ assert_equal nil, assigns(:category)
51
+ assert_equal mock_product, assigns(:product)
52
+ end
53
+
54
+ def test_expose_a_new_product_with_category
55
+ Category.expects(:find).with('37').returns(mock_category)
56
+ mock_category.expects(:products).returns(Product)
57
+ Product.expects(:build).returns(mock_product)
58
+ get :new, :category_id => '37'
59
+ assert_equal mock_category, assigns(:category)
60
+ assert_equal mock_product, assigns(:product)
61
+ end
62
+
63
+ def test_expose_a_new_product_without_category
64
+ Product.expects(:new).returns(mock_product)
65
+ get :new
66
+ assert_equal nil, assigns(:category)
67
+ assert_equal mock_product, assigns(:product)
68
+ end
69
+
70
+ def test_expose_the_requested_product_for_edition_with_category
71
+ Category.expects(:find).with('37').returns(mock_category)
72
+ mock_category.expects(:products).returns(Product)
73
+ Product.expects(:find).with('42').returns(mock_product)
74
+ get :edit, :id => '42', :category_id => '37'
75
+ assert_equal mock_category, assigns(:category)
76
+ assert_equal mock_product, assigns(:product)
77
+ end
78
+
79
+ def test_expose_the_requested_product_for_edition_without_category
80
+ Product.expects(:find).with('42').returns(mock_product)
81
+ get :edit, :id => '42'
82
+ assert_equal nil, assigns(:category)
83
+ assert_equal mock_product, assigns(:product)
84
+ end
85
+
86
+ def test_expose_a_newly_create_product_with_category
87
+ Category.expects(:find).with('37').returns(mock_category)
88
+ mock_category.expects(:products).returns(Product)
89
+ Product.expects(:build).with({'these' => 'params'}).returns(mock_product(:save => true))
90
+ post :create, :category_id => '37', :product => {:these => 'params'}
91
+ assert_equal mock_category, assigns(:category)
92
+ assert_equal mock_product, assigns(:product)
93
+ end
94
+
95
+ def test_expose_a_newly_create_product_without_category
96
+ Product.expects(:new).with({'these' => 'params'}).returns(mock_product(:save => true))
97
+ post :create, :product => {:these => 'params'}
98
+ assert_equal nil, assigns(:category)
99
+ assert_equal mock_product, assigns(:product)
100
+ end
101
+
102
+ def test_update_the_requested_object_with_category
103
+ Category.expects(:find).with('37').returns(mock_category)
104
+ mock_category.expects(:products).returns(Product)
105
+ Product.expects(:find).with('42').returns(mock_product)
106
+ mock_product.expects(:update_attributes).with({'these' => 'params'}).returns(true)
107
+
108
+ put :update, :id => '42', :category_id => '37', :product => {:these => 'params'}
109
+ assert_equal mock_category, assigns(:category)
110
+ assert_equal mock_product, assigns(:product)
111
+ end
112
+
113
+ def test_update_the_requested_object_without_category
114
+ Product.expects(:find).with('42').returns(mock_product)
115
+ mock_product.expects(:update_attributes).with({'these' => 'params'}).returns(true)
116
+
117
+ put :update, :id => '42', :product => {:these => 'params'}
118
+ assert_equal nil, assigns(:category)
119
+ assert_equal mock_product, assigns(:product)
120
+ end
121
+
122
+ def test_the_requested_product_is_destroyed_with_category
123
+ Category.expects(:find).with('37').returns(mock_category)
124
+ mock_category.expects(:products).returns(Product)
125
+ Product.expects(:find).with('42').returns(mock_product)
126
+ mock_product.expects(:destroy).returns(true)
127
+ @controller.expects(:collection_url).returns('/')
128
+
129
+ delete :destroy, :id => '42', :category_id => '37'
130
+ assert_equal mock_category, assigns(:category)
131
+ assert_equal mock_product, assigns(:product)
132
+ end
133
+
134
+ def test_the_requested_product_is_destroyed_without_category
135
+ Product.expects(:find).with('42').returns(mock_product)
136
+ mock_product.expects(:destroy).returns(true)
137
+ @controller.expects(:collection_url).returns('/')
138
+
139
+ delete :destroy, :id => '42'
140
+ assert_equal nil, assigns(:category)
141
+ assert_equal mock_product, assigns(:product)
142
+ end
143
+
144
+ def test_polymorphic_helpers
145
+ Product.expects(:all).returns([mock_product])
146
+ get :index
147
+
148
+ assert !@controller.send(:parent?)
149
+ assert_equal nil, assigns(:parent_type)
150
+ assert_equal nil, @controller.send(:parent_type)
151
+ assert_equal nil, @controller.send(:parent_class)
152
+ assert_equal nil, assigns(:category)
153
+ assert_equal nil, @controller.send(:parent)
154
+ end
155
+
156
+ protected
157
+ def mock_category(stubs={})
158
+ @mock_category ||= mock(stubs)
159
+ end
160
+
161
+ def mock_product(stubs={})
162
+ @mock_product ||= mock(stubs)
163
+ end
164
+ end