zena 1.0.0.beta2 → 1.0.0.beta3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. data/.gitignore +2 -0
  2. data/History.txt +12 -0
  3. data/app/controllers/application_controller.rb +0 -1
  4. data/app/controllers/columns_controller.rb +11 -1
  5. data/app/controllers/nodes_controller.rb +79 -19
  6. data/app/controllers/versions_controller.rb +0 -2
  7. data/app/controllers/virtual_classes_controller.rb +19 -6
  8. data/app/models/column.rb +5 -1
  9. data/app/models/comment.rb +1 -6
  10. data/app/models/node.rb +21 -3
  11. data/app/models/role.rb +21 -0
  12. data/app/models/site.rb +7 -2
  13. data/app/models/template.rb +3 -3
  14. data/app/models/text_document.rb +4 -4
  15. data/app/models/user.rb +21 -8
  16. data/app/views/columns/_li.html.erb +1 -0
  17. data/app/views/nodes/_groups.rhtml +1 -1
  18. data/app/views/sites/_form.erb +3 -1
  19. data/app/views/sites/_li.erb +1 -0
  20. data/app/views/sites/index.erb +1 -1
  21. data/app/views/virtual_classes/_form.erb +11 -2
  22. data/app/views/virtual_classes/_li.erb +5 -2
  23. data/bin/zena +1 -1
  24. data/bricks/math/lib/bricks/math.rb +1 -1
  25. data/bricks/mongrel/README +3 -0
  26. data/bricks/mongrel/zena/deploy.rb +56 -0
  27. data/bricks/passenger/README +3 -0
  28. data/bricks/passenger/zena/deploy.rb +49 -0
  29. data/config/bricks.yml +6 -0
  30. data/config/deploy.rb +24 -18
  31. data/config/gems.yml +3 -3
  32. data/db/migrate/20100915062903_add_api_group_id_to_site.rb +9 -0
  33. data/lib/tasks/zena.rake +39 -35
  34. data/lib/zena.rb +5 -6
  35. data/lib/zena/acts/enrollable.rb +37 -6
  36. data/lib/zena/app.rb +4 -2
  37. data/lib/zena/deploy.rb +110 -150
  38. data/lib/zena/deploy/awstats.conf.rhtml +4 -4
  39. data/lib/zena/deploy/httpd.rhtml +2 -1
  40. data/lib/zena/deploy/stats.vhost.rhtml +7 -7
  41. data/lib/zena/deploy/vhost.rhtml +1 -1
  42. data/lib/zena/deploy/vhost_www.rhtml +4 -4
  43. data/lib/zena/foxy_parser.rb +6 -5
  44. data/lib/zena/info.rb +1 -1
  45. data/lib/zena/integration/test_case.rb +8 -3
  46. data/lib/zena/parser.rb +11 -11
  47. data/lib/zena/parser/zafu_tags.rb +2 -2
  48. data/lib/zena/remote.rb +16 -0
  49. data/lib/zena/remote/connection.rb +67 -0
  50. data/lib/zena/remote/interface.rb +405 -0
  51. data/lib/zena/remote/klass.rb +14 -0
  52. data/lib/zena/remote/mock.rb +58 -0
  53. data/lib/zena/remote/node.rb +76 -0
  54. data/lib/zena/routes.rb +2 -1
  55. data/lib/zena/use.rb +9 -4
  56. data/lib/zena/use/ajax.rb +3 -3
  57. data/lib/zena/use/authlogic.rb +8 -1
  58. data/lib/zena/use/context.rb +22 -21
  59. data/lib/zena/use/dates.rb +26 -3
  60. data/lib/zena/use/display.rb +33 -5
  61. data/lib/zena/use/forms.rb +90 -12
  62. data/lib/zena/use/fulltext.rb +1 -1
  63. data/lib/zena/use/i18n.rb +118 -31
  64. data/lib/zena/use/query_builder.rb +7 -5
  65. data/lib/zena/use/query_node.rb +30 -4
  66. data/lib/zena/use/rendering.rb +1 -1
  67. data/lib/zena/use/search.rb +10 -7
  68. data/lib/zena/use/urls.rb +3 -3
  69. data/lib/zena/use/zafu_attributes.rb +2 -2
  70. data/lib/zena/use/zafu_eval.rb +1 -1
  71. data/lib/zena/use/zafu_safe_definitions.rb +1 -0
  72. data/lib/zena/use/zafu_templates.rb +1 -1
  73. data/lib/zena/zafu_compiler.rb +5 -1
  74. data/public/javascripts/zena.js +4 -4
  75. data/public/stylesheets/admin.css +1 -0
  76. data/test/custom_queries/complex.host.yml +3 -3
  77. data/test/fixtures/files/translations_fr.yml +4 -1
  78. data/test/functional/application_controller_test.rb +2 -2
  79. data/test/functional/nodes_controller_test.rb +57 -5
  80. data/test/functional/users_controller_test.rb +10 -9
  81. data/test/functional/virtual_classes_controller_test.rb +48 -0
  82. data/test/integration/navigation_test.rb +13 -1
  83. data/test/integration/query_node/filters.yml +5 -0
  84. data/test/integration/query_node_test.rb +1 -1
  85. data/test/integration/zafu_compiler/ajax.yml +13 -19
  86. data/test/integration/zafu_compiler/basic.yml +0 -72
  87. data/test/integration/zafu_compiler/complex.yml +1 -1
  88. data/test/integration/zafu_compiler/complex_ok.yml +19 -0
  89. data/test/integration/zafu_compiler/dates.yml +62 -1
  90. data/test/integration/zafu_compiler/display.yml +4 -4
  91. data/test/integration/zafu_compiler/forms.yml +19 -7
  92. data/test/integration/zafu_compiler/i18n.yml +56 -1
  93. data/test/integration/zafu_compiler/later.yml +23 -1
  94. data/test/integration/zafu_compiler/relations.yml +1 -1
  95. data/test/integration/zafu_compiler/roles.yml +29 -1
  96. data/test/integration/zafu_compiler/safe_definitions.yml +1 -1
  97. data/test/integration/zafu_compiler/zafu_attributes.yml +2 -1
  98. data/test/integration/zafu_compiler_test.rb +5 -3
  99. data/test/sites/zena/columns.yml +3 -0
  100. data/test/sites/zena/roles.yml +0 -1
  101. data/test/sites/zena/sites.yml +1 -0
  102. data/test/sites/zena/versions.yml +2 -0
  103. data/test/unit/node_test.rb +27 -9
  104. data/test/unit/relation_proxy_test.rb +7 -4
  105. data/test/unit/remote_test.rb +379 -0
  106. data/test/unit/user_test.rb +47 -0
  107. data/test/unit/zena/acts/enrollable_test.rb +36 -7
  108. data/test/unit/zena/acts/serializable_test.rb +14 -2
  109. data/test/unit/zena/use/i18n_test.rb +32 -5
  110. data/test/unit/zena/use/query_node_test.rb +13 -1
  111. data/zena.gemspec +25 -11
  112. metadata +24 -10
