runo 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (151) hide show
  1. data/README.rdoc +1 -118
  2. data/bin/runo +4 -29
  3. data/lib/dummy.rb +0 -0
  4. metadata +12 -278
  5. data/lib/_error.rb +0 -14
  6. data/lib/_field.rb +0 -260
  7. data/lib/_i18n.rb +0 -144
  8. data/lib/_parser.rb +0 -256
  9. data/lib/_path.rb +0 -86
  10. data/lib/_storage/_storage.rb +0 -215
  11. data/lib/_storage/file.rb +0 -201
  12. data/lib/_storage/sequel.rb +0 -174
  13. data/lib/_storage/temp.rb +0 -73
  14. data/lib/_widget/action_create.rb +0 -23
  15. data/lib/_widget/action_login.rb +0 -22
  16. data/lib/_widget/action_signup.rb +0 -16
  17. data/lib/_widget/action_update.rb +0 -16
  18. data/lib/_widget/crumb.rb +0 -24
  19. data/lib/_widget/done.rb +0 -16
  20. data/lib/_widget/login.rb +0 -25
  21. data/lib/_widget/me.rb +0 -31
  22. data/lib/_widget/message.rb +0 -51
  23. data/lib/_widget/navi.rb +0 -88
  24. data/lib/_widget/submit.rb +0 -49
  25. data/lib/_widget/view_ym.rb +0 -77
  26. data/lib/_workflow/_workflow.rb +0 -89
  27. data/lib/_workflow/attachment.rb +0 -50
  28. data/lib/_workflow/blog.rb +0 -28
  29. data/lib/_workflow/contact.rb +0 -23
  30. data/lib/_workflow/forum.rb +0 -26
  31. data/lib/_workflow/register.rb +0 -39
  32. data/lib/meta/_meta.rb +0 -20
  33. data/lib/meta/group.rb +0 -19
  34. data/lib/meta/id.rb +0 -59
  35. data/lib/meta/owner.rb +0 -21
  36. data/lib/meta/timestamp.rb +0 -118
  37. data/lib/runo.rb +0 -396
  38. data/lib/scalar/checkbox.rb +0 -68
  39. data/lib/scalar/file.rb +0 -144
  40. data/lib/scalar/img.rb +0 -112
  41. data/lib/scalar/password.rb +0 -58
  42. data/lib/scalar/radio.rb +0 -47
  43. data/lib/scalar/select.rb +0 -47
  44. data/lib/scalar/text.rb +0 -38
  45. data/lib/scalar/textarea.rb +0 -35
  46. data/lib/scalar/textarea_pre.rb +0 -14
  47. data/lib/scalar/textarea_wiki.rb +0 -173
  48. data/lib/set/_set.rb +0 -196
  49. data/lib/set/dynamic.rb +0 -177
  50. data/lib/set/static.rb +0 -102
  51. data/lib/set/static_folder.rb +0 -96
  52. data/locale/en/index.po +0 -242
  53. data/locale/index.pot +0 -243
  54. data/locale/ja/index.po +0 -242
  55. data/locale/lazy_parser.rb +0 -54
  56. data/skel/config.ru +0 -27
  57. data/skel/skin/_users/00000000_frank-avatar.jpg +0 -0
  58. data/skel/skin/_users/00000000_frank-avatar_small.jpg +0 -0
  59. data/skel/skin/_users/00000000_frank.yaml +0 -12
  60. data/skel/skin/_users/00000000_root-avatar.jpg +0 -0
  61. data/skel/skin/_users/00000000_root-avatar_small.jpg +0 -0
  62. data/skel/skin/_users/00000000_root.yaml +0 -11
  63. data/skel/skin/_users/css/users.css +0 -21
  64. data/skel/skin/_users/css/users.less +0 -25
  65. data/skel/skin/_users/done.html +0 -42
  66. data/skel/skin/_users/index.html +0 -46
  67. data/skel/skin/_users/index.yaml +0 -3
  68. data/skel/skin/_users/summary.html +0 -40
  69. data/skel/skin/css/base.css +0 -93
  70. data/skel/skin/css/base.less +0 -139
  71. data/skel/skin/css/coax.css +0 -199
  72. data/skel/skin/css/coax.less +0 -244
  73. data/skel/skin/examples/blog/20091214_0001.yaml +0 -8
  74. data/skel/skin/examples/blog/20100630_0001.yaml +0 -8
  75. data/skel/skin/examples/blog/20100630_0002.yaml +0 -14
  76. data/skel/skin/examples/blog/20100701_0001.yaml +0 -8
  77. data/skel/skin/examples/blog/20100701_0002-a-20100701_0001-f.jpg +0 -0
  78. data/skel/skin/examples/blog/20100701_0002-a-20100701_0001-f_small.jpg +0 -0
  79. data/skel/skin/examples/blog/20100701_0002.yaml +0 -19
  80. data/skel/skin/examples/blog/frank/20100701_0001.yaml +0 -10
  81. data/skel/skin/examples/blog/frank/index.yaml +0 -4
  82. data/skel/skin/examples/blog/index.html +0 -51
  83. data/skel/skin/examples/blog/rss.xml +0 -18
  84. data/skel/skin/examples/contact/20100701_0001-file.txt +0 -1
  85. data/skel/skin/examples/contact/20100701_0001.yaml +0 -15
  86. data/skel/skin/examples/contact/20100701_0002.yaml +0 -8
  87. data/skel/skin/examples/contact/20100701_0003.yaml +0 -9
  88. data/skel/skin/examples/contact/index.html +0 -47
  89. data/skel/skin/examples/contact/js/contact.js +0 -13
  90. data/skel/skin/examples/contact/summary.html +0 -54
  91. data/skel/skin/examples/forum/20100701_0001.yaml +0 -41
  92. data/skel/skin/examples/forum/20100701_0002.yaml +0 -25
  93. data/skel/skin/examples/forum/index.html +0 -68
  94. data/skel/skin/examples/forum/summary.html +0 -47
  95. data/skel/skin/examples/index.html +0 -73
  96. data/skel/skin/index.html +0 -39
  97. data/skel/skin/js/base.js +0 -50
  98. data/t/locale/de/index.po +0 -19
  99. data/t/locale/en-GB/index.po +0 -25
  100. data/t/locale/ja/index.po +0 -30
  101. data/t/skin/_users/00000000_test.yaml +0 -3
  102. data/t/skin/_users/index.html +0 -13
  103. data/t/skin/foo/20091120_0001.yaml +0 -7
  104. data/t/skin/foo/bar/20091120_0001.yaml +0 -5
  105. data/t/skin/foo/bar/index.yaml +0 -5
  106. data/t/skin/foo/baz/css/baz.css +0 -1
  107. data/t/skin/foo/css/foo.css +0 -1
  108. data/t/skin/foo/index.html +0 -14
  109. data/t/skin/foo/index.yaml +0 -7
  110. data/t/skin/foo/not_css/foo.css +0 -1
  111. data/t/skin/foo/qux/index.html +0 -8
  112. data/t/skin/foo/qux/moo/index.html +0 -6
  113. data/t/skin/foo/sub-20100306_0001.yaml +0 -3
  114. data/t/skin/index.yaml +0 -3
  115. data/t/skin/t_attachment/index.html +0 -13
  116. data/t/skin/t_contact/done.html +0 -6
  117. data/t/skin/t_contact/index.html +0 -9
  118. data/t/skin/t_file/index.html +0 -16
  119. data/t/skin/t_img/index.html +0 -14
  120. data/t/skin/t_img/test.jpg +0 -0
  121. data/t/skin/t_select/index.html +0 -9
  122. data/t/skin/t_store/index.html +0 -9
  123. data/t/skin/t_summary/20100326_0001.yaml +0 -3
  124. data/t/skin/t_summary/create.html +0 -9
  125. data/t/skin/t_summary/index.html +0 -9
  126. data/t/skin/t_summary/summary.html +0 -9
  127. data/t/t.rb +0 -27
  128. data/t/test_checkbox.rb +0 -273
  129. data/t/test_field.rb +0 -330
  130. data/t/test_file.rb +0 -900
  131. data/t/test_id.rb +0 -215
  132. data/t/test_img.rb +0 -328
  133. data/t/test_meta.rb +0 -57
  134. data/t/test_parser.rb +0 -1516
  135. data/t/test_password.rb +0 -188
  136. data/t/test_radio.rb +0 -226
  137. data/t/test_role.rb +0 -249
  138. data/t/test_runo.rb +0 -768
  139. data/t/test_runo_call.rb +0 -1281
  140. data/t/test_runo_i18n.rb +0 -325
  141. data/t/test_select.rb +0 -182
  142. data/t/test_set_complex.rb +0 -527
  143. data/t/test_set_dynamic.rb +0 -1504
  144. data/t/test_set_folder.rb +0 -515
  145. data/t/test_set_permit.rb +0 -246
  146. data/t/test_set_static.rb +0 -468
  147. data/t/test_storage.rb +0 -915
  148. data/t/test_text.rb +0 -125
  149. data/t/test_textarea.rb +0 -138
  150. data/t/test_timestamp.rb +0 -473
  151. data/t/test_workflow.rb +0 -367
