runo 0.1.0
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/LICENSE +19 -0
- data/README.rdoc +120 -0
- data/bin/runo +35 -0
- data/lib/_error.rb +14 -0
- data/lib/_field.rb +260 -0
- data/lib/_i18n.rb +141 -0
- data/lib/_parser.rb +243 -0
- data/lib/_path.rb +86 -0
- data/lib/_storage/_storage.rb +213 -0
- data/lib/_storage/file.rb +200 -0
- data/lib/_storage/sequel.rb +174 -0
- data/lib/_storage/temp.rb +73 -0
- data/lib/_widget/action_create.rb +23 -0
- data/lib/_widget/action_login.rb +22 -0
- data/lib/_widget/action_signup.rb +16 -0
- data/lib/_widget/action_update.rb +16 -0
- data/lib/_widget/crumb.rb +24 -0
- data/lib/_widget/done.rb +16 -0
- data/lib/_widget/login.rb +25 -0
- data/lib/_widget/me.rb +31 -0
- data/lib/_widget/message.rb +51 -0
- data/lib/_widget/navi.rb +88 -0
- data/lib/_widget/submit.rb +49 -0
- data/lib/_widget/view_ym.rb +77 -0
- data/lib/_workflow/_workflow.rb +89 -0
- data/lib/_workflow/attachment.rb +50 -0
- data/lib/_workflow/blog.rb +28 -0
- data/lib/_workflow/contact.rb +23 -0
- data/lib/_workflow/forum.rb +26 -0
- data/lib/_workflow/register.rb +39 -0
- data/lib/meta/_meta.rb +20 -0
- data/lib/meta/group.rb +19 -0
- data/lib/meta/id.rb +59 -0
- data/lib/meta/owner.rb +21 -0
- data/lib/meta/timestamp.rb +118 -0
- data/lib/runo.rb +396 -0
- data/lib/scalar/checkbox.rb +68 -0
- data/lib/scalar/file.rb +144 -0
- data/lib/scalar/img.rb +112 -0
- data/lib/scalar/password.rb +58 -0
- data/lib/scalar/radio.rb +47 -0
- data/lib/scalar/select.rb +47 -0
- data/lib/scalar/text.rb +38 -0
- data/lib/scalar/textarea.rb +35 -0
- data/lib/scalar/textarea_pre.rb +14 -0
- data/lib/scalar/textarea_wiki.rb +173 -0
- data/lib/set/_set.rb +195 -0
- data/lib/set/dynamic.rb +177 -0
- data/lib/set/static.rb +102 -0
- data/lib/set/static_folder.rb +96 -0
- data/locale/en/index.po +242 -0
- data/locale/index.pot +243 -0
- data/locale/ja/index.po +242 -0
- data/locale/lazy_parser.rb +54 -0
- data/skel/config.ru +27 -0
- data/skel/skin/_users/00000000_frank-avatar.jpg +0 -0
- data/skel/skin/_users/00000000_frank-avatar_small.jpg +0 -0
- data/skel/skin/_users/00000000_frank.yaml +12 -0
- data/skel/skin/_users/00000000_root-avatar.jpg +0 -0
- data/skel/skin/_users/00000000_root-avatar_small.jpg +0 -0
- data/skel/skin/_users/00000000_root.yaml +11 -0
- data/skel/skin/_users/css/users.css +21 -0
- data/skel/skin/_users/css/users.less +25 -0
- data/skel/skin/_users/done.html +42 -0
- data/skel/skin/_users/index.html +46 -0
- data/skel/skin/_users/index.yaml +3 -0
- data/skel/skin/_users/summary.html +40 -0
- data/skel/skin/css/base.css +93 -0
- data/skel/skin/css/base.less +139 -0
- data/skel/skin/css/coax.css +199 -0
- data/skel/skin/css/coax.less +244 -0
- data/skel/skin/examples/blog/20091214_0001.yaml +8 -0
- data/skel/skin/examples/blog/20100630_0001.yaml +8 -0
- data/skel/skin/examples/blog/20100630_0002.yaml +14 -0
- data/skel/skin/examples/blog/20100701_0001.yaml +8 -0
- data/skel/skin/examples/blog/20100701_0002-a-20100701_0001-f.jpg +0 -0
- data/skel/skin/examples/blog/20100701_0002-a-20100701_0001-f_small.jpg +0 -0
- data/skel/skin/examples/blog/20100701_0002.yaml +19 -0
- data/skel/skin/examples/blog/frank/20100701_0001.yaml +10 -0
- data/skel/skin/examples/blog/frank/index.yaml +4 -0
- data/skel/skin/examples/blog/index.html +51 -0
- data/skel/skin/examples/blog/rss.xml +18 -0
- data/skel/skin/examples/contact/20100701_0001-file.txt +1 -0
- data/skel/skin/examples/contact/20100701_0001.yaml +15 -0
- data/skel/skin/examples/contact/20100701_0002.yaml +8 -0
- data/skel/skin/examples/contact/20100701_0003.yaml +9 -0
- data/skel/skin/examples/contact/index.html +47 -0
- data/skel/skin/examples/contact/js/contact.js +13 -0
- data/skel/skin/examples/contact/summary.html +54 -0
- data/skel/skin/examples/forum/20100701_0001.yaml +41 -0
- data/skel/skin/examples/forum/20100701_0002.yaml +25 -0
- data/skel/skin/examples/forum/index.html +68 -0
- data/skel/skin/examples/forum/summary.html +47 -0
- data/skel/skin/examples/index.html +75 -0
- data/skel/skin/index.html +41 -0
- data/skel/skin/js/base.js +50 -0
- data/t/locale/de/index.po +19 -0
- data/t/locale/en-GB/index.po +25 -0
- data/t/locale/ja/index.po +30 -0
- data/t/skin/_users/00000000_test.yaml +3 -0
- data/t/skin/_users/index.html +13 -0
- data/t/skin/foo/20091120_0001.yaml +7 -0
- data/t/skin/foo/bar/20091120_0001.yaml +5 -0
- data/t/skin/foo/bar/index.yaml +5 -0
- data/t/skin/foo/baz/css/baz.css +1 -0
- data/t/skin/foo/css/foo.css +1 -0
- data/t/skin/foo/index.html +14 -0
- data/t/skin/foo/index.yaml +7 -0
- data/t/skin/foo/not_css/foo.css +1 -0
- data/t/skin/foo/sub-20100306_0001.yaml +3 -0
- data/t/skin/index.yaml +3 -0
- data/t/skin/t_attachment/index.html +13 -0
- data/t/skin/t_contact/done.html +6 -0
- data/t/skin/t_contact/index.html +9 -0
- data/t/skin/t_file/index.html +16 -0
- data/t/skin/t_img/index.html +14 -0
- data/t/skin/t_img/test.jpg +0 -0
- data/t/skin/t_select/index.html +9 -0
- data/t/skin/t_store/index.html +9 -0
- data/t/skin/t_summary/20100326_0001.yaml +3 -0
- data/t/skin/t_summary/create.html +9 -0
- data/t/skin/t_summary/index.html +9 -0
- data/t/skin/t_summary/summary.html +9 -0
- data/t/t.rb +27 -0
- data/t/test_checkbox.rb +273 -0
- data/t/test_field.rb +330 -0
- data/t/test_file.rb +900 -0
- data/t/test_id.rb +215 -0
- data/t/test_img.rb +328 -0
- data/t/test_meta.rb +57 -0
- data/t/test_parser.rb +1266 -0
- data/t/test_password.rb +188 -0
- data/t/test_radio.rb +226 -0
- data/t/test_role.rb +249 -0
- data/t/test_runo.rb +742 -0
- data/t/test_runo_call.rb +1286 -0
- data/t/test_runo_i18n.rb +318 -0
- data/t/test_select.rb +182 -0
- data/t/test_set_complex.rb +527 -0
- data/t/test_set_dynamic.rb +1504 -0
- data/t/test_set_folder.rb +515 -0
- data/t/test_set_permit.rb +246 -0
- data/t/test_set_static.rb +445 -0
- data/t/test_storage.rb +915 -0
- data/t/test_text.rb +125 -0
- data/t/test_textarea.rb +138 -0
- data/t/test_timestamp.rb +473 -0
- data/t/test_workflow.rb +367 -0
- metadata +345 -0
data/t/test_id.rb
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
|
|
3
|
+
# Author:: Akira FUNAI
|
|
4
|
+
# Copyright:: Copyright (c) 2009-2010 Akira FUNAI
|
|
5
|
+
|
|
6
|
+
require "#{::File.dirname __FILE__}/t"
|
|
7
|
+
|
|
8
|
+
class TC_Id < Test::Unit::TestCase
|
|
9
|
+
|
|
10
|
+
def setup
|
|
11
|
+
meta = nil
|
|
12
|
+
Runo::Parser.gsub_scalar('$(foo meta-id 3 1..5)') {|id, m|
|
|
13
|
+
meta = m
|
|
14
|
+
''
|
|
15
|
+
}
|
|
16
|
+
@f = Runo::Field.instance meta
|
|
17
|
+
|
|
18
|
+
Runo.current[:base] = nil
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def teardown
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def test_meta
|
|
25
|
+
assert_equal(
|
|
26
|
+
3,
|
|
27
|
+
@f[:size],
|
|
28
|
+
'Meta::Id#initialize should set :size from the token'
|
|
29
|
+
)
|
|
30
|
+
assert_equal(
|
|
31
|
+
1,
|
|
32
|
+
@f[:min],
|
|
33
|
+
'Meta::Id#initialize should set :min from the range token'
|
|
34
|
+
)
|
|
35
|
+
assert_equal(
|
|
36
|
+
5,
|
|
37
|
+
@f[:max],
|
|
38
|
+
'Meta::Id#initialize should set :max from the range token'
|
|
39
|
+
)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def test_val_cast
|
|
43
|
+
assert_equal(
|
|
44
|
+
'',
|
|
45
|
+
@f.val,
|
|
46
|
+
'Meta::Id#val_cast should cast the given val to String'
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
@f.load 123
|
|
50
|
+
assert_equal(
|
|
51
|
+
'123',
|
|
52
|
+
@f.val,
|
|
53
|
+
'Meta::Id#val_cast should cast the given val to String'
|
|
54
|
+
)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def test_new_id?
|
|
58
|
+
@f[:parent] = Runo::Set::Static.new(:id => '20100526_0001')
|
|
59
|
+
assert_equal(
|
|
60
|
+
false,
|
|
61
|
+
@f.send(:new_id?),
|
|
62
|
+
'Meta::Id#new_id? should return whether the ancestors is new or not'
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
@f[:parent] = Runo::Set::Static.new(:id => '_001')
|
|
66
|
+
assert_equal(
|
|
67
|
+
true,
|
|
68
|
+
@f.send(:new_id?),
|
|
69
|
+
'Meta::Id#new_id? should return whether the ancestors is new or not'
|
|
70
|
+
)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def test_get
|
|
74
|
+
@f[:parent] = Runo::Set::Static.new(:id => '_001')
|
|
75
|
+
assert_equal(
|
|
76
|
+
'<span class="meta-id"><input type="text" name="" value="" size="3" /></span>',
|
|
77
|
+
@f.get(:action => :create),
|
|
78
|
+
'Meta::Id#_g_create should return <input> if the ancestor is new'
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
@f[:parent] = Runo::Set::Static.new(:id => '20100526_0001')
|
|
82
|
+
assert_equal(
|
|
83
|
+
'',
|
|
84
|
+
@f.get(:action => :create),
|
|
85
|
+
'Meta::Id#_g_create should return val if the ancestor is not new'
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
@f.load 'bar'
|
|
89
|
+
assert_equal(
|
|
90
|
+
'bar',
|
|
91
|
+
@f.get,
|
|
92
|
+
'Meta::Id#get should return proper string'
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
@f[:parent] = Runo::Set::Static.new(:id => '_001')
|
|
96
|
+
assert_equal(
|
|
97
|
+
'<span class="meta-id"><input type="text" name="" value="bar" size="3" /></span>',
|
|
98
|
+
@f.get(:action => :update),
|
|
99
|
+
'Meta::Id#_g_update should return <input> if the ancestor is new'
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
@f[:parent] = Runo::Set::Static.new(:id => '20100526_0001')
|
|
103
|
+
assert_equal(
|
|
104
|
+
'bar',
|
|
105
|
+
@f.get(:action => :update),
|
|
106
|
+
'Meta::Id#_g_update should return val if the ancestor is not new'
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
@f.load '<bar>'
|
|
110
|
+
assert_equal(
|
|
111
|
+
'<bar>',
|
|
112
|
+
@f.get,
|
|
113
|
+
'Meta::Id#get should escape the special characters'
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
@f[:parent] = Runo::Set::Static.new(:id => '_001')
|
|
117
|
+
@f.load '<bar>'
|
|
118
|
+
assert_equal(
|
|
119
|
+
'<span class="meta-id error"><input type="text" name="" value="<bar>" size="3" /><span class="error_message">malformatted id</span>' + "\n</span>",
|
|
120
|
+
@f.get(:action => :update),
|
|
121
|
+
'Meta::Id#get should escape the special characters'
|
|
122
|
+
)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def test_post_new_ancestor
|
|
126
|
+
@f[:parent] = Runo::Set::Static.new(:id => '_001')
|
|
127
|
+
@f.create 'frank'
|
|
128
|
+
assert_equal(
|
|
129
|
+
'frank',
|
|
130
|
+
@f.val,
|
|
131
|
+
'Meta::Id#post should create like a normal field'
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
@f.update 'bobby'
|
|
135
|
+
assert_equal(
|
|
136
|
+
'bobby',
|
|
137
|
+
@f.val,
|
|
138
|
+
'Meta::Id#post should update the current val if the ancestor is new'
|
|
139
|
+
)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def test_post_old_ancestor
|
|
143
|
+
@f[:parent] = Runo::Set::Static.new(:id => '20100526_0001')
|
|
144
|
+
@f.load 'frank'
|
|
145
|
+
|
|
146
|
+
@f.update 'bobby'
|
|
147
|
+
assert_equal(
|
|
148
|
+
'frank',
|
|
149
|
+
@f.val,
|
|
150
|
+
'Meta::Id#post should not update the current val if the ancestor is not new'
|
|
151
|
+
)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def test_errors
|
|
155
|
+
@f.load '<a'
|
|
156
|
+
assert_equal(
|
|
157
|
+
['malformatted id'],
|
|
158
|
+
@f.errors,
|
|
159
|
+
'Meta::Id#errors should return the errors of the current val'
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
@f.load '123a'
|
|
163
|
+
assert_equal(
|
|
164
|
+
['malformatted id'],
|
|
165
|
+
@f.errors,
|
|
166
|
+
'Meta::Id#errors should return the errors of the current val'
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
@f.load 'abcdefghijk'
|
|
170
|
+
assert_equal(
|
|
171
|
+
['too long: 5 characters maximum'],
|
|
172
|
+
@f.errors,
|
|
173
|
+
'Meta::Id#errors should return the errors of the current val'
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
@f.load 'frank'
|
|
177
|
+
assert_equal(
|
|
178
|
+
[],
|
|
179
|
+
@f.errors,
|
|
180
|
+
'Meta::Id#errors should return an empty array if there is no error'
|
|
181
|
+
)
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def test_errors_duplicate_id
|
|
185
|
+
Runo.client = 'root'
|
|
186
|
+
sd = Runo::Set::Static::Folder.root.item('_users', 'main')
|
|
187
|
+
|
|
188
|
+
sd.update(
|
|
189
|
+
'_001' => {:action => :create, '_id' => 'test'}
|
|
190
|
+
)
|
|
191
|
+
assert_equal(
|
|
192
|
+
['duplicate id: test'],
|
|
193
|
+
sd.item('_001', '_id').errors,
|
|
194
|
+
'Meta::Id#errors should return an error if the current val is duplicated in the sd'
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
sd.update(
|
|
198
|
+
'_001' => {:action => :create, '_id' => 'frank'}
|
|
199
|
+
)
|
|
200
|
+
assert_equal(
|
|
201
|
+
[],
|
|
202
|
+
sd.item('_001', '_id').errors,
|
|
203
|
+
'Meta::Id#errors should return no error if the current val is unique in the sd'
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
f = Runo::Set::Static::Folder.root.item('_users', 'main', 'test', '_id')
|
|
207
|
+
f.update 'test'
|
|
208
|
+
assert_equal(
|
|
209
|
+
[],
|
|
210
|
+
f.errors,
|
|
211
|
+
'Meta::Id#errors should return no error if the current val is unchanged'
|
|
212
|
+
)
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
end
|
data/t/test_img.rb
ADDED
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
|
|
3
|
+
# Author:: Akira FUNAI
|
|
4
|
+
# Copyright:: Copyright (c) 2009-2010 Akira FUNAI
|
|
5
|
+
|
|
6
|
+
require "#{::File.dirname __FILE__}/t"
|
|
7
|
+
|
|
8
|
+
class TC_Img < Test::Unit::TestCase
|
|
9
|
+
|
|
10
|
+
def setup
|
|
11
|
+
Runo.current[:uri] = nil
|
|
12
|
+
|
|
13
|
+
File.open('t/skin/t_img/test.jpg') {|f|
|
|
14
|
+
@img = f.read
|
|
15
|
+
@file = Tempfile.open('tc_img')
|
|
16
|
+
@file << @img
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
meta = nil
|
|
20
|
+
Runo::Parser.gsub_scalar('$(foo img 32*32 1..100000 jpg, gif, png crop)') {|id, m|
|
|
21
|
+
meta = m
|
|
22
|
+
''
|
|
23
|
+
}
|
|
24
|
+
@f = Runo::Field.instance meta.merge(:id => 'foo')
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def test_meta
|
|
28
|
+
assert_equal(
|
|
29
|
+
1,
|
|
30
|
+
@f[:min],
|
|
31
|
+
'Img#initialize should set :min from the range token'
|
|
32
|
+
)
|
|
33
|
+
assert_equal(
|
|
34
|
+
100000,
|
|
35
|
+
@f[:max],
|
|
36
|
+
'Img#initialize should set :max from the range token'
|
|
37
|
+
)
|
|
38
|
+
assert_equal(
|
|
39
|
+
['jpg', 'gif', 'png'],
|
|
40
|
+
@f[:options],
|
|
41
|
+
'Img#initialize should set :options from the csv token'
|
|
42
|
+
)
|
|
43
|
+
assert_equal(
|
|
44
|
+
true,
|
|
45
|
+
@f[:crop],
|
|
46
|
+
'Img#initialize should set :options from the csv token'
|
|
47
|
+
)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def test_val_cast_from_rack
|
|
51
|
+
@f.create(
|
|
52
|
+
:type => 'image/jpeg',
|
|
53
|
+
:tempfile => @file,
|
|
54
|
+
:head => <<'_eos',
|
|
55
|
+
Content-Disposition: form-data; name="t_img"; filename="baz.jpg"
|
|
56
|
+
Content-Type: image/jpeg
|
|
57
|
+
_eos
|
|
58
|
+
:filename => 'baz.jpg',
|
|
59
|
+
:name => 't_img'
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
assert_equal(
|
|
63
|
+
{
|
|
64
|
+
'basename' => 'baz.jpg',
|
|
65
|
+
'type' => 'image/jpeg',
|
|
66
|
+
'size' => @file.length,
|
|
67
|
+
},
|
|
68
|
+
@f.val,
|
|
69
|
+
'Img#val_cast should re-map a hash from Rack'
|
|
70
|
+
)
|
|
71
|
+
assert_equal(
|
|
72
|
+
@img,
|
|
73
|
+
@f.body,
|
|
74
|
+
'Img#val_cast should store the file body in @body'
|
|
75
|
+
)
|
|
76
|
+
assert_equal(
|
|
77
|
+
@f.send(:_thumbnail, @file),
|
|
78
|
+
@f.thumbnail,
|
|
79
|
+
'Img#val_cast should store the thumbnail in @thumbnail'
|
|
80
|
+
)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def test_val_cast_load
|
|
84
|
+
@f.load(
|
|
85
|
+
'basename' => 'baz.jpg',
|
|
86
|
+
'type' => 'image/jpeg',
|
|
87
|
+
'size' => 123
|
|
88
|
+
)
|
|
89
|
+
assert_equal(
|
|
90
|
+
{
|
|
91
|
+
'basename' => 'baz.jpg',
|
|
92
|
+
'type' => 'image/jpeg',
|
|
93
|
+
'size' => 123,
|
|
94
|
+
},
|
|
95
|
+
@f.val,
|
|
96
|
+
'Img#val_cast should load() a hash without :tempfile like Set#load'
|
|
97
|
+
)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def test_large_thumbnail
|
|
101
|
+
@f[:width] = @f[:height] = 640
|
|
102
|
+
@f.create(
|
|
103
|
+
:type => 'image/jpeg',
|
|
104
|
+
:tempfile => @file,
|
|
105
|
+
:head => <<'_eos',
|
|
106
|
+
Content-Disposition: form-data; name="t_img"; filename="baz.jpg"
|
|
107
|
+
Content-Type: image/jpeg
|
|
108
|
+
_eos
|
|
109
|
+
:filename => 'baz.jpg',
|
|
110
|
+
:name => 't_img'
|
|
111
|
+
)
|
|
112
|
+
assert_not_equal(
|
|
113
|
+
0,
|
|
114
|
+
@f.instance_variable_get(:@thumbnail).to_s.size,
|
|
115
|
+
'Img#_thumbnail should make a thumbnail larger than the original img'
|
|
116
|
+
)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def test_get
|
|
120
|
+
Runo.client = 'root'
|
|
121
|
+
|
|
122
|
+
@f[:parent] = Runo::Set::Static::Folder.root.item('t_img', 'main')
|
|
123
|
+
Runo.current[:base] = @f[:parent]
|
|
124
|
+
tid = @f[:parent][:tid]
|
|
125
|
+
|
|
126
|
+
@f.load({})
|
|
127
|
+
assert_equal(
|
|
128
|
+
<<'_html'.chomp,
|
|
129
|
+
<span class="dummy_img" style="width: 32px; height: 32px;"></span>
|
|
130
|
+
_html
|
|
131
|
+
@f.get,
|
|
132
|
+
'Img#get should return default span when the val is empty'
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
@f.load(
|
|
136
|
+
'basename' => 'baz.jpg',
|
|
137
|
+
'type' => 'image/jpeg',
|
|
138
|
+
'size' => 12
|
|
139
|
+
)
|
|
140
|
+
assert_equal(
|
|
141
|
+
<<'_html'.chomp,
|
|
142
|
+
<a href="/t_img/main/foo/baz.jpg"><img src="/t_img/main/foo/baz_small.jpg" alt="baz.jpg" /></a>
|
|
143
|
+
_html
|
|
144
|
+
@f.get,
|
|
145
|
+
'Img#get should return proper string'
|
|
146
|
+
)
|
|
147
|
+
assert_equal(
|
|
148
|
+
<<"_html",
|
|
149
|
+
<span class="img">
|
|
150
|
+
<a href="/t_img/#{tid}/foo/baz.jpg"><img src="/t_img/#{tid}/foo/baz_small.jpg" alt="baz.jpg" /></a>
|
|
151
|
+
<input type="file" name="foo" size="" class="file" />
|
|
152
|
+
</span>
|
|
153
|
+
_html
|
|
154
|
+
@f.get(:action => :update),
|
|
155
|
+
'Img#get should return proper string'
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
@f.load(
|
|
159
|
+
'basename' => '<baz>.jpg',
|
|
160
|
+
'type' => 'image/<jpeg>',
|
|
161
|
+
'size' => 12
|
|
162
|
+
)
|
|
163
|
+
assert_equal(
|
|
164
|
+
<<'_html'.chomp,
|
|
165
|
+
<a href="/t_img/main/foo/<baz>.jpg"><img src="/t_img/main/foo/<baz>_small.jpg" alt="<baz>.jpg" /></a>
|
|
166
|
+
_html
|
|
167
|
+
@f.get,
|
|
168
|
+
'Img#get should escape the special characters in file information'
|
|
169
|
+
)
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def test_get_not_image
|
|
173
|
+
@f.create(
|
|
174
|
+
:type => 'text/plain',
|
|
175
|
+
:tempfile => @file,
|
|
176
|
+
:head => <<'_eos',
|
|
177
|
+
Content-Disposition: form-data; name="t_img"; filename="baz.txt"
|
|
178
|
+
Content-Type: text/plain
|
|
179
|
+
_eos
|
|
180
|
+
:filename => 'baz.txt',
|
|
181
|
+
:name => 't_img'
|
|
182
|
+
)
|
|
183
|
+
assert_equal(
|
|
184
|
+
'<a href="foo/baz.txt">baz.txt (3535 bytes)</a>',
|
|
185
|
+
@f.get,
|
|
186
|
+
'Img#get should fall back to File#get if the file is not an image'
|
|
187
|
+
)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def test_call_body
|
|
191
|
+
Runo.client = 'root'
|
|
192
|
+
sd = Runo::Set::Static::Folder.root.item('t_img', 'main')
|
|
193
|
+
sd.storage.clear
|
|
194
|
+
|
|
195
|
+
# post a multipart request
|
|
196
|
+
input = <<"_eos".gsub(/\r?\n/, "\r\n").sub('@img', @img)
|
|
197
|
+
---foobarbaz
|
|
198
|
+
Content-Disposition: form-data; name="_1-foo"; filename="foo.jpg"
|
|
199
|
+
Content-Type: image/jpeg
|
|
200
|
+
Content-Transfer-Encoding: binary
|
|
201
|
+
|
|
202
|
+
@img
|
|
203
|
+
---foobarbaz
|
|
204
|
+
Content-Disposition: form-data; name="_token"
|
|
205
|
+
|
|
206
|
+
#{Runo.token}
|
|
207
|
+
---foobarbaz--
|
|
208
|
+
_eos
|
|
209
|
+
res = Rack::MockRequest.new(Runo.new).post(
|
|
210
|
+
'http://example.com/t_img/main/update.html',
|
|
211
|
+
{
|
|
212
|
+
:input => input,
|
|
213
|
+
'CONTENT_TYPE' => 'multipart/form-data; boundary=-foobarbaz',
|
|
214
|
+
'CONTENT_LENGTH' => input.length,
|
|
215
|
+
}
|
|
216
|
+
)
|
|
217
|
+
tid = res.headers['Location'][Runo::REX::TID]
|
|
218
|
+
|
|
219
|
+
# commit the base
|
|
220
|
+
res = Rack::MockRequest.new(Runo.new).post(
|
|
221
|
+
"http://example.com/#{tid}/update.html",
|
|
222
|
+
{
|
|
223
|
+
:input => ".status-public=create&_token=#{Runo.token}",
|
|
224
|
+
}
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
res.headers['Location'] =~ Runo::REX::PATH_ID
|
|
228
|
+
new_id = sprintf('%.8d_%.4d', $1, $2)
|
|
229
|
+
|
|
230
|
+
res = Rack::MockRequest.new(Runo.new).get(
|
|
231
|
+
"http://example.com/t_img/#{new_id}/foo/foo.jpg"
|
|
232
|
+
)
|
|
233
|
+
assert_equal(
|
|
234
|
+
'image/jpeg',
|
|
235
|
+
res.headers['Content-Type'],
|
|
236
|
+
'Runo#call to a img item should return the mime type of the file'
|
|
237
|
+
)
|
|
238
|
+
assert_equal(
|
|
239
|
+
@img.size,
|
|
240
|
+
res.body.size,
|
|
241
|
+
'Runo#call to a img item should return the binary body of the file'
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
res = Rack::MockRequest.new(Runo.new).get(
|
|
245
|
+
"http://example.com/t_img/#{new_id}/foo/foo_small.jpg"
|
|
246
|
+
)
|
|
247
|
+
assert_equal(
|
|
248
|
+
'image/jpeg',
|
|
249
|
+
res.headers['Content-Type'],
|
|
250
|
+
"Runo#call to 'file-small.*' should return the thumbnail of the file"
|
|
251
|
+
)
|
|
252
|
+
@file.rewind
|
|
253
|
+
assert_equal(
|
|
254
|
+
@f.send(:_thumbnail, @file).size,
|
|
255
|
+
res.body.size,
|
|
256
|
+
"Runo#call to 'file-small.*' should return the thumbnail of the file"
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
# delete
|
|
260
|
+
Rack::MockRequest.new(Runo.new).post(
|
|
261
|
+
'http://example.com/t_img/update.html',
|
|
262
|
+
{
|
|
263
|
+
:input => "#{new_id}.action=delete&.status-public=delete&_token=#{Runo.token}",
|
|
264
|
+
}
|
|
265
|
+
)
|
|
266
|
+
res = Rack::MockRequest.new(Runo.new).get(
|
|
267
|
+
"http://example.com/t_img/#{new_id}/foo/foo.jpg"
|
|
268
|
+
)
|
|
269
|
+
assert_equal(
|
|
270
|
+
404,
|
|
271
|
+
res.status,
|
|
272
|
+
'Runo#call should delete child files as well'
|
|
273
|
+
)
|
|
274
|
+
res = Rack::MockRequest.new(Runo.new).get(
|
|
275
|
+
"http://example.com/t_img/#{new_id}/foo/foo_small.jpg"
|
|
276
|
+
)
|
|
277
|
+
assert_equal(
|
|
278
|
+
404,
|
|
279
|
+
res.status,
|
|
280
|
+
'Runo#call should delete child files as well'
|
|
281
|
+
)
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
def test_errors
|
|
285
|
+
File.open('t/skin/t_img/index.html') {|f|
|
|
286
|
+
@img = f.read
|
|
287
|
+
@file = Tempfile.open('tc_img')
|
|
288
|
+
@file << @img
|
|
289
|
+
}
|
|
290
|
+
@f.create(
|
|
291
|
+
:type => 'image/jpeg',
|
|
292
|
+
:tempfile => @file,
|
|
293
|
+
:head => <<'_eos',
|
|
294
|
+
Content-Disposition: form-data; name="t_img"; filename="baz.jpg"
|
|
295
|
+
Content-Type: image/jpeg
|
|
296
|
+
_eos
|
|
297
|
+
:filename => 'baz.jpg',
|
|
298
|
+
:name => 't_img'
|
|
299
|
+
)
|
|
300
|
+
assert_equal(
|
|
301
|
+
['wrong file type: should be jpg/gif/png'],
|
|
302
|
+
@f.errors,
|
|
303
|
+
"Img#errors should regard quick_magick errors as 'wrong file type'"
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
File.open('t/skin/t_img/test.jpg') {|f|
|
|
307
|
+
@img = f.read
|
|
308
|
+
@file = Tempfile.open('tc_img')
|
|
309
|
+
@file << @img
|
|
310
|
+
}
|
|
311
|
+
@f.update(
|
|
312
|
+
:type => 'image/jpeg',
|
|
313
|
+
:tempfile => @file,
|
|
314
|
+
:head => <<'_eos',
|
|
315
|
+
Content-Disposition: form-data; name="t_img"; filename="baz.jpg"
|
|
316
|
+
Content-Type: image/jpeg
|
|
317
|
+
_eos
|
|
318
|
+
:filename => 'baz.jpg',
|
|
319
|
+
:name => 't_img'
|
|
320
|
+
)
|
|
321
|
+
assert_equal(
|
|
322
|
+
[],
|
|
323
|
+
@f.errors,
|
|
324
|
+
"Img#errors should raise no errors for good imgs"
|
|
325
|
+
)
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
end
|