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

[1591] Refactor Blackouts Controller spec #1622

Open
wants to merge 1 commit 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
381 changes: 139 additions & 242 deletions spec/controllers/blackouts_controller_spec.rb

Large diffs are not rendered by default.

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
12 changes: 12 additions & 0 deletions spec/support/mockers/blackout.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true
require Rails.root.join('spec/support/mockers/mocker.rb')

class BlackoutMock < Mocker
def self.klass
Blackout
end

def self.klass_name
'Blackout'
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
103 changes: 103 additions & 0 deletions spec/support/mockers/mocker.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# frozen_string_literal: true
require 'rspec/mocks/standalone'

# This class behaves as an extension of rspec-mocks' instance_spy.
# It is intended to be extended and used to make mocking models much simpler!
#
# To create a new subclass, the following methods must be overridden:
# - self.klass must return the class that the subclass is mocking
# - self.klass_name must return a string that matches the class being mocked
#
# Some examples using the EquipmentModelMock subclass:
# A mock that can be "found" with EquipmentModel#find:
# EquipmentModelMock.new(traits: [:findable])
# A mock with a set of attributes:
# EquipmentModelMock.new(name: 'Camera', late_fee: 3)
# A mock with attributes and method stubs:
# EquipmentModelMock.new(name: 'Camera', model_restriced: false)
# A findable mock with attributes:
# EquipmentModelMock.new(traits: [:findable], name: 'Camera')
#
# A trait can be any method that exists on the mocker superclass or child class.
# To create an EquipmentModel that belongs to an existing category, camera:
# EquipmentModelMock.new(traits: [[:with_category, cat: camera]])
#
# Use caution before adding methods -- any method defined here should be usable
# by all subclasses, with the exception of the association stub methods.

class Mocker < RSpec::Mocks::InstanceVerifyingDouble
include RSpec::Mocks

FIND_METHODS = [:find, :find_by_id].freeze

def initialize(traits: [], **attrs)
# from RSpec::Mocks::ExampleMethods
# combination of #declare_verifying_double and #declare_double
ref = ObjectReference.for(self.class.klass_name)
RSpec::Mocks.configuration.verifying_double_callbacks.each do |block|
block.call(ref)
end
attrs ||= {}
super(ref, attrs)
as_null_object
process_traits(traits)
end

def process_traits(traits)
traits.each { |t| send(*t) }
end

private

def klass
Object
end

def klass_name
'Object'
end

def spy
self
end

# lets us use rspec-mock syntax in mockers
def receive(method_name, &block)
Matchers::Receive.new(method_name, block)
end

def allow(target)
AllowanceTarget.new(target)
end

# Traits
def findable
id = FactoryGirl.generate(:unique_id)
allow(spy).to receive(:id).and_return(id)
FIND_METHODS.each do |method|
allow(self.class.klass).to receive(method)
allow(self.class.klass).to receive(method).with(id).and_return(spy)
allow(self.class.klass).to receive(method).with(id.to_s).and_return(spy)
end
end

# Generalized association stubs
def child_of_has_many(mocked_parent:, parent_sym:, child_sym:)
allow(spy).to receive(parent_sym).and_return(mocked_parent)
children = if mocked_parent.send(child_sym).is_a? Array
mocked_parent.send(child_sym) << spy
else
[spy]
end
allow(mocked_parent).to receive(child_sym).and_return(children)
end

def parent_has_many(mocked_children:, parent_sym:, child_sym:)
if mocked_children.is_a? Array
mocked_children.each do |child|
allow(child).to receive(parent_sym).and_return(spy)
end
end
allow(spy).to receive(child_sym).and_return(mocked_children)
end
end
19 changes: 19 additions & 0 deletions spec/support/mockers/reservation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true
require Rails.root.join('spec/support/mockers/mocker.rb')

class ReservationMock < Mocker
def self.klass
Reservation
end

def self.klass_name
'Reservation'
end

private

def for_user(user:)
child_of_has_many(mocked_parent: user, parent_sym: :reserver,
child_sym: :reservations)
end
end
18 changes: 18 additions & 0 deletions spec/support/mockers/user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# frozen_string_literal: true
require Rails.root.join('spec/support/mockers/mocker.rb')

class UserMock < Mocker
def initialize(role = :user, traits: [], **attrs)
attrs = FactoryGirl.attributes_for(role).merge attrs
traits = [:findable] if traits.empty?
super(traits: traits, **attrs)
end

def self.klass
User
end

def self.klass_name
'User'
end
end
13 changes: 13 additions & 0 deletions spec/support/shared_examples/controller_examples.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true
require 'spec_helper'

shared_examples_for 'successful request' do |template|
it { is_expected.to respond_with(:success) }
it { is_expected.to render_template(template) }
it { is_expected.not_to set_flash }
end

shared_examples_for 'redirected request' do
it { expect(response).to be_redirect }
it { is_expected.to set_flash }
end