@@ -7,7 +7,7 @@ class RelationProxyTest < Zena::Unit::TestCase
7
7
  assert_equal relations_id(:note_has_calendars), RelationProxy.find_by_role('calendar')[:id]
8
8
  assert_nil RelationProxy.find_by_role('badrole')
9
9
  end
10
-
10
+
11
11
  def test_get_proxy
12
12
  proj = secure(Node) { nodes(:cleanWater) }
13
13
  note = secure(Note) { nodes(:opening) }
@@ -109,7 +109,9 @@ class RelationProxyTest < Zena::Unit::TestCase
109
109
  def test_bad_attribute_raises
110
110
  login(:tiger)
111
111
  node = secure!(Node) { nodes(:status) }
112
- assert_raises(ActiveRecord::UnknownAttributeError) { node.update_attributes( 'tralala_ids' => ['33'])}
112
+ #assert_raises(ActiveRecord::UnknownAttributeError) {
113
+ assert !node.update_attributes( 'tralala_ids' => ['33'])
114
+ #}
113
115
  end
114
116
 
115
117
  def test_relations_for_form
@@ -292,7 +294,8 @@ class RelationProxyTest < Zena::Unit::TestCase
292
294
 
293
295
  def test_create_invalid_target_or_empty
294
296
  login(:lion)
295
- node = assert_raises(ActiveRecord::UnknownAttributeError) {secure!(Node) { Node.create_node('parent_id' => nodes_zip(:cleanWater),'klass'=>'Page', 'foo_id'=>'342', 'title'=>'hello') }}
297
+ node = secure(Node) { Node.create_node('parent_id' => nodes_zip(:cleanWater),'klass'=>'Page', 'foo_id'=>'342', 'title'=>'hello') }
298
+ assert node.new_record?
296
299
  # invalid target
297
300
  node = secure!(Node) { Node.create_node('parent_id' => nodes_zip(:cleanWater),'klass'=>'Page', 'icon_id'=>nodes_zip(:cleanWater), 'title'=>'two') }
298
301
  assert node.errors['icon']
@@ -343,7 +346,7 @@ class RelationProxyTest < Zena::Unit::TestCase
343
346
  assert_equal 2, references.size
344
347
  assert references.select {|r| r[:zip] == nodes_zip(:letter)}.empty?
345
348
  end
346
-
349
+
347
350
  def test_toggle_link_negative_id
348
351
  login(:lion)
349
352
  node = secure!(Node) { nodes(:cleanWater) }
@@ -0,0 +1,379 @@
1
+ require 'test_helper'
2
+
3
+ class RemoteTest < Zena::Integration::TestCase
4
+ context 'With a remote application' do
5
+ setup do
6
+ test_site(:zena)
7
+ init_test_connection!
8
+ @app = Zena::Remote.connect('http://test.host:3000', 'mytoken')
9
+ @app.send(:include, Zena::Remote::Mock::Connection)
10
+ @app.logger = Node.logger
11
+ @app.message_logger = Node.logger
12
+ end
13
+
14
+ context 'and a remote class' do
15
+ subject do
16
+ @app['Tag']
17
+ end
18
+
19
+ should 'return a Klass instance' do
20
+ assert_kind_of Zena::Remote::Klass, subject
21
+ end
22
+
23
+ context 'creating nodes' do
24
+ should 'create nodes of the correct type' do
25
+ assert_difference('Node.count', 1) do
26
+ node = subject.create(:title => 'Banana', :parent_id => nodes_zip(:cleanWater))
27
+ remote = remote_node(node)
28
+ assert_equal 'Tag', remote.klass
29
+ assert_equal 'Banana', remote.title
30
+ end
31
+ end
32
+
33
+ should 'respond to new' do
34
+ node = subject.new(:title => 'Banana', :parent_id => nodes_zip(:cleanWater))
35
+ assert_difference('Node.count', 1) do
36
+ node.save
37
+ end
38
+ remote = remote_node(node)
39
+ assert_equal 'Tag', remote.klass
40
+ assert_equal 'Banana', remote.title
41
+ end
42
+ end # creating nodes
43
+
44
+ context 'finding nodes' do
45
+ should 'find with first' do
46
+ assert_equal 'Art', subject.first.title
47
+ end
48
+
49
+ should 'find with all' do
50
+ assert_equal ["Art", "Top menu", "News list"], subject.all.map(&:title)
51
+ end
52
+
53
+ should 'find with filters' do
54
+ assert_equal ['Art'], subject.all(:title => 'art').map(&:title)
55
+ end
56
+
57
+ should 'find with qb filters' do
58
+ assert_equal ['News list'], subject.all('title like "%w%"').map(&:title)
59
+ end
60
+ end # finding nodes
61
+
62
+ context 'getting Klass attributes' do
63
+ should 'return list of properties' do
64
+ # TODO
65
+ print 'P'
66
+ #assert_equal {}, subject.properties
67
+ end
68
+ end # getting Klass attributes
69
+
70
+ end # and a remote class
71
+
72
+
73
+ # ================================ Create
74
+ context 'creating' do
75
+ context 'a node with the connection' do
76
+ subject do
77
+ @app.create(:class => 'Post', :title => 'Lady Madonna', :parent_id => nodes_zip(:cleanWater))
78
+ end
79
+
80
+ should 'create a new remote node' do
81
+ assert_difference('Node.count', 1) do
82
+ subject
83
+ end
84
+ end
85
+
86
+ should 'use attributes to create node' do
87
+ node = remote_node(subject.id)
88
+ assert_equal 'Lady Madonna', node.title
89
+ assert_equal nodes_id(:cleanWater), node.parent_id
90
+ assert_equal 'Post', node.klass
91
+ end
92
+
93
+ context 'with errors' do
94
+ subject do
95
+ @app.create(:class => 'Post', :title => 'Lady Madonna', :parent_id => 9999)
96
+ end
97
+
98
+ should 'return a new record with errors' do
99
+ assert subject.new_record?
100
+ assert subject.errors
101
+ end
102
+ end # with errors
103
+
104
+
105
+ context 'by using a remote node as parent' do
106
+ subject do
107
+ @app.create(:class => 'Post', :title => 'Lady Madonna', :parent => @app.find(nodes_zip(:cleanWater)))
108
+ end
109
+
110
+ should 'use attributes to create node' do
111
+ node = remote_node(subject.id)
112
+ assert_equal 'Lady Madonna', node.title
113
+ assert_equal nodes_id(:cleanWater), node.parent_id
114
+ assert_equal 'Post', node.klass
115
+ end
116
+ end # by using a remote node as parent
117
+
118
+ end # a node with the connection
119
+ end # creating
120
+
121
+ # ================================ Read
122
+ context 'finding' do
123
+
124
+ context 'root node with root' do
125
+ subject do
126
+ @app.root
127
+ end
128
+
129
+ should 'find root node with root' do
130
+ assert_equal nodes_zip(:zena), subject.id
131
+ end
132
+ end # root node with root
133
+
134
+
135
+ context 'nodes with qb' do
136
+ subject do
137
+ # default is 'in site'
138
+ @app.find(:all, 'images')
139
+ end
140
+
141
+ should 'find through query builder' do
142
+ assert_equal 4, subject.size
143
+ end
144
+
145
+ should 'instanciate results as remote nodes' do
146
+ assert_kind_of Zena::Remote::Node, subject.first
147
+ end
148
+ end # finding nodes with qb
149
+
150
+ context 'nodes without specifying count' do
151
+ should 'return an array' do
152
+ assert_kind_of Array, @app.find('images')
153
+ assert_equal 4, @app.find('image').size
154
+ end
155
+
156
+ should 'return an array for singular queries' do
157
+ assert_kind_of Array, @app.find('image')
158
+ assert_equal 4, @app.find('image').size
159
+ end
160
+ end # finding nodes without specifying count
161
+
162
+ context 'nodes by using all' do
163
+ should 'return an array' do
164
+ assert_kind_of Array, @app.all('images')
165
+ assert_equal 4, @app.all('image').size
166
+ end
167
+
168
+ should 'return an array for singular queries' do
169
+ assert_kind_of Array, @app.all('image in site')
170
+ assert_equal 4, @app.all('image in site').size
171
+ end
172
+
173
+ context 'with a hash' do
174
+ should 'find nodes' do
175
+ assert_equal ["bird"], @app.all(:title => 'bird').map(&:title)
176
+ end
177
+ end # with a hash
178
+
179
+ end # finding nodes by using all
180
+
181
+ context 'nodes by using first' do
182
+ should 'return an instance' do
183
+ assert_kind_of Zena::Remote::Node, @app.first('images')
184
+ end
185
+
186
+ context 'with an id' do
187
+ should 'return an instance' do
188
+ assert_kind_of Zena::Remote::Node, @app.first(nodes_zip(:lake_jpg))
189
+ end
190
+ end # with an id
191
+ end # finding nodes by using first
192
+
193
+ context 'node count with qb' do
194
+ subject do
195
+ @app.find(:count, 'images')
196
+ end
197
+
198
+ should 'find through query builder' do
199
+ assert_equal 4, subject
200
+ end
201
+ end
202
+
203
+ context 'node count by using count' do
204
+ subject do
205
+ @app.count('images')
206
+ end
207
+
208
+ should 'find through query builder' do
209
+ assert_equal 4, subject
210
+ end
211
+ end
212
+
213
+ context 'nodes with search' do
214
+ subject do
215
+ @app.search('la')
216
+ end
217
+
218
+ should 'find through fulltext search' do
219
+ assert_equal ["The lake we love", "it's a lake"], subject.map(&:title)
220
+ end
221
+ end
222
+ end # finding
223
+
224
+ context 'paginating results' do
225
+ subject do
226
+ @app.all('pages order by node_name asc', :page => 2, :per_page => 3)
227
+ end
228
+
229
+ should 'paginate' do
230
+ assert_equal ["Collections", "crocodiles", "Default skin"], subject.map(&:title)
231
+ end
232
+ end # paginating results
233
+
234
+ context 'and a found remote node' do
235
+ subject do
236
+ @app.first('image where title like "%la%"')
237
+ end
238
+
239
+ should 'return attributes from method calls' do
240
+ assert_equal "it's a lake", subject.title
241
+ end
242
+
243
+ should 'contain id' do
244
+ assert_equal nodes_zip(:lake_jpg), subject.id
245
+ end
246
+
247
+ should 'enable further search queries' do
248
+ assert_equal 'Clean Water project', subject.first('icon_for').title
249
+ end
250
+
251
+ should 'map missing attributes as first queries' do
252
+ assert_equal 'Clean Water project', subject.icon_for.title
253
+ assert_equal ["Nice Bananas", "crocodiles", "status title", "Keeping things clean !"], subject.project.pages.map(&:title)
254
+ end
255
+
256
+ should 'map missing attributes as queries' do
257
+ assert_equal "Nice Bananas", subject.project.page.title
258
+ assert_equal ["Nice Bananas",
259
+ "crocodiles",
260
+ "it's a lake",
261
+ "The lake we love",
262
+ "parc opening",
263
+ "status title",
264
+ "Keeping things clean !",
265
+ "water"], subject.parent.nodes.map(&:title)
266
+ end
267
+ end # and a found remote node
268
+
269
+ # ================================ Update
270
+ context 'updating a node' do
271
+ subject do
272
+ @app.first(nodes_zip(:status))
273
+ end
274
+
275
+ context 'with changed attributes' do
276
+ should 'update remote attributes' do
277
+ subject.title = 'Shalom'
278
+ assert subject.save
279
+ assert_equal 'Shalom', nodes(:status).title
280
+ end
281
+
282
+ should 'with update attributes' do
283
+ assert subject.update_attributes(:title => 'Shalom')
284
+ assert_equal 'Shalom', nodes(:status).title
285
+ end
286
+ end # a node with the connection
287
+
288
+ context 'with a new relation' do
289
+ subject do
290
+ @app.first(nodes_zip(:lion))
291
+ end
292
+
293
+ should 'create link' do
294
+ tag = @app['Tag'].first
295
+
296
+ assert_difference('Link.count', 1) do
297
+ subject.set_tag = [tag]
298
+ subject.save
299
+ end
300
+
301
+ assert_equal subject.id, tag.first("tagged where title = 'lion'").id
302
+ end
303
+ end # with a new relation
304
+
305
+ end # updating a node
306
+
307
+ context 'mass updating' do
308
+ subject do
309
+ @app.update("images", :summary => 'porn')
310
+ end
311
+
312
+ should 'update all nodes' do
313
+ subject
314
+ login(:tiger) # user with 'mytoken'
315
+ secure(Image) do
316
+ Image.all.each do |img|
317
+ assert_equal 'porn', img.summary
318
+ end
319
+ end
320
+ end
321
+ end # mass updating
322
+
323
+
324
+ # ================================ Delete
325
+ context 'deleting' do
326
+ context 'an existing remote node' do
327
+ subject do
328
+ @app.find(nodes_zip(:news))
329
+ end
330
+
331
+ should 'remove remote object from the database' do
332
+ assert_difference('Node.count', -1) do
333
+ assert subject.destroy
334
+ end
335
+ end
336
+ end # an existing remote node
337
+ end # deleting
338
+
339
+
340
+ context 'mass deleting' do
341
+ subject do
342
+ @app.destroy("images")
343
+ end
344
+
345
+ should 'delete all nodes' do
346
+ assert_difference('Node.count', -4) do
347
+ subject
348
+ end
349
+
350
+ login(:tiger) # user with 'mytoken'
351
+ secure(Image) do
352
+ assert_equal [], Image.all
353
+ end
354
+ end
355
+ end # mass deleting
356
+
357
+ context 'bad requests' do
358
+ subject do
359
+ @app.all('foos')
360
+ end
361
+
362
+ should 'return an hash with error' do
363
+ assert_equal [], subject
364
+ end
365
+ end # bad requests
366
+
367
+ end # With a remote application
368
+
369
+ private
370
+ def remote_node(obj_or_id)
371
+ if obj_or_id.kind_of?(Fixnum)
372
+ Node.find_by_zip_and_site_id(obj_or_id, current_site.id)
373
+ elsif obj_or_id.kind_of?(Zena::Remote::Node)
374
+ Node.find_by_zip_and_site_id(obj_or_id.id, current_site.id)
375
+ else
376
+ nil
377
+ end
378
+ end
379
+ end
@@ -50,6 +50,33 @@ class UserTest < Zena::Unit::TestCase
50
50
  assert_nothing_raised( Zena::AccessViolation ) { ant.destroy }
