Cucumber tests. Added Acts as permissible

This commit is contained in:
Espen Antonsen 2009-06-04 22:28:28 +02:00
parent dc831ff7b8
commit a67066ea05
42 changed files with 1152 additions and 20 deletions

View file

@ -7,7 +7,7 @@ class Album < ActiveRecord::Base
before_validation :ensure_path before_validation :ensure_path
after_create :create_folders after_create :create_folders
before_destroy :destroy_directory after_destroy :destroy_folders
attr_accessor :tag_list attr_accessor :tag_list
attr_protected :path attr_protected :path
@ -80,9 +80,9 @@ class Album < ActiveRecord::Base
Dir.mkdir( APP_CONFIG[:thumbs_path] + self.path ) Dir.mkdir( APP_CONFIG[:thumbs_path] + self.path )
end end
def destroy_directory def destroy_folders
#puts "DELETE DIRECTORY " + APP_CONFIG[:photos_path] + self.path #puts "DELETE DIRECTORY " + APP_CONFIG[:photos_path] + self.path
Dir.delete( APP_CONFIG[:thumbs_path] + self.path ) if File.exists?( APP_CONFIG[:thumbs_path] + self.path ) Dir.delete( APP_CONFIG[:thumbs_path] + self.path ) if File.exists?( APP_CONFIG[:thumbs_path] + self.path )
Dir.delete( APP_CONFIG[:photos_path] + self.path + "/" ) if File.exists?( APP_CONFIG[:photos_path] + self.path ) Dir.delete( APP_CONFIG[:photos_path] + self.path ) if File.exists?( APP_CONFIG[:photos_path] + self.path )
end end
end end

View file

@ -1,2 +1,5 @@
<h1>Albums</h1> <h1>Albums</h1>
<%= render :partial => @albums %> <%= render :partial => @albums %>
<br /><%= link_to "New Album", new_album_path %>
<br /><%= link_to "All albums", albums_path %>

View file

@ -12,6 +12,7 @@
</head> </head>
<body> <body>
<p style="color: green"><%= flash[:notice] %></p>
<%= yield %> <%= yield %>
<%= javascript_include_tag 'jquery-1.3.2.js', 'application' %> <%= javascript_include_tag 'jquery-1.3.2.js', 'application' %>

View file

@ -4,9 +4,6 @@
<br/> <br/>
Tagged with: <%= @photo.tag_list %> Tagged with: <%= @photo.tag_list %>
<p><%= @photo.description %></p> <p><%= @photo.description %></p>
<% if @current_user.role.access_to("photo_note") %>
<p><%= @photo.note %></p>
<% end %>
<br /><%= link_to "Update photo details", edit_photo_path(@photo) %> <br /><%= link_to "Update photo details", edit_photo_path(@photo) %>
<br /><%= link_to "Back to #{@photo.album.title}", @photo.album %> <br /><%= link_to "Back to #{@photo.album.title}", @photo.album %>
<br /><%= link_to "All albums", albums_path %> <br /><%= link_to "All albums", albums_path %>

View file

@ -19,3 +19,6 @@ config.gem "cucumber", :lib => false, :version => ">=0.3.9"
config.gem "webrat", :lib => false, :version => ">=0.4.4" config.gem "webrat", :lib => false, :version => ">=0.4.4"
config.gem "rspec", :lib => false, :version => ">=1.2.6" config.gem "rspec", :lib => false, :version => ">=1.2.6"
config.gem "rspec-rails", :lib => 'spec/rails', :version => ">=1.2.6" config.gem "rspec-rails", :lib => 'spec/rails', :version => ">=1.2.6"
config.gem "thoughtbot-factory_girl",
:lib => "factory_girl",
:source => "http://gems.github.com"

View file

@ -26,8 +26,3 @@ config.action_mailer.delivery_method = :test
# This is necessary if your schema can't be completely dumped by the schema dumper, # This is necessary if your schema can't be completely dumped by the schema dumper,
# like if you have constraints or database-specific column types # like if you have constraints or database-specific column types
# config.active_record.schema_format = :sql # config.active_record.schema_format = :sql
config.gem "rspec"
config.gem "rspec-rails"
config.gem "webrat"
config.gem "cucumber"

View file

@ -2,8 +2,8 @@ development:
site_name: Gallery site_name: Gallery
admin_email: espen@inspired.no admin_email: espen@inspired.no
site_url: gallery.dev:3000 site_url: gallery.dev:3000
photos_path: '/users/Espen/gallery/' photos_path: '/users/Espen/gallery/dev/originals/'
thumbs_path: '/users/Espen/gallery_thumbs/' thumbs_path: '/users/Espen/gallery/dev/thumbs/'
photos_path_public: '/files/' photos_path_public: '/files/'
thumbs_path_public: '/thumbs/' thumbs_path_public: '/thumbs/'
thumb_width: 200 thumb_width: 200
@ -13,7 +13,7 @@ production:
admin_email: espen@inspired.no admin_email: espen@inspired.no
site_url: photos.inspired.no site_url: photos.inspired.no
photos_path: '/home/espen/photos/originals/' photos_path: '/home/espen/photos/originals/'
thumbs_path: '/home/espen/photos/modified/' thumbs_path: '/home/espen/photos/thumbs/'
photos_path_public: '/files/' photos_path_public: '/files/'
thumbs_path_public: '/thumbs/' thumbs_path_public: '/thumbs/'
thumb_width: 200 thumb_width: 200
@ -22,8 +22,8 @@ test:
site_name: Gallery site_name: Gallery
admin_email: espen@inspired.no admin_email: espen@inspired.no
site_url: gallery.dev:3000 site_url: gallery.dev:3000
photos_path: '/users/Espen/gallery_test/' photos_path: '/users/Espen/gallery/test/originals/'
thumbs_path: '/users/Espen/gallery_test_thumbs/' thumbs_path: '/users/Espen/gallery/test/thumbs/'
photos_path_public: '/files/' photos_path_public: '/files/'
thumbs_path_public: '/thumbs/' thumbs_path_public: '/thumbs/'
thumb_width: 200 thumb_width: 200

