rad_kit 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. data/Rakefile +11 -0
  2. data/lib/components/kit.rb +16 -0
  3. data/lib/components/kit.yml +3 -0
  4. data/lib/components/models.rb +7 -0
  5. data/lib/kit/factories.rb +9 -0
  6. data/lib/kit/gems.rb +16 -0
  7. data/lib/kit/http_controller.rb +4 -0
  8. data/lib/kit/http_controller/authorized.rb +51 -0
  9. data/lib/kit/http_controller/localized.rb +13 -0
  10. data/lib/kit/kit.rb +29 -0
  11. data/lib/kit/models.rb +8 -0
  12. data/lib/kit/models/attachment_uploader.rb +15 -0
  13. data/lib/kit/models/attachments_uploader_helper.rb +79 -0
  14. data/lib/kit/models/authorized.rb +188 -0
  15. data/lib/kit/models/authorized_object.rb +167 -0
  16. data/lib/kit/models/default_permissions.yml +29 -0
  17. data/lib/kit/models/file_uploader.rb +26 -0
  18. data/lib/kit/models/micelaneous.rb +1 -0
  19. data/lib/kit/models/role.rb +88 -0
  20. data/lib/kit/models_after.rb +27 -0
  21. data/lib/kit/mongoid.rb +22 -0
  22. data/lib/kit/mongoid/rad_micelaneous.rb +36 -0
  23. data/lib/kit/mongoid/text_processor.rb +44 -0
  24. data/lib/kit/spec.rb +77 -0
  25. data/lib/kit/spec/items_controller_crud.rb +64 -0
  26. data/lib/kit/support.rb +14 -0
  27. data/lib/kit/support/string.rb +6 -0
  28. data/lib/kit/tasks.rb +18 -0
  29. data/lib/kit/text_utils.rb +43 -0
  30. data/lib/kit/text_utils/code_highlighter.rb +58 -0
  31. data/lib/kit/text_utils/custom_markdown.rb +90 -0
  32. data/lib/kit/text_utils/ensure_utf.rb +8 -0
  33. data/lib/kit/text_utils/github_flavoured_markdown.rb +32 -0
  34. data/lib/kit/text_utils/html_sanitizer.rb +89 -0
  35. data/lib/kit/text_utils/image_box.rb +35 -0
  36. data/lib/kit/text_utils/markup.rb +43 -0
  37. data/lib/kit/text_utils/processor.rb +25 -0
  38. data/lib/kit/text_utils/tag_shortcuts.rb +14 -0
  39. data/lib/kit/text_utils/truncate.rb +29 -0
  40. data/lib/kit/text_utils/truncator.rb +15 -0
  41. data/lib/kit/text_utils/urls.rb +13 -0
  42. data/readme.md +10 -0
  43. data/spec/controller/authorization_spec.rb +149 -0
  44. data/spec/controller/comments_spec.rb +54 -0
  45. data/spec/controller/items_spec.rb +45 -0
  46. data/spec/models/attachments_spec.rb +24 -0
  47. data/spec/models/attachments_spec/a.txt +1 -0
  48. data/spec/models/attachments_uploader_helper_spec.rb +108 -0
  49. data/spec/models/attachments_uploader_helper_spec/v1/a.txt +1 -0
  50. data/spec/models/attachments_uploader_helper_spec/v1/b.txt +1 -0
  51. data/spec/models/attachments_uploader_helper_spec/v2/a.txt +1 -0
  52. data/spec/models/authorization_spec.rb +77 -0
  53. data/spec/models/authorized_object_spec.rb +254 -0
  54. data/spec/models/comments_spec.rb +1 -0
  55. data/spec/models/item_spec.rb +51 -0
  56. data/spec/models/role_spec.rb +17 -0
  57. data/spec/models/tags_spec.rb +44 -0
  58. data/spec/models/uploader_spec.rb +37 -0
  59. data/spec/models/uploader_spec//321/204/320/260/320/270/314/206/320/273 /321/201 /320/277/321/200/320/276/320/261/320/265/320/273/320/260/320/274/320/270.txt" +1 -0
  60. data/spec/mongoid/basic_spec.rb +36 -0
  61. data/spec/spec_helper.rb +20 -0
  62. data/spec/spec_helper/controller.rb +9 -0
  63. data/spec/spec_helper/factories.rb +24 -0
  64. data/spec/spec_helper/user.rb +17 -0
  65. data/spec/utils/text_utils_spec.rb +280 -0
  66. metadata +232 -0
