runo 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (149) hide show
  1. data/LICENSE +19 -0
  2. data/README.rdoc +120 -0
  3. data/bin/runo +35 -0
  4. data/lib/_error.rb +14 -0
  5. data/lib/_field.rb +260 -0
  6. data/lib/_i18n.rb +141 -0
  7. data/lib/_parser.rb +243 -0
  8. data/lib/_path.rb +86 -0
  9. data/lib/_storage/_storage.rb +213 -0
  10. data/lib/_storage/file.rb +200 -0
  11. data/lib/_storage/sequel.rb +174 -0
  12. data/lib/_storage/temp.rb +73 -0
  13. data/lib/_widget/action_create.rb +23 -0
  14. data/lib/_widget/action_login.rb +22 -0
  15. data/lib/_widget/action_signup.rb +16 -0
  16. data/lib/_widget/action_update.rb +16 -0
  17. data/lib/_widget/crumb.rb +24 -0
  18. data/lib/_widget/done.rb +16 -0
  19. data/lib/_widget/login.rb +25 -0
  20. data/lib/_widget/me.rb +31 -0
  21. data/lib/_widget/message.rb +51 -0
  22. data/lib/_widget/navi.rb +88 -0
  23. data/lib/_widget/submit.rb +49 -0
  24. data/lib/_widget/view_ym.rb +77 -0
  25. data/lib/_workflow/_workflow.rb +89 -0
  26. data/lib/_workflow/attachment.rb +50 -0
  27. data/lib/_workflow/blog.rb +28 -0
  28. data/lib/_workflow/contact.rb +23 -0
  29. data/lib/_workflow/forum.rb +26 -0
  30. data/lib/_workflow/register.rb +39 -0
  31. data/lib/meta/_meta.rb +20 -0
  32. data/lib/meta/group.rb +19 -0
  33. data/lib/meta/id.rb +59 -0
  34. data/lib/meta/owner.rb +21 -0
  35. data/lib/meta/timestamp.rb +118 -0
  36. data/lib/runo.rb +396 -0
  37. data/lib/scalar/checkbox.rb +68 -0
  38. data/lib/scalar/file.rb +144 -0
  39. data/lib/scalar/img.rb +112 -0
  40. data/lib/scalar/password.rb +58 -0
  41. data/lib/scalar/radio.rb +47 -0
  42. data/lib/scalar/select.rb +47 -0
  43. data/lib/scalar/text.rb +38 -0
  44. data/lib/scalar/textarea.rb +35 -0
  45. data/lib/scalar/textarea_pre.rb +14 -0
  46. data/lib/scalar/textarea_wiki.rb +173 -0
  47. data/lib/set/_set.rb +195 -0
  48. data/lib/set/dynamic.rb +177 -0
  49. data/lib/set/static.rb +102 -0
  50. data/lib/set/static_folder.rb +96 -0
  51. data/locale/en/index.po +242 -0
  52. data/locale/index.pot +243 -0
  53. data/locale/ja/index.po +242 -0
  54. data/locale/lazy_parser.rb +54 -0
  55. data/skel/config.ru +27 -0
  56. data/skel/skin/_users/00000000_frank-avatar.jpg +0 -0
  57. data/skel/skin/_users/00000000_frank-avatar_small.jpg +0 -0
  58. data/skel/skin/_users/00000000_frank.yaml +12 -0
  59. data/skel/skin/_users/00000000_root-avatar.jpg +0 -0
  60. data/skel/skin/_users/00000000_root-avatar_small.jpg +0 -0
  61. data/skel/skin/_users/00000000_root.yaml +11 -0
  62. data/skel/skin/_users/css/users.css +21 -0
  63. data/skel/skin/_users/css/users.less +25 -0
  64. data/skel/skin/_users/done.html +42 -0
  65. data/skel/skin/_users/index.html +46 -0
  66. data/skel/skin/_users/index.yaml +3 -0
  67. data/skel/skin/_users/summary.html +40 -0
  68. data/skel/skin/css/base.css +93 -0
  69. data/skel/skin/css/base.less +139 -0
  70. data/skel/skin/css/coax.css +199 -0
  71. data/skel/skin/css/coax.less +244 -0
  72. data/skel/skin/examples/blog/20091214_0001.yaml +8 -0
  73. data/skel/skin/examples/blog/20100630_0001.yaml +8 -0
  74. data/skel/skin/examples/blog/20100630_0002.yaml +14 -0
  75. data/skel/skin/examples/blog/20100701_0001.yaml +8 -0
  76. data/skel/skin/examples/blog/20100701_0002-a-20100701_0001-f.jpg +0 -0
  77. data/skel/skin/examples/blog/20100701_0002-a-20100701_0001-f_small.jpg +0 -0
  78. data/skel/skin/examples/blog/20100701_0002.yaml +19 -0
  79. data/skel/skin/examples/blog/frank/20100701_0001.yaml +10 -0
  80. data/skel/skin/examples/blog/frank/index.yaml +4 -0
  81. data/skel/skin/examples/blog/index.html +51 -0
  82. data/skel/skin/examples/blog/rss.xml +18 -0
  83. data/skel/skin/examples/contact/20100701_0001-file.txt +1 -0
  84. data/skel/skin/examples/contact/20100701_0001.yaml +15 -0
  85. data/skel/skin/examples/contact/20100701_0002.yaml +8 -0
  86. data/skel/skin/examples/contact/20100701_0003.yaml +9 -0
  87. data/skel/skin/examples/contact/index.html +47 -0
  88. data/skel/skin/examples/contact/js/contact.js +13 -0
  89. data/skel/skin/examples/contact/summary.html +54 -0
  90. data/skel/skin/examples/forum/20100701_0001.yaml +41 -0
  91. data/skel/skin/examples/forum/20100701_0002.yaml +25 -0
  92. data/skel/skin/examples/forum/index.html +68 -0
  93. data/skel/skin/examples/forum/summary.html +47 -0
  94. data/skel/skin/examples/index.html +75 -0
  95. data/skel/skin/index.html +41 -0
  96. data/skel/skin/js/base.js +50 -0
  97. data/t/locale/de/index.po +19 -0
  98. data/t/locale/en-GB/index.po +25 -0
  99. data/t/locale/ja/index.po +30 -0
  100. data/t/skin/_users/00000000_test.yaml +3 -0
  101. data/t/skin/_users/index.html +13 -0
  102. data/t/skin/foo/20091120_0001.yaml +7 -0
  103. data/t/skin/foo/bar/20091120_0001.yaml +5 -0
  104. data/t/skin/foo/bar/index.yaml +5 -0
  105. data/t/skin/foo/baz/css/baz.css +1 -0
  106. data/t/skin/foo/css/foo.css +1 -0
  107. data/t/skin/foo/index.html +14 -0
  108. data/t/skin/foo/index.yaml +7 -0
  109. data/t/skin/foo/not_css/foo.css +1 -0
  110. data/t/skin/foo/sub-20100306_0001.yaml +3 -0
  111. data/t/skin/index.yaml +3 -0
  112. data/t/skin/t_attachment/index.html +13 -0
  113. data/t/skin/t_contact/done.html +6 -0
  114. data/t/skin/t_contact/index.html +9 -0
  115. data/t/skin/t_file/index.html +16 -0
  116. data/t/skin/t_img/index.html +14 -0
  117. data/t/skin/t_img/test.jpg +0 -0
  118. data/t/skin/t_select/index.html +9 -0
  119. data/t/skin/t_store/index.html +9 -0
  120. data/t/skin/t_summary/20100326_0001.yaml +3 -0
  121. data/t/skin/t_summary/create.html +9 -0
  122. data/t/skin/t_summary/index.html +9 -0
  123. data/t/skin/t_summary/summary.html +9 -0
  124. data/t/t.rb +27 -0
  125. data/t/test_checkbox.rb +273 -0
  126. data/t/test_field.rb +330 -0
  127. data/t/test_file.rb +900 -0
  128. data/t/test_id.rb +215 -0
  129. data/t/test_img.rb +328 -0
  130. data/t/test_meta.rb +57 -0
  131. data/t/test_parser.rb +1266 -0
  132. data/t/test_password.rb +188 -0
  133. data/t/test_radio.rb +226 -0
  134. data/t/test_role.rb +249 -0
  135. data/t/test_runo.rb +742 -0
  136. data/t/test_runo_call.rb +1286 -0
  137. data/t/test_runo_i18n.rb +318 -0
  138. data/t/test_select.rb +182 -0
  139. data/t/test_set_complex.rb +527 -0
  140. data/t/test_set_dynamic.rb +1504 -0
  141. data/t/test_set_folder.rb +515 -0
  142. data/t/test_set_permit.rb +246 -0
  143. data/t/test_set_static.rb +445 -0
  144. data/t/test_storage.rb +915 -0
  145. data/t/test_text.rb +125 -0
  146. data/t/test_textarea.rb +138 -0
  147. data/t/test_timestamp.rb +473 -0
  148. data/t/test_workflow.rb +367 -0
  149. metadata +345 -0