View file

@ -0,0 +1,41 @@
Feature: Manage Albums
In order to make a gallery
As an contributor
I want to create and manage albums
Scenario: Albums List
Given the following album records
|title|
|Dizin|
|Tehran|
|Delhi|
When I go to the list of albums
Then I should see "Dizin"
And I should see "Tehran"
And I should see "Delhi"
And I should have 3 albums
Scenario: Collection List
Given I have collections titled "Iran", "India"
And I have albums titled "Dizin", "Tehran" in collection "Iran"
And I have albums titled "Delhi" in collection "India"
When I go to the list of collections
Then I should see "Iran"
And I should see "India"
And I should have 2 collections
And collection "Iran" should have 2 albums
And I should have 3 albums
Scenario: Create Valid Album
Given the following user records
| email | password |
| espen@inspired.no | megmeg |
When I am logged in as "espen@inspired.no" with password "megmeg"
And I am on the list of albums
And I have no albums
When I follow "New Album"
And I fill in "Title" with "Norway"
And I fill in "Description" with "The land of the midnight sun"
And I press "Create"
And I should see "Album created!"
Then I follow "All albums"
And I should see "Norway"
And I should have 1 album

View file

@ -0,0 +1,26 @@
Given /i am logged in as a user in the (.*) role/i do |role|
#@user = Factory.create(:user, :name => "Espen Antonsen",
# :email => "espen@inspired.no",
# :password => "megmeg")
#@role = Factory.create(:role, :rolename => role)
#@user.roles << @role
visits "/login"
fills_in("email", :with => "espen@inspired.no")
fills_in("password", :with => "megmeg")
clicks_button("Log in")
end
Given /^I have albums titled (.+) in collection (.+)$/ do |titles,collection|
titles.split(', ').each do |title|
CollectionAlbum.create( :collection => Collection.find_by_title(collection), :album => Album.create!(:title => title) )
end
end
Given /^I have no albums$/ do
Album.destroy_all
end
Then /^I should have ([0-9]+) albums?$/ do |count|
Album.count.should == count.to_i
end

View file

@ -0,0 +1,17 @@
Given /^I have collections titled (.+)$/ do |titles|
titles.split(', ').each do |title|
Collection.create!(:title => title)
end
end
Given /^I have no collectins$/ do
Collection.destroy_all
end
Then /^I should have ([0-9]+) collections?$/ do |count|
Collection.count.should == count.to_i
end
Then /^collection (.+) should have ([0-9]+) albums?$/ do |collection,count|
Collection.find_by_title(collection).albums.count.should == count.to_i
end

View file

@ -0,0 +1,13 @@
Given /^I am logged in as "([^\"]*)" with password "([^\"]*)"$/ do |email, password|
unless email.blank?
visit login_url
fill_in "Email", :with => email
fill_in "Password", :with => password
click_button "Login"
end
end
When /^I visit profile for "([^\"]*)"$/ do |email|
user = User.find_by_email!(email)
visit user_url(user)
end

View file

@ -1,5 +1,12 @@
require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "paths")) require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "paths"))
Given /^the following (.+) records?$/ do |factory, table|
table.hashes.each do |hash|
Factory(factory, hash)
end
end
# Commonly used webrat steps # Commonly used webrat steps
# http://github.com/brynary/webrat # http://github.com/brynary/webrat

View file

@ -0,0 +1,9 @@
After do
require "find"
Find.find( APP_CONFIG[:photos_path] ) { |path|
Dir.delete( path ) if path != APP_CONFIG[:photos_path] && File.directory?(path)
}
Find.find( APP_CONFIG[:thumbs_path] ) { |path|
Dir.delete( path ) if path != APP_CONFIG[:thumbs_path] && File.directory?(path)
}
end

View file

@ -8,10 +8,12 @@ Cucumber::Rails.bypass_rescue # Comment out this line if you want Rails own erro
# (e.g. rescue_action_in_public / rescue_responses / rescue_from) # (e.g. rescue_action_in_public / rescue_responses / rescue_from)
require 'webrat' require 'webrat'
Webrat.configure do |config| Webrat.configure do |config|
config.mode = :rails config.mode = :rails
end end
require 'cucumber/rails/rspec' #require 'cucumber/rails/rspec'
require 'webrat/core/matchers' #require 'webrat/core/matchers'
#require 'factory_girl'
require "#{Rails.root}/spec/factories"

View file

@ -10,6 +10,10 @@ module NavigationHelpers
when /the homepage/ when /the homepage/
'/' '/'
when /the list of albums/
albums_path
when /the list of collections/
collections_path
# Add more mappings here. # Add more mappings here.
# Here is a more fancy example: # Here is a more fancy example:

9
spec/factories.rb Normal file
View file

@ -0,0 +1,9 @@
Factory.define :user do |f|
f.password_confirmation { |u| u.password }
end
Factory.define :album do |f|
end
Factory.define :collection do |f|
end

View file

@ -0,0 +1,20 @@
Copyright (c) 2008 [name of plugin creator]
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View file