@@ -0,0 +1,35 @@
1
+ class Rad::TextUtils::ImageBox < Rad::TextUtils::Processor
2
+ # !![img] => [![img_thumb]][img]
3
+ def process markdown, env
4
+ img_urls = {}
5
+ markdown = markdown.gsub(/!!\[(.+?)\]/) do
6
+ img_key = $1 || ''
7
+ if url = markdown.scan(/\[#{img_key}\]:\s*([^\s]+)$/).first.try(:first)
8
+ unless url =~ /\.[^\.]+\.[^\.]+$/ # image.png
9
+ thumb_img_key = "#{img_key}_thumb"
10
+
11
+ # building url with thumb (foo.png => foo.thumb.png)
12
+ img_urls[thumb_img_key] = url.sub(/\.([^\.]+)$/){".thumb.#{$1}"}
13
+
14
+ "[![][#{thumb_img_key}]][#{img_key}]"
15
+ else # image.(icon|thumb|...).png
16
+ img_key_full = "#{img_key}_full"
17
+
18
+ # building url with thumb (foo.png => foo.thumb.png)
19
+ img_urls[img_key_full] = url.sub(/\.([^\.]+)\.([^\.]+)$/){".#{$2}"}
20
+
21
+ "[![][#{img_key}]][#{img_key_full}]"
22
+ end
23
+ else
24
+ $& || ''
25
+ end
26
+ end
27
+
28
+ unless img_urls.blank?
29
+ markdown << "\n"
30
+ markdown << img_urls.to_a.collect{|k, v| "[#{k}]: #{v}"}.join("\n")
31
+ end
32
+
33
+ call_next markdown, env
34
+ end
35
+ end
@@ -0,0 +1,43 @@
1
+ class Rad::TextUtils::Markup < Rad::TextUtils::Processor
2
+
3
+ def initialize processor = nil
4
+ super
5
+
6
+ @markup = build_from(
7
+ Rad::TextUtils::EnsureUtf,
8
+ Rad::TextUtils::HtmlSanitizer,
9
+
10
+ Rad::TextUtils::CodeHighlighter,
11
+
12
+ Rad::TextUtils::CustomMarkdown,
13
+
14
+ Rad::TextUtils::Urls,
15
+ Rad::TextUtils::TagShortcuts
16
+ )
17
+
18
+ @html = build_from(
19
+ Rad::TextUtils::EnsureUtf,
20
+ Rad::TextUtils::HtmlSanitizer,
21
+ Rad::TextUtils::CodeHighlighter
22
+ )
23
+ end
24
+
25
+ def process text, env
26
+ return text if text.blank?
27
+
28
+ if text =~ /\A\[html\]/i
29
+ text = text.sub(/\A\[html\][\s\n\r]*/i, '')
30
+ chain = @html
31
+ else
32
+ chain = @markup
33
+ end
34
+
35
+ text = chain.process text, env
36
+
37
+ unless text.encoding == Encoding::UTF_8
38
+ raise "something wrong happens, invalid encoding (#{text.encoding} instead of utf-8)!"
39
+ end
40
+
41
+ call_next text, env
42
+ end
43
+ end
@@ -0,0 +1,25 @@
1
+ class Rad::TextUtils::Processor
2
+ def initialize next_processor = nil
3
+ @next_processor = next_processor
4
+ end
5
+
6
+ protected
7
+ def call_next data, env
8
+ if @next_processor
9
+ @next_processor.process data, env
10
+ else
11
+ data
12
+ end
13
+ end
14
+
15
+ def build_from *processors
16
+ processors.reverse.inject nil do |next_processor, meta|
17
+ klass, args = if meta.is_a? Array
18
+ [meta[0], meta[1..-1]]
19
+ else
20
+ [meta, []]
21
+ end
22
+ klass.new next_processor, *args
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,14 @@
1
+ class Rad::TextUtils::TagShortcuts < Rad::TextUtils::Processor
2
+ TAGS = {
3
+ /\[clear\]/ => lambda{|match| "<div class='clear'></div>"},
4
+ /\[space\]/ => lambda{|match| "<div class='space'></div>"}
5
+ }
6
+
7
+ def process markdown, env
8
+ TAGS.each do |k, v|
9
+ markdown.gsub!(k, &v)
10
+ end
11
+
12
+ call_next markdown, env
13
+ end
14
+ end
@@ -0,0 +1,29 @@
1
+ class Rad::TextUtils::Truncate < Rad::TextUtils::Processor
2
+ def initialize processor, length
3
+ super(processor)
4
+ @length = length
5
+ end
6
+
7
+ def process str_or_html, env
8
+ str_or_html ||= ""
9
+
10
+ # Strip from HTML tags
11
+ str_or_html = str_or_html.gsub("<br", " <br").gsub("<p", " <p") # to preserve space in place of <> html elements
12
+ doc = Nokogiri::XML("<div class='root'>#{str_or_html}</div>")
13
+ str = doc.css('.root').first.content
14
+
15
+ str = str.gsub(/\s+/, ' ')
16
+
17
+ # Truncate with no broken words
18
+ str = if str.length >= @length
19
+ shortened = str[0, @length]
20
+ splitted = shortened.split(/\s/)
21
+ words = splitted.length
22
+ splitted[0, words-1].join(" ") + ' ...'
23
+ else
24
+ str
25
+ end
26
+
27
+ call_next str, env
28
+ end
29
+ end
@@ -0,0 +1,15 @@
1
+ class Rad::TextUtils::Truncator < Rad::TextUtils::Processor
2
+ def initialize processor, length
3
+ super(processor)
4
+
5
+ @chain = build_from(
6
+ Rad::TextUtils::EnsureUtf,
7
+ [Rad::TextUtils::Truncate, length]
8
+ )
9
+ end
10
+
11
+ def process text_or_html, env
12
+ text_or_html = @chain.process text_or_html, env
13
+ call_next text_or_html, env
14
+ end
15
+ end
@@ -0,0 +1,13 @@
1
+ class Rad::TextUtils::Urls < Rad::TextUtils::Processor
2
+ # Creates <a> tags for all urls.
3
+ # IMPORTANT: make sure you've used #urls_to_images method first
4
+ # if you wanted all images urls to become <img> tags.
5
+ def process html, env
6
+ # becouse it finds only one url in such string "http://some_domain.com http://some_domain.com" we need to aply it twice
7
+ regexp, sub = /(\s|^|\A|\n|\t|\r)(http:\/\/.*?)([,.])?(\s|$|\n|\Z|\t|\r|<)/, '\1<a href="\2">\2</a>\3\4'
8
+ html = html.gsub regexp, sub
9
+ html.gsub regexp, sub
10
+
11
+ call_next html, env
12
+ end
13
+ end
data/readme.md ADDED
@@ -0,0 +1,10 @@
1
+ # Rapid Application Development Kit for Rad Framework
2
+
3
+ [add docs]
4
+
5
+ # Low
6
+
7
+ - WYSIWYG from WordPress/GitHub
8
+ - remove unused locale tokens
9
+
10
+ # TODO
@@ -0,0 +1,149 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Authorizations" do
4
+ with_controllers
5
+
6
+ isolate :config
7
+
8
+ before :all do
9
+ @permissions = {
10
+ 'call_controller_level' => [],
11
+ 'call_business_logic_level' => [],
12
+ 'call_with_owner' => []
13
+ }
14
+
15
+ class ::AuthorizationController
16
+ inherit Rad::Controller::Http
17
+
18
+ inherit Rad::Controller::Http::Authorized
19
+
20
+ require_permission :call_controller_level, only: :controller_level
21
+
22
+ def unprotected
23
+ render_ok
24
+ end
25
+
26
+ def controller_level
27
+ render_ok
28
+ end
29
+
30
+ def business_logic_level
31
+ require_permission :call_business_logic_level
32
+ render_ok
33
+ end
34
+
35
+ def with_owner
36
+ require_permission :call_with_owner, owned_object
37
+ render_ok
38
+ end
39
+
40
+ def with_owner_controller_level
41
+ render_ok
42
+ end
43
+ require_permission :call_with_owner, only: :with_owner_controller_level do
44
+ owned_object
45
+ end
46
+
47
+ protected
48
+ def owned_object
49
+ @@owned_object
50
+ end
51
+
52
+ def self.owned_object= o
53
+ @@owned_object = o
54
+ end
55
+ end
56
+
57
+ rad.router.configure do |c|
58
+ c.resource :authorization_controllers, class_name: 'AuthorizationController'
59
+ end
60
+
61
+ I18n.locale = :en
62
+ end
63
+
64
+ after :all do
65
+ remove_constants %w(AuthorizationController)
66
+ end
67
+
68
+ before do
69
+ AuthorizationController.owned_object = nil
70
+
71
+ rad.config.permissions = @permissions
72
+
73
+ @user = Models::User.new
74
+ rad.user = @user
75
+ end
76
+
77
+ def raise_authorization_error
78
+ raise_error(UserError, /Access Denied/)
79
+ end
80
+
81
+ it "should allow to call unprotected methods" do
82
+ call('/authorization_controllers/unprotected')
83
+ response.body.should == "ok"
84
+ end
85
+
86
+ it "should allow declarative authorization at controller level" do
87
+ @user.stub!(:can?).and_return(false)
88
+ lambda{
89
+ call '/authorization_controllers/controller_level'
90
+ }.should raise_authorization_error
91
+ # response.should be_redirect
92
+
93
+ @user.stub!(:can?).and_return(true)
94
+ call '/authorization_controllers/controller_level'
95
+ response.body.should == "ok"
96
+ end
97
+
98
+ it "should allow declarative authorization at business logic level" do
99
+ @user.stub!(:can?).and_return(false)
100
+ lambda{
101
+ call '/authorization_controllers/business_logic_level'
102
+ }.should raise_authorization_error
103
+ # response.should be_redirect
104
+
105
+ @user.stub!(:can?).and_return(true)
106
+ call '/authorization_controllers/business_logic_level'
107
+ response.body.should == "ok"
108
+ end
109
+
110
+ it "should use owner if provided" do
111
+ @user.stub!(:can?){false}
112
+ lambda{
113
+ call '/authorization_controllers/with_owner'
114
+ }.should raise_authorization_error
115
+ # response.should be_redirect
116
+
117
+
118
+ o = Object.new
119
+ o.stub!(:owner_name){@user.name}
120
+ AuthorizationController.owned_object = o
121
+
122
+ @user.stub!(:can?) do |operation, object|
123
+ object and object.owner_name == @user.name
124
+ end
125
+
126
+ call '/authorization_controllers/with_owner'
127
+ response.body.should == "ok"
128
+ end
129
+
130
+ it "should use owner if provided (action level)" do
131
+ @user.stub!(:can?){false}
132
+ lambda{
133
+ call '/authorization_controllers/with_owner_controller_level'
134
+ }.should raise_authorization_error
135
+ # response.should be_redirect
136
+
137
+
138
+ o = Object.new
139
+ o.stub!(:owner_name){@user.name}
140
+ AuthorizationController.owned_object = o
141
+
142
+ @user.stub!(:can?) do |operation, object|
143
+ object and object.owner_name == @user.name
144
+ end
145
+
146
+ call '/authorization_controllers/with_owner_controller_level'
147
+ response.body.should == "ok"
148
+ end
149
+ end
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Comments" do
4
+ with_controllers
5
+ set_controller Controllers::Comments
6
+ login_as :user
7
+
8
+ before do
9
+ @item = Factory.create :item
10
+ end
11
+
12
+ def create_comment original_text = 'text'
13
+ Factory.create :comment, item: @item, owner: @user
14
+ end
15
+
16
+ it "should display new dialog" do
17
+ call :new, format: 'js', item_id: @item.to_param
18
+ response.should be_ok
19
+ end
20
+
21
+ it "should create Comment" do
22
+ comment_attributes = Factory.attributes_for :comment
23
+ pcall :create, format: 'js', item_id: @item.to_param, model: comment_attributes
24
+ response.should be_ok
25
+
26
+ Models::Comment.count.should == 1
27
+ comment = Models::Comment.first
28
+ comment.original_text.should == comment_attributes[:original_text]
29
+ comment.owner.should == @user
30
+ comment.item.should == @item
31
+ end
32
+
33
+ it "should display edit dialog" do
34
+ comment = create_comment
35
+ call :edit, format: 'js', id: comment.to_param
36
+ response.should be_ok
37
+ end
38
+
39
+ it "should update Comment" do
40
+ comment = create_comment
41
+ new_attributes = {original_text: 'new text'}
42
+ pcall :update, format: 'js', id: comment.to_param, model: new_attributes
43
+ response.should be_ok
44
+
45
+ comment.reload
46
+ comment.original_text.should == 'new text'
47
+ end
48
+
49
+ it "should delete Comment" do
50
+ comment = create_comment
51
+ pcall :destroy, format: 'js', id: comment.to_param
52
+ Models::Comment.count.should == 0
53
+ end
54
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Items" do
4
+ with_controllers
5
+ login_as :manager, name: 'auser'
6
+
7
+ describe "Basic" do
8
+ set_controller Controllers::Items
9
+
10
+ it "should update layout" do
11
+ @item = Factory.create :item
12
+ @item.layout.should == nil
13
+
14
+ pcall :layout, id: @item.to_param, value: 'home', format: 'js'
15
+ response.should be_ok
16
+
17
+ @item.reload
18
+ @item.layout.should == 'home'
19
+ end
20
+
21
+ it 'viewers, add_roles' do
22
+ @item = Factory.create :item
23
+ @item.viewers.should == %w{manager user:auser}
24
+ @item.owner_name.should == @user.name
25
+
26
+ pcall :viewers, id: @item.to_param, add_roles: 'user', format: 'js'
27
+ response.should be_ok
28
+
29
+ @item.reload
30
+ @item.viewers.should == %w{manager member user user:auser}
31
+ end
32
+
33
+ it "should redirect to /items if no default_url specified" do
34
+ call :redirect
35
+ response.should redirect_to(rad.router.default_url)
36
+ end
37
+
38
+ it "should display :all"
39
+ # do
40
+ # call :all
41
+ # response.should be_ok
42
+ # end
43
+
44
+ end
45
+ end