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

[1594] Refactor Requirements Controller Spec #1619

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
203 changes: 66 additions & 137 deletions spec/controllers/requirements_controller_spec.rb
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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is testing for show removed?

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'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume removed because the route doesn't get used?

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'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this doesn't check permissions, since a successful request will also redirect

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'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also doesn't check permissions, for same reason

end
end
end
25 changes: 16 additions & 9 deletions spec/support/controller_helpers.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
# some basic helpers to simulate devise controller methods in specs
# frozen_string_literal: true
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
21 changes: 21 additions & 0 deletions spec/support/mockers/category.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# frozen_string_literal: true
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
21 changes: 21 additions & 0 deletions spec/support/mockers/equipment_item.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# frozen_string_literal: true
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
32 changes: 32 additions & 0 deletions spec/support/mockers/equipment_model.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# frozen_string_literal: true
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
Loading