@ -0,0 +1,68 @@
ActsAsPermissible
=================
Source:
http://github.com/NoamB/acts_as_permissible/tree/master
More information at:
http://github.com/NoamB/acts_as_permissible/wikis
This plugin enables any activerecord model to have permissions.
It provides a set of methods for querying the model's permissions.
In addition, the plugin can generate roles support, which turns in into a full RBAC (Role Based Access Control) solution.
Any model which includes the line "acts_as_permissible" can have permissions, and with roles support it can also have roles which in turn have their own permissions.
Roles can also belong to roles, which creates a sort of inheritance hierarchy.
When permissions are calculated, the model's permissions are merged with the model's role permissions (if any), which in turn are merged with the role's roles permissions, until a finite permissions hash is generated.
In the case of identical keys, a false value overrides a true value, A true value overrides a nil value, and a nil value is false.
Setup
=====
script/generate permissible <PermissionModelName> [RoleModelName]
The role model name is optional. If you do not want the roles support generated, use the --skip-roles option.
examples: script/generate permissible Permission Role
script/generate permissible Permission Group
script/generate permissible Allowance --skip-roles
use --skip-migration if you don't want a migration created for the permissions model.
use --rspec to force rspec tests installed (currenty these are the only ones available).
Add any permissions you want to your permissions table.
Add any roles you want to your roles table.
Add user->role relationships in your roles_memberships table.
Add role->role relationships in your roles_memberships table.
Usage
=====
class User < Activerecord::Base
acts_as_permissible
end
Now a user will have the following methods:
@user.permissions_hash() # => {:view_something => true, :delete_something => false}
@user.has_permission?("view_something") # => true
@user.has_permission?("view_something", "delete_something") # => false
@user.has_permission?("delete_something") # => false
@user.has_permission?("create_something") # => false
@user.permissions_hash() # => {:view_something => true, :delete_something => false}
@user.permissions << Permission.new(:action => "new_thing", :granted => true)
@user.permissions_hash() # => {:view_something => true, :delete_something => false}
@user.reload_permissions!() # => {:view_something => true, :delete_something => false, :new_thing => true}
@user.permissions_hash() # => {:view_something => true, :delete_something => false, :new_thing => true}
# this is useful for getting the hash again into memory after the permissions table was updated.
And with roles support:
@user.in_role?("publisher") # => true
@user.in_role?("publisher","advertiser") # => false
@user.in_any_role?("publisher","advertiser") => true
@user.full_permissions_hash() # will return a merged hash of user and roles permissions.
Copyright (c) 2008 Noam Ben-Ari, released under the MIT license

View file

@ -0,0 +1,22 @@
require 'rake'
require 'rake/testtask'
require 'rake/rdoctask'
desc 'Default: run unit tests.'
task :default => :test
desc 'Test the acts_as_permissible plugin.'
Rake::TestTask.new(:test) do |t|
t.libs << 'lib'
t.pattern = 'test/**/*_test.rb'
t.verbose = true
end
desc 'Generate documentation for the acts_as_permissible plugin.'
Rake::RDocTask.new(:rdoc) do |rdoc|
rdoc.rdoc_dir = 'rdoc'
rdoc.title = 'ActsAsPermissible'
rdoc.options << '--line-numbers' << '--inline-source'
rdoc.rdoc_files.include('README')
rdoc.rdoc_files.include('lib/**/*.rb')
end

View file

@ -0,0 +1 @@
./script/generate permissible <PermissionsModelName> [RolesModelName | --skip-roles] [--skip-migrations] [--rspec]

View file

@ -0,0 +1,154 @@
#require 'acts_as_permissible/rails_commands'
class PermissibleGenerator < Rails::Generator::NamedBase
default_options :skip_migrations => false, :skip_timestamps => false
attr_reader :role_model_name
attr_reader :role_model_file_name
attr_reader :role_membership_model_name
attr_reader :role_membership_model_file_name
def initialize(runtime_args, runtime_options = {})
super
unless options[:skip_roles]
if @args.first.blank?
puts "No Roles model name supplied! Please use --skip-roles if you do not want roles support generated."
exit()
end
@role_model_name = @args.first
@role_model_file_name = role_model_name.underscore
@role_membership_model_name = role_model_name + "Membership"
@role_membership_model_file_name = role_membership_model_name.underscore
end
@rspec = has_rspec?
end
def manifest
recorded_session = record do |m|
m.directory File.join('app/models', class_path)
if @rspec
m.directory File.join('spec/models', class_path)
m.directory File.join('spec/fixtures', class_path)
# else
# m.directory File.join('test/unit', class_path)
end
m.template 'model.rb',
File.join('app/models',
class_path,
"#{file_name}.rb")
m.template 'acts_as_permissible.rb',
File.join('lib',
"acts_as_permissible.rb")
# m.template 'initializer.rb',
# File.join('config/initializers',
# "acts_as_permissible_init.rb")
unless options[:skip_roles]
m.template 'role_model.rb',
File.join('app/models',
"#{role_model_file_name}.rb")
m.template 'role_membership_model.rb',
File.join('app/models',
"#{role_membership_model_file_name}.rb")
end
if @rspec
m.template 'model_spec.rb',
File.join('spec/models',
class_path,
"#{file_name}_spec.rb")
m.template 'fixtures.yml',
File.join('spec/fixtures',
"#{table_name}.yml")
m.template 'acts_as_permissible_spec.rb',
File.join('spec/models',
"acts_as_permissible_spec.rb")
unless options[:skip_roles]
m.template 'role_model_spec.rb',
File.join('spec/models',
"#{role_model_file_name}_spec.rb")
m.template 'role_membership_model_spec.rb',
File.join('spec/models',
"#{role_model_file_name}_membership_spec.rb")
m.template 'role_model_fixtures.yml',
File.join('spec/fixtures',
"#{role_model_file_name.pluralize}.yml")
m.template 'role_membership_model_fixtures.yml',
File.join('spec/fixtures',
"#{role_membership_model_file_name.pluralize}.yml")
end
# else
# m.template 'unit_test.rb',
# File.join('test/unit',
# class_path,
# "#{file_name}_test.rb")
# m.template 'fixtures.yml',
# File.join('test/fixtures',
# "#{table_name}.yml")
end
unless options[:skip_migrations]
m.migration_template 'migration.rb', 'db/migrate', :assigns => {
:migration_name => "Create#{class_name.pluralize.gsub(/::/, '')}"
}, :migration_file_name => "create_#{file_name.pluralize}"
unless options[:skip_roles]
m.migration_template 'role_migration.rb', 'db/migrate', :assigns => {
:migration_name => "Create#{role_model_name.pluralize.gsub(/::/, '')}"
}, :migration_file_name => "create_#{role_model_file_name.pluralize}"
m.migration_template 'role_membership_migration.rb', 'db/migrate', :assigns => {
:migration_name => "Create#{role_membership_model_name.pluralize.gsub(/::/, '')}"
}, :migration_file_name => "create_#{role_membership_model_file_name.pluralize}"
end
end
end
action = nil
action = $0.split("/")[1]
case action
when "generate"
puts
puts ("-" * 70)
puts
puts "acts_as_permissible"
puts
puts ("-" * 70)
puts
when "destroy"
puts
puts ("-" * 70)
puts
puts "Thanks for using acts_as_permissible"
puts
puts ("-" * 70)
puts
else
puts
end
recorded_session
end
def has_rspec?
options[:rspec] || (File.exist?('spec') && File.directory?('spec'))
end
protected
def banner
"Usage: #{$0} permissible <PermissionsModelName> [RoleModelName]"
end
def add_options!(opt)
opt.separator ''
opt.separator 'Options:'
opt.on("--skip-roles",
"Don't generate roles support") { |v| options[:skip_roles] = v }
opt.on("--skip-migrations",
"Don't generate migration files for these models") { |v| options[:skip_migrations] = v }
opt.on("--skip-timestamps",
"Don't add timestamps to the migration file for this model") { |v| options[:skip_timestamps] = v }
opt.on("--rspec",
"Force rspec mode (checks for RAILS_ROOT/spec by default)") { |v| options[:rspec] = true }
end
end

