Skip to content

Commit

Permalink
legit deny_access matcher
Browse files Browse the repository at this point in the history
  • Loading branch information
Dan Croak committed Jun 30, 2011
1 parent 48f27f1 commit b2cd877
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 6 deletions.
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,32 @@ To use them, require the test matchers. For example, in spec/support/clearance.r

require 'clearance/shoulda_matchers'

You'll then have access to methods like:

sign_in
sign_in_as(user)
sign_out

And matchers like:

deny_access

Example:

context "a visitor" do
before { get :show }
it { should deny_access }
end

context "a user" do
before do
sign_in
get :show
end

it { should respond_with(:success) }
end

Extensions
----------

Expand Down
2 changes: 1 addition & 1 deletion lib/clearance/authentication.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def authorize
# @param [String] optional flash message to display to denied user
def deny_access(flash_message = nil)
store_location
flash[:failure] = flash_message if flash_message
flash[:notice] = flash_message if flash_message
if signed_in?
redirect_to(url_after_denied_access_when_signed_in)
else
Expand Down
68 changes: 63 additions & 5 deletions lib/clearance/test_matchers.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,72 @@
module Clearance
module Test
module Matchers
# Ensures a controller denied access.
#
# @example
# it { should deny_access }
# it { should deny_access(:flash => "Denied access.") }
# it { should deny_access(:redirect => sign_in_url) }
def deny_access(opts = {})
if opts[:flash]
should set_the_flash.to(opts[:flash])
else
should_not set_the_flash
DenyAccessMatcher.new(self, opts)
end

class DenyAccessMatcher
attr_reader :failure_message, :negative_failure_message

def initialize(context, opts)
@context = context
@flash = opts[:flash]
@url = opts[:redirect]

@failure_message = ""
@negative_failure_message = ""
end

def matches?(controller)
@controller = controller
sets_the_flash? && redirects_to_url?
end

def description
"deny access"
end

private

def sets_the_flash?
if @flash.blank?
true
else
if @controller.flash[:notice].try(:values).try(:first) == @flash
@negative_failure_message << "Didn't expect to set the flash to #{@flash}"
true
else
@failure_message << "Expected the flash to be set to #{@flash} but was #{@controller.flash[:notice].try(:values).try(:first)}"
false
end
end
end

redirect_to(Clearance.configuration.denied_access_url.call)
def redirects_to_url?
@url ||= denied_access_url
begin
@context.send(:assert_redirected_to, @url)
@negative_failure_message << "Didn't expect to redirect to #{@url}."
true
rescue MiniTest::Assertion
@failure_message << "Expected to redirect to #{@url} but did not."
false
end
end

def denied_access_url
if @controller.signed_in?
'/'
else
@controller.sign_in_url
end
end
end
end

Expand Down
60 changes: 60 additions & 0 deletions spec/controllers/denies_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
require 'spec_helper'

class DeniesController < ActionController::Base
include Clearance::Authentication
before_filter :authorize, :only => :show

def new
render :text => "New page"
end

def show
render :text => "Show page"
end

protected

def authorize
deny_access(:flash => "Access denied.")
end
end

describe DeniesController do
before do
Rails.application.routes.draw do
resource :deny, :only => [:new, :show]
match 'sign_in' => 'clearance/sessions#new', :as => 'sign_in'
end
end

after do
Rails.application.reload_routes!
end

context "signed in user" do
before { sign_in }

it "allows access to new" do
get :new
subject.should_not deny_access
end

it "denies access to show" do
get :show
subject.should deny_access(:redirect => '/')
end
end

context "visitor" do
it "allows access to new" do
get :new
subject.should_not deny_access
end

it "denies access to show" do
get :show
subject.should deny_access
subject.should deny_access(:redirect => sign_in_url, :flash => "Access denied.")
end
end
end

0 comments on commit b2cd877

Please sign in to comment.