rapid 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|