View file

@ -0,0 +1,106 @@
# ActsAsPermissible
module NoamBenAri
module Acts #:nodoc:
module Permissible #:nodoc:
def self.included(base)
base.extend ClassMethods
end
module ClassMethods
def acts_as_permissible
has_many :<%= table_name %>, :as => :permissible, :dependent => :destroy
<% unless options[:skip_roles] %>
has_many :<%= role_membership_model_file_name.pluralize %>, :as => :roleable, :dependent => :destroy
has_many :<%= role_model_file_name.pluralize %>, :through => :<%= role_membership_model_file_name.pluralize %>, :source => :<%= role_model_file_name %>
<% end %>
include NoamBenAri::Acts::Permissible::InstanceMethods
extend NoamBenAri::Acts::Permissible::SingletonMethods
alias_method :full_permissions_hash, :permissions_hash
end
end
# This module contains class methods
module SingletonMethods
# Helper method to lookup for permissions for a given object.
# This method is equivalent to obj.permissions.
def find_permissions_for(obj)
permissible = ActiveRecord::Base.send(:class_name_of_active_record_descendant, self).to_s
<%= class_name %>.find(:all,
:conditions => ["permissible_id = ? and permissible_type = ?", obj.id, permissible]
)
end
end
# This module contains instance methods
module InstanceMethods
# returns permissions in hash form
# from all levels recursively
def permissions_hash
@permissions_hash ||= lambda do
@permissions_hash = <%= table_name %>.inject({}) { |hsh,perm| hsh.merge(perm.to_hash) }.symbolize_keys!
<% unless options[:skip_roles] -%><%= role_model_file_name %>s.each do |<%= role_model_file_name %>|
merge_permissions!(<%= role_model_file_name %>.permissions_hash)
end
<% end -%>@permissions_hash
end.call()
end
# accepts a permission identifier string or an array of permission identifier strings
# and return true if the user has all of the permissions given by the parameters
# false if not.
def has_permission?(*perms)
perms.all? {|perm| permissions_hash.include?(perm.to_sym) && (permissions_hash[perm.to_sym] == true) }
end
# accepts a permission identifier string or an array of permission identifier strings
# and return true if the user has any of the permissions given by the parameters
# false if none.
def has_any_permission?(*perms)
perms.any? {|perm| permissions_hash.include?(perm.to_sym) && (permissions_hash[perm.to_sym] == true) }
end
# Merges another permissible object's permissions into this permissible's permissions hash
# In the case of identical keys, a false value wins over a true value.
def merge_permissions!(other_permissions_hash)
permissions_hash.merge!(other_permissions_hash) {|key,oldval,newval| oldval.nil? ? newval : oldval && newval}
end
# Resets permissions and then loads them.
def reload_permissions!
reset_permissions!
permissions_hash
end
<% unless options[:skip_roles] %>
def <%= role_model_file_name %>s_list
list = []
<%= role_model_file_name %>s.inject(list) do |list,<%= role_model_file_name %>|
list << <%= role_model_file_name %>.name
<%= role_model_file_name %>.<%= role_model_file_name.pluralize %>_list.inject(list) {|list,<%= role_model_file_name %>| list << <%= role_model_file_name %>}
end
list.uniq
end
def in_<%= role_model_file_name %>?(*<%= role_model_file_name %>_names)
<%= role_model_file_name %>_names.all? {|<%= role_model_file_name %>| <%= role_model_file_name %>s_list.include?(<%= role_model_file_name %>) }
end
def in_any_<%= role_model_file_name %>?(*<%= role_model_file_name %>_names)
<%= role_model_file_name %>_names.any? {|<%= role_model_file_name %>| <%= role_model_file_name %>s_list.include?(<%= role_model_file_name %>) }
end
<% end %>
private
# Nilifies permissions_hash instance variable.
def reset_permissions!
@permissions_hash = nil
end
end
end
end
end

View file