51
51
  end
52
52
 
53
+ context 'Creating a new User' do
54
+ setup do
55
+ login(:lion)
56
+ end
57
+
58
+ subject do
59
+ {
60
+ 'name' => 'Dupont',
61
+ 'lang' => 'fr',
62
+ 'time_zone' => 'Europe/Zurich',
63
+ 'status' => '50',
64
+ 'password' => 'secret',
65
+ 'login' => 'bolomey',
66
+ 'first_name' => 'Paul',
67
+ 'group_ids' => [groups_id(:public), ''],
68
+ 'email' => 'paul.bolomey@brainfuck.com',
69
+ }
70
+ end
71
+
72
+ should 'succeed' do
73
+ assert_difference('User.count', 1) do
74
+ user = secure(User) { User.new(subject) }
75
+ user.save
76
+ end
77
+ end
78
+ end # Creating a new User
79
+
53
80
  def test_create
54
81
  User.connection.execute "UPDATE users SET lang='ru' WHERE id IN (#{users_id(:incognito)},#{users_id(:whale)})"
55
82
  User.connection.execute "UPDATE sites SET languages='fr,ru' WHERE id=#{sites_id(:ocean)}"
@@ -294,4 +321,24 @@ class UserTest < Zena::Unit::TestCase
294
321
  end
295
322
  end
296
323
  end
324
+
325
+ context 'A user not in the api_group' do
326
+ subject do
327
+ users(:ant)
328
+ end
329
+
330
+ should 'not be authorized access to API' do
331
+ assert !subject.api_authorized?
332
+ end
333
+ end # A user not in the api_group
334
+
335
+ context 'A user in the api_group' do
336
+ subject do
337
+ users(:tiger)
338
+ end
339
+
340
+ should 'be authorized access to API' do
341
+ assert subject.api_authorized?
342
+ end
343
+ end # A user in the api_group
297
344
  end