Skip to content
This repository was archived by the owner on Jul 24, 2020. It is now read-only.

Commit e23bf23

Browse files
author
Sydney Young
committed
Refactor Requirements Controller Spec
Resolves #1594
1 parent e8ffd13 commit e23bf23

10 files changed

+312
-146
lines changed
+66-137
Original file line numberDiff line numberDiff line change
@@ -1,213 +1,142 @@
1+
# frozen_string_literal: true
12
require 'spec_helper'
23

3-
# note, these tests are complex in order to test the admin security features
4-
# -- namely, it was necessary to test two contexts for each method: the user
5-
# being an admin, and not.
64
describe RequirementsController, type: :controller do
7-
before(:each) do
8-
mock_app_config
9-
@requirement = FactoryGirl.create(:requirement, contact_name: 'Adam Bray')
10-
end
5+
# NOTE: many of these are essentially just testing permissions
6+
before(:each) { mock_app_config }
117
describe 'GET index' do
128
context 'is admin' do
139
before(:each) do
14-
sign_in FactoryGirl.create(:admin)
10+
allow(Requirement).to receive(:all).and_return(Requirement.none)
11+
mock_user_sign_in(UserMock.new(:admin))
1512
get :index
1613
end
17-
it { is_expected.to respond_with(:success) }
18-
it { is_expected.to render_template(:index) }
19-
it { is_expected.not_to set_flash }
14+
it_behaves_like 'successful request', :index
2015
it 'should populate an array of all requirements' do
21-
expect(assigns(:requirements)).to eq([@requirement])
16+
expect(Requirement).to have_received(:all).twice
2217
end
2318
end
2419
context 'not an admin' do
25-
it 'should redirect to root url if not an admin' do
26-
sign_in FactoryGirl.create(:user)
20+
before do
21+
mock_user_sign_in
2722
get :index
28-
expect(response).to redirect_to(root_url)
29-
end
30-
end
31-
end
32-
describe 'GET show' do
33-
context 'is an admin' do
34-
before(:each) do
35-
sign_in FactoryGirl.create(:admin)
36-
get :show, id: @requirement
37-
end
38-
it { is_expected.to respond_with(:success) }
39-
it { is_expected.to render_template(:show) }
40-
it { is_expected.not_to set_flash }
41-
it 'should set @requirement to the selected requirement' do
42-
expect(assigns(:requirement)).to eq(@requirement)
43-
end
44-
end
45-
context 'not an admin' do
46-
it 'should redirect to root url if not an admin' do
47-
sign_in FactoryGirl.create(:user)
48-
get :show, id: @requirement
49-
expect(response).to redirect_to(root_url)
5023
end
24+
it_behaves_like 'redirected request'
5125
end
5226
end
27+
5328
describe 'GET new' do
5429
context 'is admin' do
5530
before(:each) do
56-
sign_in FactoryGirl.create(:admin)
31+
allow(Requirement).to receive(:new)
32+
mock_user_sign_in(UserMock.new(:admin))
5733
get :new
5834
end
59-
it { is_expected.to respond_with(:success) }
60-
it { is_expected.to render_template(:new) }
61-
it { is_expected.not_to set_flash }
35+
it_behaves_like 'successful request', :new
6236
it 'assigns a new requirement to @requirement' do
63-
expect(assigns(:requirement)).to be_new_record
64-
expect(assigns(:requirement).is_a?(Requirement)).to be_truthy
37+
expect(Requirement).to have_received(:new).twice
6538
end
6639
end
6740
context 'not an admin' do
68-
it 'should redirect to root url if not an admin' do
69-
sign_in FactoryGirl.create(:user)
41+
before do
42+
mock_user_sign_in
7043
get :new
71-
expect(response).to redirect_to(root_url)
72-
end
73-
end
74-
end
75-
describe 'GET edit' do
76-
context 'is admin' do
77-
before(:each) do
78-
sign_in FactoryGirl.create(:admin)
79-
get :edit, id: @requirement
80-
end
81-
it 'should set @requirement to the selected requirement' do
82-
expect(assigns(:requirement)).to eq(@requirement)
83-
end
84-
it { is_expected.to respond_with(:success) }
85-
it { is_expected.to render_template(:edit) }
86-
it { is_expected.not_to set_flash }
87-
end
88-
context 'not admin' do
89-
it 'should redirect to root url if not an admin' do
90-
sign_in FactoryGirl.create(:user)
91-
get :edit, id: @requirement
92-
expect(response).to redirect_to(root_url)
9344
end
45+
it_behaves_like 'redirected request'
9446
end
9547
end
96-
describe 'PUT update' do
48+
49+
describe 'POST create' do
9750
context 'is admin' do
98-
before(:each) do
99-
sign_in FactoryGirl.create(:admin)
100-
end
101-
context 'with valid attributes' do
51+
before(:each) { mock_user_sign_in(UserMock.new(:admin)) }
52+
context 'successful save' do
53+
let!(:req) { FactoryGirl.build_stubbed(:requirement) }
10254
before(:each) do
103-
put :update,
104-
id: @requirement,
105-
requirement: FactoryGirl.attributes_for(:requirement,
106-
contact_name: 'John Doe')
55+
allow(Requirement).to receive(:new).and_return(req)
56+
allow(req).to receive(:save).and_return(true)
57+
post :create, requirement: { contact_name: 'name' }
10758
end
108-
it 'should set @requirement to the correct requirement' do
109-
expect(assigns(:requirement)).to eq(@requirement)
110-
end
111-
it 'should update the attributes of @requirement' do
112-
@requirement.reload
113-
expect(@requirement.contact_name).to eq('John Doe')
59+
it 'saves a new requirement' do
60+
expect(Requirement).to have_received(:new).twice
61+
expect(req).to have_received(:save)
11462
end
115-
it { is_expected.to redirect_to(@requirement) }
63+
it { is_expected.to redirect_to(req) }
11664
it { is_expected.to set_flash }
11765
end
11866
context 'with invalid attributes' do
11967
before(:each) do
120-
put :update,
121-
id: @requirement,
122-
requirement: FactoryGirl.attributes_for(:requirement,
123-
contact_name: '')
68+
req = RequirementMock.new(save: false)
69+
allow(Requirement).to receive(:new).and_return(req)
70+
post :create, requirement: { contact_name: 'name' }
12471
end
125-
it 'should not update the attributes of @requirement' do
126-
@requirement.reload
127-
expect(@requirement.contact_name).not_to eq('')
128-
expect(@requirement.contact_name).to eq('Adam Bray')
129-
end
130-
it { is_expected.to render_template(:edit) }
13172
it { is_expected.not_to set_flash }
73+
it { is_expected.to render_template(:new) }
13274
end
13375
end
13476
context 'not admin' do
135-
it 'should redirect to root url if not an admin' do
136-
sign_in FactoryGirl.create(:user)
137-
get :update,
138-
id: @requirement,
139-
requirement: FactoryGirl.attributes_for(:requirement)
140-
expect(response).to redirect_to(root_url)
77+
before do
78+
mock_user_sign_in
79+
post :create, requirement: { contact_name: 'name' }
14180
end
81+
it_behaves_like 'redirected request'
14282
end
14383
end
144-
describe 'POST create' do
84+
85+
describe 'PUT update' do
14586
context 'is admin' do
146-
before(:each) do
147-
sign_in FactoryGirl.create(:admin)
148-
end
87+
before(:each) { mock_user_sign_in(UserMock.new(:admin)) }
14988
context 'with valid attributes' do
89+
let!(:req) { FactoryGirl.build_stubbed(:requirement) }
15090
before(:each) do
151-
post :create, requirement: FactoryGirl.attributes_for(:requirement)
91+
allow(Requirement).to receive(:find).with(req.id.to_s).and_return(req)
92+
allow(req).to receive(:update_attributes).and_return(true)
93+
put :update, id: req.id, requirement: { contact_name: 'Name' }
15294
end
153-
it 'saves a new requirement' do
154-
expect do
155-
post :create, requirement: FactoryGirl.attributes_for(:requirement)
156-
end.to change(Requirement, :count).by(1)
95+
it 'should update the attributes of @requirement' do
96+
expect(req).to have_received(:update_attributes)
15797
end
158-
it { is_expected.to redirect_to(Requirement.last) }
98+
it { is_expected.to redirect_to(req) }
15999
it { is_expected.to set_flash }
160100
end
161101
context 'with invalid attributes' do
102+
let!(:req) { RequirementMock.new(traits: [:findable]) }
162103
before(:each) do
163-
post :create,
164-
requirement: FactoryGirl.attributes_for(:requirement,
165-
contact_name: nil)
166-
end
167-
it 'fails to save a new requirment' do
168-
expect do
169-
post :create,
170-
requirement: FactoryGirl.attributes_for(:requirement,
171-
contact_name: nil)
172-
end.not_to change(Requirement, :count)
104+
allow(req).to receive(:update_attributes).and_return(false)
105+
put :update, id: req.id, requirement: { contact_name: 'Name' }
173106
end
107+
it { is_expected.to render_template(:edit) }
174108
it { is_expected.not_to set_flash }
175-
it { is_expected.to render_template(:new) }
176109
end
177110
end
178111
context 'not admin' do
179-
it 'should redirect to root url if not an admin' do
180-
sign_in FactoryGirl.create(:user)
181-
post :create, requirement: FactoryGirl.attributes_for(:requirement)
182-
expect(response).to redirect_to(root_url)
112+
before do
113+
mock_user_sign_in
114+
put :update, id: 1, requirement: { contact_name: 'Name' }
183115
end
116+
it_behaves_like 'redirected request'
184117
end
185118
end
119+
186120
describe 'DELETE destroy' do
187121
context 'is admin' do
122+
let!(:req) { RequirementMock.new(traits: [:findable]) }
188123
before(:each) do
189-
sign_in FactoryGirl.create(:admin)
190-
end
191-
it 'assigns the selected requirement to @requirement' do
192-
delete :destroy, id: @requirement
193-
expect(assigns(:requirement)).to eq(@requirement)
124+
mock_user_sign_in(UserMock.new(:admin))
125+
delete :destroy, id: req.id
194126
end
195-
it 'removes @requirement from the database' do
196-
expect do
197-
delete :destroy, id: @requirement
198-
end.to change(Requirement, :count).by(-1)
127+
it 'destroys the requirement' do
128+
expect(req).to have_received(:destroy).with(:force)
199129
end
200130
it 'should redirect to the requirements index page' do
201-
delete :destroy, id: @requirement
202131
expect(response).to redirect_to requirements_url
203132
end
204133
end
205134
context 'not admin' do
206-
it 'should redirect to root url if not an admin' do
207-
sign_in FactoryGirl.create(:user)
208-
delete :destroy, id: @requirement
209-
expect(response).to redirect_to(root_url)
135+
before do
136+
mock_user_sign_in
137+
delete :destroy, id: 1
210138
end
139+
it_behaves_like 'redirected request'
211140
end
212141
end
213142
end

spec/support/controller_helpers.rb

+15-9
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
1-
# some basic helpers to simulate devise controller methods in specs
1+
require Rails.root.join('spec/support/mockers/user.rb')
2+
23
module ControllerHelpers
3-
def current_user
4-
user_session_info =
5-
response.request.env['rack.session']['warden.user.user.key']
6-
return unless user_session_info
7-
user_id = user_session_info[0][0]
8-
User.find(user_id)
4+
def mock_user_sign_in(user = UserMock.new(traits: [:findable]))
5+
pass_app_setup_check
6+
allow(request.env['warden']).to receive(:authenticate!).and_return(user)
7+
# necessary for permissions to work
8+
allow(ApplicationController).to receive(:current_user).and_return(user)
9+
allow(Ability).to receive(:new).and_return(Ability.new(user))
10+
allow_any_instance_of(described_class).to \
11+
receive(:current_user).and_return(user)
912
end
1013

11-
def user_signed_in?
12-
!current_user.nil?
14+
private
15+
16+
def pass_app_setup_check
17+
allow(AppConfig).to receive(:first).and_return(true) unless AppConfig.first
18+
allow(User).to receive(:count).and_return(1) unless User.first
1319
end
1420
end

spec/support/mockers/category.rb

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
require Rails.root.join('spec/support/mockers/mocker.rb')
2+
require Rails.root.join('spec/support/mockers/equipment_model.rb')
3+
4+
class CategoryMock < Mocker
5+
def self.klass
6+
Category
7+
end
8+
9+
def self.klass_name
10+
'Category'
11+
end
12+
13+
private
14+
15+
def with_equipment_models(models: nil, count: 1)
16+
models ||= Array.new(count) { EquipmentModelMock.new }
17+
parent_has_many(mocked_children: models, parent_sym: :category,
18+
child_sym: :equipment_models)
19+
end
20+
end
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
require Rails.root.join('spec/support/mockers/mocker.rb')
2+
require Rails.root.join('spec/support/mockers/equipment_model.rb')
3+
4+
class EquipmentItemMock < Mocker
5+
def self.klass
6+
EquipmentItem
7+
end
8+
9+
def self.klass_name
10+
'EquipmentItem'
11+
end
12+
13+
private
14+
15+
def with_model(model: nil)
16+
model ||= EquipmentModelMock.new
17+
child_of_has_many(mocked_parent: model, parent_sym: :equipment_model,
18+
child_sym: :equipment_items)
19+
end
20+
end
+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
require Rails.root.join('spec/support/mockers/mocker.rb')
2+
require Rails.root.join('spec/support/mockers/category.rb')
3+
require Rails.root.join('spec/support/mockers/equipment_item.rb')
4+
5+
class EquipmentModelMock < Mocker
6+
def self.klass
7+
EquipmentModel
8+
end
9+
10+
def self.klass_name
11+
'EquipmentModel'
12+
end
13+
14+
private
15+
16+
def with_item(item:)
17+
with_items(items: [item])
18+
end
19+
20+
def with_items(items: nil, count: 1)
21+
items ||= Array.new(count) { EquipmentItemMock.new }
22+
parent_has_many(mocked_children: items, parent_sym: :equipment_model,
23+
child_sym: :equipment_items)
24+
end
25+
26+
def with_category(cat: nil)
27+
cat ||= CategoryMock.new
28+
child_of_has_many(mocked_parent: cat, parent_sym: :category,
29+
child_sym: :equipment_models)
30+
end
31+
end

0 commit comments

Comments
 (0)