@ -0,0 +1,208 @@
require File.dirname(__FILE__) + '/../spec_helper'
class <%= class_name %> < ActiveRecord::Base
acts_as_permissible
end
describe "acts_as_permissible" do
fixtures :<%= table_name %>
before(:each) do
@perm = <%= table_name %>(:perm)
end
describe "class methods" do
it "should find_permissions_for(obj) correctly" do
<%= class_name %>.find_permissions_for(@perm).size.should == 2
<%= class_name %>.find_permissions_for(@perm).first.action.should == "view_something"
<%= class_name %>.find_permissions_for(@perm).last.action.should == "delete_something"
end
end
describe "permissions_hash" do
it "should return the correct permissions_hash" do
@perm.permissions_hash.should == {:view_something => true, :delete_something => false}
end
end
describe "has_permission?" do
it "should return true if permission found" do
@perm.has_permission?("view_something").should == true
end
it "should return false if permission not found" do
@perm.has_permission?("create_something").should == false
end
it "should return false if permission found and is denied" do
@perm.has_permission?("delete_something").should == false
end
end
describe "merge_permissions!" do
before(:each) do
@perm2 = <%= table_name %>(:perm2)
@merged_permissions = @perm.merge_permissions!(@perm2.permissions_hash)
# {:update_something=>true, :view_something=>true, :delete_something=>false, :create_something=>false}
end
it "should include all keys from both hashes" do
@merged_permissions.keys.should ==
(@perm.permissions_hash.keys + @perm2.permissions_hash.keys).uniq
end
it "should override identical keys with false value" do
@merged_permissions[:delete_something].should == false
end
end
describe "reload_permissions!" do
before(:each) do
@original_hash = @perm.permissions_hash
@perm.<%= table_name %> << <%= class_name %>.new(:action => "add_something", :granted => true)
end
it "should catch-up with database changes" do
@perm.permissions_hash.should == @original_hash
reloaded_hash = @perm.reload_permissions!
reloaded_hash.should_not == @original_hash
end
it "should get the changes correctly" do
reloaded_hash = @perm.reload_permissions!
reloaded_hash.keys.should include(:add_something)
end
end
<% unless options[:skip_roles] %>
describe "<%= role_model_file_name.pluralize %>_list" do
before(:each) do
@perm.<%= role_model_file_name.pluralize %>_list.should == []
@mutables = <%= role_model_name %>.new(:name => "mutables")
@mutables.save!
@wierdos = <%= role_model_name %>.new(:name => "wierdos")
@wierdos.save!
@mutables.<%= role_model_file_name.pluralize %> << @wierdos
end
after(:each) do
@mutables.destroy
@wierdos.destroy
@perm.<%= role_model_file_name.pluralize %>.reset
@perm.<%= role_model_file_name.pluralize %>_list.should == []
end
it "should return the correct list" do
@perm.<%= role_model_file_name.pluralize %> << @wierdos
@perm.<%= role_model_file_name.pluralize %>_list.size.should == 1
@perm.<%= role_model_file_name.pluralize %>_list.should include("wierdos")
end
it "should return the correct list including parent <%= role_model_file_name.pluralize %> of <%= role_model_file_name.pluralize %> recursively." do
@perm.<%= role_model_file_name.pluralize %> << @mutables
@perm.<%= role_model_file_name.pluralize %>_list.size.should == 2
@perm.<%= role_model_file_name.pluralize %>_list.should include("mutables")
@perm.<%= role_model_file_name.pluralize %>_list.should include("wierdos")
end
end
describe "in_<%= role_model_file_name %>?" do
before(:each) do
@mutables = <%= role_model_name %>.new(:name => "mutables")
@mutables.save!
@immutables = <%= role_model_name %>.new(:name => "immutables")
@immutables.save!
end
after(:each) do
@mutables.destroy
@immutables.destroy
@perm.<%= role_model_file_name.pluralize %>.reset
end
it "should return true if member of one" do
@perm.<%= role_model_file_name.pluralize %> << @mutables
@perm.in_<%= role_model_file_name %>?("mutables").should == true
end
it "should return false if not a member" do
@perm.in_<%= role_model_file_name %>?("mutables").should == false
end
it "should return true if member of all" do
@perm.<%= role_model_file_name.pluralize %> << @mutables
@perm.<%= role_model_file_name.pluralize %> << @immutables
@perm.in_<%= role_model_file_name %>?("mutables","immutables").should == true
end
it "should return false if member of some" do
@perm.<%= role_model_file_name.pluralize %> << @mutables
@perm.in_<%= role_model_file_name %>?("mutables","immutables").should == false
end
end
describe "in_any_<%= role_model_file_name %>?" do
before(:each) do
@mutables = <%= role_model_name %>.new(:name => "mutables")
@mutables.save!
@immutables = <%= role_model_name %>.new(:name => "immutables")
@immutables.save!
end
it "should return true if member of one" do
@perm.<%= role_model_file_name.pluralize %> << @mutables
@perm.in_any_<%= role_model_file_name %>?("mutables","immutables").should == true
end
it "should return false if not a member" do
@perm.in_any_<%= role_model_file_name %>?("mutables","immutables").should == false
end
it "should return true if member of all" do
@perm.<%= role_model_file_name.pluralize %> << @mutables
@perm.<%= role_model_file_name.pluralize %> << @immutables
@perm.in_any_<%= role_model_file_name %>?("mutables","immutables").should == true
end
end
describe "full_permissions_hash" do
before(:each) do
@mutables = <%= role_model_name %>.new(:name => "mutables")
@mutables.save!
@mutable_permission = <%= class_name %>.new(:permissible_id => @mutables.id, :permissible_type => @mutables.class.to_s, :action => "view_something", :granted => false)
@mutable_permission.save!
@immutables = <%= role_model_name %>.new(:name => "immutables")
@immutables.save!
@immutable_permission = <%= class_name %>.new(:permissible_id => @immutables.id, :permissible_type => @immutables.class.to_s, :action => "download_something", :granted => true)
@immutable_permission.save!
end
it "should return the correct hash if object doesn't belong to <%= role_model_file_name.pluralize %>" do
@perm.<%= role_model_file_name.pluralize %>.should == []
@perm.full_permissions_hash.should == {:view_something=>true, :delete_something=>false}
end
it "should return the correct hash if object belongs to one <%= role_model_file_name %>" do
@perm.<%= role_model_file_name.pluralize %> << @mutables
@perm.full_permissions_hash.should == {:view_something=>false, :delete_something=>false}
end
it "should return the correct hash if object belongs to one <%= role_model_file_name %> which belongs to another <%= role_model_file_name %>" do
@mutables.<%= role_model_file_name.pluralize %> << @immutables
@perm.<%= role_model_file_name.pluralize %> << @mutables
@perm.full_permissions_hash.should == {:view_something=>false, :delete_something=>false, :download_something=>true}
end
it "should return the correct hash if object belongs to 2 <%= role_model_file_name.pluralize %>" do
@perm.<%= role_model_file_name.pluralize %> << @immutables
@perm.<%= role_model_file_name.pluralize %> << @mutables
@perm.full_permissions_hash.should == {:view_something=>false, :delete_something=>false, :download_something=>true}
end
after(:each) do
@mutables.destroy
@immutables.destroy
@perm.<%= role_model_file_name.pluralize %>.reset
end
end
<% end %>
end

