cubicweb/server/test/unittest_hook.py
changeset 11057 0b59724cb3f2
parent 9758 91f3cb7db2aa
child 11269 73ac69970047
equal deleted inserted replaced
11052:058bb3dc685f 11057:0b59724cb3f2
       
     1 # -*- coding: utf-8 -*-
       
     2 # copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
       
     3 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
       
     4 #
       
     5 # This file is part of CubicWeb.
       
     6 #
       
     7 # CubicWeb is free software: you can redistribute it and/or modify it under the
       
     8 # terms of the GNU Lesser General Public License as published by the Free
       
     9 # Software Foundation, either version 2.1 of the License, or (at your option)
       
    10 # any later version.
       
    11 #
       
    12 # CubicWeb is distributed in the hope that it will be useful, but WITHOUT
       
    13 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
       
    14 # FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
       
    15 # details.
       
    16 #
       
    17 # You should have received a copy of the GNU Lesser General Public License along
       
    18 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
       
    19 """unit/functional tests for cubicweb.server.hook"""
       
    20 
       
    21 from logilab.common.testlib import TestCase, unittest_main, mock_object
       
    22 
       
    23 from cubicweb.devtools import TestServerConfiguration, fake
       
    24 from cubicweb.devtools.testlib import CubicWebTC
       
    25 from cubicweb.server import hook
       
    26 from cubicweb.hooks import integrity, syncschema
       
    27 
       
    28 class OperationsTC(CubicWebTC):
       
    29 
       
    30     def setUp(self):
       
    31         CubicWebTC.setUp(self)
       
    32         self.hm = self.repo.hm
       
    33 
       
    34     def test_late_operation(self):
       
    35         with self.admin_access.repo_cnx() as cnx:
       
    36             l1 = hook.LateOperation(cnx)
       
    37             l2 = hook.LateOperation(cnx)
       
    38             l3 = hook.Operation(cnx)
       
    39             self.assertEqual(cnx.pending_operations, [l3, l1, l2])
       
    40 
       
    41     def test_single_last_operation(self):
       
    42         with self.admin_access.repo_cnx() as cnx:
       
    43             l0 = hook.SingleLastOperation(cnx)
       
    44             l1 = hook.LateOperation(cnx)
       
    45             l2 = hook.LateOperation(cnx)
       
    46             l3 = hook.Operation(cnx)
       
    47             self.assertEqual(cnx.pending_operations, [l3, l1, l2, l0])
       
    48             l4 = hook.SingleLastOperation(cnx)
       
    49             self.assertEqual(cnx.pending_operations, [l3, l1, l2, l4])
       
    50 
       
    51     def test_global_operation_order(self):
       
    52         with self.admin_access.repo_cnx() as cnx:
       
    53             op1 = syncschema.RDefDelOp(cnx)
       
    54             op2 = integrity._CheckORelationOp(cnx)
       
    55             op3 = syncschema.MemSchemaNotifyChanges(cnx)
       
    56             self.assertEqual([op1, op2, op3], cnx.pending_operations)
       
    57 
       
    58 class HookCalled(Exception): pass
       
    59 
       
    60 config = TestServerConfiguration('data')
       
    61 config.bootstrap_cubes()
       
    62 schema = config.load_schema()
       
    63 
       
    64 def tearDownModule(*args):
       
    65     global config, schema
       
    66     del config, schema
       
    67 
       
    68 class AddAnyHook(hook.Hook):
       
    69     __regid__ = 'addany'
       
    70     category = 'cat1'
       
    71     events = ('before_add_entity',)
       
    72     def __call__(self):
       
    73         raise HookCalled()
       
    74 
       
    75 
       
    76 class HooksRegistryTC(TestCase):
       
    77 
       
    78     def setUp(self):
       
    79         """ called before each test from this class """
       
    80         self.vreg = mock_object(config=config, schema=schema)
       
    81         self.o = hook.HooksRegistry(self.vreg)
       
    82 
       
    83     def test_register_bad_hook1(self):
       
    84         class _Hook(hook.Hook):
       
    85             events = ('before_add_entiti',)
       
    86         with self.assertRaises(Exception) as cm:
       
    87             self.o.register(_Hook)
       
    88         self.assertEqual(str(cm.exception), 'bad event before_add_entiti on %s._Hook' % __name__)
       
    89 
       
    90     def test_register_bad_hook2(self):
       
    91         class _Hook(hook.Hook):
       
    92             events = None
       
    93         with self.assertRaises(Exception) as cm:
       
    94             self.o.register(_Hook)
       
    95         self.assertEqual(str(cm.exception), 'bad .events attribute None on %s._Hook' % __name__)
       
    96 
       
    97     def test_register_bad_hook3(self):
       
    98         class _Hook(hook.Hook):
       
    99             events = 'before_add_entity'
       
   100         with self.assertRaises(Exception) as cm:
       
   101             self.o.register(_Hook)
       
   102         self.assertEqual(str(cm.exception), 'bad event b on %s._Hook' % __name__)
       
   103 
       
   104     def test_call_hook(self):
       
   105         self.o.register(AddAnyHook)
       
   106         dis = set()
       
   107         cw = fake.FakeSession()
       
   108         cw.is_hook_activated = lambda cls: cls.category not in dis
       
   109         self.assertRaises(HookCalled,
       
   110                           self.o.call_hooks, 'before_add_entity', cw)
       
   111         dis.add('cat1')
       
   112         self.o.call_hooks('before_add_entity', cw) # disabled hooks category, not called
       
   113         dis.remove('cat1')
       
   114         self.assertRaises(HookCalled,
       
   115                           self.o.call_hooks, 'before_add_entity', cw)
       
   116         self.o.unregister(AddAnyHook)
       
   117         self.o.call_hooks('before_add_entity', cw) # nothing to call
       
   118 
       
   119 
       
   120 class SystemHooksTC(CubicWebTC):
       
   121 
       
   122     def test_startup_shutdown(self):
       
   123         import hooks # cubicweb/server/test/data/hooks.py
       
   124         self.assertEqual(hooks.CALLED_EVENTS['server_startup'], True)
       
   125         # don't actually call repository.shutdown !
       
   126         self.repo.hm.call_hooks('server_shutdown', repo=self.repo)
       
   127         self.assertEqual(hooks.CALLED_EVENTS['server_shutdown'], True)
       
   128 
       
   129     def test_session_open_close(self):
       
   130         import hooks # cubicweb/server/test/data/hooks.py
       
   131         anonaccess = self.new_access('anon')
       
   132         with anonaccess.repo_cnx() as cnx:
       
   133             self.assertEqual(hooks.CALLED_EVENTS['session_open'], 'anon')
       
   134         anonaccess.close()
       
   135         self.assertEqual(hooks.CALLED_EVENTS['session_close'], 'anon')
       
   136 
       
   137 
       
   138 # class RelationHookTC(TestCase):
       
   139 #     """testcase for relation hooks grouping"""
       
   140 #     def setUp(self):
       
   141 #         """ called before each test from this class """
       
   142 #         self.o = HooksManager(schema)
       
   143 #         self.called = []
       
   144 
       
   145 #     def test_before_add_relation(self):
       
   146 #         """make sure before_xxx_relation hooks are called directly"""
       
   147 #         self.o.register(self._before_relation_hook,
       
   148 #                              'before_add_relation', 'concerne')
       
   149 #         self.assertEqual(self.called, [])
       
   150 #         self.o.call_hooks('before_add_relation', 'concerne', 'USER',
       
   151 #                           1, 'concerne', 2)
       
   152 #         self.assertEqual(self.called, [(1, 'concerne', 2)])
       
   153 
       
   154 #     def test_after_add_relation(self):
       
   155 #         """make sure after_xxx_relation hooks are deferred"""
       
   156 #         self.o.register(self._after_relation_hook,
       
   157 #                              'after_add_relation', 'concerne')
       
   158 #         self.assertEqual(self.called, [])
       
   159 #         self.o.call_hooks('after_add_relation', 'concerne', 'USER',
       
   160 #                           1, 'concerne', 2)
       
   161 #         self.o.call_hooks('after_add_relation', 'concerne', 'USER',
       
   162 #                           3, 'concerne', 4)
       
   163 #         self.assertEqual(self.called, [(1, 'concerne', 2), (3, 'concerne', 4)])
       
   164 
       
   165 #     def test_before_delete_relation(self):
       
   166 #         """make sure before_xxx_relation hooks are called directly"""
       
   167 #         self.o.register(self._before_relation_hook,
       
   168 #                              'before_delete_relation', 'concerne')
       
   169 #         self.assertEqual(self.called, [])
       
   170 #         self.o.call_hooks('before_delete_relation', 'concerne', 'USER',
       
   171 #                           1, 'concerne', 2)
       
   172 #         self.assertEqual(self.called, [(1, 'concerne', 2)])
       
   173 
       
   174 #     def test_after_delete_relation(self):
       
   175 #         """make sure after_xxx_relation hooks are deferred"""
       
   176 #         self.o.register(self._after_relation_hook,
       
   177 #                         'after_delete_relation', 'concerne')
       
   178 #         self.o.call_hooks('after_delete_relation', 'concerne', 'USER',
       
   179 #                           1, 'concerne', 2)
       
   180 #         self.o.call_hooks('after_delete_relation', 'concerne', 'USER',
       
   181 #                           3, 'concerne', 4)
       
   182 #         self.assertEqual(self.called, [(1, 'concerne', 2), (3, 'concerne', 4)])
       
   183 
       
   184 
       
   185 #     def _before_relation_hook(self, cnxset, subject, r_type, object):
       
   186 #         self.called.append((subject, r_type, object))
       
   187 
       
   188 #     def _after_relation_hook(self, cnxset, subject, r_type, object):
       
   189 #         self.called.append((subject, r_type, object))
       
   190 
       
   191 
       
   192 if __name__ == '__main__':
       
   193     unittest_main()