@@ -1,1281 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- # Author:: Akira FUNAI
4
- # Copyright:: Copyright (c) 2009 Akira FUNAI
5
-
6
- require "#{::File.dirname __FILE__}/t"
7
-
8
- class TC_Runo_Call < Test::Unit::TestCase
9
-
10
- def setup
11
- @runo = Runo.new
12
- end
13
-
14
- def teardown
15
- end
16
-
17
- def test_get
18
- Runo.client = nil
19
- res = Rack::MockRequest.new(@runo).get(
20
- 'http://example.com/foo/'
21
- )
22
- assert_match(
23
- /<html/,
24
- res.body,
25
- 'Runo#call() should return the folder.get if the base field is a SD'
26
- )
27
- end
28
-
29
- def test_get_non_exist
30
- Runo.client = nil
31
- res = Rack::MockRequest.new(@runo).get(
32
- 'http://example.com/foo/non/exist/'
33
- )
34
- assert_equal(
35
- 404,
36
- res.status,
37
- 'Runo#call() should return 404 if the given path is non-existent'
38
- )
39
- end
40
-
41
- def test_get_partial
42
- Runo.client = nil
43
- res = Rack::MockRequest.new(@runo).get(
44
- 'http://example.com/foo/20091120_0001/name/'
45
- )
46
- assert_equal(
47
- 'FZ',
48
- res.body,
49
- 'Runo#call() should return the base.get unless the base field is a SD'
50
- )
51
- end
52
-
53
- def test_get_sub
54
- Runo.client = nil
55
- res = Rack::MockRequest.new(@runo).get(
56
- 'http://example.com/foo/'
57
- )
58
- assert_match(
59
- %r{<li><a>qux</a></li>},
60
- res.body,
61
- "Runo#call() should return sets other than 'main' as well"
62
- )
63
-
64
- res = Rack::MockRequest.new(@runo).get(
65
- 'http://example.com/foo/sub/d=2010/'
66
- )
67
- assert_match(
68
- %r{<li><a>qux</a></li>},
69
- res.body,
70
- "Runo#call() should pass args for a sd other than 'main' as well"
71
- )
72
-
73
- res = Rack::MockRequest.new(@runo).get(
74
- 'http://example.com/foo/sub/d=2009/'
75
- )
76
- assert_no_match(
77
- %r{<li><a>qux</a></li>},
78
- res.body,
79
- "Runo#call() should pass args for a sd other than 'main' as well"
80
- )
81
- end
82
-
83
- def test_get_contact
84
- Runo.client = nil
85
- Runo::Set::Static::Folder.root.item('t_contact', 'main').storage.clear
86
-
87
- res = Rack::MockRequest.new(@runo).get(
88
- 'http://example.com/1234567890.0123/t_contact/'
89
- )
90
- assert_equal(
91
- 200,
92
- res.status,
93
- 'Runo#call to contact by nobody should return status 200'
94
- )
95
- assert_equal(
96
- <<_html,
97
- <html>
98
- <head><base href="http:///t_contact/" /><title></title></head>
99
- <body>
100
- <h1></h1>
101
- <form id="form_main" method="post" enctype="multipart/form-data" action="/t_contact/1234567890.0123/update.html">
102
- <input name="_token" type="hidden" value="#{Runo.token}" />
103
- <ul id="main" class="app-contact">
104
- <li><a><span class="text"><input type="text" name="_001-name" value="foo" size="32" /></span></a>: <span class="text"><input type="text" name="_001-comment" value="bar!" size="64" /></span></li>
105
- </ul>
106
- <div class="submit">
107
- <input name=".status-public" type="submit" value="create" />
108
- </div>
109
- </form>
110
- </body>
111
- </html>
112
- _html
113
- res.body,
114
- 'Runo#call to contact by nobody should return :create'
115
- )
116
- end
117
-
118
- def test_get_contact_forbidden
119
- Runo.client = nil
120
- Runo::Set::Static::Folder.root.item('t_contact', 'main').storage.build(
121
- '20100425_1234' => {'name' => 'cz', 'comment' => 'howdy.'}
122
- )
123
-
124
- res = Rack::MockRequest.new(@runo).get(
125
- 'http://example.com/t_contact/20100425/1234/index.html'
126
- )
127
- assert_no_match(
128
- /howdy/,
129
- res.body,
130
- 'getting an contact by nobody should not return any contents'
131
- )
132
- res = Rack::MockRequest.new(@runo).get(
133
- 'http://example.com/t_contact/20100425_1234/'
134
- )
135
- assert_no_match(
136
- /howdy/,
137
- res.body,
138
- 'peeking an contact by nobody should not return any contents'
139
- )
140
- res = Rack::MockRequest.new(@runo).get(
141
- 'http://example.com/t_contact/20100425_1234/comment/'
142
- )
143
- assert_no_match(
144
- /howdy/,
145
- res.body,
146
- 'peeking an contact by nobody should not return any contents'
147
- )
148
-
149
- res = Rack::MockRequest.new(@runo).get(
150
- 'http://example.com/t_contact/20100425/1234/done.html'
151
- )
152
- assert_no_match(
153
- /howdy/,
154
- res.body,
155
- 'getting an contact by nobody should not return any contents'
156
- )
157
- res = Rack::MockRequest.new(@runo).get(
158
- 'http://example.com/t_contact/20100425_1234/done.html'
159
- )
160
- assert_no_match(
161
- /howdy/,
162
- res.body,
163
- 'peeking an contact by nobody should not return any contents'
164
- )
165
- res = Rack::MockRequest.new(@runo).get(
166
- 'http://example.com/t_contact/20100425_1234/comment/done.html'
167
- )
168
- assert_no_match(
169
- /howdy/,
170
- res.body,
171
- 'peeking an contact by nobody should not return any contents'
172
- )
173
-
174
- res = Rack::MockRequest.new(@runo).get(
175
- 'http://example.com/t_contact/20100425/1234/preview_create.html'
176
- )
177
- assert_no_match(
178
- /howdy/,
179
- res.body,
180
- 'getting an contact by nobody should not return any contents'
181
- )
182
- res = Rack::MockRequest.new(@runo).get(
183
- 'http://example.com/t_contact/20100425_1234/preview_create.html'
184
- )
185
- assert_no_match(
186
- /howdy/,
187
- res.body,
188
- 'peeking an contact by nobody should not return any contents'
189
- )
190
- res = Rack::MockRequest.new(@runo).get(
191
- 'http://example.com/t_contact/20100425_1234/comment/preview_create.html'
192
- )
193
- assert_no_match(
194
- /howdy/,
195
- res.body,
196
- 'peeking an contact by nobody should not return any contents'
197
- )
198
- end
199
-
200
- def test_get_summary
201
- Runo.client = nil
202
- res = Rack::MockRequest.new(@runo).get(
203
- 'http://example.com/t_summary/p=1/'
204
- )
205
- assert_equal(
206
- <<'_html',
207
- <html>
208
- <head><base href="http:///t_summary/" /><title>summary</title></head>
209
- <body>
210
- <h1>summary</h1>
211
- <table id="main" class="app-blog">
212
- <tr><td><a href="/t_summary/20100326/1/read_detail.html">frank</a></td><td>hi.</td></tr>
213
- </table>
214
- </body>
215
- </html>
216
- _html
217
- res.body,
218
- 'Runo#call() should use [:tmpl][:summary] when available and appropriate'
219
- )
220
-
221
- res = Rack::MockRequest.new(@runo).get(
222
- 'http://example.com/t_summary/p=1/read_detail.html'
223
- )
224
- assert_equal(
225
- <<'_html',
226
- <html>
227
- <head><base href="http:///t_summary/" /><title>index</title></head>
228
- <body>
229
- <h1>index</h1>
230
- <ul id="main" class="app-blog">
231
- <li><a>frank</a>: hi.</li>
232
- </ul>
233
- </body>
234
- </html>
235
- _html
236
- res.body,
237
- 'Runo#call() should use [:tmpl] when the action is :read -> :detail'
238
- )
239
-
240
- Runo.client = 'root'
241
- res = Rack::MockRequest.new(@runo).get(
242
- "http://example.com/t_summary/p=1/update.html"
243
- )
244
- tid = res.body[%r{/(#{Runo::REX::TID})/}, 1]
245
- assert_equal(
246
- <<"_html",
247
- <html>
248
- <head><base href="http:///t_summary/" /><title>index</title></head>
249
- <body>
250
- <h1>index</h1>
251
- <form id="form_main" method="post" enctype="multipart/form-data" action="/t_summary/#{tid}/update.html">
252
- <input name="_token" type="hidden" value="#{Runo.token}" />
253
- <ul id="main" class="app-blog">
254
- <li><a><span class="text"><input type="text" name="20100326_0001-name" value="frank" size="32" /></span></a>: <span class="text"><input type="text" name="20100326_0001-comment" value="hi." size="64" /></span></li>
255
- </ul>
256
- <div class="submit">
257
- <input name=".status-public" type="submit" value="update" />
258
- <input name=".action-preview_delete" type="submit" value="delete..." />
259
- </div>
260
- </form>
261
- </body>
262
- </html>
263
- _html
264
- res.body,
265
- 'Runo#call() should use [:tmpl] unless the action is :read'
266
- )
267
- end
268
-
269
- def test_get_static
270
- Runo.client = 'root'
271
- res = Rack::MockRequest.new(@runo).get(
272
- 'http://example.com/foo/css/foo.css'
273
- )
274
- assert_equal(
275
- 200,
276
- res.status,
277
- 'Runo#call should return a static file if the given path is under css/, js/, etc.'
278
- )
279
- assert_equal(
280
- 'text/css',
281
- res.headers['Content-Type'],
282
- 'Runo#call should return a static file if the given path is under css/, js/, etc.'
283
- )
284
- assert_equal(
285
- "#foo {bar: baz;}\n",
286
- res.body,
287
- 'Runo#call should return a static file if the given path is under css/, js/, etc.'
288
- )
289
- end
290
-
291
- def test_get_static_not_css
292
- Runo.client = 'root'
293
- res = Rack::MockRequest.new(@runo).get(
294
- 'http://example.com/foo/not_css/foo.css'
295
- )
296
- assert_not_equal(
297
- "#foo {bar: baz;}\n",
298
- res.body,
299
- 'Runo#call should not return a static file if the step is not exactly css/, js/, etc.'
300
- )
301
- end
302
-
303
- def test_get_static_non_exist
304
- Runo.client = 'root'
305
- res = Rack::MockRequest.new(@runo).get(
306
- 'http://example.com/foo/css/non-exist.css'
307
- )
308
- assert_equal(
309
- 404,
310
- res.status,
311
- 'Runo#call should return 404 if the static file is not found'
312
- )
313
- end
314
-
315
- def test_get_static_ambiguous
316
- Runo.client = 'root'
317
- res = Rack::MockRequest.new(@runo).get(
318
- 'http://example.com/foo/css/0123456789.1234/_001/img/bar.jpg'
319
- )
320
- assert_equal(
321
- 'Not Found', # from Runo#call
322
- res.body,
323
- 'Runo#call should not look for a static file if the path includes a tid'
324
- )
325
-
326
- res = Rack::MockRequest.new(@runo).get(
327
- 'http://example.com/foo/css/20100613_1234/img/bar.jpg'
328
- )
329
- assert_equal(
330
- 'Not Found', # from Runo#call
331
- res.body,
332
- 'Runo#call should not look for a static file if the path includes an id'
333
- )
334
-
335
- res = Rack::MockRequest.new(@runo).get(
336
- 'http://example.com/foo/css/0123456789.1234/20100613_1234/img/bar.jpg'
337
- )
338
- assert_equal(
339
- 'Not Found', # from Runo#call
340
- res.body,
341
- 'Runo#call should not look for a static file if the path includes an id'
342
- )
343
-
344
- res = Rack::MockRequest.new(@runo).get(
345
- 'http://example.com/foo/css/20100613_1234/bar/id=img/'
346
- )
347
- assert_equal(
348
- 'Not Found', # from Runo#call
349
- res.body,
350
- 'Runo#call should not look for a static file if the path includes an id'
351
- )
352
- end
353
-
354
- def test_get_static_forbidden
355
- Runo.client = 'root'
356
- res = Rack::MockRequest.new(@runo).get(
357
- 'http://example.com/_users/00000000_test.yaml'
358
- )
359
- assert_no_match(
360
- /^password/,
361
- res.body,
362
- 'Runo#call should not return meta files nor raw data'
363
- )
364
-
365
- res = Rack::MockRequest.new(@runo).get(
366
- 'http://example.com/_users/css/../00000000_test.yaml'
367
- )
368
- assert_no_match(
369
- /password/,
370
- res.body,
371
- 'Runo#call should not allow bad paths'
372
- )
373
- end
374
-
375
- def test_get_static_cascade
376
- Runo.client = 'root'
377
-
378
- res = Rack::MockRequest.new(@runo).get(
379
- 'http://example.com/foo/bar/css/foo.css'
380
- )
381
- assert_equal(
382
- "#foo {bar: baz;}\n",
383
- res.body,
384
- 'Runo#call should look the acnestor dirs for the static directory'
385
- )
386
-
387
- res = Rack::MockRequest.new(@runo).get(
388
- 'http://example.com/foo/bar/css/non_exist.css'
389
- )
390
- assert_equal(
391
- 404,
392
- res.status,
393
- 'Runo#call should return 404 if the file is not found in the nearest static dir'
394
- )
395
-
396
- res = Rack::MockRequest.new(@runo).get(
397
- 'http://example.com/foo/baz/css/foo.css'
398
- )
399
- assert_equal(
400
- 404,
401
- res.status,
402
- 'Runo#call should not look the ancestor dirs if the file is not found in the nearest dir'
403
- )
404
-
405
- res = Rack::MockRequest.new(@runo).get(
406
- 'http://example.com/foo/bar/js/non_exist.css'
407
- )
408
- assert_equal(
409
- 404,
410
- res.status,
411
- 'Runo#call should return 404 if the static dir is not found in any ancestor dirs'
412
- )
413
- end
414
-
415
- def test_post_simple_create
416
- Runo.client = 'root'
417
- Runo::Set::Static::Folder.root.item('t_store', 'main').storage.clear
418
-
419
- res = Rack::MockRequest.new(@runo).post(
420
- 'http://example.com/t_store/main/update.html',
421
- {
422
- :input => "_1-name=fz&_1-comment=hi.&.status-public=create&_token=#{Runo.token}"
423
- }
424
- )
425
- assert_equal(
426
- 303,
427
- res.status,
428
- 'Runo#call with post method should return status 303'
429
- )
430
- assert_match(
431
- Runo::REX::PATH_ID,
432
- res.headers['Location'],
433
- 'Runo#call with post method should return a proper location'
434
- )
435
-
436
- res.headers['Location'] =~ Runo::REX::PATH_ID
437
- new_id = sprintf('%.8d_%.4d', $1, $2)
438
-
439
- val = Runo::Set::Static::Folder.root.item('t_store', 'main', new_id).val
440
- assert_instance_of(
441
- ::Hash,
442
- val,
443
- 'Runo#call with post method should store the item in the storage'
444
- )
445
- val.delete '_timestamp'
446
- assert_equal(
447
- {'_owner' => 'root', 'name' => 'fz', 'comment' => 'hi.'},
448
- val,
449
- 'Runo#call with post method should store the item in the storage'
450
- )
451
- end
452
-
453
- def test_post_invalid_create
454
- Runo.client = 'root'
455
- Runo::Set::Static::Folder.root.item('t_store', 'main').storage.clear
456
-
457
- res = Rack::MockRequest.new(@runo).post(
458
- "http://example.com/t_store/main/update.html",
459
- {
460
- :input => "_1-name=tooooooooooooloooooooooooooooooooooooooooong&_1-comment=hi.&.status-public=create&_token=#{Runo.token}"
461
- }
462
- )
463
- tid = res.body[%r{/(#{Runo::REX::TID})/}, 1]
464
-
465
- assert_equal(
466
- 422,
467
- res.status,
468
- 'Runo#post with an invalid new item should be an error'
469
- )
470
- assert_instance_of(
471
- Runo::Set::Dynamic,
472
- Runo.transaction[tid],
473
- 'the suspended SD should be kept in Runo.transaction'
474
- )
475
- end
476
-
477
- def test_post_empty_create
478
- Runo.client = 'root'
479
- Runo::Set::Static::Folder.root.item('t_store', 'main').storage.clear
480
-
481
- res = Rack::MockRequest.new(@runo).post(
482
- 'http://example.com/t_store/main/update.html',
483
- {
484
- :input => "_1-name=&_1-comment=&.status-public=create&_token=#{Runo.token}"
485
- }
486
- )
487
- assert_equal(
488
- 422,
489
- res.status,
490
- 'Runo#post with an empty new item should be an error'
491
- )
492
- end
493
-
494
- def test_post_empty_update
495
- Runo.client = 'root'
496
-
497
- res = Rack::MockRequest.new(@runo).post(
498
- 'http://example.com/t_store/main/update.html',
499
- {
500
- :input => "_1-name=don&_1-comment=brown.&.status-public=create&_token=#{Runo.token}"
501
- }
502
- )
503
- res.headers['Location'] =~ Runo::REX::PATH_ID
504
- new_id = sprintf('%.8d_%.4d', $1, $2)
505
-
506
- res = Rack::MockRequest.new(@runo).post(
507
- 'http://example.com/t_store/main/update.html',
508
- {
509
- :input => "#{new_id}-name=don&.status-public=update&_token=#{Runo.token}"
510
- }
511
- )
512
- assert_equal(
513
- 303,
514
- res.status,
515
- 'Runo#post without any update on the item should not raise an error'
516
- )
517
-
518
- res = Rack::MockRequest.new(@runo).get(
519
- res.headers['Location']
520
- )
521
- assert_no_match(
522
- /message/,
523
- res.body,
524
- 'Runo#post without any update on the item should not set any messages'
525
- )
526
- end
527
-
528
- def test_post_back_and_forth
529
- Runo.client = 'root'
530
-
531
- # post from a form without status
532
- res = Rack::MockRequest.new(@runo).post(
533
- 'http://example.com/t_store/main/1234567890.9999/update.html',
534
- {
535
- :input => "_1-comment=brown."
536
- }
537
- )
538
-
539
- # back to the form, post again with status
540
- res = Rack::MockRequest.new(@runo).post(
541
- 'http://example.com/t_store/main/1234567890.9999/update.html',
542
- {
543
- :input => "_1-name=don&_1-comment=brown.&.status-public=create&_token=#{Runo.token}"
544
- }
545
- )
546
- assert_equal(
547
- 303,
548
- res.status,
549
- 'Runo#post twice from the same form should work if the previous post is without status'
550
- )
551
-
552
- # back to the form one more time, post again with status
553
- res = Rack::MockRequest.new(@runo).post(
554
- 'http://example.com/t_store/main/1234567890.9999/update.html',
555
- {
556
- :input => "_1-name=roy&_1-comment=brown.&.status-public=create&_token=#{Runo.token}"
557
- }
558
- )
559
- assert_equal(
560
- 422,
561
- res.status,
562
- 'Runo#post twice from the same form should not work if the previous post is with status'
563
- )
564
- assert_equal(
565
- 'transaction expired',
566
- res.body,
567
- 'Runo#post twice from the same form should not work if the previous post is with status'
568
- )
569
- end
570
-
571
- def test_post_with_invalid_token
572
- Runo.client = 'root'
573
- res = Rack::MockRequest.new(@runo).post(
574
- 'http://example.com/t_store/main/update.html',
575
- {
576
- :input => "_1-name=fz&_1-comment=hi.&.status-public=create&_token=invalid"
577
- }
578
- )
579
- assert_equal(
580
- 403,
581
- res.status,
582
- 'Runo#call without a valid token should return status 403'
583
- )
584
- assert_equal(
585
- 'invalid token',
586
- res.body,
587
- 'Runo#call without a valid token should return status 403'
588
- )
589
- end
590
-
591
- def test_post_with_attachment
592
- Runo.client = 'root'
593
- Runo::Set::Static::Folder.root.item('t_attachment', 'main').storage.clear
594
-
595
- # post an attachment
596
- res = Rack::MockRequest.new(@runo).post(
597
- 'http://example.com/t_attachment/main/update.html',
598
- {
599
- :input => "_012-files-_1-file=wow.jpg&_012-files-_1.action-create=create&_token=#{Runo.token}"
600
- }
601
- )
602
- assert_match(
603
- 'update.html',
604
- res.headers['Location'],
605
- 'Runo#call without the root status should always return :update'
606
- )
607
- assert_equal(
608
- {},
609
- Runo::Set::Static::Folder.root.item('t_attachment', 'main').val,
610
- 'Runo#call without the root status should not update the persistent storage'
611
- )
612
-
613
- tid = res.headers['Location'][Runo::REX::TID]
614
- assert_instance_of(
615
- Runo::Set::Dynamic,
616
- Runo.transaction[tid],
617
- 'the suspended SD should be kept in Runo.transaction'
618
- )
619
-
620
- # post the item
621
- res = Rack::MockRequest.new(@runo).post(
622
- "http://example.com/#{tid}/update.html",
623
- {
624
- :input => "_012-comment=hello.&.status-public=create&_token=#{Runo.token}"
625
- }
626
- )
627
- assert_no_match(
628
- /update\.html/,
629
- res.headers['Location'],
630
- 'Runo#call with the root status should commit the transaction'
631
- )
632
- assert_not_equal(
633
- {},
634
- Runo::Set::Static::Folder.root.item('t_attachment', 'main').val,
635
- 'Runo#call with the root status should update the persistent storage'
636
- )
637
-
638
- res.headers['Location'] =~ Runo::REX::PATH_ID
639
- new_id = sprintf('%.8d_%.4d', $1, $2)
640
- new_item = Runo::Set::Static::Folder.root.item('t_attachment', 'main', new_id)
641
- assert_not_equal(
642
- {},
643
- new_item.val,
644
- 'Runo#call with the root status should commit all the pending items'
645
- )
646
- assert_equal(
647
- 'hello.',
648
- new_item.val['comment'],
649
- 'Runo#call with the root status should commit the root items'
650
- )
651
- assert_equal(
652
- {'file' => 'wow.jpg'},
653
- new_item.val['files'].values.first,
654
- 'Runo#call with the root status should commit the descendant items'
655
- )
656
-
657
- # post a reply
658
- res = Rack::MockRequest.new(@runo).post(
659
- "http://example.com/t_attachment/main/#{new_id}/replies/update.html",
660
- {
661
- :input => "_001-reply=wow.&.status-public=create&_token=#{Runo.token}"
662
- }
663
- )
664
- assert_equal(303, res.status)
665
- assert_match(
666
- %r{/#{Runo::REX::TID}/t_attachment/#{new_id}/replies/read_detail.html},
667
- res.headers['Location'],
668
- 'Runo#call with a sub-app status should commit the root item'
669
- )
670
- assert_not_equal(
671
- {},
672
- Runo::Set::Static::Folder.root.item('t_attachment', 'main', new_id, 'replies').val,
673
- 'Runo#call with a sub-app status should update the persistent storage'
674
- )
675
- end
676
-
677
- def test_post_only_attachment
678
- Runo.client = 'root'
679
- Runo::Set::Static::Folder.root.item('t_attachment', 'main').storage.clear
680
-
681
- # post an item
682
- res = Rack::MockRequest.new(@runo).post(
683
- "http://example.com/t_attachment/main/update.html",
684
- {
685
- :input => "_012-comment=abc&.status-public=create&_token=#{Runo.token}"
686
- }
687
- )
688
- res.headers['Location'] =~ Runo::REX::PATH_ID
689
- new_id = sprintf('%.8d_%.4d', $1, $2)
690
-
691
- # post an attachment
692
- tid = '1234567890.1234'
693
- res = Rack::MockRequest.new(@runo).post(
694
- "http://example.com/#{tid}/t_attachment/update.html",
695
- {
696
- :input => "#{new_id}-files-_1-file=boo.jpg&#{new_id}-files-_1.action-create=create&_token=#{Runo.token}"
697
- }
698
- )
699
- attachment_id = Runo.transaction[tid].item(new_id, 'files').val.keys.first
700
- res = Rack::MockRequest.new(@runo).post(
701
- "http://example.com/#{tid}/update.html",
702
- {
703
- :input => "#{new_id}-files-#{attachment_id}-file=boo.jpg&#{new_id}-files-_1-file=&.status-public=create&_token=#{Runo.token}"
704
- }
705
- )
706
-
707
- assert_not_nil(
708
- Runo::Set::Static::Folder.root.item('t_attachment', 'main', new_id).val['files'],
709
- 'Runo#call should treat the post with only an attachement nicely'
710
- )
711
- end
712
-
713
- def test_post_with_invalid_attachment
714
- Runo.client = 'root'
715
- Runo::Set::Static::Folder.root.item('t_attachment', 'main').storage.clear
716
-
717
- # post an invalid empty attachment
718
- res = Rack::MockRequest.new(@runo).post(
719
- 'http://example.com/t_attachment/main/update.html',
720
- {
721
- :input => "_012-files-_1-file=&_012-files-_1.action-create=create&_token=#{Runo.token}"
722
- }
723
- )
724
- tid = res.headers['Location'][Runo::REX::TID]
725
-
726
- # post the root item
727
- res = Rack::MockRequest.new(@runo).post(
728
- "http://example.com/#{tid}/update.html",
729
- {
730
- :input => "_012-comment=hello.&.status-public=create&_token=#{Runo.token}"
731
- }
732
- )
733
- assert_equal(
734
- 303,
735
- res.status,
736
- 'Runo#call with the root status should ignore the invalid empty attachment'
737
- )
738
- assert_not_equal(
739
- {},
740
- Runo::Set::Static::Folder.root.item('t_attachment', 'main').val,
741
- 'Runo#call with the root status should ignore the invalid empty attachment'
742
- )
743
-
744
- # post an invalid non-empty attachment
745
- res = Rack::MockRequest.new(@runo).post(
746
- 'http://example.com/t_attachment/main/update.html',
747
- {
748
- :input => "_012-files-_1-file=tooloooooooooooong&_012-files-_1.action-create=create&_token=#{Runo.token}"
749
- }
750
- )
751
- tid = res.headers['Location'][Runo::REX::TID]
752
-
753
- # post the root item
754
- res = Rack::MockRequest.new(@runo).post(
755
- "http://example.com/#{tid}/update.html",
756
- {
757
- :input => "_012-comment=hello.&.status-public=create&_token=#{Runo.token}"
758
- }
759
- )
760
- assert_equal(
761
- 422,
762
- res.status,
763
- 'Runo#call with the root status should not ignore the invalid non-empty attachment'
764
- )
765
- end
766
-
767
- def test_post_preview_update
768
- Runo.client = 'root'
769
- Runo::Set::Static::Folder.root.item('t_store', 'main').storage.clear
770
- base_uri = ''
771
-
772
- res = Rack::MockRequest.new(@runo).post(
773
- "http://#{base_uri}/t_store/main/update.html",
774
- {
775
- :input => ".action-preview_update=submit&_1-name=fz&_1-comment=howdy.&.status-public=create"
776
- }
777
- )
778
- tid = res.headers['Location'][Runo::REX::TID]
779
-
780
- assert_equal(
781
- 303,
782
- res.status,
783
- 'Runo#call with :preview action should return status 303 upon success'
784
- )
785
- assert_equal(
786
- "http://#{base_uri}/#{tid}/id=_1/preview_update.html",
787
- res.headers['Location'],
788
- 'Runo#call with :preview action should return a proper location'
789
- )
790
- assert_instance_of(
791
- Runo::Set::Dynamic,
792
- Runo.transaction[tid],
793
- 'the suspended SD should be kept in Runo.transaction'
794
- )
795
-
796
- res = Rack::MockRequest.new(@runo).get(
797
- "http://#{base_uri}/#{tid}/id=_1/preview_update.html"
798
- )
799
- assert_equal(
800
- <<"_html",
801
- <html>
802
- <head><base href="http://#{base_uri}/t_store/" /><title></title></head>
803
- <body>
804
- <h1></h1>
805
- <ul class="message notice">
806
- <li>please confirm.</li>
807
- </ul>
808
- <form id="form_main" method="post" enctype="multipart/form-data" action="/#{tid}/update.html">
809
- <input name="_token" type="hidden" value="#{Runo.token}" />
810
- <ul id="main" class="app-blog">
811
- <li><a>fz</a>: howdy.<input type="hidden" name="_1.action" value="create" /></li>
812
- </ul>
813
- <div class="submit">
814
- <input name=".status-public" type="submit" value="create" />
815
- </div>
816
- </form>
817
- </body>
818
- </html>
819
- _html
820
- res.body,
821
- 'Runo#call with :preview action should set a proper transaction upon success'
822
- )
823
-
824
- res = Rack::MockRequest.new(@runo).post(
825
- "http://example.com/#{tid}/update.html",
826
- {
827
- :input => "_1.action=create&.status-public=create&_token=#{Runo.token}"
828
- }
829
- )
830
- assert_equal(
831
- 303,
832
- res.status,
833
- 'Runo#call with post method should return status 303'
834
- )
835
- assert_match(
836
- Runo::REX::PATH_ID,
837
- res.headers['Location'],
838
- 'Runo#call with post method should return a proper location'
839
- )
840
-
841
- res.headers['Location'] =~ Runo::REX::PATH_ID
842
- new_id = sprintf('%.8d_%.4d', $1, $2)
843
-
844
- val = Runo::Set::Static::Folder.root.item('t_store', 'main', new_id).val
845
- assert_instance_of(
846
- ::Hash,
847
- val,
848
- 'Runo#call with post method should store the item in the storage'
849
- )
850
- val.delete '_timestamp'
851
- assert_equal(
852
- {'_owner' => 'root', 'name' => 'fz', 'comment' => 'howdy.'},
853
- val,
854
- 'Runo#call with post method should store the item in the storage'
855
- )
856
- end
857
-
858
- def test_post_preview_invalid
859
- Runo.client = 'root'
860
-
861
- res = Rack::MockRequest.new(@runo).post(
862
- 'http://example.com/t_store/main/update.html',
863
- {
864
- :input => ".action-preview_update=submit&_1-name=verrrrrrrrrrrrrrrrrrrrrrrrrrrrrrylong&_1-comment=howdy.&.status-public=create"
865
- }
866
- )
867
- assert_equal(
868
- 422,
869
- res.status,
870
- 'Runo#call with :preview action & malformed input should return status 422'
871
- )
872
- assert_match(
873
- /malformed input\./,
874
- res.body,
875
- 'Runo#call with :preview action & malformed input should return :update'
876
- )
877
-
878
- tid = res.body[%r{/(#{Runo::REX::TID})/}, 1]
879
- assert_instance_of(
880
- Runo::Set::Dynamic,
881
- Runo.transaction[tid],
882
- 'the suspended SD should be kept in Runo.transaction'
883
- )
884
- end
885
-
886
- def test_post_contact
887
- Runo.client = nil
888
- Runo::Set::Static::Folder.root.item('t_contact', 'main').storage.clear
889
-
890
- res = Rack::MockRequest.new(@runo).post(
891
- 'http://example.com/t_contact/main/update.html',
892
- {
893
- :input => "_1-name=fz&_1-comment=hi.&.status-public=create&_token=#{Runo.token}"
894
- }
895
- )
896
- assert_equal(
897
- 303,
898
- res.status,
899
- 'Runo#call with post method should return status 303'
900
- )
901
- assert_no_match(
902
- Runo::REX::PATH_ID,
903
- res.headers['Location'],
904
- 'Runo#call should not tell the item location when the workflow is contact'
905
- )
906
-
907
- res = Rack::MockRequest.new(@runo).get(
908
- res.headers['Location'],
909
- {}
910
- )
911
- assert_match(
912
- /thank you!/,
913
- res.body,
914
- 'Runo#call should refer to (action).html if available'
915
- )
916
- assert_no_match(
917
- /message/,
918
- res.body,
919
- 'Runo#call should not include messages for action :done'
920
- )
921
- assert_no_match(
922
- /login/,
923
- res.body,
924
- 'Runo#call should always allow action :done'
925
- )
926
- end
927
-
928
- def test_post_contact_forbidden
929
- Runo.client = nil
930
- Runo::Set::Static::Folder.root.item('t_contact', 'main').storage.build(
931
- '20100425_1234' => {'_owner' => 'nobody', 'name' => 'cz', 'comment' => 'howdy.'}
932
- )
933
-
934
- res = Rack::MockRequest.new(@runo).post(
935
- 'http://example.com/t_contact/main/update.html',
936
- {
937
- :input => "20100425_1234-comment=modified&20100425_1234.action=create&.status-public=create"
938
- }
939
- )
940
- assert_equal(
941
- 403,
942
- res.status,
943
- 'Runo#call should not allow nobody to update an existing contact'
944
- )
945
- assert_equal(
946
- {'20100425_1234' => {'_owner' => 'nobody', 'name' => 'cz', 'comment' => 'howdy.'}},
947
- Runo::Set::Static::Folder.root.item('t_contact', 'main').storage.val,
948
- 'Runo#call should not allow nobody to update an existing contact'
949
- )
950
-
951
- res = Rack::MockRequest.new(@runo).post(
952
- 'http://example.com/t_contact/main/create.html',
953
- {
954
- :input => "20100425_1234-comment=modified&20100425_1234.action=create&.status-public=create"
955
- }
956
- )
957
- assert_equal(
958
- 403,
959
- res.status,
960
- 'Runo#call should not allow nobody to update an existing contact'
961
- )
962
- assert_equal(
963
- {'20100425_1234' => {'_owner' => 'nobody', 'name' => 'cz', 'comment' => 'howdy.'}},
964
- Runo::Set::Static::Folder.root.item('t_contact', 'main').storage.val,
965
- 'Runo#call should not allow nobody to update an existing contact'
966
- )
967
-
968
- res = Rack::MockRequest.new(@runo).post(
969
- 'http://example.com/t_contact/main/20100425_1234/create.html',
970
- {
971
- :input => "comment=modified&.action=create&.status-public=create"
972
- }
973
- )
974
- assert_equal(
975
- 403,
976
- res.status,
977
- 'Runo#call should not allow nobody to update an existing contact'
978
- )
979
- assert_equal(
980
- {'20100425_1234' => {'_owner' => 'nobody', 'name' => 'cz', 'comment' => 'howdy.'}},
981
- Runo::Set::Static::Folder.root.item('t_contact', 'main').storage.val,
982
- 'Runo#call should not allow nobody to update an existing contact'
983
- )
984
- end
985
-
986
- def test_post_wrong_action
987
- Runo.client = nil
988
- res = Rack::MockRequest.new(@runo).post(
989
- 'http://example.com/t_store/main/read.html',
990
- {
991
- :input => "_1-name=fz&_1-comment=hi.&.status-public=create"
992
- }
993
- )
994
- assert_equal(
995
- 403,
996
- res.status,
997
- 'post with an action other than :update should be regarded as :update'
998
- )
999
-
1000
- Runo.client = 'root'
1001
- res = Rack::MockRequest.new(@runo).post(
1002
- 'http://example.com/t_store/main/read.html',
1003
- {
1004
- :input => "_1-name=fz&_1-comment=hi.&.status-public=create&_token=#{Runo.token}"
1005
- }
1006
- )
1007
- assert_equal(
1008
- 303,
1009
- res.status,
1010
- 'post with an action other than :update should be regarded as :update'
1011
- )
1012
- end
1013
-
1014
- def test_post_login
1015
- Runo.client = nil
1016
- res = Rack::MockRequest.new(@runo).post(
1017
- "http://example.com/foo/20100222/1/login.html",
1018
- {
1019
- :input => "id=test&pw=test&dest_action=update"
1020
- }
1021
- )
1022
- assert_equal(
1023
- 'test',
1024
- Runo.client,
1025
- 'Runo#call with :login action should set Runo.client upon success'
1026
- )
1027
- assert_equal(
1028
- 303,
1029
- res.status,
1030
- 'Runo#call with :login action should return status 303'
1031
- )
1032
- assert_match(
1033
- %r{/foo/20100222/1/update.html},
1034
- res.headers['Location'],
1035
- 'Runo#call with :login action should return a proper location'
1036
- )
1037
- end
1038
-
1039
- def test_post_login_with_wrong_pw
1040
- Runo.client = nil
1041
- res = Rack::MockRequest.new(@runo).post(
1042
- "http://example.com/foo/20100222/1/login.html",
1043
- {
1044
- :input => "id=test&pw=wrong&dest_action=update"
1045
- }
1046
- )
1047
- assert_equal(
1048
- 'nobody',
1049
- Runo.client,
1050
- 'Runo#call with :login action should not set Runo.client upon failure'
1051
- )
1052
- assert_equal(
1053
- 422,
1054
- res.status,
1055
- 'Runo#call with :login action should return status 422 upon failure'
1056
- )
1057
- end
1058
-
1059
- def test_post_logout
1060
- Runo.client = 'frank'
1061
- res = Rack::MockRequest.new(@runo).post(
1062
- "http://example.com/foo/20100222/1/logout.html?_token=#{Runo.token}",
1063
- {}
1064
- )
1065
- assert_equal(
1066
- 'nobody',
1067
- Runo.client,
1068
- 'Runo#call with :logout action should unset Runo.client'
1069
- )
1070
- assert_equal(
1071
- 303,
1072
- res.status,
1073
- 'Runo#call with :logout action should return status 303'
1074
- )
1075
- assert_match(
1076
- %r{/foo/20100222/1/index.html},
1077
- res.headers['Location'],
1078
- 'Runo#call with :logout action should return a proper location'
1079
- )
1080
- end
1081
-
1082
- def test_post_logout_with_invalid_token
1083
- Runo.client = 'frank'
1084
- res = Rack::MockRequest.new(@runo).post(
1085
- "http://example.com/foo/20100222/1/logout.html?_token=invalid",
1086
- {}
1087
- )
1088
- assert_equal(
1089
- 403,
1090
- res.status,
1091
- 'Runo#call without a valid token should return status 403'
1092
- )
1093
- assert_equal(
1094
- 'invalid token',
1095
- res.body,
1096
- 'Runo#call without a valid token should return status 403'
1097
- )
1098
- assert_equal(
1099
- 'frank',
1100
- Runo.client,
1101
- 'Runo#call without a valid token should return status 403'
1102
- )
1103
- end
1104
-
1105
- def test_get_logout
1106
- Runo.client = 'frank'
1107
- res = Rack::MockRequest.new(@runo).get(
1108
- "http://example.com/foo/20100222/1/logout.html?_token=#{Runo.token}",
1109
- {}
1110
- )
1111
- assert_equal(
1112
- 'nobody',
1113
- Runo.client,
1114
- 'Runo#call with :logout action should work via both get and post'
1115
- )
1116
- assert_match(
1117
- %r{/foo/20100222/1/index.html},
1118
- res.headers['Location'],
1119
- 'Runo#call with :logout action should work via both get and post'
1120
- )
1121
- end
1122
-
1123
- def test_message_notice
1124
- Runo.client = 'root'
1125
- Runo::Set::Static::Folder.root.item('t_store', 'main').storage.clear
1126
-
1127
- res = Rack::MockRequest.new(@runo).post(
1128
- 'http://example.com/t_store/main/update.html',
1129
- {
1130
- :input => "_2-name=fz&_2-comment=hi.&.status-public=create&_token=#{Runo.token}"
1131
- }
1132
- )
1133
- assert_match(
1134
- %r{#{Runo::REX::TID}/t_store/},
1135
- res.headers['Location'],
1136
- 'Runo#call should return both the base path and tid at :done'
1137
- )
1138
-
1139
- location = res.headers['Location']
1140
- location =~ Runo::REX::PATH_ID
1141
- new_id = sprintf('%.8d_%.4d', $1, $2)
1142
-
1143
- res = Rack::MockRequest.new(@runo).get location
1144
- assert_match(
1145
- /created 1 entry\./,
1146
- res.body,
1147
- 'Runo#call should include the current message'
1148
- )
1149
-
1150
- res = Rack::MockRequest.new(@runo).get location
1151
- assert_no_match(
1152
- /created 1 entry\./,
1153
- res.body,
1154
- 'Runo#call should not include the message twice'
1155
- )
1156
-
1157
- res = Rack::MockRequest.new(@runo).post(
1158
- 'http://example.com/t_store/main/update.html',
1159
- {
1160
- :input => "#{new_id}-comment=howdy.&.status-public=update&_token=#{Runo.token}"
1161
- }
1162
- )
1163
- res = Rack::MockRequest.new(@runo).get(
1164
- res.headers['Location']
1165
- )
1166
- assert_match(
1167
- /updated 1 entry\./,
1168
- res.body,
1169
- 'Runo#call should include a message according to the action'
1170
- )
1171
-
1172
- res = Rack::MockRequest.new(@runo).post(
1173
- 'http://example.com/t_store/main/update.html',
1174
- {
1175
- :input => "#{new_id}.action=delete&.status-public=delete&_token=#{Runo.token}"
1176
- }
1177
- )
1178
- res = Rack::MockRequest.new(@runo).get(
1179
- res.headers['Location']
1180
- )
1181
- assert_match(
1182
- /deleted 1 entry\./,
1183
- res.body,
1184
- 'Runo#call should include a message according to the action'
1185
- )
1186
- end
1187
-
1188
- def test_message_notice_plural
1189
- Runo.client = 'root'
1190
-
1191
- res = Rack::MockRequest.new(@runo).post(
1192
- 'http://example.com/t_attachment/main/update.html',
1193
- {
1194
- :input => "_1-comment=foo&_2-comment=bar&.status-public=create&_token=#{Runo.token}"
1195
- }
1196
- )
1197
- res = Rack::MockRequest.new(@runo).get(
1198
- res.headers['Location']
1199
- )
1200
- assert_match(
1201
- /created 2 tArticles\./,
1202
- res.body,
1203
- 'the message should be plural if more than one item have results.'
1204
- )
1205
- end
1206
-
1207
- def test_message_alert
1208
- Runo.client = 'nobody'
1209
-
1210
- res = Rack::MockRequest.new(@runo).get(
1211
- "http://example.com/foo/20091120/1/update.html"
1212
- )
1213
- assert_match(
1214
- /please login\./,
1215
- res.body,
1216
- 'Runo#call should include the current message'
1217
- )
1218
- end
1219
-
1220
- def test_message_error
1221
- Runo.client = 'root'
1222
- Runo::Set::Static::Folder.root.item('t_store', 'main').storage.clear
1223
-
1224
- res = Rack::MockRequest.new(@runo).post(
1225
- 'http://example.com/t_store/main/update.html',
1226
- {
1227
- :input => "_2-name=verrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrylongname&.status-public=create&_token=#{Runo.token}"
1228
- }
1229
- )
1230
- assert_match(
1231
- /malformed input\./,
1232
- res.body,
1233
- 'Runo#call should include the current message'
1234
- )
1235
- end
1236
-
1237
- def test_message_i18n
1238
- Runo.client = 'root'
1239
- Runo::Set::Static::Folder.root.item('t_store', 'main').storage.clear
1240
-
1241
- res = Rack::MockRequest.new(@runo).post(
1242
- 'http://example.com/t_store/main/update.html',
1243
- {
1244
- :input => "_3-name=&.status-public=create&_token=#{Runo.token}",
1245
- 'HTTP_ACCEPT_LANGUAGE' => 'en, de',
1246
- }
1247
- )
1248
- assert_match(
1249
- /malformed input/,
1250
- res.body,
1251
- "Runo::I18n.find_msg should return at least an empty hash for 'en' as HTTP_ACCEPT_LANGUAGE."
1252
- )
1253
-
1254
- res = Rack::MockRequest.new(@runo).post(
1255
- 'http://example.com/t_store/main/update.html',
1256
- {
1257
- :input => "_3-name=&.status-public=create&_token=#{Runo.token}",
1258
- 'HTTP_ACCEPT_LANGUAGE' => 'en-US, de',
1259
- }
1260
- )
1261
- assert_match(
1262
- /malformed input/,
1263
- res.body,
1264
- "Runo::I18n.find_msg should return at least an empty hash for 'en' as HTTP_ACCEPT_LANGUAGE."
1265
- )
1266
-
1267
- res = Rack::MockRequest.new(@runo).post(
1268
- 'http://example.com/t_store/main/update.html',
1269
- {
1270
- :input => "_3-name=&.status-public=create&_token=#{Runo.token}",
1271
- 'HTTP_ACCEPT_LANGUAGE' => 'de, en',
1272
- }
1273
- )
1274
- assert_match(
1275
- /Fehlerhafte Eingabe/,
1276
- res.body,
1277
- 'Set::Dynamic#_g_message should be i18nized according to HTTP_ACCEPT_LANGUAGE.'
1278
- )
1279
- end
1280
-
1281
- end