View file

@ -0,0 +1,48 @@
one:
id: 1
permissible_id: 7
permissible_type: "<%= class_name %>"
action: "view_something"
granted: 1
two:
id: 2
permissible_id: 7
permissible_type: "<%= class_name %>"
action: "delete_something"
granted: 0
three:
id: 3
permissible_id: 8
permissible_type: "<%= class_name %>"
action: "view_something"
granted: 1
four:
id: 4
permissible_id: 8
permissible_type: "<%= class_name %>"
action: "delete_something"
granted: 1
five:
id: 5
permissible_id: 8
permissible_type: "<%= class_name %>"
action: "update_something"
granted: 1
six:
id: 6
permissible_id: 8
permissible_type: "<%= class_name %>"
action: "create_something"
granted: 0
perm:
id: 7
permissible_id: 47
permissible_type: "User"
action: "non_important"
granted: 1
perm2:
id: 8
permissible_id: 48
permissible_type: "User"
action: "non_important"
granted: 1

View file

@ -0,0 +1,2 @@
require 'lib/acts_as_permissible'
ActiveRecord::Base.send(:include, NoamBenAri::Acts::Permissible)

View file

@ -0,0 +1,16 @@
class <%= migration_name %> < ActiveRecord::Migration
def self.up
create_table "<%= table_name %>", :force => true do |t|
t.integer :permissible_id
t.string :permissible_type
t.string :action
t.boolean :granted
<% unless options[:skip_timestamps] %>t.timestamps<% end %>
end
end
def self.down
drop_table "<%= table_name %>"
end
end

View file

@ -0,0 +1,19 @@
class <%= class_name %> < ActiveRecord::Base
# uncomment any of the following lines which is relevant to your application,
# or create your own with the name of the model which acts_as_permissible.
#belongs_to :user
<% unless options[:skip_roles] %>
belongs_to :<%= role_model_file_name %>
<% end %>
belongs_to :permissible, :polymorphic => true
validates_presence_of :permissible_id, :permissible_type, :action
validates_format_of :action, :with => /^[a-z_]+$/
validates_numericality_of :permissible_id
validates_uniqueness_of :action, :scope => [:permissible_id,:permissible_type]
def to_hash
self.new_record? ? {} : {self.action => self.granted}
end
end

View file

@ -0,0 +1,51 @@
require File.dirname(__FILE__) + '/../spec_helper'
describe <%= class_name %>, "to_hash" do
before(:each) do
@permission = <%= class_name %>.new(:permissible_id => 1, :permissible_type => "User", :action => "some_action", :granted => 1)
end
it "to_hash returns {} if new record" do
@permission.to_hash.should == {}
end
it "to_hash returns {action => granted}" do
@permission.save
@permission.to_hash.should == {"some_action" => true}
end
end
describe <%= class_name %>, "validations" do
before(:each) do
@permission = <%= class_name %>.new(:permissible_id => 1, :permissible_type => "User", :action => "some_action", :granted => 1)
end
it "should be valid" do
@permission.should be_valid
end
it "action should be unique to a permissible id and type" do
@permission.save
@permission2 = <%= class_name %>.new(:permissible_id => 1, :permissible_type => "User", :action => "some_action", :granted => 0)
@permission2.should_not be_valid
end
it "must have a permissible_id" do
@permission.permissible_id = nil
@permission.should_not be_valid
end
it "must have a permissible_type" do
@permission.permissible_type = nil
@permission.should_not be_valid
end
it "must have an action" do
@permission.action = nil
@permission.should_not be_valid
@permission.action = ""
@permission.should_not be_valid
end
end

View file

@ -0,0 +1,15 @@
class <%= migration_name %> < ActiveRecord::Migration
def self.up
create_table :<%= role_membership_model_file_name %>s do |t|
t.integer :roleable_id
t.string :roleable_type
t.integer :<%= role_model_file_name %>_id
<% unless options[:skip_timestamps] %>t.timestamps<% end %>
end
end
def self.down
drop_table :<%= role_membership_model_file_name %>s
end
end

View file

@ -0,0 +1,36 @@
class <%= role_membership_model_name %> < ActiveRecord::Base
#belongs_to :user
belongs_to :<%= role_model_file_name %>
belongs_to :roleable, :polymorphic => true
validates_presence_of :roleable_id, :roleable_type, :<%= role_model_file_name %>_id
validates_uniqueness_of :<%= role_model_file_name %>_id, :scope => [:roleable_id, :roleable_type]
validates_numericality_of :roleable_id, :<%= role_model_file_name %>_id
validates_format_of :roleable_type, :with => /^[A-Z]{1}[a-z0-9]+([A-Z]{1}[a-z0-9]+)*$/
validate :<%= role_model_file_name %>_does_not_belong_to_itself_in_a_loop
protected
def <%= role_model_file_name %>_does_not_belong_to_itself_in_a_loop
if roleable_type == "<%= role_model_name %>"
if <%= role_model_file_name %>_id == roleable_id
errors.add_to_base("A <%= role_model_file_name %> cannot belong to itself.")
else
if belongs_to_itself_through_other?(roleable_id, <%= role_model_file_name %>_id)
errors.add_to_base("A <%= role_model_file_name %> cannot belong to a <%= role_model_file_name %> which belongs to it.")
end
end
end
end
def belongs_to_itself_through_other?(original_roleable_id, current_<%= role_model_file_name %>_id)
if self.class.find(:first, :select => "id", :conditions => ["roleable_id=? AND roleable_type='<%= role_model_name %>' AND <%= role_model_file_name %>_id=?",current_<%= role_model_file_name %>_id,original_roleable_id])
return true
else
memberships = self.class.find(:all, :select => "<%= role_model_file_name %>_id", :conditions => ["roleable_id=? AND roleable_type='<%= role_model_name %>'",current_<%= role_model_file_name %>_id])
if memberships.any? {|membership| belongs_to_itself_through_other?(original_roleable_id,membership.<%= role_model_file_name %>_id)}
return true
end
end
return false
end
end

