kibali 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/Gemfile +22 -0
- data/Gemfile.lock +110 -0
- data/LICENSE.txt +20 -0
- data/README.md +183 -0
- data/Rakefile +47 -0
- data/VERSION +1 -0
- data/lib/kibali/access_control.rb +89 -0
- data/lib/kibali/base.rb +79 -0
- data/lib/kibali/control.rb +39 -0
- data/lib/kibali/railtie.rb +17 -0
- data/lib/kibali/subject_extensions.rb +91 -0
- data/lib/kibali.rb +28 -0
- data/markdown.rb +38 -0
- data/test/app/controllers/application_controller.rb +21 -0
- data/test/app/controllers/empty_controller.rb +34 -0
- data/test/config/routes.rb +6 -0
- data/test/config.ru +0 -0
- data/test/ctlr_helper.rb +77 -0
- data/test/factories/units_factory.rb +39 -0
- data/test/helper.rb +61 -0
- data/test/script/rails +0 -0
- data/test/support/models.rb +8 -0
- data/test/support/schema.rb +25 -0
- data/test/test_access.rb +142 -0
- data/test/test_kibali.rb +140 -0
- metadata +140 -0
@@ -0,0 +1,91 @@
|
|
1
|
+
module Kibali
|
2
|
+
module SubjectExtensions
|
3
|
+
|
4
|
+
# #############################################################################
|
5
|
+
# #############################################################################
|
6
|
+
|
7
|
+
# ------------------------------------------------------------------------------
|
8
|
+
# has_role? -- returns true if subject has the given role
|
9
|
+
# ------------------------------------------------------------------------------
|
10
|
+
def has_role?(role_name)
|
11
|
+
!get_role( role_name ).nil?
|
12
|
+
end
|
13
|
+
|
14
|
+
# ------------------------------------------------------------------------------
|
15
|
+
# has_role! -- forces subject to have the given role
|
16
|
+
# ------------------------------------------------------------------------------
|
17
|
+
def has_role!(role_name)
|
18
|
+
role = _auth_role_class.where( :name => role_name.to_s ). # acts as the find part
|
19
|
+
first_or_create( :name => role_name.to_s ) # acts as the create part
|
20
|
+
role_objects << role unless self.role_objects.member?(role)
|
21
|
+
role
|
22
|
+
end
|
23
|
+
|
24
|
+
# ------------------------------------------------------------------------------
|
25
|
+
# remove_role! -- foreces subject to NOT have the given role
|
26
|
+
# ------------------------------------------------------------------------------
|
27
|
+
def remove_role!(role_name)
|
28
|
+
role_objects.delete( get_role( role_name ) )
|
29
|
+
end
|
30
|
+
|
31
|
+
# ------------------------------------------------------------------------------
|
32
|
+
# get_role -- returns a role obj for subject; else nil
|
33
|
+
# EXCEPTION: EmptyRolesException if role_objects collection is empty
|
34
|
+
# ------------------------------------------------------------------------------
|
35
|
+
def get_role( role_name=nil )
|
36
|
+
|
37
|
+
raise Kibali::EmptyRoles if role_objects.empty?
|
38
|
+
|
39
|
+
if role_name.nil?
|
40
|
+
role_objects.first
|
41
|
+
else
|
42
|
+
role_objects.where( :name => role_name.to_s ).first
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
# #############################################################################
|
49
|
+
private
|
50
|
+
# #############################################################################
|
51
|
+
|
52
|
+
|
53
|
+
# #############################################################################
|
54
|
+
protected
|
55
|
+
# #############################################################################
|
56
|
+
|
57
|
+
# ------------------------------------------------------------------------------
|
58
|
+
# _auth_role_class -- retuns the Klass for the Role model
|
59
|
+
# ------------------------------------------------------------------------------
|
60
|
+
def _auth_role_class
|
61
|
+
self.class._auth_role_class_name.constantize
|
62
|
+
end
|
63
|
+
|
64
|
+
# ------------------------------------------------------------------------------
|
65
|
+
# _auth_role_assoc -- returns the habtm symbol for the array of subject.roles
|
66
|
+
# ------------------------------------------------------------------------------
|
67
|
+
def _auth_role_assoc
|
68
|
+
self.class._auth_role_assoc_name
|
69
|
+
end
|
70
|
+
|
71
|
+
# ------------------------------------------------------------------------------
|
72
|
+
# role_objects -- returns the habtm array of roles for the subject
|
73
|
+
# ------------------------------------------------------------------------------
|
74
|
+
def role_objects
|
75
|
+
send(self._auth_role_assoc)
|
76
|
+
end
|
77
|
+
#
|
78
|
+
# ------------------------------------------------------------------------------
|
79
|
+
# ------------------------------------------------------------------------------
|
80
|
+
|
81
|
+
# ------------------------------------------------------------------------------
|
82
|
+
# ------------------------------------------------------------------------------
|
83
|
+
|
84
|
+
# ------------------------------------------------------------------------------
|
85
|
+
# ------------------------------------------------------------------------------
|
86
|
+
|
87
|
+
# #############################################################################
|
88
|
+
# #############################################################################
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
data/lib/kibali.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
|
2
|
+
require File.dirname(__FILE__) + '/kibali/base'
|
3
|
+
require File.dirname(__FILE__) + '/kibali/control'
|
4
|
+
require File.dirname(__FILE__) + '/kibali/subject_extensions'
|
5
|
+
require File.dirname(__FILE__) + '/kibali/access_control'
|
6
|
+
|
7
|
+
require File.dirname(__FILE__) + '/kibali/railtie' if defined?(Rails::Railtie)
|
8
|
+
|
9
|
+
module Kibali
|
10
|
+
@@config = {
|
11
|
+
:default_role_class_name => 'Role',
|
12
|
+
:default_subject_class_name => 'User',
|
13
|
+
:default_subject_method => :current_user,
|
14
|
+
:default_roles_collection_name => :roles,
|
15
|
+
:default_users_collection_name => :users,
|
16
|
+
:default_join_table_name => "roles_users"
|
17
|
+
}
|
18
|
+
|
19
|
+
mattr_reader :config
|
20
|
+
|
21
|
+
class AccessDenied < SecurityError; end
|
22
|
+
class EmptyRoles < RuntimeError; end
|
23
|
+
class SyntaxError < ArgumentError; end
|
24
|
+
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
|
data/markdown.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'redcarpet'
|
5
|
+
|
6
|
+
class ShowMd
|
7
|
+
|
8
|
+
TEMPFILE = "/tmp/markdown.html"
|
9
|
+
|
10
|
+
def initialize( file )
|
11
|
+
@body = IO.read( file )
|
12
|
+
end
|
13
|
+
|
14
|
+
def markdown
|
15
|
+
options = [ :autolink, :no_intraemphasis, :fenced_code, :gh_blockcode]
|
16
|
+
|
17
|
+
File.open( TEMPFILE, "w" ) do |file|
|
18
|
+
file.write( RedcarpetCompat.new( @body, *options).to_html )
|
19
|
+
end # do file
|
20
|
+
end
|
21
|
+
|
22
|
+
def show
|
23
|
+
system("google-chrome #{TEMPFILE} &")
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
end # class
|
28
|
+
|
29
|
+
md = ShowMd.new( ARGV[0] )
|
30
|
+
md.markdown
|
31
|
+
md.show
|
32
|
+
|
33
|
+
# puts RedcarpetCompat.new(ARGF.read,
|
34
|
+
# :fenced_code,
|
35
|
+
# :hard_wrap,
|
36
|
+
# :filter_html,
|
37
|
+
# :smart).to_html
|
38
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class ApplicationController < ActionController::Base
|
2
|
+
attr_accessor :my_current_user
|
3
|
+
|
4
|
+
# rescue_from Kibali::AccessDenied do |e|
|
5
|
+
# render :text => 'AccessDenied'
|
6
|
+
# end
|
7
|
+
|
8
|
+
#protected
|
9
|
+
|
10
|
+
def set_current_user
|
11
|
+
if params[:user]
|
12
|
+
self.my_current_user = User.find params[:user]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def current_user
|
17
|
+
self.my_current_user
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
end # class
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class EmptyController < ApplicationController
|
2
|
+
before_filter :set_current_user
|
3
|
+
# before_filter :trace_setup
|
4
|
+
|
5
|
+
control_hash = {
|
6
|
+
:admin1 => { } ,
|
7
|
+
:admin2 => { :allow => [] },
|
8
|
+
:manager1 => { :allow => [ :index, :edit ] },
|
9
|
+
:denier1 => { :deny => [ ] },
|
10
|
+
:denier2 => { :deny => [ :index, :edit ] },
|
11
|
+
:error1 => { :wild => [ :index ] },
|
12
|
+
:error2 => { 'allow' => [ :index ] },
|
13
|
+
:error3 => { :allow => [ :index, 'show' ] }
|
14
|
+
|
15
|
+
}
|
16
|
+
|
17
|
+
access_control control_hash
|
18
|
+
|
19
|
+
|
20
|
+
[:index, :show, :new, :edit, :update, :delete, :destroy].each do |act|
|
21
|
+
define_method(act) { render :text => 'OK' }
|
22
|
+
end
|
23
|
+
|
24
|
+
protected
|
25
|
+
|
26
|
+
def trace_setup
|
27
|
+
puts ">>>>>> trace/self: #{self.class.name} <<<<<<"
|
28
|
+
puts ">>>>>> trace/current_user: #{self.respond_to?(:current_user).to_s} <<<<<<"
|
29
|
+
puts ">>>>>> trace/method_defined: #{EmptyController.method_defined?(:current_user).to_s} <<<<<<"
|
30
|
+
puts ">>>>>> trace/user is: #{current_user.name.to_s} <<<<<<"
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
data/test/config.ru
ADDED
File without changes
|
data/test/ctlr_helper.rb
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
ENV["RAILS_ENV"] = "test"
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
|
6
|
+
begin
|
7
|
+
Bundler.setup(:default, :development, :test)
|
8
|
+
rescue Bundler::BundlerError => e
|
9
|
+
$stderr.puts e.message
|
10
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
11
|
+
exit e.status_code
|
12
|
+
end
|
13
|
+
|
14
|
+
require 'test/unit'
|
15
|
+
|
16
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
17
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
18
|
+
|
19
|
+
# require "rails_app/config/environment"
|
20
|
+
# require "rails/test_help"
|
21
|
+
|
22
|
+
require 'rails'
|
23
|
+
require 'active_support'
|
24
|
+
require 'active_record'
|
25
|
+
require 'action_controller'
|
26
|
+
require 'rails/test_help'
|
27
|
+
require 'shoulda'
|
28
|
+
require 'factory_girl'
|
29
|
+
|
30
|
+
require "action_controller/railtie"
|
31
|
+
require "rails/test_unit/railtie"
|
32
|
+
|
33
|
+
require 'kibali'
|
34
|
+
|
35
|
+
ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => 'test.sqlite3')
|
36
|
+
ActiveRecord::Base.send(:include, Kibali::Base)
|
37
|
+
|
38
|
+
require 'support/models'
|
39
|
+
load 'support/schema.rb'
|
40
|
+
|
41
|
+
#Logger = ActiveRecord::Base.logger
|
42
|
+
|
43
|
+
class Test::Unit::TestCase
|
44
|
+
|
45
|
+
FactoryGirl.find_definitions
|
46
|
+
include FactoryGirl::Syntax::Methods
|
47
|
+
include ActiveSupport::Testing::Assertions
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
root = File.expand_path(File.dirname(__FILE__))
|
52
|
+
|
53
|
+
# Define the application and configuration
|
54
|
+
module TestKibali
|
55
|
+
class Application < ::Rails::Application
|
56
|
+
# configuration here if needed
|
57
|
+
config.active_support.deprecation = :stderr
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Initialize the application
|
62
|
+
TestKibali::Application.initialize!
|
63
|
+
|
64
|
+
# ActionController::Routing::Routes.draw do |map|
|
65
|
+
# map.connect ":controller/:action/:id"
|
66
|
+
# end
|
67
|
+
|
68
|
+
ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
|
69
|
+
ActionController::Base.logger = ActiveRecord::Base.logger
|
70
|
+
ActiveRecord::Base.silence { ActiveRecord::Migration.verbose = false }
|
71
|
+
|
72
|
+
class ActiveSupport::TestCase
|
73
|
+
|
74
|
+
# Add more helper methods to be used by all tests here...
|
75
|
+
|
76
|
+
end
|
77
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'factory_girl'
|
2
|
+
|
3
|
+
FactoryGirl.define do |binding|
|
4
|
+
|
5
|
+
|
6
|
+
# #############################################################################
|
7
|
+
# ************* HELPER METHODS FOR THIS FACTORY *******************************
|
8
|
+
# #############################################################################
|
9
|
+
class << binding
|
10
|
+
|
11
|
+
USERNAMES = %w(demarcus deshaun jemell jermaine jabari kwashaun musa nigel kissamu yona brenden terell treven tyrese adonys)
|
12
|
+
|
13
|
+
# pick_name -- construct a unique user name based on sequence & world
|
14
|
+
def pick_name(n,w)
|
15
|
+
return USERNAMES[ (n % USERNAMES.size) ] + n.to_s + "_w#{w.to_s}"
|
16
|
+
end
|
17
|
+
|
18
|
+
end # anon class extensions
|
19
|
+
# #############################################################################
|
20
|
+
# #############################################################################
|
21
|
+
|
22
|
+
|
23
|
+
factory :user do |f|
|
24
|
+
f.sequence( :email ) { |n| "#{binding.pick_name(n,w)}@example.com" }
|
25
|
+
f.sequence( :name ) { |n| "#{binding.pick_name(n,w)}@example.com" }
|
26
|
+
end # user
|
27
|
+
|
28
|
+
factory :role do
|
29
|
+
name "lime_sublime"
|
30
|
+
end #
|
31
|
+
|
32
|
+
#
|
33
|
+
# factory :team_asset do |f|
|
34
|
+
# f.association :team
|
35
|
+
# f.association :author
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
|
39
|
+
end # FactoryGirl.define
|
data/test/helper.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
ENV["RAILS_ENV"] = "test"
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
|
6
|
+
begin
|
7
|
+
Bundler.setup(:default, :development, :test)
|
8
|
+
rescue Bundler::BundlerError => e
|
9
|
+
$stderr.puts e.message
|
10
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
11
|
+
exit e.status_code
|
12
|
+
end
|
13
|
+
|
14
|
+
require 'test/unit'
|
15
|
+
|
16
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
17
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
18
|
+
|
19
|
+
# require "rails_app/config/environment"
|
20
|
+
# require "rails/test_help"
|
21
|
+
|
22
|
+
require 'rails'
|
23
|
+
require 'active_support'
|
24
|
+
require 'active_record'
|
25
|
+
require 'action_controller'
|
26
|
+
require 'rails/test_help'
|
27
|
+
require 'shoulda'
|
28
|
+
require 'factory_girl'
|
29
|
+
require 'kibali'
|
30
|
+
|
31
|
+
ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => 'test.sqlite3')
|
32
|
+
ActiveRecord::Base.send(:include, Kibali::Base)
|
33
|
+
|
34
|
+
require 'support/models'
|
35
|
+
|
36
|
+
#Logger = ActiveRecord::Base.logger
|
37
|
+
load 'support/schema.rb'
|
38
|
+
|
39
|
+
class Test::Unit::TestCase
|
40
|
+
|
41
|
+
FactoryGirl.find_definitions
|
42
|
+
include FactoryGirl::Syntax::Methods
|
43
|
+
include ActiveSupport::Testing::Assertions
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
# ActionController::Routing::Routes.draw do |map|
|
49
|
+
# map.connect ":controller/:action/:id"
|
50
|
+
# end
|
51
|
+
|
52
|
+
ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
|
53
|
+
ActionController::Base.logger = ActiveRecord::Base.logger
|
54
|
+
ActiveRecord::Base.silence { ActiveRecord::Migration.verbose = false }
|
55
|
+
|
56
|
+
class ActiveSupport::TestCase
|
57
|
+
|
58
|
+
# Add more helper methods to be used by all tests here...
|
59
|
+
|
60
|
+
end
|
61
|
+
|
data/test/script/rails
ADDED
File without changes
|
@@ -0,0 +1,25 @@
|
|
1
|
+
ActiveRecord::Schema.define(:version => 0) do
|
2
|
+
|
3
|
+
create_table "roles", :force => true do |t|
|
4
|
+
t.string "name", :limit => 40
|
5
|
+
t.string "authorizable_type", :limit => 40
|
6
|
+
t.string "authorizable_id"
|
7
|
+
t.boolean "system", :default=>false
|
8
|
+
t.datetime "created_at"
|
9
|
+
t.datetime "updated_at"
|
10
|
+
end
|
11
|
+
|
12
|
+
create_table "users", :force => true do |t|
|
13
|
+
t.string "name", :limit => 40
|
14
|
+
t.string "email", :limit => 40
|
15
|
+
end
|
16
|
+
|
17
|
+
create_table "roles_users", :id => false, :force => true do |t|
|
18
|
+
t.integer "user_id"
|
19
|
+
t.integer "role_id"
|
20
|
+
t.datetime "created_at"
|
21
|
+
t.datetime "updated_at"
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
data/test/test_access.rb
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
require 'ctlr_helper'
|
2
|
+
|
3
|
+
require 'empty_controller'
|
4
|
+
|
5
|
+
class EmptyControllerTest < ActionController::TestCase
|
6
|
+
|
7
|
+
context "ctlr" do
|
8
|
+
|
9
|
+
setup do
|
10
|
+
@demarcus = FactoryGirl.create( :user )
|
11
|
+
@deshaun = FactoryGirl.create( :user )
|
12
|
+
end
|
13
|
+
|
14
|
+
teardown do
|
15
|
+
User.destroy_all
|
16
|
+
Role.destroy_all
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
should 'be true' do
|
21
|
+
assert true
|
22
|
+
end # should do
|
23
|
+
|
24
|
+
should 'permit admin1 access _ implicit all' do
|
25
|
+
@demarcus.has_role!( :admin1 )
|
26
|
+
|
27
|
+
get :index, :user => @demarcus.id.to_s
|
28
|
+
assert_response :success
|
29
|
+
|
30
|
+
get :show, :user => @demarcus.id.to_s
|
31
|
+
assert_response :success
|
32
|
+
|
33
|
+
end # should do
|
34
|
+
|
35
|
+
should 'permit admin2 access _ implicit all 2' do
|
36
|
+
@demarcus.has_role!( :admin2 )
|
37
|
+
|
38
|
+
get :index, :user => @demarcus.id.to_s
|
39
|
+
assert_response :success
|
40
|
+
|
41
|
+
get :show, :user => @demarcus.id.to_s
|
42
|
+
assert_response :success
|
43
|
+
|
44
|
+
end # should do
|
45
|
+
|
46
|
+
|
47
|
+
should 'permit manager1 only access to index, edit' do
|
48
|
+
@deshaun.has_role!( :manager1 )
|
49
|
+
|
50
|
+
get :index, :user => @deshaun.id.to_s
|
51
|
+
assert_response :success
|
52
|
+
get :edit, :user => @deshaun.id.to_s
|
53
|
+
assert_response :success
|
54
|
+
|
55
|
+
assert_raise( Kibali::AccessDenied ) do
|
56
|
+
get :show, :user => @deshaun.id.to_s
|
57
|
+
end # block
|
58
|
+
|
59
|
+
end # should do
|
60
|
+
|
61
|
+
|
62
|
+
should 'deny denier1 access to everything' do
|
63
|
+
@deshaun.has_role!( :denier1 )
|
64
|
+
|
65
|
+
assert_raise( Kibali::AccessDenied ) do
|
66
|
+
get :show, :user => @deshaun.id.to_s
|
67
|
+
end # block
|
68
|
+
|
69
|
+
assert_raise( Kibali::AccessDenied ) do
|
70
|
+
get :index, :user => @deshaun.id.to_s
|
71
|
+
end # block
|
72
|
+
|
73
|
+
assert_raise( Kibali::AccessDenied ) do
|
74
|
+
get :edit, :user => @deshaun.id.to_s
|
75
|
+
end # block
|
76
|
+
|
77
|
+
end # should do
|
78
|
+
|
79
|
+
|
80
|
+
should 'deny denier2 access to index edit' do
|
81
|
+
@deshaun.has_role!( :denier2 )
|
82
|
+
|
83
|
+
get :show, :user => @deshaun.id.to_s
|
84
|
+
assert_response :success
|
85
|
+
|
86
|
+
assert_raise( Kibali::AccessDenied ) do
|
87
|
+
get :index, :user => @deshaun.id.to_s
|
88
|
+
end # block
|
89
|
+
|
90
|
+
assert_raise( Kibali::AccessDenied ) do
|
91
|
+
get :edit, :user => @deshaun.id.to_s
|
92
|
+
end # block
|
93
|
+
|
94
|
+
end # should do
|
95
|
+
|
96
|
+
|
97
|
+
|
98
|
+
should 'deny others all access ' do
|
99
|
+
@deshaun.has_role!( :wildblue )
|
100
|
+
|
101
|
+
assert_raise( Kibali::AccessDenied ) do
|
102
|
+
get :index, :user => @deshaun.id.to_s
|
103
|
+
end # block
|
104
|
+
|
105
|
+
end # should do
|
106
|
+
|
107
|
+
|
108
|
+
should 'error unknown limit type ' do
|
109
|
+
@deshaun.has_role!( :error1 )
|
110
|
+
|
111
|
+
assert_raise( Kibali::SyntaxError ) do
|
112
|
+
get :index, :user => @deshaun.id.to_s
|
113
|
+
end # block
|
114
|
+
|
115
|
+
end # should do
|
116
|
+
|
117
|
+
|
118
|
+
should 'error unknown limit type non symbol' do
|
119
|
+
@deshaun.has_role!( :error2 )
|
120
|
+
|
121
|
+
assert_raise( Kibali::SyntaxError ) do
|
122
|
+
get :index, :user => @deshaun.id.to_s
|
123
|
+
end # block
|
124
|
+
|
125
|
+
end # should do
|
126
|
+
|
127
|
+
|
128
|
+
should 'error unknown action ' do
|
129
|
+
@deshaun.has_role!( :error3 )
|
130
|
+
|
131
|
+
assert_raise( Kibali::SyntaxError ) do
|
132
|
+
get :show, :user => @deshaun.id.to_s
|
133
|
+
end # block
|
134
|
+
|
135
|
+
end # should do
|
136
|
+
|
137
|
+
|
138
|
+
|
139
|
+
|
140
|
+
end # context
|
141
|
+
|
142
|
+
end # class test
|