|
1 # -*- coding: iso-8859-1 -*- |
|
2 """XXX rename, split, reorganize this |
|
3 |
|
4 """ |
|
5 |
|
6 import os.path as osp |
|
7 |
|
8 from logilab.common.testlib import TestCase, unittest_main |
|
9 from cubicweb.devtools.apptest import EnvBasedTC |
|
10 |
|
11 |
|
12 from cubicweb import CW_SOFTWARE_ROOT as BASE, Binary |
|
13 from cubicweb.common.selectors import in_group_selector |
|
14 |
|
15 from cubicweb.web._exceptions import NoSelectableObject |
|
16 from cubicweb.web.action import Action |
|
17 from cubicweb.web.views import (baseviews, tableview, baseforms, calendar, |
|
18 management, embedding, actions, startup, |
|
19 euser, schemaentities, xbel, vcard, |
|
20 idownloadable, wdoc, debug) |
|
21 from cubicweb.entities.lib import Card |
|
22 from cubicweb.interfaces import IMileStone |
|
23 |
|
24 USERACTIONS = [('myprefs', actions.UserPreferencesAction), |
|
25 ('myinfos', actions.UserInfoAction), |
|
26 ('logout', actions.LogoutAction)] |
|
27 SITEACTIONS = [('siteconfig', actions.SiteConfigurationAction), |
|
28 ('manage', actions.ManageAction), |
|
29 ('schema', actions.ViewSchemaAction)] |
|
30 |
|
31 |
|
32 class ViewSelectorTC(EnvBasedTC): |
|
33 |
|
34 def setup_database(self): |
|
35 self.add_entity('BlogEntry', title=u"une news !", content=u"cubicweb c'est beau") |
|
36 self.add_entity('Bookmark', title=u"un signet !", path=u"view?vid=index") |
|
37 self.add_entity('Card', title=u'mandatory', content=u"DoC !") |
|
38 self.add_entity('EmailAddress', address=u"devel@logilab.fr", alias=u'devel') |
|
39 self.add_entity('Tag', name=u'x') |
|
40 |
|
41 def pactions(self, req, rset): |
|
42 resdict = self.vreg.possible_actions(req, rset) |
|
43 for cat, actions in resdict.items(): |
|
44 resdict[cat] = [(a.id, a.__class__) for a in actions] |
|
45 return resdict |
|
46 |
|
47 |
|
48 class VRegistryTC(ViewSelectorTC): |
|
49 """test the view selector""" |
|
50 |
|
51 def _test_registered(self, registry, content): |
|
52 try: |
|
53 expected = getattr(self, 'all_%s' % registry) |
|
54 except AttributeError: |
|
55 return |
|
56 if registry == 'hooks': |
|
57 self.assertEquals(len(content), expected, content) |
|
58 return |
|
59 try: |
|
60 self.assertSetEqual(content.keys(), expected) |
|
61 except: |
|
62 print registry, sorted(expected), sorted(content.keys()) |
|
63 print 'no more', [v for v in expected if not v in content.keys()] |
|
64 print 'missing', [v for v in content.keys() if not v in expected] |
|
65 raise |
|
66 |
|
67 |
|
68 def test_possible_views(self): |
|
69 # no entity |
|
70 req = self.request() |
|
71 self.assertListEqual(self.pviews(req, None), |
|
72 [('changelog', wdoc.ChangeLogView), |
|
73 ('debug', debug.DebugView), |
|
74 ('epropertiesform', management.EpropertiesForm), |
|
75 ('index', startup.IndexView), |
|
76 ('info', management.ProcessInformationView), |
|
77 ('manage', startup.ManageView), |
|
78 ('schema', startup.SchemaView), |
|
79 ('systemepropertiesform', management.SystemEpropertiesForm)]) |
|
80 # no entity but etype |
|
81 rset, req = self.env.get_rset_and_req('Any X WHERE X eid 999999') |
|
82 self.assertListEqual(self.pviews(req, rset), |
|
83 [#('changelog', wdoc.ChangeLogView), |
|
84 #('epropertiesform', management.EpropertiesForm), |
|
85 #('index', startup.IndexView), |
|
86 #('info', management.ProcessInformationView), |
|
87 #('manage', startup.ManageView), |
|
88 #('schema', startup.SchemaView), |
|
89 #('systemepropertiesform', management.SystemEpropertiesForm) |
|
90 ]) |
|
91 # one entity |
|
92 rset, req = self.env.get_rset_and_req('EGroup X WHERE X name "managers"') |
|
93 self.assertListEqual(self.pviews(req, rset), |
|
94 [('csvexport', baseviews.CSVRsetView), |
|
95 ('ecsvexport', baseviews.CSVEntityView), |
|
96 ('editable-table', tableview.EditableTableView), |
|
97 ('list', baseviews.ListView), |
|
98 ('oneline', baseviews.OneLineView), |
|
99 ('primary', baseviews.PrimaryView), |
|
100 ('rss', baseviews.RssView), |
|
101 ('secondary', baseviews.SecondaryView), |
|
102 ('security', management.SecurityManagementView), |
|
103 ('table', tableview.TableView), |
|
104 ('text', baseviews.TextView), |
|
105 ('xbel', xbel.XbelView), |
|
106 ('xml', baseviews.XmlView), |
|
107 ]) |
|
108 # list of entities of the same type |
|
109 rset, req = self.env.get_rset_and_req('EGroup X') |
|
110 self.assertListEqual(self.pviews(req, rset), |
|
111 [('csvexport', baseviews.CSVRsetView), |
|
112 ('ecsvexport', baseviews.CSVEntityView), |
|
113 ('editable-table', tableview.EditableTableView), |
|
114 ('list', baseviews.ListView), |
|
115 ('oneline', baseviews.OneLineView), |
|
116 ('primary', baseviews.PrimaryView), |
|
117 ('rss', baseviews.RssView), |
|
118 ('secondary', baseviews.SecondaryView), |
|
119 ('security', management.SecurityManagementView), |
|
120 ('table', tableview.TableView), |
|
121 ('text', baseviews.TextView), |
|
122 ('xbel', xbel.XbelView), |
|
123 ('xml', baseviews.XmlView), |
|
124 ]) |
|
125 # list of entities of different types |
|
126 rset, req = self.env.get_rset_and_req('Any X') |
|
127 self.assertListEqual(self.pviews(req, rset), |
|
128 [('csvexport', baseviews.CSVRsetView), |
|
129 ('ecsvexport', baseviews.CSVEntityView), |
|
130 ('editable-table', tableview.EditableTableView), |
|
131 ('list', baseviews.ListView), |
|
132 ('oneline', baseviews.OneLineView), |
|
133 ('primary', baseviews.PrimaryView), |
|
134 ('rss', baseviews.RssView), |
|
135 ('secondary', baseviews.SecondaryView), |
|
136 ('security', management.SecurityManagementView), |
|
137 ('table', tableview.TableView), |
|
138 ('text', baseviews.TextView), |
|
139 ('xbel', xbel.XbelView), |
|
140 ('xml', baseviews.XmlView), |
|
141 ]) |
|
142 # whatever |
|
143 rset, req = self.env.get_rset_and_req('Any N, X WHERE X in_group Y, Y name N') |
|
144 self.assertListEqual(self.pviews(req, rset), |
|
145 [('csvexport', baseviews.CSVRsetView), |
|
146 ('editable-table', tableview.EditableTableView), |
|
147 ('table', tableview.TableView), |
|
148 ]) |
|
149 # list of euser entities |
|
150 rset, req = self.env.get_rset_and_req('EUser X') |
|
151 self.assertListEqual(self.pviews(req, rset), |
|
152 [('csvexport', baseviews.CSVRsetView), |
|
153 ('ecsvexport', baseviews.CSVEntityView), |
|
154 ('editable-table', tableview.EditableTableView), |
|
155 ('list', baseviews.ListView), |
|
156 ('oneline', baseviews.OneLineView), |
|
157 ('primary', euser.EUserPrimaryView), |
|
158 ('rss', baseviews.RssView), |
|
159 ('secondary', baseviews.SecondaryView), |
|
160 ('security', management.SecurityManagementView), |
|
161 ('table', tableview.TableView), |
|
162 ('text', baseviews.TextView), |
|
163 ('vcard', vcard.VCardEUserView), |
|
164 ('xbel', xbel.XbelView), |
|
165 ('xml', baseviews.XmlView), |
|
166 ]) |
|
167 |
|
168 def test_possible_actions_none_rset(self): |
|
169 req = self.request() |
|
170 self.assertDictEqual(self.pactions(req, None), |
|
171 {'useractions': USERACTIONS, |
|
172 'siteactions': SITEACTIONS, |
|
173 }) |
|
174 def test_possible_actions_no_entity(self): |
|
175 rset, req = self.env.get_rset_and_req('Any X WHERE X eid 999999') |
|
176 self.assertDictEqual(self.pactions(req, rset), |
|
177 {'useractions': USERACTIONS, |
|
178 'siteactions': SITEACTIONS, |
|
179 }) |
|
180 def test_possible_actions_same_type_entities(self): |
|
181 rset, req = self.env.get_rset_and_req('EGroup X') |
|
182 self.assertDictEqual(self.pactions(req, rset), |
|
183 {'useractions': USERACTIONS, |
|
184 'siteactions': SITEACTIONS, |
|
185 'mainactions': [('muledit', actions.MultipleEditAction)], |
|
186 'moreactions': [('delete', actions.DeleteAction), |
|
187 ('addentity', actions.AddNewAction)], |
|
188 }) |
|
189 def test_possible_actions_different_types_entities(self): |
|
190 rset, req = self.env.get_rset_and_req('Any X') |
|
191 self.assertDictEqual(self.pactions(req, rset), |
|
192 {'useractions': USERACTIONS, |
|
193 'siteactions': SITEACTIONS, |
|
194 'moreactions': [('delete', actions.DeleteAction)], |
|
195 }) |
|
196 def test_possible_actions_final_entities(self): |
|
197 rset, req = self.env.get_rset_and_req('Any N, X WHERE X in_group Y, Y name N') |
|
198 self.assertDictEqual(self.pactions(req, rset), |
|
199 {'useractions': USERACTIONS, |
|
200 'siteactions': SITEACTIONS}) |
|
201 |
|
202 def test_possible_actions_eetype_euser_entity(self): |
|
203 rset, req = self.env.get_rset_and_req('EEType X WHERE X name "EUser"') |
|
204 self.assertDictEqual(self.pactions(req, rset), |
|
205 {'useractions': USERACTIONS, |
|
206 'siteactions': SITEACTIONS, |
|
207 'mainactions': [('edit', actions.ModifyAction), |
|
208 ('workflow', schemaentities.ViewWorkflowAction),], |
|
209 'moreactions': [('delete', actions.DeleteAction), |
|
210 ('copy', actions.CopyAction)], |
|
211 }) |
|
212 |
|
213 def test_load_subinterface_based_vojects(self): |
|
214 self.vreg._lastmodifs = {} # clear cache |
|
215 self.vreg.register_objects([osp.join(BASE, 'web', 'views', 'iprogress.py')]) |
|
216 # check progressbar was kicked |
|
217 self.failIf('progressbar' in self.vreg['views']) |
|
218 class MyCard(Card): |
|
219 __implements__ = (IMileStone,) |
|
220 self.vreg.register_vobject_class(MyCard) |
|
221 self.vreg._lastmodifs = {} # clear cache |
|
222 self.vreg.register_objects([osp.join(BASE, 'web', 'views', 'iprogress.py')]) |
|
223 # check progressbar isn't kicked |
|
224 self.assertEquals(len(self.vreg['views']['progressbar']), 1) |
|
225 |
|
226 |
|
227 def test_select_creation_form(self): |
|
228 rset = None |
|
229 req = self.request() |
|
230 # creation form |
|
231 req.form['etype'] = 'EGroup' |
|
232 self.assertIsInstance(self.vreg.select_view('creation', req, rset), |
|
233 baseforms.CreationForm) |
|
234 del req.form['etype'] |
|
235 # custom creation form |
|
236 class EUserCreationForm(baseforms.CreationForm): |
|
237 accepts = ('EUser',) |
|
238 self.vreg.register_vobject_class(EUserCreationForm) |
|
239 req.form['etype'] = 'EUser' |
|
240 self.assertIsInstance(self.vreg.select_view('creation', req, rset), |
|
241 EUserCreationForm) |
|
242 |
|
243 def test_select_view(self): |
|
244 # no entity |
|
245 rset = None |
|
246 req = self.request() |
|
247 self.assertIsInstance(self.vreg.select_view('index', req, rset), |
|
248 startup.IndexView) |
|
249 self.failUnlessRaises(NoSelectableObject, |
|
250 self.vreg.select_view, 'primary', req, rset) |
|
251 self.failUnlessRaises(NoSelectableObject, |
|
252 self.vreg.select_view, 'table', req, rset) |
|
253 |
|
254 # no entity |
|
255 rset, req = self.env.get_rset_and_req('Any X WHERE X eid 999999') |
|
256 self.failUnlessRaises(NoSelectableObject, |
|
257 self.vreg.select_view, 'index', req, rset) |
|
258 self.failUnlessRaises(NoSelectableObject, |
|
259 self.vreg.select_view, 'creation', req, rset) |
|
260 self.failUnlessRaises(NoSelectableObject, |
|
261 self.vreg.select_view, 'primary', req, rset) |
|
262 self.failUnlessRaises(NoSelectableObject, |
|
263 self.vreg.select_view, 'table', req, rset) |
|
264 # one entity |
|
265 rset, req = self.env.get_rset_and_req('EGroup X WHERE X name "managers"') |
|
266 self.assertIsInstance(self.vreg.select_view('primary', req, rset), |
|
267 baseviews.PrimaryView) |
|
268 self.assertIsInstance(self.vreg.select_view('list', req, rset), |
|
269 baseviews.ListView) |
|
270 self.assertIsInstance(self.vreg.select_view('edition', req, rset), |
|
271 baseforms.EditionForm) |
|
272 self.assertIsInstance(self.vreg.select_view('table', req, rset), |
|
273 tableview.TableView) |
|
274 self.failUnlessRaises(NoSelectableObject, |
|
275 self.vreg.select_view, 'creation', req, rset) |
|
276 self.failUnlessRaises(NoSelectableObject, |
|
277 self.vreg.select_view, 'index', req, rset) |
|
278 # list of entities of the same type |
|
279 rset, req = self.env.get_rset_and_req('EGroup X') |
|
280 self.assertIsInstance(self.vreg.select_view('primary', req, rset), |
|
281 baseviews.PrimaryView) |
|
282 self.assertIsInstance(self.vreg.select_view('list', req, rset), |
|
283 baseviews.ListView) |
|
284 self.assertIsInstance(self.vreg.select_view('table', req, rset), |
|
285 tableview.TableView) |
|
286 self.failUnlessRaises(NoSelectableObject, |
|
287 self.vreg.select_view, 'creation', req, rset) |
|
288 # list of entities of different types |
|
289 rset, req = self.env.get_rset_and_req('Any X') |
|
290 self.assertIsInstance(self.vreg.select_view('primary', req, rset), |
|
291 baseviews.PrimaryView) |
|
292 self.assertIsInstance(self.vreg.select_view('list', req, rset), |
|
293 baseviews.ListView) |
|
294 self.assertIsInstance(self.vreg.select_view('table', req, rset), |
|
295 tableview.TableView) |
|
296 self.failUnlessRaises(NoSelectableObject, |
|
297 self.vreg.select_view, 'creation', req, rset) |
|
298 self.failUnlessRaises(NoSelectableObject, |
|
299 self.vreg.select_view, 'index', req, rset) |
|
300 # whatever |
|
301 rset, req = self.env.get_rset_and_req('Any N, X WHERE X in_group Y, Y name N') |
|
302 self.assertIsInstance(self.vreg.select_view('table', req, rset), |
|
303 tableview.TableView) |
|
304 self.failUnlessRaises(NoSelectableObject, |
|
305 self.vreg.select_view, 'index', req, rset) |
|
306 self.failUnlessRaises(NoSelectableObject, |
|
307 self.vreg.select_view, 'creation', req, rset) |
|
308 self.failUnlessRaises(NoSelectableObject, |
|
309 self.vreg.select_view, 'primary', req, rset) |
|
310 self.failUnlessRaises(NoSelectableObject, |
|
311 self.vreg.select_view, 'list', req, rset) |
|
312 self.failUnlessRaises(NoSelectableObject, |
|
313 self.vreg.select_view, 'edition', req, rset) |
|
314 # mixed query |
|
315 rset, req = self.env.get_rset_and_req('Any U,G WHERE U is EUser, G is EGroup') |
|
316 self.failUnlessRaises(NoSelectableObject, |
|
317 self.vreg.select_view, 'edition', req, rset) |
|
318 self.failUnlessRaises(NoSelectableObject, |
|
319 self.vreg.select_view, 'creation', req, rset) |
|
320 self.assertIsInstance(self.vreg.select_view('table', req, rset), |
|
321 tableview.TableView) |
|
322 # euser primary view priority |
|
323 rset, req = self.env.get_rset_and_req('EUser X WHERE X login "admin"') |
|
324 self.assertIsInstance(self.vreg.select_view('primary', req, rset), |
|
325 euser.EUserPrimaryView) |
|
326 self.assertIsInstance(self.vreg.select_view('text', req, rset), |
|
327 baseviews.TextView) |
|
328 |
|
329 def test_interface_selector(self): |
|
330 image = self.add_entity('Image', name=u'bim.png', data=Binary('bim')) |
|
331 # image primary view priority |
|
332 rset, req = self.env.get_rset_and_req('Image X WHERE X name "bim.png"') |
|
333 self.assertIsInstance(self.vreg.select_view('primary', req, rset), |
|
334 idownloadable.IDownloadablePrimaryView) |
|
335 |
|
336 |
|
337 def test_score_entity_selector(self): |
|
338 image = self.add_entity('Image', name=u'bim.png', data=Binary('bim')) |
|
339 # image primary view priority |
|
340 rset, req = self.env.get_rset_and_req('Image X WHERE X name "bim.png"') |
|
341 self.assertIsInstance(self.vreg.select_view('image', req, rset), |
|
342 idownloadable.ImageView) |
|
343 fileobj = self.add_entity('File', name=u'bim.txt', data=Binary('bim')) |
|
344 # image primary view priority |
|
345 rset, req = self.env.get_rset_and_req('File X WHERE X name "bim.txt"') |
|
346 self.assertRaises(NoSelectableObject, self.vreg.select_view, 'image', req, rset) |
|
347 |
|
348 |
|
349 |
|
350 def _test_view(self, vid, rql, args): |
|
351 if rql is None: |
|
352 rset = None |
|
353 req = self.request() |
|
354 else: |
|
355 rset, req = self.env.get_rset_and_req(rql) |
|
356 try: |
|
357 self.vreg.render('views', vid, req, rset=rset, **args) |
|
358 except: |
|
359 print vid, rset, args |
|
360 raise |
|
361 |
|
362 def test_form(self): |
|
363 for vid, rql, args in ( |
|
364 #('creation', 'Any X WHERE X eid 999999', {}), |
|
365 ('edition', 'EGroup X WHERE X name "managers"', {}), |
|
366 ('copy', 'EGroup X WHERE X name "managers"', {}), |
|
367 ('muledit', 'EGroup X', {}), |
|
368 #('muledit', 'Any X', {}), |
|
369 ): |
|
370 self._test_view(vid, rql, args) |
|
371 |
|
372 |
|
373 def test_properties(self): |
|
374 self.assertEquals(sorted(k for k in self.vreg['propertydefs'].keys() |
|
375 if k.startswith('boxes.edit_box')), |
|
376 ['boxes.edit_box.context', |
|
377 'boxes.edit_box.order', |
|
378 'boxes.edit_box.visible']) |
|
379 self.assertEquals([k for k in self.vreg['propertyvalues'].keys() |
|
380 if not k.startswith('system.version')], |
|
381 []) |
|
382 self.assertEquals(self.vreg.property_value('boxes.edit_box.visible'), True) |
|
383 self.assertEquals(self.vreg.property_value('boxes.edit_box.order'), 2) |
|
384 self.assertEquals(self.vreg.property_value('boxes.possible_views_box.visible'), False) |
|
385 self.assertEquals(self.vreg.property_value('boxes.possible_views_box.order'), 10) |
|
386 self.assertRaises(KeyError, self.vreg.property_value, 'boxes.actions_box') |
|
387 |
|
388 |
|
389 |
|
390 def test_owners_in_group_selector(self): |
|
391 """tests usage of 'owners' group with in_group_selector""" |
|
392 class SomeAction(Action): |
|
393 id = 'yo' |
|
394 category = 'foo' |
|
395 __selectors__ = (in_group_selector,) |
|
396 require_groups = ('owners', ) |
|
397 self.vreg.register_vobject_class(SomeAction) |
|
398 self.failUnless(SomeAction in self.vreg['actions']['yo'], self.vreg['actions']) |
|
399 try: |
|
400 # login as a simple user |
|
401 self.create_user('john') |
|
402 self.login('john') |
|
403 # it should not be possible to use SomeAction not owned objects |
|
404 rset, req = self.env.get_rset_and_req('Any G WHERE G is EGroup, G name "managers"') |
|
405 self.failIf('foo' in self.pactions(req, rset)) |
|
406 # insert a new card, and check that we can use SomeAction on our object |
|
407 self.execute('INSERT Card C: C title "zoubidou"') |
|
408 self.commit() |
|
409 rset, req = self.env.get_rset_and_req('Card C WHERE C title "zoubidou"') |
|
410 self.failUnless('foo' in self.pactions(req, rset)) |
|
411 # make sure even managers can't use the action |
|
412 self.restore_connection() |
|
413 rset, req = self.env.get_rset_and_req('Card C WHERE C title "zoubidou"') |
|
414 self.failIf('foo' in self.pactions(req, rset)) |
|
415 finally: |
|
416 del self.vreg[SomeAction.__registry__][SomeAction.id] |
|
417 |
|
418 |
|
419 |
|
420 |
|
421 |
|
422 from cubicweb.web.action import EntityAction |
|
423 |
|
424 class EETypeRQLAction(EntityAction): |
|
425 id = 'testaction' |
|
426 accepts = ('EEType',) |
|
427 condition = 'X name "EEType"' |
|
428 title = 'bla' |
|
429 |
|
430 class RQLActionTC(ViewSelectorTC): |
|
431 |
|
432 def setUp(self): |
|
433 super(RQLActionTC, self).setUp() |
|
434 self.vreg.register_vobject_class(EETypeRQLAction) |
|
435 |
|
436 def tearDown(self): |
|
437 super(RQLActionTC, self).tearDown() |
|
438 del self.vreg._registries['actions']['testaction'] |
|
439 |
|
440 def test(self): |
|
441 rset, req = self.env.get_rset_and_req('EEType X WHERE X name "EEType"') |
|
442 self.assertDictEqual(self.pactions(req, rset), |
|
443 {'useractions': USERACTIONS, |
|
444 'siteactions': SITEACTIONS, |
|
445 'mainactions': [('edit', actions.ModifyAction)], |
|
446 'moreactions': [('delete', actions.DeleteAction), |
|
447 ('copy', actions.CopyAction), |
|
448 ('testaction', EETypeRQLAction)], |
|
449 }) |
|
450 rset, req = self.env.get_rset_and_req('EEType X WHERE X name "ERType"') |
|
451 self.assertDictEqual(self.pactions(req, rset), |
|
452 {'useractions': USERACTIONS, |
|
453 'siteactions': SITEACTIONS, |
|
454 'mainactions': [('edit', actions.ModifyAction)], |
|
455 'moreactions': [('delete', actions.DeleteAction), |
|
456 ('copy', actions.CopyAction)], |
|
457 }) |
|
458 |
|
459 |
|
460 |
|
461 if __name__ == '__main__': |
|
462 unittest_main() |