rapid 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +66 -0
- data/lib/rad/http_controller/acts_as/authenticated.rb +131 -0
- data/lib/rad/http_controller/acts_as/authenticated_master_domain.rb +119 -0
- data/lib/rad/http_controller/acts_as/authorized.rb +83 -0
- data/lib/rad/http_controller/acts_as/localized.rb +27 -0
- data/lib/rad/http_controller/acts_as/multitenant.rb +53 -0
- data/lib/rad/http_controller/helpers/service_mix_helper.rb +50 -0
- data/lib/rad/http_controller.rb +15 -0
- data/lib/rad/lib/text_utils.rb +334 -0
- data/lib/rad/locales/en.yml +80 -0
- data/lib/rad/locales/ru.yml +83 -0
- data/lib/rad/locales.rb +2 -0
- data/lib/rad/models/account.rb +88 -0
- data/lib/rad/models/default_permissions.yml +26 -0
- data/lib/rad/models/micelaneous.rb +1 -0
- data/lib/rad/models/role.rb +88 -0
- data/lib/rad/models/secure_token.rb +33 -0
- data/lib/rad/models/space.rb +184 -0
- data/lib/rad/models/user.rb +158 -0
- data/lib/rad/models.rb +41 -0
- data/lib/rad/mongo_mapper/acts_as/authenticated_by_open_id.rb +29 -0
- data/lib/rad/mongo_mapper/acts_as/authenticated_by_password.rb +120 -0
- data/lib/rad/mongo_mapper/acts_as/authorized.rb +197 -0
- data/lib/rad/mongo_mapper/acts_as/authorized_object.rb +171 -0
- data/lib/rad/mongo_mapper/multitenant.rb +34 -0
- data/lib/rad/mongo_mapper/rad_micelaneous.rb +43 -0
- data/lib/rad/mongo_mapper/space_keys.rb +62 -0
- data/lib/rad/mongo_mapper/text_processor.rb +47 -0
- data/lib/rad/mongo_mapper.rb +20 -0
- data/lib/rad/paperclip/callbacks.rb +40 -0
- data/lib/rad/paperclip/extensions.rb +64 -0
- data/lib/rad/paperclip/integration.rb +165 -0
- data/lib/rad/paperclip/mime.rb +5 -0
- data/lib/rad/paperclip/validations.rb +64 -0
- data/lib/rad/paperclip.rb +11 -0
- data/lib/rad/spec/controller.rb +51 -0
- data/lib/rad/spec/model/factories.rb +65 -0
- data/lib/rad/spec/model.rb +85 -0
- data/lib/rad/spec/rem_helper.rb +145 -0
- data/lib/rad/spec.rb +4 -0
- data/lib/rad/tasks/backup.rake +64 -0
- data/lib/rad/tasks/initialize.rake +35 -0
- data/lib/rad.rb +32 -0
- data/readme.md +3 -0
- data/spec/controller/authorization_spec.rb +146 -0
- data/spec/controller/helper.rb +14 -0
- data/spec/lib/helper.rb +7 -0
- data/spec/lib/text_utils_spec.rb +238 -0
- data/spec/models/authorization_spec.rb +93 -0
- data/spec/models/authorized_object_spec.rb +258 -0
- data/spec/models/file_audit_spec/100.txt +1 -0
- data/spec/models/file_audit_spec/302.txt +3 -0
- data/spec/models/file_audit_spec.rb +168 -0
- data/spec/models/helper.rb +11 -0
- data/spec/models/space_key_spec.rb +68 -0
- data/spec/models/user_spec.rb +80 -0
- data/spec/mongo_mapper/basic_spec.rb +41 -0
- data/spec/mongo_mapper/helper.rb +10 -0
- data/spec/spec.opts +4 -0
- metadata +138 -0
data/lib/rad.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# crystal
|
2
|
+
require 'crystal_ext/profiles/web_ext'
|
3
|
+
|
4
|
+
# crystal plugins
|
5
|
+
require 'crystal_jquery'
|
6
|
+
require 'common_interface'
|
7
|
+
|
8
|
+
# gems
|
9
|
+
%w(
|
10
|
+
mongo_mapper
|
11
|
+
nokogiri
|
12
|
+
bluecloth
|
13
|
+
sanitize
|
14
|
+
state_machine
|
15
|
+
rack
|
16
|
+
).each{|n| gem n}
|
17
|
+
# paperclip
|
18
|
+
|
19
|
+
#
|
20
|
+
# rad
|
21
|
+
#
|
22
|
+
|
23
|
+
# lib
|
24
|
+
module Rad
|
25
|
+
autoload :TextUtils, 'rad/lib/text_utils'
|
26
|
+
end
|
27
|
+
|
28
|
+
require 'rad/locales'
|
29
|
+
crystal.after :environment do
|
30
|
+
require 'rad/models'
|
31
|
+
end
|
32
|
+
require 'rad/http_controller'
|
data/readme.md
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
require "#{File.expand_path(File.dirname(__FILE__))}/helper"
|
2
|
+
|
3
|
+
describe "Authorizations" do
|
4
|
+
with_environment
|
5
|
+
with_http
|
6
|
+
with_rad_model
|
7
|
+
|
8
|
+
before :all do
|
9
|
+
load 'crystal_ext/profiles/web_ext.rb'
|
10
|
+
|
11
|
+
permissions = {
|
12
|
+
'call_controller_level' => [],
|
13
|
+
'call_business_logic_level' => [],
|
14
|
+
'call_with_owner' => []
|
15
|
+
}
|
16
|
+
Space.stub!(:permissions).and_return(permissions)
|
17
|
+
|
18
|
+
class ::AuthorizationController
|
19
|
+
inherit Crystal::HttpController
|
20
|
+
|
21
|
+
acts_as_authorized
|
22
|
+
|
23
|
+
require_permission :call_controller_level, :only => :controller_level
|
24
|
+
|
25
|
+
def unprotected
|
26
|
+
render_ok
|
27
|
+
end
|
28
|
+
|
29
|
+
def controller_level
|
30
|
+
render_ok
|
31
|
+
end
|
32
|
+
|
33
|
+
def business_logic_level
|
34
|
+
require_permission :call_business_logic_level
|
35
|
+
render_ok
|
36
|
+
end
|
37
|
+
|
38
|
+
def with_owner
|
39
|
+
require_permission :call_with_owner, owned_object
|
40
|
+
render_ok
|
41
|
+
end
|
42
|
+
|
43
|
+
def with_owner_controller_level
|
44
|
+
render_ok
|
45
|
+
end
|
46
|
+
require_permission :call_with_owner, :only => :with_owner_controller_level do
|
47
|
+
owned_object
|
48
|
+
end
|
49
|
+
|
50
|
+
protected
|
51
|
+
def owned_object
|
52
|
+
@@owned_object
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.owned_object= o
|
56
|
+
@@owned_object = o
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
I18n.locale = :en
|
61
|
+
end
|
62
|
+
|
63
|
+
after :all do
|
64
|
+
remove_constants %w(AuthorizationController)
|
65
|
+
end
|
66
|
+
|
67
|
+
before :each do
|
68
|
+
AuthorizationController.owned_object = nil
|
69
|
+
|
70
|
+
@user = User.new
|
71
|
+
User.stub!(:current).and_return(@user)
|
72
|
+
end
|
73
|
+
|
74
|
+
def raise_authorization_error
|
75
|
+
raise_error(UserError, /Access Denied/)
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should allow to call unprotected methods" do
|
79
|
+
wcall('/authorization_controller/unprotected')
|
80
|
+
response.body.should == "ok"
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should allow declarative authorization at controller level" do
|
84
|
+
@user.stub!(:can?).and_return(false)
|
85
|
+
lambda{
|
86
|
+
wcall '/authorization_controller/controller_level'
|
87
|
+
}.should raise_authorization_error
|
88
|
+
# response.should be_redirect
|
89
|
+
|
90
|
+
@user.stub!(:can?).and_return(true)
|
91
|
+
wcall '/authorization_controller/controller_level'
|
92
|
+
response.body.should == "ok"
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should allow declarative authorization at business logic level" do
|
96
|
+
@user.stub!(:can?).and_return(false)
|
97
|
+
lambda{
|
98
|
+
wcall '/authorization_controller/business_logic_level'
|
99
|
+
}.should raise_authorization_error
|
100
|
+
# response.should be_redirect
|
101
|
+
|
102
|
+
@user.stub!(:can?).and_return(true)
|
103
|
+
wcall '/authorization_controller/business_logic_level'
|
104
|
+
response.body.should == "ok"
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should use owner if provided" do
|
108
|
+
@user.stub!(:can?){false}
|
109
|
+
lambda{
|
110
|
+
wcall '/authorization_controller/with_owner'
|
111
|
+
}.should raise_authorization_error
|
112
|
+
# response.should be_redirect
|
113
|
+
|
114
|
+
|
115
|
+
o = Object.new
|
116
|
+
o.stub!(:owner_name){@user.name}
|
117
|
+
AuthorizationController.owned_object = o
|
118
|
+
|
119
|
+
@user.stub!(:can?) do |operation, object|
|
120
|
+
object and object.owner_name == @user.name
|
121
|
+
end
|
122
|
+
|
123
|
+
wcall '/authorization_controller/with_owner'
|
124
|
+
response.body.should == "ok"
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should use owner if provided (action level)" do
|
128
|
+
@user.stub!(:can?){false}
|
129
|
+
lambda{
|
130
|
+
wcall '/authorization_controller/with_owner_controller_level'
|
131
|
+
}.should raise_authorization_error
|
132
|
+
# response.should be_redirect
|
133
|
+
|
134
|
+
|
135
|
+
o = Object.new
|
136
|
+
o.stub!(:owner_name){@user.name}
|
137
|
+
AuthorizationController.owned_object = o
|
138
|
+
|
139
|
+
@user.stub!(:can?) do |operation, object|
|
140
|
+
object and object.owner_name == @user.name
|
141
|
+
end
|
142
|
+
|
143
|
+
wcall '/authorization_controller/with_owner_controller_level'
|
144
|
+
response.body.should == "ok"
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
dir = File.expand_path(File.dirname(__FILE__))
|
2
|
+
lib_dir = File.expand_path("#{dir}/../../../lib")
|
3
|
+
$LOAD_PATH << lib_dir unless $LOAD_PATH.include? lib_dir
|
4
|
+
|
5
|
+
require 'crystal_ext/profiles/web_ext_require'
|
6
|
+
|
7
|
+
|
8
|
+
require 'mongo_mapper'
|
9
|
+
require 'mongo_mapper_ext'
|
10
|
+
require 'rad/http_controller'
|
11
|
+
|
12
|
+
|
13
|
+
require 'crystal/spec'
|
14
|
+
require 'rad/spec'
|
data/spec/lib/helper.rb
ADDED
@@ -0,0 +1,238 @@
|
|
1
|
+
require "#{File.expand_path(File.dirname(__FILE__))}/helper"
|
2
|
+
|
3
|
+
require 'rad/lib/text_utils.rb'
|
4
|
+
|
5
|
+
describe "TextUtils" do
|
6
|
+
def to_doc markup
|
7
|
+
Nokogiri::HTML(to_html(markup))
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_html markup
|
11
|
+
TextUtils.markup(markup)
|
12
|
+
end
|
13
|
+
|
14
|
+
::Nokogiri::XML::Node.class_eval do
|
15
|
+
def should_be_equal_to attributes
|
16
|
+
attributes.stringify_keys!
|
17
|
+
self.content.should == content if content = attributes.delete('content')
|
18
|
+
|
19
|
+
attributes.each do |attr_name, value|
|
20
|
+
self[attr_name].to_s.should == value.to_s
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "MarkdDown" do
|
26
|
+
it "should do basic markup" do
|
27
|
+
doc = to_doc "**text**"
|
28
|
+
doc.css("p b, p strong").first.should_be_equal_to :content => 'text'
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should guess urls" do
|
32
|
+
doc = to_doc "This is a http://www.some.com/some link"
|
33
|
+
doc.content.strip.should == "This is a http://www.some.com/some link"
|
34
|
+
doc.css("p a").first.should_be_equal_to :href => "http://www.some.com/some"
|
35
|
+
|
36
|
+
# from error
|
37
|
+
doc = to_doc "http://www.some.com/some"
|
38
|
+
doc.content.strip.should == "http://www.some.com/some"
|
39
|
+
doc.css("p a").first.should_be_equal_to :href => "http://www.some.com/some"
|
40
|
+
|
41
|
+
# from error
|
42
|
+
# http://mastertalk.ru/topic111478.html
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should allow 'a' elements" do
|
46
|
+
html = <<HTML
|
47
|
+
<a href="http://www.some.com/some">Absolute Link</a>
|
48
|
+
<a href="/some">Relative Link</a>
|
49
|
+
HTML
|
50
|
+
|
51
|
+
doc = to_doc html
|
52
|
+
doc.css("a").first[:href].should == "http://www.some.com/some"
|
53
|
+
doc.css("a").last[:href].should == "/some"
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should embed YouTube Videos" do
|
57
|
+
html =<<HTML
|
58
|
+
<object width="425" height="344">
|
59
|
+
<param name="movie" value="http://www.youtube.com/v/s8hYKKXV5wU&hl=en_US&fs=1&"></param>
|
60
|
+
<param name="allowFullScreen" value="true"></param>
|
61
|
+
<param name="allowscriptaccess" value="always"></param>
|
62
|
+
<embed src="http://www.youtube.com/v/s8hYKKXV5wU&hl=en_US&fs=1&" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed>
|
63
|
+
</object>
|
64
|
+
HTML
|
65
|
+
|
66
|
+
doc = to_doc html
|
67
|
+
obj = doc.css("object").first.should_be_equal_to :width => 425, :height => 344
|
68
|
+
p1, p2, p3, embed = doc.css("object *")
|
69
|
+
p1.should_be_equal_to :name => "movie", :value => "http://www.youtube.com/v/s8hYKKXV5wU&hl=en_US&fs=1&"
|
70
|
+
p2.should_be_equal_to :name => "allowFullScreen", :value => "true"
|
71
|
+
p3.should_be_equal_to :name => "allowscriptaccess", :value => "always"
|
72
|
+
embed.should_be_equal_to :src => "http://www.youtube.com/v/s8hYKKXV5wU&hl=en_US&fs=1&",
|
73
|
+
:type => "application/x-shockwave-flash", :allowscriptaccess => "always",
|
74
|
+
:allowfullscreen => "true", :width => "425", :height => "344"
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should skip empty paragraphs" do
|
78
|
+
html = "line 1\n\nline 2\n\n\n\nline 3"
|
79
|
+
to_html(html).should =~ /<p> line 1<\/p>\n<p>line 2<\/p>\n<p>line 3 <\/p>.?/
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should convert \n to <br/>" do
|
83
|
+
to_doc("foo\nbar").css('br').size.should == 1
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should not touch single underscores inside words" do
|
87
|
+
to_html("foo_bar").should include("foo_bar")
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should works with unicode" do
|
91
|
+
html = %{Юникод <a href="http://www.some.com/" class="_image_box">Юникод</a>}
|
92
|
+
doc = to_doc html
|
93
|
+
doc.css('p').first.content.should =~ /Юникод/
|
94
|
+
doc.css('p a').first.should_be_equal_to :href => "http://www.some.com/", :class => "_image_box", :content => "Юникод"
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'should allow class and rel attribute' do
|
98
|
+
html = %{<a href="http://www.some.com/" class="_image_box" rel="nofollow">Some</a>}
|
99
|
+
doc = to_doc html
|
100
|
+
doc.css('a').first.should_be_equal_to :href => "http://www.some.com/", :class => "_image_box", :rel => "nofollow"
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should allow image inside of link" do
|
104
|
+
html = <<HTML
|
105
|
+
<a rel="article_images" class="_image_box" href="/some_image">
|
106
|
+
<img src="/some_image"></img>
|
107
|
+
</a>
|
108
|
+
HTML
|
109
|
+
|
110
|
+
doc = to_doc html
|
111
|
+
doc.css('a').first.should_be_equal_to :href => "/some_image", :class => "_image_box"
|
112
|
+
doc.css('a img').first.should_be_equal_to :src => "/some_image"
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should use simplifyed syntax for image boxes (!![img_thumb] => [![img_thumb]][img_full_version])" do
|
116
|
+
html = <<HTML
|
117
|
+
!![img]
|
118
|
+
![img]
|
119
|
+
|
120
|
+
!![img_2]
|
121
|
+
![img_2]
|
122
|
+
|
123
|
+
[img]: /some_prefix/image_name.png
|
124
|
+
[img_2]: /some_prefix/image_name2.icon.png
|
125
|
+
HTML
|
126
|
+
|
127
|
+
doc = to_doc html
|
128
|
+
doc.css('a').first.should_be_equal_to :href => "/some_prefix/image_name.png"
|
129
|
+
doc.css('a img').first.should_be_equal_to :src => "/some_prefix/image_name.thumb.png"
|
130
|
+
|
131
|
+
doc.css('a').last.should_be_equal_to :href => "/some_prefix/image_name2.png"
|
132
|
+
doc.css('a img').last.should_be_equal_to :src => "/some_prefix/image_name2.icon.png"
|
133
|
+
|
134
|
+
doc.css('img').size.should == 4
|
135
|
+
end
|
136
|
+
|
137
|
+
it "simplifyed syntax for image boxes should be robust (from error)" do
|
138
|
+
html = "!![img] " # without resolved reference
|
139
|
+
to_html(html)
|
140
|
+
lambda{to_html(html)}.should_not raise_error
|
141
|
+
end
|
142
|
+
|
143
|
+
it "should create teaser from text" do
|
144
|
+
text = %{Hi there, I have a page that will list news articles}
|
145
|
+
TextUtils.truncate(text, 20).should == "Hi there, I have a ..."
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should create teaser from html" do
|
149
|
+
text = %{Hi <div><b>there</b>, I have a page that will list news articles</div>}
|
150
|
+
TextUtils.truncate(text, 20).should == "Hi there, I have a ..."
|
151
|
+
|
152
|
+
TextUtils.truncate(%{a<br/>b}, 20).should == "a b" # from error
|
153
|
+
end
|
154
|
+
|
155
|
+
it "embed metaweb.com wiget" do
|
156
|
+
html = <<HTML
|
157
|
+
<div itemtype="http://www.freebase.com/id/computer/software" itemid="http://www.freebase.com/id/en/google_web_toolkit" itemscope="" style="border: 0pt none; outline: 0pt none; padding: 0pt; margin: 0pt; position: relative;" id="fbtb-6ffc2545598340cbbc7945f43ebd45de" class="fb-widget">
|
158
|
+
<iframe frameborder="0" scrolling="no" src="http://www.freebase.com/widget/topic?track=topicblocks_homepage&mode=content&id=%2Fen%2Fgoogle_web_toolkit" style="height: 285px; width: 413px; border: 0pt none; outline: 0pt none; padding: 0pt; margin: 0pt;" classname="fb-widget-iframe" allowtransparency="true" class=" "></iframe>
|
159
|
+
<script defer="" type="text/javascript" src="http://freebaselibs.com/static/widgets/2/widget.js"></script>
|
160
|
+
</div>
|
161
|
+
HTML
|
162
|
+
|
163
|
+
text = "{metaweb:google_web_toolkit}"
|
164
|
+
to_html(text).should include(html)
|
165
|
+
end
|
166
|
+
|
167
|
+
it "should correctly insert newline (from error)" do
|
168
|
+
html = <<HTML
|
169
|
+
![img] Open Design.
|
170
|
+
http://oomps.com
|
171
|
+
|
172
|
+
[img]: /some_link
|
173
|
+
HTML
|
174
|
+
|
175
|
+
to_doc(html).css('br').size.should == 1
|
176
|
+
end
|
177
|
+
|
178
|
+
it "clear div" do
|
179
|
+
html = "[clear]"
|
180
|
+
|
181
|
+
doc = to_doc html
|
182
|
+
doc.css('div.clear').size.should == 1
|
183
|
+
end
|
184
|
+
|
185
|
+
it "space div" do
|
186
|
+
html = "[space]"
|
187
|
+
|
188
|
+
doc = to_doc html
|
189
|
+
doc.css('div.space').size.should == 1
|
190
|
+
end
|
191
|
+
|
192
|
+
it "should correctly guess links (from error)" do
|
193
|
+
to_doc("http://some_domain.com http://some_domain.com").css('a').size == 2
|
194
|
+
end
|
195
|
+
|
196
|
+
it "should leave existing links intact" do
|
197
|
+
doc = to_doc(%{<a href="http://some_domain.com">http://some_domain.com</a>})
|
198
|
+
doc.css('a').size.should == 1
|
199
|
+
doc.css('a').first['href'].should == "http://some_domain.com"
|
200
|
+
end
|
201
|
+
|
202
|
+
it "should leave existing links intact" do
|
203
|
+
md = %{\
|
204
|
+
[Download Page][dl]
|
205
|
+
[dl]: http://www.mozilla.org/products/firefox/}
|
206
|
+
|
207
|
+
to_doc(md).css('a').first['href'].should == 'http://www.mozilla.org/products/firefox/'
|
208
|
+
end
|
209
|
+
|
210
|
+
it "should allow div with any classes (from error)" do
|
211
|
+
html = %{<div class="col3 left"><a href='#'>text</a></div>}
|
212
|
+
to_doc(html).css("div.col3.left a").size.should == 1
|
213
|
+
end
|
214
|
+
|
215
|
+
it "should apply markup inside of html elements (from error)" do
|
216
|
+
html = <<HTML
|
217
|
+
<div class='right'>
|
218
|
+
![img]
|
219
|
+
</div>
|
220
|
+
|
221
|
+
[img]: /some_link
|
222
|
+
HTML
|
223
|
+
|
224
|
+
to_doc(html).css('.right img').size.should == 1
|
225
|
+
end
|
226
|
+
|
227
|
+
it "shouldn't create newline after > sign (from error)" do
|
228
|
+
html = %{\
|
229
|
+
<div>text</div>
|
230
|
+
text}
|
231
|
+
to_doc(html).css('br').size.should == 0
|
232
|
+
end
|
233
|
+
|
234
|
+
it "shouldn't add empty <p> before first line (from error)" do
|
235
|
+
to_html("<span>text</span>text").should_not =~ /<p>\s*<\/p>/
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require "#{File.expand_path(File.dirname(__FILE__))}/helper"
|
2
|
+
|
3
|
+
describe "Authorization" do
|
4
|
+
with_rad_model
|
5
|
+
|
6
|
+
before :each do
|
7
|
+
set_default_space
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "Roles" do
|
11
|
+
it "normalization" do
|
12
|
+
Role.normalize_roles(%w{manager member specific_role user:user1}).should == %w{member specific_role user:user1}
|
13
|
+
end
|
14
|
+
|
15
|
+
it "denormalization to higher roles" do
|
16
|
+
Role.denormalize_to_higher_roles(%w{member specific_role user:user1}).should == %w{manager member specific_role user:user1}
|
17
|
+
end
|
18
|
+
|
19
|
+
it "denormalization to lower roles" do
|
20
|
+
Role.denormalize_to_lower_roles(%w{member specific_role user:user1}).should == %w{member specific_role user user:user1}
|
21
|
+
end
|
22
|
+
|
23
|
+
it "user should have it's name in roles" do
|
24
|
+
user = Factory.build :user, :name => 'some_name'
|
25
|
+
user.roles.include?('user:some_name').should be_true
|
26
|
+
end
|
27
|
+
|
28
|
+
it ":anonymous, :registered, :user roles" do
|
29
|
+
anonymous = Factory.build :anonymous
|
30
|
+
anonymous.roles.should == %w{anonymous user user:anonymous}
|
31
|
+
|
32
|
+
user = Factory.build :user, :name => 'name'
|
33
|
+
user.roles.should == %w{registered user user:name}
|
34
|
+
|
35
|
+
admin = Factory.build :admin, :name => 'john'
|
36
|
+
admin.roles.should == %w{admin manager member registered user user:john}
|
37
|
+
end
|
38
|
+
|
39
|
+
it "all managers should also have the member role, always" do
|
40
|
+
user = Factory.build :manager, :name => 'john'
|
41
|
+
user.roles.should == %w{manager member registered user user:john}
|
42
|
+
end
|
43
|
+
|
44
|
+
it "handy methods" do
|
45
|
+
u = User.anonymous
|
46
|
+
u.roles.anonymous?.should be_true
|
47
|
+
u.roles.registered?.should be_false
|
48
|
+
u.roles.has?(:anonymous).should be_true
|
49
|
+
u.should have_role(:anonymous)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "add_role" do
|
53
|
+
u = Factory.create :member
|
54
|
+
u.should_not have_role('manager')
|
55
|
+
u.add_role :manager
|
56
|
+
u.save!
|
57
|
+
u.reload
|
58
|
+
u.should have_role('manager')
|
59
|
+
end
|
60
|
+
|
61
|
+
it "remove_role" do
|
62
|
+
u = Factory.create :manager
|
63
|
+
u.remove_role :member
|
64
|
+
u.save!
|
65
|
+
u.reload
|
66
|
+
u.should_not have_role('manger')
|
67
|
+
u.should_not have_role('member')
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should add also all lover roles" do
|
71
|
+
u = Factory.create :user
|
72
|
+
u.roles.should_not include('member')
|
73
|
+
u.add_role :manager
|
74
|
+
u.roles.should include('member')
|
75
|
+
end
|
76
|
+
|
77
|
+
it "special case, admin role" do
|
78
|
+
u = Factory.create :user
|
79
|
+
u.should_not have_role('manager')
|
80
|
+
u.add_role :admin
|
81
|
+
u.save!
|
82
|
+
u.reload
|
83
|
+
u.should have_role('admin')
|
84
|
+
u.should have_role('manager')
|
85
|
+
end
|
86
|
+
|
87
|
+
it "major_roles" do
|
88
|
+
u = Factory.create :member, :name => 'aname'
|
89
|
+
u.add_role :director
|
90
|
+
u.major_roles.should == %w{director member user:aname}
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|