@@ -0,0 +1,515 @@
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_Set_Folder < Test::Unit::TestCase
9
+
10
+ def setup
11
+ Runo.client = 'root'
12
+ Runo.current[:base] = nil
13
+ Runo.current[:uri] = nil
14
+ end
15
+
16
+ def teardown
17
+ end
18
+
19
+ def test_root
20
+ root = Runo::Set::Static::Folder.root
21
+ assert_instance_of(
22
+ Runo::Set::Static::Folder,
23
+ root,
24
+ 'Folder.root should return the root folder instance'
25
+ )
26
+ end
27
+
28
+ def test_initialize
29
+ folder = Runo::Set::Static::Folder.new(:id => 'foo', :parent => nil)
30
+ assert_match(
31
+ /^<html>/,
32
+ folder[:html],
33
+ 'Folder#initialize should load [:html] from [:dir]/index.html'
34
+ )
35
+ assert_instance_of(
36
+ Runo::Set::Dynamic,
37
+ folder.item('main'),
38
+ 'Folder#initialize should load the items according to [:html]'
39
+ )
40
+ end
41
+
42
+ def test_meta_html_dir
43
+ folder = Runo::Set::Static::Folder.root.item('foo')
44
+ assert_equal(
45
+ '/foo',
46
+ folder[:html_dir],
47
+ "Folder#meta_html_dir should return meta_dir if there is 'index.html'"
48
+ )
49
+
50
+ folder = Runo::Set::Static::Folder.root.item('foo', 'bar')
51
+ assert_equal(
52
+ '/foo',
53
+ folder[:html_dir],
54
+ "Folder#meta_html_dir should return parent[:html_dir] if there is no 'index.html' in [:dir]"
55
+ )
56
+ end
57
+
58
+ def test_meta_href
59
+ folder = Runo::Set::Static::Folder.root.item('t_summary')
60
+
61
+ Runo.current[:uri] = 'http://example.com'
62
+ assert_equal(
63
+ 'http://example.com/t_summary/',
64
+ folder[:href],
65
+ 'Folder#meta_href should return a full URI when Runo.uri is available'
66
+ )
67
+
68
+ Runo.current[:uri] = nil
69
+ assert_equal(
70
+ '/t_summary/',
71
+ folder[:href],
72
+ 'Folder#meta_href should return [:dir] when Runo.uri is not available'
73
+ )
74
+ end
75
+
76
+ def test_load_yaml
77
+ folder = Runo::Set::Static::Folder.new(:id => 'foo', :parent => nil)
78
+ assert_equal(
79
+ 'Foo Folder',
80
+ folder[:label],
81
+ 'Folder#initialize should load metas from index.yaml'
82
+ )
83
+ assert_equal(
84
+ 'frank',
85
+ folder[:admin],
86
+ 'Folder#initialize should load metas from index.yaml'
87
+ )
88
+ end
89
+
90
+ def test_load_yaml_child_folder
91
+ folder = Runo::Set::Static::Folder.new(:id => 'foo', :parent => nil)
92
+ child = folder.item('bar')
93
+ assert_instance_of(
94
+ Runo::Set::Static::Folder,
95
+ child,
96
+ 'Folder#item should look the real directory for the child item'
97
+ )
98
+ assert_equal(
99
+ 'Bar Folder',
100
+ child[:label],
101
+ 'Folder#initialize should load metas from index.yaml'
102
+ )
103
+ assert_equal(
104
+ nil,
105
+ child[:admin],
106
+ 'Folder#initialize should not inherit metas from [:parent]'
107
+ )
108
+ end
109
+
110
+ def test_item
111
+ folder = Runo::Set::Static::Folder.root.item('foo')
112
+ assert_instance_of(
113
+ Runo::Set::Static,
114
+ folder.item('main', '20091120_0001'),
115
+ 'Folder#item should work just like any other sets'
116
+ )
117
+ assert_instance_of(
118
+ Runo::Set::Static,
119
+ folder.item('20091120_0001'),
120
+ "Folder#item should delegate to item('main') if full-formatted :id is given"
121
+ )
122
+ end
123
+
124
+ def test_merge_tmpl
125
+ folder = Runo::Set::Static::Folder.root
126
+
127
+ index = {
128
+ :item => {
129
+ 'main' => {
130
+ :item => {
131
+ 'default' => {
132
+ :tmpl => {:index => '<li><ul>$(files)</ul></li>'},
133
+ :item => {
134
+ 'files' => {
135
+ :tmpl => {:index => '<ol>$()</ol>'},
136
+ :item => {
137
+ 'default' => {
138
+ :tmpl => {:index => '<li>$(file)</li>'},
139
+ :item => {'file' => {:klass => 'text'}},
140
+ },
141
+ },
142
+ },
143
+ },
144
+ },
145
+ },
146
+ :tmpl => {:index => '<ul>$()</ul>'},
147
+ },
148
+ },
149
+ :tmpl => {:index => '<html>$(main)</html>'},
150
+ }
151
+ summary = {
152
+ :item => {
153
+ 'main' => {
154
+ :foo => 'this should not be merged.',
155
+ :item => {
156
+ 'default' => {
157
+ :bar => 'this should not be merged.',
158
+ :tmpl => {:summary => '<li class ="s"><ul>$(files)</ul></li>'},
159
+ :item => {
160
+ 'files' => {
161
+ :baz => 'this should not be merged.',
162
+ :tmpl => {:summary => '<ol class ="s">$()</ol>'},
163
+ :item => {
164
+ 'default' => {
165
+ :qux => 'this should not be merged.',
166
+ :tmpl => {:summary => '<li class ="s">$(file)</li>'},
167
+ },
168
+ },
169
+ },
170
+ },
171
+ },
172
+ },
173
+ :tmpl => {:summary => '<ul class ="s">$()</ul>'},
174
+ },
175
+ },
176
+ :tmpl => {:summary => '<html class ="s">$(main)</html>'},
177
+ }
178
+
179
+ assert_equal(
180
+ {
181
+ :item => {
182
+ 'main' => {
183
+ :item => {
184
+ 'default' => {
185
+ :tmpl => {
186
+ :index => '<li><ul>$(files)</ul></li>',
187
+ :summary => '<li class ="s"><ul>$(files)</ul></li>',
188
+ },
189
+ :item => {
190
+ 'files' => {
191
+ :tmpl => {
192
+ :index => '<ol>$()</ol>',
193
+ :summary => '<ol class ="s">$()</ol>',
194
+ },
195
+ :item => {
196
+ 'default' => {
197
+ :tmpl => {
198
+ :index => '<li>$(file)</li>',
199
+ :summary => '<li class ="s">$(file)</li>',
200
+ },
201
+ :item => {'file' => {:klass => 'text'}},
202
+ },
203
+ },
204
+ },
205
+ },
206
+ },
207
+ },
208
+ :tmpl => {
209
+ :index => '<ul>$()</ul>',
210
+ :summary => '<ul class ="s">$()</ul>',
211
+ },
212
+ },
213
+ },
214
+ :tmpl => {
215
+ :index => '<html>$(main)</html>',
216
+ :summary => '<html class ="s">$(main)</html>',
217
+ },
218
+ },
219
+ folder.send(:merge_tmpl, index, summary),
220
+ 'Folder#merge_tmpl should merge parsed metas'
221
+ )
222
+ end
223
+
224
+ def test_tmpl_summary
225
+ folder = Runo::Set::Static::Folder.root.item('t_summary')
226
+ assert_equal(
227
+ <<'_html',
228
+ <html>
229
+ <head><base href="@(href)" /><title>index</title></head>
230
+ <body>
231
+ <h1>index</h1>
232
+ $(main.message)$(main)</body>
233
+ </html>
234
+ _html
235
+ folder[:tmpl][:index],
236
+ 'Folder#initialize should load [:tmpl][:index] from [:dir]/index.html'
237
+ )
238
+ assert_equal(
239
+ <<'_html',
240
+ <html>
241
+ <head><base href="@(href)" /><title>summary</title></head>
242
+ <body>
243
+ <h1>summary</h1>
244
+ $(main.message)$(main)</body>
245
+ </html>
246
+ _html
247
+ folder[:tmpl][:summary],
248
+ 'Folder#initialize should load [:tmpl][:summary] from [:dir]/summary.html'
249
+ )
250
+
251
+ assert_equal(
252
+ <<'_html'.chomp,
253
+ <ul id="@(name)" class="runo-blog">
254
+ $()</ul>
255
+ $(.navi)$(.submit)$(.action_create)
256
+ _html
257
+ folder[:item]['main'][:tmpl][:index],
258
+ 'Folder#initialize should load [:tmpl] of the child items'
259
+ )
260
+ assert_equal(
261
+ <<'_html'.chomp,
262
+ <table id="@(name)" class="runo-blog">
263
+ $()</table>
264
+ $(.navi)$(.submit)$(.action_create)
265
+ _html
266
+ folder[:item]['main'][:tmpl][:summary],
267
+ 'Folder#initialize should load [:tmpl][:summary] of the child items'
268
+ )
269
+
270
+ assert_equal(
271
+ <<'_html',
272
+ <li>$(.a_update)$(name)</a>: $(comment)$(.hidden)</li>
273
+ _html
274
+ folder[:item]['main'][:item]['default'][:tmpl][:index],
275
+ 'Folder#initialize should load [:tmpl] of all the decendant items'
276
+ )
277
+ assert_equal(
278
+ <<'_html',
279
+ <tr><td><a href="$(.uri_detail)">$(name)</a></td><td>$(comment)</td></tr>
280
+ _html
281
+ folder[:item]['main'][:item]['default'][:tmpl][:summary],
282
+ 'Folder#initialize should load [:tmpl][:summary] of all the decendant items'
283
+ )
284
+ end
285
+
286
+ def test_href
287
+ folder = Runo::Set::Static::Folder.root.item('t_summary')
288
+
289
+ assert_match(
290
+ '<base href="@(href)" />',
291
+ folder[:tmpl][:index],
292
+ 'Folder#initialize should supplement <base href=...> to [:tmpl][*]'
293
+ )
294
+ assert_match(
295
+ '<base href="@(href)" />',
296
+ folder[:tmpl][:summary],
297
+ 'Folder#initialize should supplement <base href=...> to [:tmpl][*]'
298
+ )
299
+ end
300
+
301
+ def test_get_summary
302
+ folder = Runo::Set::Static::Folder.root.item('t_summary')
303
+
304
+ assert_equal(
305
+ <<'_html',
306
+ <html>
307
+ <head><base href="/t_summary/" /><title>summary</title></head>
308
+ <body>
309
+ <h1>summary</h1>
310
+ <table id="main" class="runo-blog">
311
+ <tr><td><a href="/t_summary/20100326/1/read_detail.html">frank</a></td><td>hi.</td></tr>
312
+ </table>
313
+ <div class="action_create"><a href="/t_summary/create.html">create new entry...</a></div>
314
+ </body>
315
+ </html>
316
+ _html
317
+ folder.get(
318
+ 'main' => {:conds => {:p => 1}}
319
+ ),
320
+ 'Set#get should use [:tmpl][:summary] when available and appropriate'
321
+ )
322
+ assert_equal(
323
+ <<'_html',
324
+ <html>
325
+ <head><base href="/t_summary/" /><title>index</title></head>
326
+ <body>
327
+ <h1>index</h1>
328
+ <ul id="main" class="runo-blog">
329
+ <li><a href="/t_summary/20100326/1/update.html">frank</a>: hi.</li>
330
+ </ul>
331
+ <div class="action_create"><a href="/t_summary/create.html">create new entry...</a></div>
332
+ </body>
333
+ </html>
334
+ _html
335
+ folder.get(
336
+ :action => :read,
337
+ :sub_action => :detail,
338
+ 'main' => {:action => :read, :sub_action => :detail, :conds => {:p => 1}}
339
+ ),
340
+ 'Set#get should not use [:tmpl][:summary] for :read -> :detail'
341
+ )
342
+
343
+ Runo.client = 'root'
344
+ Runo.current[:base] = folder.item('main')
345
+ folder.item('main')[:tid] = '12345.012'
346
+ assert_equal(
347
+ <<_html,
348
+ <html>
349
+ <head><base href="/t_summary/" /><title>index</title></head>
350
+ <body>
351
+ <h1>index</h1>
352
+ <form id="form_main" method="post" enctype="multipart/form-data" action="/t_summary/12345.012/update.html">
353
+ <input name="_token" type="hidden" value="#{Runo.token}" />
354
+ <ul id="main" class="runo-blog">
355
+ <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>
356
+ </ul>
357
+ <div class="submit">
358
+ <input name=".status-public" type="submit" value="update" />
359
+ <input name=".action-preview_delete" type="submit" value="delete..." />
360
+ </div>
361
+ </form>
362
+ </body>
363
+ </html>
364
+ _html
365
+ folder.get(
366
+ :action => :read,
367
+ :sub_action => :detail,
368
+ 'main' => {:action => :update, :sub_action => nil, :conds => {:p => 1}}
369
+ ),
370
+ 'Set#get should not use [:tmpl][:summary] for :update'
371
+ )
372
+ end
373
+
374
+ def test_tmpl_create
375
+ folder = Runo::Set::Static::Folder.root.item('t_summary')
376
+
377
+ assert_equal(
378
+ <<'_html',
379
+ <html>
380
+ <head><base href="/t_summary/" /><title>create</title></head>
381
+ <body>
382
+ <h1>create</h1>
383
+ <ul id="main" class="runo-blog">
384
+ <li>main-create</li>
385
+ </ul>
386
+ <div class="submit">
387
+ <input name="main.status-public" type="submit" value="create" />
388
+ </div>
389
+ </body>
390
+ </html>
391
+ _html
392
+ folder.get(
393
+ 'main' => {:action => :create}
394
+ ),
395
+ 'Set#get should use [:tmpl][:create] when available and appropriate'
396
+ )
397
+ end
398
+
399
+ def test_tmpl_done
400
+ folder = Runo::Set::Static::Folder.root.item('t_contact')
401
+ assert_equal(
402
+ <<'_html',
403
+ <html>
404
+ <head><base href="@(href)" /><title>@(label)</title></head>
405
+ <body>
406
+ <p>thank you!</p>
407
+ </body>
408
+ </html>
409
+ _html
410
+ folder[:tmpl][:done],
411
+ 'Folder#initialize should load [:tmpl][:done] from [:dir]/done.html'
412
+ )
413
+ end
414
+
415
+ def test_g_login
416
+ folder = Runo::Set::Static::Folder.root.item('t_contact')
417
+
418
+ Runo.client = nil
419
+ assert_equal(
420
+ <<'_html',
421
+ <div class="action_login"><a href="/t_contact/login.html">login</a></div>
422
+ _html
423
+ folder.get(:action => :action_login),
424
+ 'Folder#_g_login should return a link to login/logout according to the current client'
425
+ )
426
+
427
+ Runo.client = 'frank'
428
+ assert_equal(
429
+ <<_html,
430
+ <div class="action_logout"><a href="/t_contact/logout.html?_token=#{Runo.token}">logout</a></div>
431
+ _html
432
+ folder.get(:action => :action_login),
433
+ 'Folder#_g_login should return a link to login/logout according to the current client'
434
+ )
435
+ end
436
+
437
+ def test_g_signup
438
+ folder = Runo::Set::Static::Folder.root.item('t_contact')
439
+
440
+ Runo.client = nil
441
+ assert_equal(
442
+ <<'_html',
443
+ <div class="action_signup"><a href="/_users/create.html">signup</a></div>
444
+ _html
445
+ folder.get(:action => :action_signup),
446
+ 'Folder#_g_signup should return a link to sign-up if the current client is nobody'
447
+ )
448
+
449
+ Runo.client = 'frank'
450
+ assert_nil(
451
+ folder.get(:action => :action_signup),
452
+ 'Folder#_g_signup should return nil unless the current client is nobody'
453
+ )
454
+ end
455
+
456
+ def test_g_me
457
+ folder = Runo::Set::Static::Folder.root.item('t_contact')
458
+
459
+ Runo.client = nil
460
+ assert_equal(
461
+ <<'_html',
462
+ <div class="me">
463
+ <div class="action_login"><a href="/t_contact/login.html">login</a></div>
464
+ </div>
465
+ _html
466
+ folder.get(:action => :me),
467
+ 'Folder#_g_me should return a link to login if the current client is nobody'
468
+ )
469
+
470
+ Runo.client = 'test'
471
+ assert_equal(
472
+ <<_html,
473
+ <div class="me">
474
+ <a href="/_users/id=test/update.html">
475
+ <span class="dummy_img" style="width: 72px; height: 72px;"></span>
476
+ </a>
477
+ <div class="client">test</div>
478
+ <div class="roles">(user)</div>
479
+ <div class="action_logout"><a href="/t_contact/logout.html?_token=#{Runo.token}">logout</a></div>
480
+ </div>
481
+ _html
482
+ folder.get(:action => :me),
483
+ 'Folder#_g_me should return a thumbnail of the current client and a link to logout'
484
+ )
485
+ end
486
+
487
+ def test_g_crumb
488
+ folder = Runo::Set::Static::Folder.root.item('foo','bar')
489
+ assert_equal(
490
+ <<'_html',
491
+ <div class="crumb">
492
+ <a href="/">Root</a>
493
+ &raquo;
494
+ <a href="/foo/">Foo Folder</a>
495
+ &raquo;
496
+ <a href="/foo/bar/">Bar Folder</a>
497
+ </div>
498
+ _html
499
+ folder.get(:action => :crumb),
500
+ 'Folder#_g_crumb should return crumbs from the root to the current folder'
501
+ )
502
+
503
+ folder = Runo::Set::Static::Folder.root
504
+ assert_equal(
505
+ <<'_html',
506
+ <div class="crumb">
507
+ <a href="/">Root</a>
508
+ </div>
509
+ _html
510
+ folder.get(:action => :crumb),
511
+ 'Folder#_g_crumb should return crumbs from the root to the current folder'
512
+ )
513
+ end
514
+
515
+ end