View file

@ -0,0 +1,25 @@
publishers_to_customers:
id: 1
roleable_id: 1
roleable_type: "<%= role_model_name %>"
<%= role_model_file_name %>_id: 3
advertisers_to_customers:
id: 2
roleable_id: 2
roleable_type: "<%= role_model_name %>"
<%= role_model_file_name %>_id: 3
admins_to_company:
id: 3
roleable_id: 5
roleable_type: "<%= role_model_name %>"
<%= role_model_file_name %>_id: 4
company_to_admins:
id: 4
roleable_id: 4
roleable_type: "<%= role_model_name %>"
<%= role_model_file_name %>_id: 5
publishers_to_company:
id: 5
roleable_id: 1
roleable_type: "<%= role_model_name %>"
<%= role_model_file_name %>_id: 4

View file

@ -0,0 +1,100 @@
require File.dirname(__FILE__) + '/../spec_helper'
describe "<%= role_membership_model_name %>" do
describe "validations" do
before(:all) do
@<%= role_model_file_name.pluralize %> = []
@<%= role_model_file_name.pluralize %>[0] = <%= role_model_name %>.new(:name => "<%= role_model_file_name %>0")
@<%= role_model_file_name.pluralize %>[1] = <%= role_model_name %>.new(:name => "<%= role_model_file_name %>1")
@<%= role_model_file_name.pluralize %>[2] = <%= role_model_name %>.new(:name => "<%= role_model_file_name %>2")
@<%= role_model_file_name.pluralize %>[3] = <%= role_model_name %>.new(:name => "<%= role_model_file_name %>3")
@<%= role_model_file_name.pluralize %>[4] = <%= role_model_name %>.new(:name => "<%= role_model_file_name %>4")
@<%= role_model_file_name.pluralize %>[5] = <%= role_model_name %>.new(:name => "<%= role_model_file_name %>5")
@<%= role_model_file_name.pluralize %>[6] = <%= role_model_name %>.new(:name => "<%= role_model_file_name %>6")
@<%= role_model_file_name.pluralize %>[7] = <%= role_model_name %>.new(:name => "<%= role_model_file_name %>7")
@<%= role_model_file_name.pluralize %>[8] = <%= role_model_name %>.new(:name => "<%= role_model_file_name %>8")
@<%= role_model_file_name.pluralize %>[9] = <%= role_model_name %>.new(:name => "<%= role_model_file_name %>9")
@<%= role_model_file_name.pluralize %>[10] = <%= role_model_name %>.new(:name => "<%= role_model_file_name %>10")
@<%= role_model_file_name.pluralize %>[11] = <%= role_model_name %>.new(:name => "<%= role_model_file_name %>11")
@<%= role_model_file_name.pluralize %>.each {|<%= role_model_file_name %>| <%= role_model_file_name %>.save!}
end
before(:each) do
@membership = <%= role_membership_model_name %>.new(:roleable_id => @<%= role_model_file_name.pluralize %>[0].id, :roleable_type => "<%= role_model_name %>", :<%= role_model_file_name %>_id => @<%= role_model_file_name.pluralize %>[1].id)
end
it "should be valid" do
@membership.should be_valid
end
# roleable_id
it "should have a roleable_id" do
@membership.roleable_id = nil
@membership.should_not be_valid
end
it "roleable_id should be an integer" do
@membership.roleable_id = "asd"
@membership.should_not be_valid
end
# roleable_type
it "should have a roleable_type" do
@membership.roleable_type = nil
@membership.should_not be_valid
end
it "roleable_type should be a string" do
@membership.roleable_type = 123
@membership.should_not be_valid
end
it "roleable_type should have a class name format" do
@membership.roleable_type = "asd"
@membership.should_not be_valid
@membership.roleable_type = "User"
@membership.should be_valid
@membership.roleable_type = "Some95WierdClassN4m3"
@membership.should be_valid
end
# <%= role_model_file_name %>_id
it "should have a <%= role_model_file_name %>_id" do
@membership.<%= role_model_file_name %>_id = nil
@membership.should_not be_valid
end
it "<%= role_model_file_name %>_id should be an integer" do
@membership.<%= role_model_file_name %>_id = "asd"
@membership.should_not be_valid
end
it "should not allow a <%= role_model_file_name %> to belong to itself" do
@membership.<%= role_model_file_name %>_id = @<%= role_model_file_name.pluralize %>[0].id
@membership.should_not be_valid
end
# <%= role_model_file_name.pluralize %> cannot belong to each other in a loop
it "should not a allow a <%= role_model_file_name %> to belong to a <%= role_model_file_name %> which belongs to it in a loop" do
@<%= role_model_file_name.pluralize %>[0].<%= role_model_file_name.pluralize %> << @<%= role_model_file_name.pluralize %>[1]
@<%= role_model_file_name.pluralize %>[1].<%= role_model_file_name.pluralize %> << @<%= role_model_file_name.pluralize %>[2]
@<%= role_model_file_name.pluralize %>[2].<%= role_model_file_name.pluralize %> << @<%= role_model_file_name.pluralize %>[3]
@<%= role_model_file_name.pluralize %>[2].<%= role_model_file_name.pluralize %> << @<%= role_model_file_name.pluralize %>[4]
@<%= role_model_file_name.pluralize %>[2].<%= role_model_file_name.pluralize %> << @<%= role_model_file_name.pluralize %>[5]
@<%= role_model_file_name.pluralize %>[3].<%= role_model_file_name.pluralize %> << @<%= role_model_file_name.pluralize %>[6]
@<%= role_model_file_name.pluralize %>[1].<%= role_model_file_name.pluralize %> << @<%= role_model_file_name.pluralize %>[7]
@<%= role_model_file_name.pluralize %>[3].<%= role_model_file_name.pluralize %> << @<%= role_model_file_name.pluralize %>[8]
@<%= role_model_file_name.pluralize %>[4].<%= role_model_file_name.pluralize %> << @<%= role_model_file_name.pluralize %>[9]
@<%= role_model_file_name.pluralize %>[4].<%= role_model_file_name.pluralize %> << @<%= role_model_file_name.pluralize %>[10]
@<%= role_model_file_name.pluralize %>[5].<%= role_model_file_name.pluralize %> << @<%= role_model_file_name.pluralize %>[11]
@membership3 = <%= role_membership_model_name %>.new(:roleable_id => @<%= role_model_file_name.pluralize %>[11].id, :roleable_type => "<%= role_model_name %>", :<%= role_model_file_name %>_id => @<%= role_model_file_name.pluralize %>[0].id)
@membership3.should_not be_valid
@membership3.errors.full_messages.should include("A <%= role_model_file_name %> cannot belong to a <%= role_model_file_name %> which belongs to it.")
end
after(:all) do
@<%= role_model_file_name.pluralize %>.each {|<%= role_model_file_name %>| <%= role_model_file_name %>.destroy}
end
end
end

