This repository has been archived by the owner on Jul 24, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 57
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor Requirements Controller Spec
Resolves #1594
- Loading branch information
Sydney Young
committed
Aug 9, 2016
1 parent
e8ffd13
commit e23bf23
Showing
10 changed files
with
312 additions
and
146 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,213 +1,142 @@ | ||
# frozen_string_literal: true | ||
require 'spec_helper' | ||
|
||
# note, these tests are complex in order to test the admin security features | ||
# -- namely, it was necessary to test two contexts for each method: the user | ||
# being an admin, and not. | ||
describe RequirementsController, type: :controller do | ||
before(:each) do | ||
mock_app_config | ||
@requirement = FactoryGirl.create(:requirement, contact_name: 'Adam Bray') | ||
end | ||
# NOTE: many of these are essentially just testing permissions | ||
before(:each) { mock_app_config } | ||
describe 'GET index' do | ||
context 'is admin' do | ||
before(:each) do | ||
sign_in FactoryGirl.create(:admin) | ||
allow(Requirement).to receive(:all).and_return(Requirement.none) | ||
mock_user_sign_in(UserMock.new(:admin)) | ||
get :index | ||
end | ||
it { is_expected.to respond_with(:success) } | ||
it { is_expected.to render_template(:index) } | ||
it { is_expected.not_to set_flash } | ||
it_behaves_like 'successful request', :index | ||
it 'should populate an array of all requirements' do | ||
expect(assigns(:requirements)).to eq([@requirement]) | ||
expect(Requirement).to have_received(:all).twice | ||
end | ||
end | ||
context 'not an admin' do | ||
it 'should redirect to root url if not an admin' do | ||
sign_in FactoryGirl.create(:user) | ||
before do | ||
mock_user_sign_in | ||
get :index | ||
expect(response).to redirect_to(root_url) | ||
end | ||
end | ||
end | ||
describe 'GET show' do | ||
context 'is an admin' do | ||
before(:each) do | ||
sign_in FactoryGirl.create(:admin) | ||
get :show, id: @requirement | ||
end | ||
it { is_expected.to respond_with(:success) } | ||
it { is_expected.to render_template(:show) } | ||
it { is_expected.not_to set_flash } | ||
it 'should set @requirement to the selected requirement' do | ||
expect(assigns(:requirement)).to eq(@requirement) | ||
end | ||
end | ||
context 'not an admin' do | ||
it 'should redirect to root url if not an admin' do | ||
sign_in FactoryGirl.create(:user) | ||
get :show, id: @requirement | ||
expect(response).to redirect_to(root_url) | ||
end | ||
it_behaves_like 'redirected request' | ||
end | ||
end | ||
|
||
describe 'GET new' do | ||
context 'is admin' do | ||
before(:each) do | ||
sign_in FactoryGirl.create(:admin) | ||
allow(Requirement).to receive(:new) | ||
mock_user_sign_in(UserMock.new(:admin)) | ||
get :new | ||
end | ||
it { is_expected.to respond_with(:success) } | ||
it { is_expected.to render_template(:new) } | ||
it { is_expected.not_to set_flash } | ||
it_behaves_like 'successful request', :new | ||
it 'assigns a new requirement to @requirement' do | ||
expect(assigns(:requirement)).to be_new_record | ||
expect(assigns(:requirement).is_a?(Requirement)).to be_truthy | ||
expect(Requirement).to have_received(:new).twice | ||
end | ||
end | ||
context 'not an admin' do | ||
it 'should redirect to root url if not an admin' do | ||
sign_in FactoryGirl.create(:user) | ||
before do | ||
mock_user_sign_in | ||
get :new | ||
expect(response).to redirect_to(root_url) | ||
end | ||
end | ||
end | ||
describe 'GET edit' do | ||
context 'is admin' do | ||
before(:each) do | ||
sign_in FactoryGirl.create(:admin) | ||
get :edit, id: @requirement | ||
end | ||
it 'should set @requirement to the selected requirement' do | ||
expect(assigns(:requirement)).to eq(@requirement) | ||
end | ||
it { is_expected.to respond_with(:success) } | ||
it { is_expected.to render_template(:edit) } | ||
it { is_expected.not_to set_flash } | ||
end | ||
context 'not admin' do | ||
it 'should redirect to root url if not an admin' do | ||
sign_in FactoryGirl.create(:user) | ||
get :edit, id: @requirement | ||
expect(response).to redirect_to(root_url) | ||
end | ||
it_behaves_like 'redirected request' | ||
end | ||
end | ||
describe 'PUT update' do | ||
|
||
describe 'POST create' do | ||
context 'is admin' do | ||
before(:each) do | ||
sign_in FactoryGirl.create(:admin) | ||
end | ||
context 'with valid attributes' do | ||
before(:each) { mock_user_sign_in(UserMock.new(:admin)) } | ||
context 'successful save' do | ||
let!(:req) { FactoryGirl.build_stubbed(:requirement) } | ||
before(:each) do | ||
put :update, | ||
id: @requirement, | ||
requirement: FactoryGirl.attributes_for(:requirement, | ||
contact_name: 'John Doe') | ||
allow(Requirement).to receive(:new).and_return(req) | ||
allow(req).to receive(:save).and_return(true) | ||
post :create, requirement: { contact_name: 'name' } | ||
end | ||
it 'should set @requirement to the correct requirement' do | ||
expect(assigns(:requirement)).to eq(@requirement) | ||
end | ||
it 'should update the attributes of @requirement' do | ||
@requirement.reload | ||
expect(@requirement.contact_name).to eq('John Doe') | ||
it 'saves a new requirement' do | ||
expect(Requirement).to have_received(:new).twice | ||
expect(req).to have_received(:save) | ||
end | ||
it { is_expected.to redirect_to(@requirement) } | ||
it { is_expected.to redirect_to(req) } | ||
it { is_expected.to set_flash } | ||
end | ||
context 'with invalid attributes' do | ||
before(:each) do | ||
put :update, | ||
id: @requirement, | ||
requirement: FactoryGirl.attributes_for(:requirement, | ||
contact_name: '') | ||
req = RequirementMock.new(save: false) | ||
allow(Requirement).to receive(:new).and_return(req) | ||
post :create, requirement: { contact_name: 'name' } | ||
end | ||
it 'should not update the attributes of @requirement' do | ||
@requirement.reload | ||
expect(@requirement.contact_name).not_to eq('') | ||
expect(@requirement.contact_name).to eq('Adam Bray') | ||
end | ||
it { is_expected.to render_template(:edit) } | ||
it { is_expected.not_to set_flash } | ||
it { is_expected.to render_template(:new) } | ||
end | ||
end | ||
context 'not admin' do | ||
it 'should redirect to root url if not an admin' do | ||
sign_in FactoryGirl.create(:user) | ||
get :update, | ||
id: @requirement, | ||
requirement: FactoryGirl.attributes_for(:requirement) | ||
expect(response).to redirect_to(root_url) | ||
before do | ||
mock_user_sign_in | ||
post :create, requirement: { contact_name: 'name' } | ||
end | ||
it_behaves_like 'redirected request' | ||
end | ||
end | ||
describe 'POST create' do | ||
|
||
describe 'PUT update' do | ||
context 'is admin' do | ||
before(:each) do | ||
sign_in FactoryGirl.create(:admin) | ||
end | ||
before(:each) { mock_user_sign_in(UserMock.new(:admin)) } | ||
context 'with valid attributes' do | ||
let!(:req) { FactoryGirl.build_stubbed(:requirement) } | ||
before(:each) do | ||
post :create, requirement: FactoryGirl.attributes_for(:requirement) | ||
allow(Requirement).to receive(:find).with(req.id.to_s).and_return(req) | ||
allow(req).to receive(:update_attributes).and_return(true) | ||
put :update, id: req.id, requirement: { contact_name: 'Name' } | ||
end | ||
it 'saves a new requirement' do | ||
expect do | ||
post :create, requirement: FactoryGirl.attributes_for(:requirement) | ||
end.to change(Requirement, :count).by(1) | ||
it 'should update the attributes of @requirement' do | ||
expect(req).to have_received(:update_attributes) | ||
end | ||
it { is_expected.to redirect_to(Requirement.last) } | ||
it { is_expected.to redirect_to(req) } | ||
it { is_expected.to set_flash } | ||
end | ||
context 'with invalid attributes' do | ||
let!(:req) { RequirementMock.new(traits: [:findable]) } | ||
before(:each) do | ||
post :create, | ||
requirement: FactoryGirl.attributes_for(:requirement, | ||
contact_name: nil) | ||
end | ||
it 'fails to save a new requirment' do | ||
expect do | ||
post :create, | ||
requirement: FactoryGirl.attributes_for(:requirement, | ||
contact_name: nil) | ||
end.not_to change(Requirement, :count) | ||
allow(req).to receive(:update_attributes).and_return(false) | ||
put :update, id: req.id, requirement: { contact_name: 'Name' } | ||
end | ||
it { is_expected.to render_template(:edit) } | ||
it { is_expected.not_to set_flash } | ||
it { is_expected.to render_template(:new) } | ||
end | ||
end | ||
context 'not admin' do | ||
it 'should redirect to root url if not an admin' do | ||
sign_in FactoryGirl.create(:user) | ||
post :create, requirement: FactoryGirl.attributes_for(:requirement) | ||
expect(response).to redirect_to(root_url) | ||
before do | ||
mock_user_sign_in | ||
put :update, id: 1, requirement: { contact_name: 'Name' } | ||
end | ||
it_behaves_like 'redirected request' | ||
end | ||
end | ||
|
||
describe 'DELETE destroy' do | ||
context 'is admin' do | ||
let!(:req) { RequirementMock.new(traits: [:findable]) } | ||
before(:each) do | ||
sign_in FactoryGirl.create(:admin) | ||
end | ||
it 'assigns the selected requirement to @requirement' do | ||
delete :destroy, id: @requirement | ||
expect(assigns(:requirement)).to eq(@requirement) | ||
mock_user_sign_in(UserMock.new(:admin)) | ||
delete :destroy, id: req.id | ||
end | ||
it 'removes @requirement from the database' do | ||
expect do | ||
delete :destroy, id: @requirement | ||
end.to change(Requirement, :count).by(-1) | ||
it 'destroys the requirement' do | ||
expect(req).to have_received(:destroy).with(:force) | ||
end | ||
it 'should redirect to the requirements index page' do | ||
delete :destroy, id: @requirement | ||
expect(response).to redirect_to requirements_url | ||
end | ||
end | ||
context 'not admin' do | ||
it 'should redirect to root url if not an admin' do | ||
sign_in FactoryGirl.create(:user) | ||
delete :destroy, id: @requirement | ||
expect(response).to redirect_to(root_url) | ||
before do | ||
mock_user_sign_in | ||
delete :destroy, id: 1 | ||
end | ||
it_behaves_like 'redirected request' | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,20 @@ | ||
# some basic helpers to simulate devise controller methods in specs | ||
require Rails.root.join('spec/support/mockers/user.rb') | ||
|
||
module ControllerHelpers | ||
def current_user | ||
user_session_info = | ||
response.request.env['rack.session']['warden.user.user.key'] | ||
return unless user_session_info | ||
user_id = user_session_info[0][0] | ||
User.find(user_id) | ||
def mock_user_sign_in(user = UserMock.new(traits: [:findable])) | ||
pass_app_setup_check | ||
allow(request.env['warden']).to receive(:authenticate!).and_return(user) | ||
# necessary for permissions to work | ||
allow(ApplicationController).to receive(:current_user).and_return(user) | ||
allow(Ability).to receive(:new).and_return(Ability.new(user)) | ||
allow_any_instance_of(described_class).to \ | ||
receive(:current_user).and_return(user) | ||
end | ||
|
||
def user_signed_in? | ||
!current_user.nil? | ||
private | ||
|
||
def pass_app_setup_check | ||
allow(AppConfig).to receive(:first).and_return(true) unless AppConfig.first | ||
allow(User).to receive(:count).and_return(1) unless User.first | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
require Rails.root.join('spec/support/mockers/mocker.rb') | ||
require Rails.root.join('spec/support/mockers/equipment_model.rb') | ||
|
||
class CategoryMock < Mocker | ||
def self.klass | ||
Category | ||
end | ||
|
||
def self.klass_name | ||
'Category' | ||
end | ||
|
||
private | ||
|
||
def with_equipment_models(models: nil, count: 1) | ||
models ||= Array.new(count) { EquipmentModelMock.new } | ||
parent_has_many(mocked_children: models, parent_sym: :category, | ||
child_sym: :equipment_models) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
require Rails.root.join('spec/support/mockers/mocker.rb') | ||
require Rails.root.join('spec/support/mockers/equipment_model.rb') | ||
|
||
class EquipmentItemMock < Mocker | ||
def self.klass | ||
EquipmentItem | ||
end | ||
|
||
def self.klass_name | ||
'EquipmentItem' | ||
end | ||
|
||
private | ||
|
||
def with_model(model: nil) | ||
model ||= EquipmentModelMock.new | ||
child_of_has_many(mocked_parent: model, parent_sym: :equipment_model, | ||
child_sym: :equipment_items) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
require Rails.root.join('spec/support/mockers/mocker.rb') | ||
require Rails.root.join('spec/support/mockers/category.rb') | ||
require Rails.root.join('spec/support/mockers/equipment_item.rb') | ||
|
||
class EquipmentModelMock < Mocker | ||
def self.klass | ||
EquipmentModel | ||
end | ||
|
||
def self.klass_name | ||
'EquipmentModel' | ||
end | ||
|
||
private | ||
|
||
def with_item(item:) | ||
with_items(items: [item]) | ||
end | ||
|
||
def with_items(items: nil, count: 1) | ||
items ||= Array.new(count) { EquipmentItemMock.new } | ||
parent_has_many(mocked_children: items, parent_sym: :equipment_model, | ||
child_sym: :equipment_items) | ||
end | ||
|
||
def with_category(cat: nil) | ||
cat ||= CategoryMock.new | ||
child_of_has_many(mocked_parent: cat, parent_sym: :category, | ||
child_sym: :equipment_models) | ||
end | ||
end |
Oops, something went wrong.