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

Commit

Permalink
Refactor Requirements Controller Spec
Browse files Browse the repository at this point in the history
Resolves #1594
  • Loading branch information
Sydney Young committed Aug 9, 2016
1 parent e8ffd13 commit e23bf23
Show file tree
Hide file tree
Showing 10 changed files with 312 additions and 146 deletions.
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
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
24 changes: 15 additions & 9 deletions spec/support/controller_helpers.rb
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
20 changes: 20 additions & 0 deletions spec/support/mockers/category.rb
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
20 changes: 20 additions & 0 deletions spec/support/mockers/equipment_item.rb
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
31 changes: 31 additions & 0 deletions spec/support/mockers/equipment_model.rb
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
Loading

0 comments on commit e23bf23

Please sign in to comment.