Skip to content

Instantly share code, notes, and snippets.

@hugocorbucci
Created February 22, 2010 16:52
Show Gist options
  • Save hugocorbucci/311247 to your computer and use it in GitHub Desktop.
Save hugocorbucci/311247 to your computer and use it in GitHub Desktop.
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest
alias_action :edit, :update, :destroy, :to => :modify
can(:read, :all)
can(:manage, UserSession)
can(:create, User)
can(:update, User) { |u| u == user }
can(:create, Comment)
can(:modify, Comment) { |c| c.user == user }
can(:create, Vote) do
first_vote = Vote.for_user(user.id).count == 0
first_vote && Time.zone.now <= Time.zone.local(2010, 3, 7, 23, 59, 59)
end
can(:update, Vote) do
first_vote = Vote.for_user(user.id).count == 1
first_vote && Time.zone.now <= Time.zone.local(2010, 3, 7, 23, 59, 59)
end
can(:new, Vote)
if user.admin?
can :manage, :all
elsif user.author?
can :create, Session
can :update, Session do |session|
is_author = session.try(:author) == user || session.try(:second_author) == user
is_author && Time.zone.now <= Time.zone.local(2010, 2, 28, 23, 59, 59)
end
end
end
end
require 'spec/spec_helper'
describe Ability do
before(:each) do
@user = Factory(:user)
end
shared_examples_for "all users" do
it "can read all" do
@ability.should be_can(:read, :all)
end
it "can login/logout" do
@ability.should be_can(:create, UserSession)
@ability.should be_can(:destroy, UserSession)
end
it "can create a new account" do
@ability.should be_can(:create, User)
end
it "can update their own account" do
@ability.should be_can(:update, @user)
@ability.should be_cannot(:update, User.new)
end
it "can create comments" do
@ability.should be_can(:create, Comment)
end
it "can edit their comments" do
comment = Comment.new
@ability.should be_cannot(:edit, comment)
comment.user = @user
@ability.should be_can(:edit, comment)
end
it "can update their comments" do
comment = Comment.new
@ability.should be_cannot(:update, comment)
comment.user = @user
@ability.should be_can(:update, comment)
end
it "can destroy their comments" do
comment = Comment.new
@ability.should be_cannot(:destroy, comment)
comment.user = @user
@ability.should be_can(:destroy, comment)
end
it "can read votes" do
vote = Vote.new
@ability.should be_can(:read, vote)
end
describe "can vote if:" do
before(:each) do
Time.zone.stubs(:now).returns(Time.zone.local(2010, 1, 1))
end
it "- haven't voted yet" do
@ability.should be_can(:create, Vote)
Factory(:vote, :user => @user)
@ability.should be_cannot(:create, Vote)
end
it "- before deadline of 7/3/2010" do
Time.zone.expects(:now).returns(Time.zone.local(2010, 3, 7, 23, 59, 59))
@ability.should be_can(:create, Vote)
end
it "- after deadline can't vote" do
Time.zone.expects(:now).returns(Time.zone.local(2010, 3, 8, 0, 0, 0))
@ability.should be_cannot(:create, Vote)
end
end
describe "can change vote if:" do
before(:each) do
Time.zone.stubs(:now).returns(Time.zone.local(2010, 1, 1))
end
it "has already voted" do
@ability.should be_cannot(:update, Vote)
Factory(:vote, :user => @user)
@ability.should be_can(:update, Vote)
end
it "- before deadline of 7/3/2010" do
Time.zone.expects(:now).returns(Time.zone.local(2010, 3, 7, 23, 59, 59))
@ability.should be_can(:update, Vote)
end
it "- after deadline can't vote" do
Time.zone.expects(:now).returns(Time.zone.local(2010, 3, 8, 0, 0, 0))
@ability.should be_cannot(:update, Vote)
end
end
it "can new vote after voting" do
@ability.should be_can(:new, Vote)
Factory(:vote, :user => @user)
@ability.should be_can(:new, Vote)
end
end
context "- all users (guests)" do
before(:each) do
@ability = Ability.new(@user)
end
it_should_behave_like "all users"
end
context "- admin" do
before(:each) do
@user.add_role "admin"
@ability = Ability.new(@user)
end
it "can manage all" do
@ability.should be_can(:manage, :all)
end
end
context "- author" do
before(:each) do
@user.add_role "author"
@ability = Ability.new(@user)
end
it_should_behave_like "all users"
it "can create sessions" do
@ability.should be_can(:create, Session)
end
describe "can update session if:" do
before(:each) do
@session = Factory(:session)
Time.zone.stubs(:now).returns(Time.zone.local(2010, 1, 1))
end
it "- user is first author" do
@ability.should be_cannot(:update, @session)
@session.author = @user
@ability.should be_can(:update, @session)
end
it "- user is second author" do
@ability.should be_cannot(:update, @session)
@session.second_author = @user
@ability.should be_can(:update, @session)
end
it "- before deadline of 28/2/2010" do
@session.author = @user
Time.zone.expects(:now).returns(Time.zone.local(2010, 2, 28, 23, 59, 59))
@ability.should be_can(:update, @session)
end
it "- after deadline author can't update" do
@session.author = @user
Time.zone.expects(:now).returns(Time.zone.local(2010, 3, 1, 0, 0, 0))
@ability.should be_cannot(:update, @session)
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment