web/test/unittest_viewselector.py
changeset 0 b97547f5f1fa
child 431 18b4dd650ef8
equal deleted inserted replaced
-1:000000000000 0:b97547f5f1fa
       
     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()