rad_kit 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 +11 -0
- data/lib/components/kit.rb +16 -0
- data/lib/components/kit.yml +3 -0
- data/lib/components/models.rb +7 -0
- data/lib/kit/factories.rb +9 -0
- data/lib/kit/gems.rb +16 -0
- data/lib/kit/http_controller.rb +4 -0
- data/lib/kit/http_controller/authorized.rb +51 -0
- data/lib/kit/http_controller/localized.rb +13 -0
- data/lib/kit/kit.rb +29 -0
- data/lib/kit/models.rb +8 -0
- data/lib/kit/models/attachment_uploader.rb +15 -0
- data/lib/kit/models/attachments_uploader_helper.rb +79 -0
- data/lib/kit/models/authorized.rb +188 -0
- data/lib/kit/models/authorized_object.rb +167 -0
- data/lib/kit/models/default_permissions.yml +29 -0
- data/lib/kit/models/file_uploader.rb +26 -0
- data/lib/kit/models/micelaneous.rb +1 -0
- data/lib/kit/models/role.rb +88 -0
- data/lib/kit/models_after.rb +27 -0
- data/lib/kit/mongoid.rb +22 -0
- data/lib/kit/mongoid/rad_micelaneous.rb +36 -0
- data/lib/kit/mongoid/text_processor.rb +44 -0
- data/lib/kit/spec.rb +77 -0
- data/lib/kit/spec/items_controller_crud.rb +64 -0
- data/lib/kit/support.rb +14 -0
- data/lib/kit/support/string.rb +6 -0
- data/lib/kit/tasks.rb +18 -0
- data/lib/kit/text_utils.rb +43 -0
- data/lib/kit/text_utils/code_highlighter.rb +58 -0
- data/lib/kit/text_utils/custom_markdown.rb +90 -0
- data/lib/kit/text_utils/ensure_utf.rb +8 -0
- data/lib/kit/text_utils/github_flavoured_markdown.rb +32 -0
- data/lib/kit/text_utils/html_sanitizer.rb +89 -0
- data/lib/kit/text_utils/image_box.rb +35 -0
- data/lib/kit/text_utils/markup.rb +43 -0
- data/lib/kit/text_utils/processor.rb +25 -0
- data/lib/kit/text_utils/tag_shortcuts.rb +14 -0
- data/lib/kit/text_utils/truncate.rb +29 -0
- data/lib/kit/text_utils/truncator.rb +15 -0
- data/lib/kit/text_utils/urls.rb +13 -0
- data/readme.md +10 -0
- data/spec/controller/authorization_spec.rb +149 -0
- data/spec/controller/comments_spec.rb +54 -0
- data/spec/controller/items_spec.rb +45 -0
- data/spec/models/attachments_spec.rb +24 -0
- data/spec/models/attachments_spec/a.txt +1 -0
- data/spec/models/attachments_uploader_helper_spec.rb +108 -0
- data/spec/models/attachments_uploader_helper_spec/v1/a.txt +1 -0
- data/spec/models/attachments_uploader_helper_spec/v1/b.txt +1 -0
- data/spec/models/attachments_uploader_helper_spec/v2/a.txt +1 -0
- data/spec/models/authorization_spec.rb +77 -0
- data/spec/models/authorized_object_spec.rb +254 -0
- data/spec/models/comments_spec.rb +1 -0
- data/spec/models/item_spec.rb +51 -0
- data/spec/models/role_spec.rb +17 -0
- data/spec/models/tags_spec.rb +44 -0
- data/spec/models/uploader_spec.rb +37 -0
- 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
- data/spec/mongoid/basic_spec.rb +36 -0
- data/spec/spec_helper.rb +20 -0
- data/spec/spec_helper/controller.rb +9 -0
- data/spec/spec_helper/factories.rb +24 -0
- data/spec/spec_helper/user.rb +17 -0
- data/spec/utils/text_utils_spec.rb +280 -0
- metadata +232 -0
@@ -0,0 +1 @@
|
|
1
|
+
# check that comments are inherited properties of item, see CONTAINER_INHERITABLE_ATTRIBUTES
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "item" do
|
4
|
+
with_models
|
5
|
+
login_as :user
|
6
|
+
|
7
|
+
it 'slug validation (from error)' do
|
8
|
+
i = Factory.create :item
|
9
|
+
i.slug = 'space '
|
10
|
+
i.should_not be_valid
|
11
|
+
end
|
12
|
+
|
13
|
+
describe 'safe_query' do
|
14
|
+
it "general case" do
|
15
|
+
Models::Item.safe_query(
|
16
|
+
name: 'name',
|
17
|
+
created_at: '10/11/2000',
|
18
|
+
order: "state asc",
|
19
|
+
owner_name: 'name',
|
20
|
+
state: ['state'],
|
21
|
+
tags: 'tag',
|
22
|
+
_type: 'Note',
|
23
|
+
updated_at: ['10/11/2000'],
|
24
|
+
|
25
|
+
viewers: 'role',
|
26
|
+
collaborators: 'role'
|
27
|
+
).should == [{
|
28
|
+
"name"=>"name",
|
29
|
+
"created_at" => "10/11/2000".to_time,
|
30
|
+
"order" => "state asc",
|
31
|
+
"owner_name" => "name",
|
32
|
+
"state" => ["state"],
|
33
|
+
"tags" => "tag",
|
34
|
+
"_type" => "Note",
|
35
|
+
"updated_at" => ["10/11/2000".to_time]
|
36
|
+
}, true]
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should allow only one-level order and only indexed keywords" do
|
40
|
+
Models::Item.safe_query(order: "name").should == [{'order' => "name"}, false]
|
41
|
+
Models::Item.safe_query(order: "name desc").should == [{'order' => "name desc"}, false]
|
42
|
+
Models::Item.safe_query(order: "name asc").should == [{'order' => "name asc"}, false]
|
43
|
+
|
44
|
+
Models::Item.safe_query(order: "dependent").should == [{}, true] # not indexed
|
45
|
+
|
46
|
+
# two level order
|
47
|
+
Models::Item.safe_query(order: "name created_at").should == [{'order' => 'name'}, true]
|
48
|
+
Models::Item.safe_query(order: "name created_at desc").should == [{'order' => 'name'}, true]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Role" do
|
4
|
+
with_models
|
5
|
+
|
6
|
+
it "normalization" do
|
7
|
+
Role.normalize_roles(%w{manager member specific_role user:user1}).should == %w{member specific_role user:user1}
|
8
|
+
end
|
9
|
+
|
10
|
+
it "denormalization to higher roles" do
|
11
|
+
Role.denormalize_to_higher_roles(%w{member specific_role user:user1}).should == %w{manager member specific_role user:user1}
|
12
|
+
end
|
13
|
+
|
14
|
+
it "denormalization to lower roles" do
|
15
|
+
Role.denormalize_to_lower_roles(%w{member specific_role user:user1}).should == %w{member specific_role user user:user1}
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Tags" do
|
4
|
+
with_models
|
5
|
+
login_as :user
|
6
|
+
|
7
|
+
it "should create tags with constructor initializer (from error)" do
|
8
|
+
item = Models::Item.new name: 'item', tags: ['a', 'b']
|
9
|
+
item.save!
|
10
|
+
|
11
|
+
item.reload
|
12
|
+
item.tags.should == ['a', 'b']
|
13
|
+
Models::Tag.count.should == 2
|
14
|
+
Models::Tag.all.collect(&:name).sort.should == ['a', 'b']
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should create tags" do
|
18
|
+
item = Factory.create :item, tags_as_string: 'a, b'
|
19
|
+
Models::Item.count.should == 1
|
20
|
+
item.reload
|
21
|
+
item.tags.should == ['a', 'b']
|
22
|
+
|
23
|
+
Models::Tag.count.should == 2
|
24
|
+
Models::Tag.all.collect(&:name).sort.should == ['a', 'b']
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should update tags after item update" do
|
28
|
+
item = Factory.create :item, tags_as_string: 'a, b'
|
29
|
+
Models::Tag.count.should == 2
|
30
|
+
|
31
|
+
item.tags = ['a', 'c']
|
32
|
+
item.save!
|
33
|
+
|
34
|
+
Models::Tag.count.should == 2
|
35
|
+
Models::Tag.all.collect(&:name).sort.should == ['a', 'c']
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should update tags after item deletion" do
|
39
|
+
item = Factory.create :item, tags_as_string: 'a, b'
|
40
|
+
Models::Tag.count.should == 2
|
41
|
+
item.destroy
|
42
|
+
Models::Tag.count.should == 0
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Uploading" do
|
4
|
+
with_tmp_spec_dir
|
5
|
+
with_mongoid
|
6
|
+
with_files
|
7
|
+
|
8
|
+
before :all do
|
9
|
+
class TheImageUploader < Models::FileUploader
|
10
|
+
end
|
11
|
+
|
12
|
+
class ThePost
|
13
|
+
include Mongoid::Document
|
14
|
+
|
15
|
+
field :name, type: String, default: ""
|
16
|
+
validates_uniqueness_of :name
|
17
|
+
|
18
|
+
mount_uploader :image, TheImageUploader
|
19
|
+
end
|
20
|
+
end
|
21
|
+
after(:all){remove_constants :ThePost, :TheImageUploader}
|
22
|
+
|
23
|
+
it "should preserve spaces and unicode characters in filename" do
|
24
|
+
File.open "#{spec_dir}/файл с пробелами.txt" do |f|
|
25
|
+
ship = ThePost.new image: f
|
26
|
+
|
27
|
+
ship.image.url.should =~ /\/файл с пробелами\.txt/
|
28
|
+
ship.image.filename =~ /файл с пробелами\.txt/
|
29
|
+
ship.image.path =~ /\/файл с пробелами\.txt/
|
30
|
+
|
31
|
+
# ship.smart_url.should =~ /files\/file with spaces\/file with spaces\.txt\?\d/
|
32
|
+
# f.smart_url.should =~ /files\/data\/ship\?\d+/
|
33
|
+
# f.smart_url(:icon).should =~ /images\/mime\/dat_icon\.png/
|
34
|
+
# f.smart_url(:thumb).should =~ /images\/mime\/dat_thumb\.png/
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
1
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Rad Mongoid basics" do
|
4
|
+
with_mongoid
|
5
|
+
|
6
|
+
after(:all){remove_constants :ToRsonTest}
|
7
|
+
|
8
|
+
it "to_rson" do
|
9
|
+
class ToRsonTest
|
10
|
+
include Mongoid::Document
|
11
|
+
|
12
|
+
field :name, type: String
|
13
|
+
field :text, type: String
|
14
|
+
validates_presence_of :name
|
15
|
+
end
|
16
|
+
ToRsonTest.delete_all
|
17
|
+
|
18
|
+
ToRsonTest.create! name: 'a'
|
19
|
+
ToRsonTest.create! name: 'b'
|
20
|
+
|
21
|
+
# model.to_rson
|
22
|
+
o = ToRsonTest.first
|
23
|
+
r = o.to_rson
|
24
|
+
r.delete 'id'
|
25
|
+
r.should == {"name" => "a"}
|
26
|
+
|
27
|
+
o.to_rson(only: :name).should == {"name" => "a"}
|
28
|
+
|
29
|
+
# collections.to_rson
|
30
|
+
r = ToRsonTest.all.to_rson
|
31
|
+
r.collect!{|h| h.delete('id'); h}
|
32
|
+
r.should == [{"name" => "a"}, {"name" => "b"}]
|
33
|
+
|
34
|
+
ToRsonTest.all.to_rson(only: :name).should == [{"name" => "a"}, {"name" => "b"}]
|
35
|
+
end
|
36
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rspec_ext'
|
2
|
+
|
3
|
+
require 'rad'
|
4
|
+
require 'rad/spec'
|
5
|
+
|
6
|
+
require 'rad_ext'
|
7
|
+
require 'rad_ext/spec'
|
8
|
+
|
9
|
+
# require 'mongoid_rad'
|
10
|
+
|
11
|
+
require 'kit/spec'
|
12
|
+
|
13
|
+
# rad.config.runtime_path = 'tmp'
|
14
|
+
rad.kit
|
15
|
+
|
16
|
+
require 'kit/factories'
|
17
|
+
|
18
|
+
require 'spec_helper/user.rb'
|
19
|
+
require 'spec_helper/controller'
|
20
|
+
require 'spec_helper/factories'
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'factory_girl'
|
2
|
+
|
3
|
+
#
|
4
|
+
# User
|
5
|
+
#
|
6
|
+
Factory.define :anonymous, class: 'Models::User' do |u|
|
7
|
+
u.name 'anonymous'
|
8
|
+
end
|
9
|
+
|
10
|
+
Factory.define :user, class: 'Models::User' do |u|
|
11
|
+
u.sequence(:name){|i| "user#{i}"}
|
12
|
+
end
|
13
|
+
|
14
|
+
Factory.define :admin, parent: :user do |u|
|
15
|
+
u.admin true
|
16
|
+
end
|
17
|
+
|
18
|
+
Factory.define :member, parent: :user do |u|
|
19
|
+
u.roles %w(member)
|
20
|
+
end
|
21
|
+
|
22
|
+
Factory.define :manager, parent: :user do |u|
|
23
|
+
u.roles %w(manager)
|
24
|
+
end
|
@@ -0,0 +1,280 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# require 'kit/utils/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
|
+
Rad::TextUtils.markup(markup)
|
12
|
+
end
|
13
|
+
|
14
|
+
::Nokogiri::XML::Node.class_eval do
|
15
|
+
def should_be_fuzzy_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 "code highlighting" do
|
26
|
+
it "basic" do
|
27
|
+
to_html(%{<p> text </p><code lang='ruby'>class A; p "Hello World" end</code><p> text </p>}).should =~ /span/i
|
28
|
+
to_html(%{<p> text </p><code language='ruby'>class A; p "Hello World" end</code><p> text </p>}).should =~ /span/i
|
29
|
+
to_html(%{<code lang='ruby'>\nclass A \n def p\n 10\n end\nend \n</code>}).should =~ /span/i
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should works with < and > in code" do
|
33
|
+
to_html(%{<code lang='ruby'>class A < ClassB; end</code>}).should include('ClassB')
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should preserve custom classes in <code>' do
|
37
|
+
to_html(%{<code lang='ruby' class='my_code'>\nclass A \n def p\n 10\n end\nend \n</code>}).should =~ /my_code/i
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should not raise error on empty string" do
|
42
|
+
to_html('').should == ''
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "MarkdDown" do
|
46
|
+
|
47
|
+
|
48
|
+
it "should do basic markup" do
|
49
|
+
doc = to_doc "**text**"
|
50
|
+
doc.css("p b, p strong").first.should_be_fuzzy_equal_to content: 'text'
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should guess urls" do
|
54
|
+
doc = to_doc "This is a http://www.some.com/some link"
|
55
|
+
doc.content.strip.should == "This is a http://www.some.com/some link"
|
56
|
+
doc.css("p a").first.should_be_fuzzy_equal_to href: "http://www.some.com/some"
|
57
|
+
|
58
|
+
# from error
|
59
|
+
doc = to_doc "http://www.some.com/some"
|
60
|
+
doc.content.strip.should == "http://www.some.com/some"
|
61
|
+
doc.css("p a").first.should_be_fuzzy_equal_to href: "http://www.some.com/some"
|
62
|
+
|
63
|
+
# from error
|
64
|
+
# http://mastertalk.ru/topic111478.html
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should allow 'a' elements" do
|
68
|
+
html = <<HTML
|
69
|
+
<a href="http://www.some.com/some">Absolute Link</a>
|
70
|
+
<a href="/some">Relative Link</a>
|
71
|
+
HTML
|
72
|
+
|
73
|
+
doc = to_doc html
|
74
|
+
doc.css("a").first[:href].should == "http://www.some.com/some"
|
75
|
+
doc.css("a").last[:href].should == "/some"
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should embed YouTube Videos" do
|
79
|
+
html =<<HTML
|
80
|
+
<object width="425" height="344">
|
81
|
+
<param name="movie" value="http://www.youtube.com/v/s8hYKKXV5wU&hl=en_US&fs=1&"></param>
|
82
|
+
<param name="allowFullScreen" value="true"></param>
|
83
|
+
<param name="allowscriptaccess" value="always"></param>
|
84
|
+
<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>
|
85
|
+
</object>
|
86
|
+
HTML
|
87
|
+
|
88
|
+
doc = to_doc html
|
89
|
+
obj = doc.css("object").first.should_be_fuzzy_equal_to width: 425, height: 344
|
90
|
+
p1, p2, p3, embed = doc.css("object *")
|
91
|
+
p1.should_be_fuzzy_equal_to name: "movie", value: "http://www.youtube.com/v/s8hYKKXV5wU&hl=en_US&fs=1&"
|
92
|
+
p2.should_be_fuzzy_equal_to name: "allowFullScreen", value: "true"
|
93
|
+
p3.should_be_fuzzy_equal_to name: "allowscriptaccess", value: "always"
|
94
|
+
embed.should_be_fuzzy_equal_to src: "http://www.youtube.com/v/s8hYKKXV5wU&hl=en_US&fs=1&",
|
95
|
+
type: "application/x-shockwave-flash", allowscriptaccess: "always",
|
96
|
+
allowfullscreen: "true", width: "425", height: "344"
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should skip empty paragraphs" do
|
100
|
+
html = "line 1\n\nline 2\n\n\n\nline 3"
|
101
|
+
to_html(html).should =~ /<p>\s*line 1<\/p>\n<p>line 2<\/p>\n<p>line 3\s*<\/p>.?/
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should convert \n to <br/>" do
|
105
|
+
to_doc("foo\nbar").css('br').size.should == 1
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should not touch single underscores inside words" do
|
109
|
+
to_html("foo_bar").should include("foo_bar")
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should works with unicode" do
|
113
|
+
html = %{Юникод <a href="http://www.some.com/" class="_image_box">Юникод</a>}
|
114
|
+
doc = to_doc html
|
115
|
+
doc.css('p').first.content.should =~ /Юникод/
|
116
|
+
doc.css('p a').first.should_be_fuzzy_equal_to href: "http://www.some.com/", class: "_image_box", content: "Юникод"
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'should allow class and rel attribute' do
|
120
|
+
html = %{<a href="http://www.some.com/" class="_image_box" rel="nofollow">Some</a>}
|
121
|
+
doc = to_doc html
|
122
|
+
doc.css('a').first.should_be_fuzzy_equal_to href: "http://www.some.com/", class: "_image_box", rel: "nofollow"
|
123
|
+
end
|
124
|
+
|
125
|
+
it "should allow image inside of link" do
|
126
|
+
html = <<HTML
|
127
|
+
<a rel="article_images" class="_image_box" href="/some_image">
|
128
|
+
<img src="/some_image"></img>
|
129
|
+
</a>
|
130
|
+
HTML
|
131
|
+
|
132
|
+
doc = to_doc html
|
133
|
+
doc.css('a').first.should_be_fuzzy_equal_to href: "/some_image", class: "_image_box"
|
134
|
+
doc.css('a img').first.should_be_fuzzy_equal_to src: "/some_image"
|
135
|
+
end
|
136
|
+
|
137
|
+
it "should use simplifyed syntax for image boxes (!![img_thumb] => [![img_thumb]][img_full_version])" do
|
138
|
+
html = <<HTML
|
139
|
+
!![img]
|
140
|
+
![img]
|
141
|
+
|
142
|
+
!![img_2]
|
143
|
+
![img_2]
|
144
|
+
|
145
|
+
[img]: /some_prefix/image_name.png
|
146
|
+
[img_2]: /some_prefix/image_name2.icon.png
|
147
|
+
HTML
|
148
|
+
|
149
|
+
doc = to_doc html
|
150
|
+
doc.css('a').first.should_be_fuzzy_equal_to href: "/some_prefix/image_name.png"
|
151
|
+
doc.css('a img').first.should_be_fuzzy_equal_to src: "/some_prefix/image_name.thumb.png"
|
152
|
+
|
153
|
+
doc.css('a').last.should_be_fuzzy_equal_to href: "/some_prefix/image_name2.png"
|
154
|
+
doc.css('a img').last.should_be_fuzzy_equal_to src: "/some_prefix/image_name2.icon.png"
|
155
|
+
|
156
|
+
doc.css('img').size.should == 4
|
157
|
+
end
|
158
|
+
|
159
|
+
it "simplifyed syntax for image boxes should be robust (from error)" do
|
160
|
+
html = "!![img] " # without resolved reference
|
161
|
+
to_html(html)
|
162
|
+
lambda{to_html(html)}.should_not raise_error
|
163
|
+
end
|
164
|
+
|
165
|
+
it "should create teaser from text" do
|
166
|
+
text = %{Hi there, I have a page that will list news articles}
|
167
|
+
Rad::TextUtils.truncate(text, 20).should == "Hi there, I have a ..."
|
168
|
+
end
|
169
|
+
|
170
|
+
it "should create teaser from html" do
|
171
|
+
text = %{Hi <div><b>there</b>, I have a page that will list news articles</div>}
|
172
|
+
Rad::TextUtils.truncate(text, 20).should == "Hi there, I have a ..."
|
173
|
+
|
174
|
+
Rad::TextUtils.truncate(%{a<br/>b}, 20).should == "a b" # from error
|
175
|
+
end
|
176
|
+
|
177
|
+
# it "embed metaweb.com wiget" do
|
178
|
+
# html = <<HTML
|
179
|
+
# <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">
|
180
|
+
# <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>
|
181
|
+
# <script defer="" type="text/javascript" src="http://freebaselibs.com/static/widgets/2/widget.js"></script>
|
182
|
+
# </div>
|
183
|
+
# HTML
|
184
|
+
#
|
185
|
+
# text = "{metaweb:google_web_toolkit}"
|
186
|
+
# to_html(text).should include(html)
|
187
|
+
# end
|
188
|
+
|
189
|
+
it "should correctly insert newline (from error)" do
|
190
|
+
html = <<HTML
|
191
|
+
![img] Open Design.
|
192
|
+
http://oomps.com
|
193
|
+
|
194
|
+
[img]: /some_link
|
195
|
+
HTML
|
196
|
+
|
197
|
+
to_doc(html).css('br').size.should == 1
|
198
|
+
end
|
199
|
+
|
200
|
+
it "clear div" do
|
201
|
+
html = "[clear]"
|
202
|
+
|
203
|
+
doc = to_doc html
|
204
|
+
doc.css('div.clear').size.should == 1
|
205
|
+
end
|
206
|
+
|
207
|
+
it "space div" do
|
208
|
+
html = "[space]"
|
209
|
+
|
210
|
+
doc = to_doc html
|
211
|
+
doc.css('div.space').size.should == 1
|
212
|
+
end
|
213
|
+
|
214
|
+
it "should correctly guess links (from error)" do
|
215
|
+
to_doc("http://some_domain.com http://some_domain.com").css('a').size == 2
|
216
|
+
end
|
217
|
+
|
218
|
+
it "should leave existing links intact" do
|
219
|
+
doc = to_doc(%{<a href="http://some_domain.com">http://some_domain.com</a>})
|
220
|
+
doc.css('a').size.should == 1
|
221
|
+
doc.css('a').first['href'].should == "http://some_domain.com"
|
222
|
+
end
|
223
|
+
|
224
|
+
it "should leave existing links intact" do
|
225
|
+
md = %{\
|
226
|
+
[Download Page][dl]
|
227
|
+
[dl]: http://www.mozilla.org/products/firefox/}
|
228
|
+
|
229
|
+
to_doc(md).css('a').first['href'].should == 'http://www.mozilla.org/products/firefox/'
|
230
|
+
end
|
231
|
+
|
232
|
+
it "should allow div with any classes (from error)" do
|
233
|
+
html = %{<div class="col3 left"><a href='#'>text</a></div>}
|
234
|
+
to_doc(html).css("div.col3.left a").size.should == 1
|
235
|
+
end
|
236
|
+
|
237
|
+
it "should apply markup inside of html elements (from error)" do
|
238
|
+
html = <<HTML
|
239
|
+
<div class='right'>
|
240
|
+
![img]
|
241
|
+
</div>
|
242
|
+
|
243
|
+
[img]: /some_link
|
244
|
+
HTML
|
245
|
+
|
246
|
+
to_doc(html).css('.right img').size.should == 1
|
247
|
+
end
|
248
|
+
|
249
|
+
it "shouldn't create newline after > sign (from error)" do
|
250
|
+
html = %{\
|
251
|
+
<div>text</div>
|
252
|
+
text}
|
253
|
+
to_doc(html).css('br').size.should == 0
|
254
|
+
end
|
255
|
+
|
256
|
+
it "shouldn't add empty <p> before first line (from error)" do
|
257
|
+
to_html("<span>text</span>text").should_not =~ /<p>\s*<\/p>/
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
it "should not aply markdown if document specified as [html]" do
|
262
|
+
html = %{\
|
263
|
+
[html]
|
264
|
+
first line
|
265
|
+
**text**
|
266
|
+
second line}
|
267
|
+
|
268
|
+
r = to_html(html)
|
269
|
+
r.should_not include('<')
|
270
|
+
r.should_not include('[html]')
|
271
|
+
end
|
272
|
+
|
273
|
+
it "should still escape input in [html] mode" do
|
274
|
+
html = %{\
|
275
|
+
[html]
|
276
|
+
<script>some dangerous code</script>}
|
277
|
+
|
278
|
+
to_html(html).should_not include('script')
|
279
|
+
end
|
280
|
+
end
|