View file

@ -0,0 +1,13 @@
class <%= migration_name %> < ActiveRecord::Migration
def self.up
create_table :<%= role_model_file_name %>s do |t|
t.string :name
<% unless options[:skip_timestamps] %>t.timestamps<% end %>
end
end
def self.down
drop_table :<%= role_model_file_name %>s
end
end

View file

@ -0,0 +1,12 @@
class <%= role_model_name %> < ActiveRecord::Base
has_many :<%= role_membership_model_file_name %>s, :as => :roleable, :dependent => :destroy
has_many :<%= role_model_file_name %>s, :through => :<%= role_membership_model_file_name %>s, :source => :<%= role_model_file_name %>
has_many :roleables, :class_name => "<%= role_membership_model_name %>", :foreign_key => "<%= role_model_file_name %>_id", :dependent => :destroy
has_many :sub<%= role_model_file_name %>s, :through => :roleables, :source => :roleable, :source_type => '<%= role_model_name %>'
#has_many :users, :through => :roleables, :source => :roleable, :source_type => 'User'
validates_uniqueness_of :name
acts_as_permissible
end

View file

@ -0,0 +1,15 @@
publishers:
id: 1
name: "Publishers"
advertisers:
id: 2
name: "Advertisers"
customers:
id: 3
name: "Customers"
company:
id: 4
name: "Company"
admins:
id: 5
name: "Admins"

View file

@ -0,0 +1,53 @@
require File.dirname(__FILE__) + '/../spec_helper'
describe "<%= role_model_name %>" do
describe "validations" do
before(:each) do
@<%= role_model_file_name %> = <%= role_model_name %>.new(:name => "Hunters")
end
it "should be valid" do
@<%= role_model_file_name %>.should be_valid
end
it "should have a unique name" do
@<%= role_model_file_name %>.save
@<%= role_model_file_name %>2 = <%= role_model_name %>.new(:name => "Hunters")
@<%= role_model_file_name %>2.should_not be_valid
end
end
describe "associations" do
fixtures :<%= role_model_file_name %>s, :<%= role_membership_model_file_name %>s
it "should get subgroups correctly" do
<%= role_model_file_name %>s(:company).sub<%= role_model_file_name %>s.size.should == 2
arr = []
arr << <%= role_model_file_name %>s(:publishers)
arr << <%= role_model_file_name %>s(:admins)
<%= role_model_file_name %>s(:company).sub<%= role_model_file_name %>s.should include(arr.first)
<%= role_model_file_name %>s(:company).sub<%= role_model_file_name %>s.should include(arr.last)
<%= role_model_file_name %>s(:customers).sub<%= role_model_file_name %>s.size.should == 2
arr = []
arr << <%= role_model_file_name %>s(:publishers)
arr << <%= role_model_file_name %>s(:advertisers)
<%= role_model_file_name %>s(:customers).sub<%= role_model_file_name %>s.should include(arr.first)
<%= role_model_file_name %>s(:customers).sub<%= role_model_file_name %>s.should include(arr.last)
end
it "should get <%= role_model_file_name %>s correctly" do
<%= role_model_file_name %>s(:publishers).<%= role_model_file_name %>s.size.should == 2
arr = []
arr << <%= role_model_file_name %>s(:customers)
arr << <%= role_model_file_name %>s(:company)
<%= role_model_file_name %>s(:publishers).<%= role_model_file_name %>s.should == arr
<%= role_model_file_name %>s(:admins).<%= role_model_file_name %>s.size.should == 1
arr = []
arr << <%= role_model_file_name %>s(:company)
<%= role_model_file_name %>s(:admins).<%= role_model_file_name %>s.should == arr
end
end
end

View file

@ -0,0 +1,7 @@
# Include hook code here
begin
require "#{RAILS_ROOT}/lib/acts_as_permissible"
ActiveRecord::Base.send(:include, NoamBenAri::Acts::Permissible)
rescue MissingSourceFile => m
end

View file

@ -0,0 +1 @@
puts IO.read(File.join(File.dirname(__FILE__), 'README'))

View file

View file

@ -0,0 +1,4 @@
# desc "Explaining what the task does"
# task :acts_as_permissible do
# # Task goes here
# end

View file

@ -0,0 +1,8 @@
require 'test/unit'
class ActsAsPermissibleTest < Test::Unit::TestCase
# Replace this with your real tests.
def test_this_plugin
flunk
end
end

View file

@ -0,0 +1 @@
# Uninstall hook code here