Created
September 1, 2010 14:42
-
-
Save chipiga/560771 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Ability | |
include CanCan::Ability | |
def initialize(user) | |
user ||= User.new # guest user | |
can :read, [Project, News, Article, Page], :state => 'published' | |
if user.roles?(:admin) | |
can :manage, :all | |
else | |
if user.roles?(:user) | |
end | |
if user.roles?(:author) | |
can :index, [Project, News, Article, Page], ["(state = 'published') OR (user_id = ?)", user.id] | |
can :show, [Project, News, Article, Page] # TODO redo this gap! | |
can :read, [Asset, Vcard], :user_id => user.id | |
can :create, [Project, News, Article, Page, Asset, Vcard] | |
can :update, [Project, News, Article, Page, Asset, Vcard], :user_id => user.id | |
end | |
if user.roles?(:moderator) | |
can :read, [Project, News, Article, Page, Asset, Vcard] | |
can :update, [Project, News, Article, Page, Asset, Vcard] | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'spec_helper' | |
require 'cancan/matchers' | |
describe Ability do | |
context "as a guest" do | |
let(:user) { User.new } | |
let(:ability) { Ability.new(user) } | |
context "for Project" do | |
it "should be able to read published projects" do | |
ability.should be_able_to(:read, Factory.build(:published_project)) | |
end | |
it "should not be able to read draft projects" do | |
ability.should_not be_able_to(:read, Factory.build(:draft_project)) | |
end | |
it "should not be able to create project" do | |
ability.should_not be_able_to(:create, Project) | |
end | |
it "should not be able to update project" do | |
ability.should_not be_able_to(:update, Factory.build(:project)) | |
end | |
it "should not be able to destroy project" do | |
ability.should_not be_able_to(:destroy, Factory.build(:project)) | |
end | |
end | |
end | |
context "as a user" do | |
let(:user) { Factory.create(:user) } | |
let(:ability) { Ability.new(user) } | |
context "for Project" do | |
it "should be able to read published projects" do | |
ability.should be_able_to(:read, Factory.build(:published_project)) | |
end | |
it "should not be able to read draft projects" do | |
ability.should_not be_able_to(:read, Factory.build(:draft_project)) | |
end | |
it "should not be able to create project" do | |
ability.should_not be_able_to(:create, Project) | |
end | |
it "should not be able to update project" do | |
ability.should_not be_able_to(:update, Factory.build(:project)) | |
end | |
it "should not be able to destroy project" do | |
ability.should_not be_able_to(:destroy, Factory.build(:project)) | |
end | |
end | |
end | |
context "as an author" do | |
let(:user) { Factory.create(:author_user) } | |
let(:ability) { Ability.new(user) } | |
context "for Project" do | |
it "should be able to read published projects" do | |
ability.should be_able_to(:read, Factory.build(:published_project)) | |
end | |
pending "should not be able to read all draft projects" do | |
# ability.should_not be_able_to(:read, Factory.build(:draft_project)) | |
ability.should_not be_able_to(:index, Factory.build(:draft_project)) | |
ability.should_not be_able_to(:show, Factory.build(:draft_project)) | |
end | |
it "should be able to read own draft projects" do | |
# ability.should be_able_to(:read, Factory.build(:draft_project, :user => user)) | |
ability.should be_able_to(:index, Factory.build(:draft_project, :user => user)) | |
ability.should be_able_to(:show, Factory.build(:draft_project, :user => user)) | |
end | |
it "should be able to create project" do | |
ability.should be_able_to(:create, Project) | |
end | |
it "should not be able to update any project" do | |
ability.should_not be_able_to(:update, Factory.build(:project)) | |
end | |
it "should be able to update own project" do | |
ability.should be_able_to(:update, Factory.build(:project, :user => user)) | |
end | |
it "should not be able to destroy project" do | |
ability.should_not be_able_to(:destroy, Factory.build(:project, :user => user)) | |
end | |
end | |
end | |
context "as a moderator" do | |
let(:user) { Factory.create(:moderator_user) } | |
let(:ability) { Ability.new(user) } | |
context "for Project" do | |
it "should be able to read all projects" do | |
ability.should be_able_to(:read, Factory.build(:project)) | |
end | |
it "should_not be able to create project" do | |
ability.should_not be_able_to(:create, Project) | |
end | |
it "should be able to update any project" do | |
ability.should be_able_to(:update, Factory.build(:project)) | |
end | |
it "should not be able to destroy project" do | |
ability.should_not be_able_to(:destroy, Factory.build(:project)) | |
end | |
end | |
end | |
context "as an admin" do | |
let(:user) { Factory.create(:admin_user) } | |
let(:ability) { Ability.new(user) } | |
context "for Project" do | |
it "should be able to read all projects" do | |
ability.should be_able_to(:read, Factory.build(:project)) | |
end | |
it "should be able to create project" do | |
ability.should be_able_to(:create, Project) | |
end | |
it "should be able to update any project" do | |
ability.should be_able_to(:update, Factory.build(:project)) | |
end | |
it "should be able to destroy project" do | |
ability.should be_able_to(:destroy, Factory.build(:project)) | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Add paternity (authorship) link | |
module Platform | |
module Controllers | |
module Paternity | |
extend ActiveSupport::Concern | |
included do | |
before_filter :build_resource, lambda{ resource.user = current_user }, :only => :create | |
end | |
module InstanceMethods | |
end | |
module ClassMethods | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
share_examples_for "paternity" do | |
it "should set authorship for resource" do | |
resource.class.stub(:new) { resource } | |
resource.should_receive(:user=).with(controller.current_user) | |
post :create, :project => {} | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Project < ActiveRecord::Base | |
belongs_to :user | |
scope :published, where(:state => 'published') | |
scope :draft, where(:state => 'draft') | |
scope :ordered, order('priority DESC').order('id DESC') | |
# default_scope ordered | |
after_initialize lambda { self.started_at ||= Time.zone.now } # Date.today | |
validates :name, :aim, :description, :started_at, :presence => true | |
# attr_accessible | |
has_friendly_id :name, :use_slug => true | |
include Platform::Models::Slug | |
include Platform::Models::Tag | |
def news | |
@news ||= News.tagged_with(name) | |
end | |
def articles | |
@articles ||= tag_list.map { |t| Article.where('title LIKE ?', "%#{t}%") }.flatten.uniq | |
end | |
def assets | |
@assets ||= Asset.tagged_with(name) | |
end | |
# TODO redo to connect through categories? | |
def vcards | |
family_name, given_name = name.split(' ') | |
@vcards ||= Vcard.where('agent_id IS NOT NULL').where(:family_name => family_name, :given_name => given_name) | |
@vcards = Vcard.where('agent_id IS NOT NULL').where("? LIKE #{db_concat('%', :family_name, '%')}", name) if @vcards.blank? | |
# @vcards ||= Vcard.where('agent_id IS NOT NULL').where("? = CONCAT(family_name, ' ', given_name)", name) # mysql only | |
# @vcards = Vcard.where('agent_id IS NOT NULL').where("? LIKE CONCAT('%', family_name, '%')", name) if @vcards.blank? # mysql only | |
@vcards | |
end | |
# TODO move to gem || plugin ? | |
private | |
def db_concat(*args) | |
case ActiveRecord::Base.connection.adapter_name.downcase | |
when 'mysql' then "CONCAT(#{quote_args(*args).join(', ')})" | |
when 'sqlite', 'sqlite3', 'postgresql' then quote_args(*args).join(' || ') | |
else raise 'Sorry. Current adapter is not supported yet!' | |
end | |
end | |
def quote_args(*args) | |
args.map do |arg| | |
case arg | |
when Symbol then ActiveRecord::Base.connection.quote_column_name(arg) | |
else ActiveRecord::Base.connection.quote(arg) | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'spec_helper' | |
describe Project do | |
let(:project) { Factory.create(:project) } | |
context "#news" do | |
let(:news) { Factory.create(:news) } | |
it "should have news" do | |
project.should respond_to(:news) | |
end | |
it "should return collection of related news connected through tags" do | |
news.tag_list = project.name; news.save | |
project.news.should eq([news]) | |
end | |
end | |
context "#articles" do | |
let(:article) { Factory.create(:article) } | |
it "should have articles" do | |
project.should respond_to(:articles) | |
end | |
it "should return collection of related articles connected through tags" do | |
project.tag_list = article.title; project.save | |
project.articles.should eq([article]) | |
end | |
end | |
context "#assets" do | |
let(:asset) { Factory.create(:attachment) } | |
it "should have assets" do | |
project.should respond_to(:assets) | |
end | |
it "should return collection of related assets connected through tags" do | |
asset.tag_list = project.name; asset.save | |
project.assets.should eq([asset]) | |
end | |
end | |
context "#vcards" do | |
it "should have vcards" do | |
project.should respond_to(:vcards) | |
end | |
pending "TODO change logic" | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ProjectsController < InheritedResources::Base | |
respond_to :html | |
has_scope :tag | |
include Platform::Controllers::Slug | |
include Platform::Controllers::Auth | |
include Platform::Controllers::Paternity | |
include Platform::Controllers::Paginate | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'spec_helper' | |
require 'controllers/shared/paternity' | |
require 'controllers/shared/slug' | |
describe ProjectsController do | |
def mock_project(stubs={}) | |
@mock_project ||= mock_model(Project, stubs).as_null_object | |
end | |
context "paternity" do | |
let(:resource) { mock_project } | |
before(:each) { sign_in Factory.create(:author_user) } | |
it_should_behave_like "paternity" | |
end | |
context "slug" do | |
let(:resource) { Factory.create(:published_project) } | |
it_should_behave_like "slug" | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Check current slug is the best | |
module Platform | |
module Controllers | |
module Slug | |
extend ActiveSupport::Concern | |
included do | |
before_filter :ensure_current_resource_url, :only => :show | |
end | |
module InstanceMethods | |
protected | |
def ensure_current_resource_url | |
redirect_to resource, :status => :moved_permanently unless resource.friendly_id_status.best? | |
end | |
end | |
module ClassMethods | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
share_examples_for "slug" do | |
it "should redirect to correct URL" do | |
get :show, :id => "#{resource.id}-wrong-slug" | |
response.should redirect_to(controller.polymorphic_url(resource)) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment