Skip to content

Commit

Permalink
add support for rspec to allow authentication on controllers
Browse files Browse the repository at this point in the history
  • Loading branch information
Chocksy committed Apr 11, 2016
1 parent ca04add commit 206437e
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 18 deletions.
2 changes: 1 addition & 1 deletion app/controllers/errors_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def update

def notify_subscribers
@message = params[:message]
@error.website.members.each do |member|
@error.website.users.each do |member|
UserMailer.notify_subscriber(@error, member, @message).deliver_later
end
end
Expand Down
11 changes: 3 additions & 8 deletions app/models/website.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ class Website < ActiveRecord::Base
has_many :subscribers, dependent: :destroy
has_many :grouped_issues, dependent: :destroy
has_many :website_members, -> { uniq }, autosave: true
has_many :members, through: :website_members
has_many :users, through: :website_members

validates :title, presence: true
validates :domain, presence: true
Expand All @@ -20,15 +20,10 @@ def website_dependent
end

def unique_domain
begin
domain = URI.parse(self.domain)
rescue
errors.add :domain, 'The domain entered is not valid'
return false
end
domain = URI.parse(self.domain)
website_cases = ["http://#{domain.host}", "https://#{domain.host}", "ftp://#{domain.host}", self.domain]
return true unless Website.exists?(domain: website_cases)
errors.add :domain, 'This website already exists for you'
errors.add :website, 'This website already exists for you'
false
end

Expand Down
6 changes: 1 addition & 5 deletions spec/controllers/errors_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,14 @@

describe 'POST #notify_subscribers' do
context 'if logged in' do
include Warden::Test::Helpers
after { Warden.test_reset! }

before { login_as(user) }
let(:params) { default_params.merge(user: {password: 'hello123', email: user.email}, message: message, id: group.id) }

it 'should email subscribers' do
mailer = double('UserMailer')
expect(mailer).to receive(:deliver_later)
expect(UserMailer).to receive(:notify_subscriber).with(group, user, message).and_return(mailer).once

post :notify_subscribers, params
post_with user, :notify_subscribers, params
end

it 'should email 2 subscribers' do
Expand Down
1 change: 1 addition & 0 deletions spec/rails_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
# explicitly tag your specs with their type, e.g.:

config.include ErrorRequestMock
config.include Warden::Test::ControllerHelpers, type: :controller

# RSpec.describe UsersController, :type => :controller do
# # ...
Expand Down
29 changes: 25 additions & 4 deletions spec/support/auth_helper.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,25 @@
def auth_user(user)
sign_in user
request.headers.merge!(user.create_new_auth_token)
end
module Authorization
def request_with(user, http_method, action, parameters = {}, session = {}, flash = {} )
warden.set_user user
process action, http_method.to_s.upcase, parameters, session, flash
end

[:get, :put, :post, :delete].each do |method|
module_eval <<-EOV, __FILE__, __LINE__
def #{method}_with(user, *args)
request_with(user, #{method.inspect}, *args)
end
EOV
end

def render_with user, options = {}, local_assigns = {}, &block
allow_any_instance_of(ApplicationController).to receive(:current_user).and_return(user)
allow(view).to receive(:current_user).and_return(user)
allow(view).to receive(:authenticated?).and_return(true)
render options, local_assigns, &block
end
end

RSpec::configure do |c|
c.include Authorization
end
57 changes: 57 additions & 0 deletions spec/support/warden.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
module Warden
# Warden::Test::ControllerHelpers provides a facility to test controllers in isolation
# Most of the code was extracted from Devise's Devise::TestHelpers.
module Test
module ControllerHelpers
def self.included(base)
base.class_eval do
setup :setup_controller_for_warden, :warden if respond_to?(:setup)
end
end

# Override process to consider warden.
def process(*)
# Make sure we always return @response, a la ActionController::TestCase::Behavior#process, even if warden interrupts
_catch_warden {super} || @response
end

# We need to setup the environment variables and the response in the controller
def setup_controller_for_warden
@request.env['action_controller.instance'] = @controller
end

# Quick access to Warden::Proxy.
def warden
@warden ||= begin
manager = Warden::Manager.new(nil, &Rails.application.config.middleware.detect{|m| m.name == 'Warden::Manager'}.block)
@request.env['warden'] = Warden::Proxy.new(@request.env, manager)
end
end

protected

# Catch warden continuations and handle like the middleware would.
# Returns nil when interrupted, otherwise the normal result of the block.
def _catch_warden(&block)
result = catch(:warden, &block)

if result.is_a?(Hash) && !warden.custom_failure? && !@controller.send(:performed?)
result[:action] ||= :unauthenticated

env = @controller.request.env
env['PATH_INFO'] = "/#{result[:action]}"
env['warden.options'] = result
Warden::Manager._run_callbacks(:before_failure, env, result)

status, headers, body = warden.config[:failure_app].call(env).to_a
@controller.send :render, :status => status, :text => body,
:content_type => headers['Content-Type'], :location => headers['Location']

nil
else
result
end
end
end
end
end

0 comments on commit 206437e

Please sign in to comment.