• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

zopefoundation / Products.GenericSetup / 5104175550

pending completion
5104175550

push

github

web-flow
Merge pull request #128 from zopefoundation/serialize_utility_registration_global

Prefer `component` (over  `factory`) in the serialization of utility registrations

1668 of 1988 branches covered (83.9%)

Branch coverage included in aggregate %.

26 of 26 new or added lines in 3 files covered. (100.0%)

9340 of 9819 relevant lines covered (95.12%)

0.95 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.91
/src/Products/GenericSetup/tests/test_components.py
1
##############################################################################
2
#
3
# Copyright (c) 2006 Zope Foundation and Contributors.
4
#
5
# This software is subject to the provisions of the Zope Public License,
6
# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
7
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
8
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
9
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
10
# FOR A PARTICULAR PURPOSE.
11
#
12
##############################################################################
13
"""Component registry export / import support unit tests.
1✔
14
"""
15

16
import unittest
1✔
17

18
from AccessControl.class_init import InitializeClass
1✔
19
from AccessControl.SecurityInfo import ClassSecurityInfo
1✔
20
from Acquisition import aq_base
1✔
21
from OFS.Folder import Folder
1✔
22
from OFS.SimpleItem import SimpleItem
1✔
23
from Products.Five.component import enableSite
1✔
24
from Products.Five.component.interfaces import IObjectManagerSite
1✔
25
from zope.component import getGlobalSiteManager
1✔
26
from zope.component import getMultiAdapter
1✔
27
from zope.component import getSiteManager
1✔
28
from zope.component import handle
1✔
29
from zope.component import queryAdapter
1✔
30
from zope.component import queryUtility
1✔
31
from zope.component import subscribers
1✔
32
from zope.component.globalregistry import base
1✔
33
from zope.component.hooks import clearSite
1✔
34
from zope.component.hooks import setHooks
1✔
35
from zope.component.hooks import setSite
1✔
36
from zope.interface import Interface
1✔
37
from zope.interface import implementer
1✔
38

39
from ..interfaces import IBody
1✔
40
from ..interfaces import IComponentsHandlerBlacklist
1✔
41
from ..testing import BodyAdapterTestCase
1✔
42
from ..testing import DummySetupEnviron
1✔
43
from ..testing import ExportImportZCMLLayer
1✔
44
from ..tests.common import DummyImportContext
1✔
45

46

47
try:
1✔
48
    from five.localsitemanager.registry import PersistentComponents
1✔
49
except ImportError:
50
    # Avoid generating a spurious dependency
51
    PersistentComponents = None
52

53

54
def createComponentRegistry(context):
1✔
55
    enableSite(context, iface=IObjectManagerSite)
1✔
56

57
    components = PersistentComponents('++etc++site')
1✔
58
    components.__bases__ = (base,)
1✔
59
    components.__parent__ = aq_base(context)
1✔
60
    # Make sure calls to getSiteManager on me return myself
61
    # necessary because OFS.ObjectManager.getSiteManager expects _components
62
    components._components = components
1✔
63
    context.setSiteManager(components)
1✔
64

65

66
class IDummyInterface(Interface):
1✔
67
    """A dummy interface."""
68

69
    def verify():
1✔
70
        """Returns True."""
71

72

73
class IDummyInterface2(Interface):
1✔
74
    """A second dummy interface."""
75

76
    def verify():
1✔
77
        """Returns True."""
78

79

80
@implementer(IDummyInterface)
1✔
81
class DummyUtility:
1✔
82
    """A dummy utility."""
83

84
    def verify(self):
1✔
85
        return True
1✔
86

87

88
class IAnotherDummy(Interface):
1✔
89
    """A third dummy interface."""
90

91
    def inc():
1✔
92
        """Increments handle count"""
93

94

95
class IAnotherDummy2(Interface):
1✔
96
    """A second dummy interface."""
97

98
    def verify():
1✔
99
        """Returns True."""
100

101

102
@implementer(IAnotherDummy)
1✔
103
class DummyObject:
1✔
104
    """A dummy object to pass to the handler."""
105

106
    handled = 0
1✔
107

108
    def inc(self):
1✔
109
        self.handled += 1
1✔
110

111

112
@implementer(IAnotherDummy2)
1✔
113
class DummyAdapter:
1✔
114
    """A dummy adapter."""
115

116
    def __init__(self, context):
1✔
117
        pass
1✔
118

119
    def verify(self):
1✔
120
        return True
1✔
121

122

123
def dummy_handler(context):
1✔
124
    """A dummy event handler."""
125

126
    context.inc()
1✔
127

128

129
@implementer(IDummyInterface)
1✔
130
class DummyTool(SimpleItem):
1✔
131
    """A dummy tool."""
132

133
    id = 'dummy_tool'
1✔
134
    meta_type = 'dummy tool'
1✔
135
    security = ClassSecurityInfo()
1✔
136

137
    @security.public
1✔
138
    def verify(self):
1✔
139
        return True
1✔
140

141

142
InitializeClass(DummyTool)
1✔
143

144

145
@implementer(IDummyInterface2)
1✔
146
class DummyTool2(SimpleItem):
1✔
147
    """A second dummy tool."""
148

149
    id = 'dummy_tool2'
1✔
150
    meta_type = 'dummy tool2'
1✔
151
    security = ClassSecurityInfo()
1✔
152

153
    @security.public
1✔
154
    def verify(self):
1✔
155
        return True
1✔
156

157

158
InitializeClass(DummyTool2)
1✔
159

160

161
@implementer(IComponentsHandlerBlacklist)
1✔
162
class DummyBlacklist:
1✔
163
    """A blacklist."""
164

165
    def getExcludedInterfaces(self):
1✔
166
        return (IDummyInterface, )
1✔
167

168

169
_COMPONENTS_BODY = b"""\
1✔
170
<?xml version="1.0" encoding="utf-8"?>
171
<componentregistry>
172
 <adapters>
173
  <adapter factory="Products.GenericSetup.tests.test_components.DummyAdapter"
174
     for="zope.interface.Interface"
175
     provides="Products.GenericSetup.tests.test_components.IAnotherDummy2"/>
176
  <adapter name="foo"
177
     factory="Products.GenericSetup.tests.test_components.DummyAdapter"
178
     for="zope.interface.Interface"
179
     provides="Products.GenericSetup.tests.test_components.IAnotherDummy2"/>
180
 </adapters>
181
 <subscribers>
182
  <subscriber
183
     factory="Products.GenericSetup.tests.test_components.DummyAdapter"
184
     for="Products.GenericSetup.tests.test_components.IAnotherDummy"
185
     provides="Products.GenericSetup.tests.test_components.IAnotherDummy2"/>
186
  <subscriber for="Products.GenericSetup.tests.test_components.IAnotherDummy"
187
     handler="Products.GenericSetup.tests.test_components.dummy_handler"/>
188
 </subscribers>
189
 <utilities>
190
  <utility factory="Products.GenericSetup.tests.test_components.DummyUtility"
191
     id="dummy_utility"
192
     interface="Products.GenericSetup.tests.test_components.IDummyInterface"/>
193
  <utility name="dummy tool name"
194
     interface="Products.GenericSetup.tests.test_components.IDummyInterface"
195
     object="dummy_tool"/>
196
  <utility name="dummy tool name2"
197
     interface="Products.GenericSetup.tests.test_components.IDummyInterface2"
198
     object="dummy_tool2"/>
199
  <utility name="foo"
200
     factory="Products.GenericSetup.tests.test_components.DummyUtility"
201
     interface="Products.GenericSetup.tests.test_components.IDummyInterface2"/>
202
 </utilities>
203
</componentregistry>
204
"""
205

206
_REMOVE_IMPORT = b"""\
1✔
207
<?xml version="1.0" encoding="utf-8"?>
208
<componentregistry>
209
 <adapters>
210
  <adapter factory="Products.GenericSetup.tests.test_components.DummyAdapter"
211
     provides="Products.GenericSetup.tests.test_components.IAnotherDummy2"
212
     for="*" remove="True"/>
213
 </adapters>
214
 <subscribers>
215
  <subscriber
216
     factory="Products.GenericSetup.tests.test_components.DummyAdapter"
217
     for="Products.GenericSetup.tests.test_components.IAnotherDummy"
218
     provides="Products.GenericSetup.tests.test_components.IAnotherDummy2"
219
     remove="True"/>
220
  <subscriber
221
     for="Products.GenericSetup.tests.test_components.IAnotherDummy"
222
     handler="Products.GenericSetup.tests.test_components.dummy_handler"
223
     remove="True"/>
224
 </subscribers>
225
 <utilities>
226
  <utility id="dummy_utility"
227
     factory="Products.GenericSetup.tests.test_components.DummyUtility"
228
     interface="Products.GenericSetup.tests.test_components.IDummyInterface"
229
     remove="True"/>
230
  <utility name="dummy tool name"
231
     interface="Products.GenericSetup.tests.test_components.IDummyInterface"
232
     object="dummy_tool" remove="True"/>
233
  <utility name="foo"
234
     factory="Products.GenericSetup.tests.test_components.DummyUtility"
235
     interface="Products.GenericSetup.tests.test_components.IDummyInterface2"
236
     remove="True"/>
237
 </utilities>
238
</componentregistry>
239
"""
240

241

242
_INTERFACE_COMPONENT = b"""\
1✔
243
<?xml version="1.0" encoding="utf-8"?>
244
<componentregistry>
245
 <adapters/>
246
 <subscribers/>
247
 <utilities>
248
  <utility name="test_interface"
249
     component="Products.GenericSetup.tests.test_components.ITestInterface"
250
     interface="Products.GenericSetup.tests.test_components.ITestInterfaceType"/>
251
 </utilities>
252
</componentregistry>
253
"""
254

255

256
class ComponentRegistryXMLAdapterTests(BodyAdapterTestCase, unittest.TestCase):
1✔
257

258
    layer = ExportImportZCMLLayer
1✔
259

260
    def _getTargetClass(self):
1✔
261
        from Products.GenericSetup.components import \
1✔
262
            ComponentRegistryXMLAdapter
263
        return ComponentRegistryXMLAdapter
1✔
264

265
    def _populate(self, obj):
1✔
266
        obj.registerAdapter(DummyAdapter, required=(None,))
1✔
267
        obj.registerAdapter(DummyAdapter, required=(None,), name='foo')
1✔
268

269
        obj.registerSubscriptionAdapter(DummyAdapter,
1✔
270
                                        required=(IAnotherDummy,))
271
        obj.registerHandler(dummy_handler, required=(IAnotherDummy,))
1✔
272

273
        util = DummyUtility()
1✔
274
        name = 'dummy_utility'
1✔
275
        util.__name__ = name
1✔
276
        util.__parent__ = aq_base(obj)
1✔
277
        obj._setObject(name, aq_base(util),
1✔
278
                       set_owner=False, suppress_events=True)
279
        obj.registerUtility(aq_base(obj[name]), IDummyInterface)
1✔
280

281
        util = DummyUtility()
1✔
282
        name = ('Products.GenericSetup.tests.test_components.'
1✔
283
                'IDummyInterface2-foo')
284
        util.__name__ = name
1✔
285
        util.__parent__ = aq_base(obj)
1✔
286
        obj._setObject(name, aq_base(util),
1✔
287
                       set_owner=False, suppress_events=True)
288
        obj.registerUtility(aq_base(obj[name]), IDummyInterface2, name='foo')
1✔
289

290
        tool = aq_base(obj.aq_parent['dummy_tool'])
1✔
291
        obj.registerUtility(tool, IDummyInterface, name='dummy tool name')
1✔
292

293
        tool2 = aq_base(obj.aq_parent['dummy_tool2'])
1✔
294
        obj.registerUtility(tool2, IDummyInterface2, name='dummy tool name2')
1✔
295

296
    def _verifyImport(self, obj):
1✔
297
        adapted = queryAdapter(object(), IAnotherDummy2)
1✔
298
        self.assertTrue(IAnotherDummy2.providedBy(adapted))
1✔
299
        self.assertTrue(adapted.verify())
1✔
300

301
        adapted = queryAdapter(object(), IAnotherDummy2, name='foo')
1✔
302
        self.assertTrue(IAnotherDummy2.providedBy(adapted))
1✔
303
        self.assertTrue(adapted.verify())
1✔
304

305
        dummy = DummyObject()
1✔
306
        results = [adap.verify() for adap in
1✔
307
                   subscribers([dummy], IAnotherDummy2)]
308
        self.assertEqual(results, [True])
1✔
309

310
        dummy = DummyObject()
1✔
311
        handle(dummy)
1✔
312
        self.assertEqual(dummy.handled, 1)
1✔
313

314
        util = queryUtility(IDummyInterface2, name='foo')
1✔
315
        self.assertTrue(IDummyInterface.providedBy(util))
1✔
316
        self.assertTrue(util.verify())
1✔
317
        self.assertTrue(util.__parent__ == obj)
1✔
318
        name = ('Products.GenericSetup.tests.test_components.'
1✔
319
                'IDummyInterface2-foo')
320
        self.assertEqual(util.__name__, name)
1✔
321
        self.assertTrue(name in obj.objectIds())
1✔
322

323
        util = queryUtility(IDummyInterface)
1✔
324
        self.assertTrue(IDummyInterface.providedBy(util))
1✔
325
        self.assertTrue(util.verify())
1✔
326
        self.assertTrue(util.__parent__ == obj)
1✔
327
        name = 'dummy_utility'
1✔
328
        self.assertEqual(util.__name__, name)
1✔
329
        self.assertTrue(name in obj.objectIds())
1✔
330

331
        util = queryUtility(IDummyInterface, name='dummy tool name')
1✔
332
        self.assertTrue(IDummyInterface.providedBy(util))
1✔
333
        self.assertTrue(util.verify())
1✔
334
        self.assertEqual(util.meta_type, 'dummy tool')
1✔
335

336
        # make sure we can get the tool by normal means
337
        tool = getattr(obj.aq_parent, 'dummy_tool')
1✔
338
        self.assertEqual(tool.meta_type, 'dummy tool')
1✔
339
        self.assertEqual(repr(aq_base(util)), repr(aq_base(tool)))
1✔
340

341
        util = queryUtility(IDummyInterface2, name='dummy tool name2')
1✔
342
        self.assertTrue(IDummyInterface2.providedBy(util))
1✔
343
        self.assertTrue(util.verify())
1✔
344
        self.assertEqual(util.meta_type, 'dummy tool2')
1✔
345

346
        # make sure we can get the tool by normal means
347
        tool = getattr(obj.aq_parent, 'dummy_tool2')
1✔
348
        self.assertEqual(tool.meta_type, 'dummy tool2')
1✔
349
        self.assertEqual(repr(aq_base(util)), repr(aq_base(tool)))
1✔
350

351
    def test_blacklist_get(self):
1✔
352
        obj = self._obj
1✔
353
        self._populate(obj)
1✔
354

355
        # Register our blacklist
356
        gsm = getGlobalSiteManager()
1✔
357
        gsm.registerUtility(DummyBlacklist(),
1✔
358
                            IComponentsHandlerBlacklist,
359
                            name='dummy')
360

361
        context = DummySetupEnviron()
1✔
362
        adapted = getMultiAdapter((obj, context), IBody)
1✔
363

364
        body = adapted.body
1✔
365
        self.assertFalse(b'IComponentsHandlerBlacklist' in body)
1✔
366
        self.assertFalse(b'test_components.IDummyInterface"' in body)
1✔
367

368
    def test_blacklist_set(self):
1✔
369
        obj = self._obj
1✔
370
        # Register our blacklist
371
        gsm = getGlobalSiteManager()
1✔
372
        gsm.registerUtility(DummyBlacklist(),
1✔
373
                            IComponentsHandlerBlacklist,
374
                            name='dummy')
375

376
        context = DummySetupEnviron()
1✔
377
        adapted = getMultiAdapter((obj, context), IBody)
1✔
378
        adapted.body = self._BODY
1✔
379

380
        util = queryUtility(IDummyInterface2, name='foo')
1✔
381
        self.assertTrue(IDummyInterface.providedBy(util))
1✔
382
        self.assertTrue(util.verify())
1✔
383
        util = queryUtility(IDummyInterface)
1✔
384
        self.assertTrue(util is None)
1✔
385

386
        # now in update mode
387
        context._should_purge = False
1✔
388
        adapted = getMultiAdapter((obj, context), IBody)
1✔
389
        adapted.body = self._BODY
1✔
390

391
        util = queryUtility(IDummyInterface2, name='foo')
1✔
392
        self.assertTrue(IDummyInterface.providedBy(util))
1✔
393
        self.assertTrue(util.verify())
1✔
394
        util = queryUtility(IDummyInterface)
1✔
395
        self.assertTrue(util is None)
1✔
396

397
        # and again in update mode
398
        adapted = getMultiAdapter((obj, context), IBody)
1✔
399
        adapted.body = self._BODY
1✔
400

401
        util = queryUtility(IDummyInterface2, name='foo')
1✔
402
        self.assertTrue(IDummyInterface.providedBy(util))
1✔
403
        self.assertTrue(util.verify())
1✔
404
        util = queryUtility(IDummyInterface)
1✔
405
        self.assertTrue(util is None)
1✔
406

407
    def test_remove_components(self):
1✔
408
        from ..components import importComponentRegistry
1✔
409

410
        obj = self._obj
1✔
411
        self._populate(obj)
1✔
412
        self._verifyImport(obj)
1✔
413

414
        context = DummyImportContext(obj, False)
1✔
415
        context._files['componentregistry.xml'] = _REMOVE_IMPORT
1✔
416
        importComponentRegistry(context)
1✔
417

418
        adapted = queryAdapter(object(), IAnotherDummy2)
1✔
419
        self.assertTrue(adapted is None)
1✔
420

421
        # This one should still exist
422
        adapted = queryAdapter(object(), IAnotherDummy2, name='foo')
1✔
423
        self.assertFalse(adapted is None)
1✔
424

425
        dummy = DummyObject()
1✔
426
        results = [adap.verify() for adap in
1✔
427
                   subscribers([dummy], IAnotherDummy2)]
428
        self.assertEqual(results, [])
1✔
429

430
        dummy = DummyObject()
1✔
431
        handle(dummy)
1✔
432
        self.assertEqual(dummy.handled, 0)
1✔
433

434
        util = queryUtility(IDummyInterface2, name='foo')
1✔
435
        name = ('Products.GenericSetup.tests.test_components.'
1✔
436
                'IDummyInterface2-foo')
437
        self.assertTrue(util is None)
1✔
438
        self.assertFalse(name in obj.objectIds())
1✔
439

440
        util = queryUtility(IDummyInterface)
1✔
441
        self.assertTrue(util is None)
1✔
442
        self.assertFalse('dummy_utility' in obj.objectIds())
1✔
443

444
        util = queryUtility(IDummyInterface, name='dummy tool name')
1✔
445
        self.assertTrue(util is None)
1✔
446

447
        # This one should still exist
448
        util = queryUtility(IDummyInterface2, name='dummy tool name2')
1✔
449
        self.assertFalse(util is None)
1✔
450

451
    def test_export_interface_component(self):
1✔
452
        sm = self._obj
1✔
453
        sm.registerUtility(ITestInterface,
1✔
454
                           ITestInterfaceType,
455
                           "test_interface")
456
        context = DummySetupEnviron()
1✔
457
        adapted = getMultiAdapter((sm, context), IBody)
1✔
458
        body = adapted.body
1✔
459
        self.assertEqual(body, _INTERFACE_COMPONENT)
1✔
460

461
    def test_import_interface_component(self):
1✔
462
        from ..components import importComponentRegistry
1✔
463
        sm = self._obj
1✔
464
        context = DummyImportContext(sm, False)
1✔
465
        context._files['componentregistry.xml'] = _INTERFACE_COMPONENT
1✔
466
        importComponentRegistry(context)
1✔
467
        self.assertIs(
1✔
468
            sm.queryUtility(ITestInterfaceType, name="test_interface"),
469
            ITestInterface)
470

471
    def setUp(self):
1✔
472
        # Create and enable a local component registry
473
        site = Folder()
1✔
474
        createComponentRegistry(site)
1✔
475
        setHooks()
1✔
476
        setSite(site)
1✔
477
        sm = getSiteManager()
1✔
478

479
        tool = DummyTool()
1✔
480
        site._setObject(tool.id, tool)
1✔
481

482
        tool2 = DummyTool2()
1✔
483
        site._setObject(tool2.id, tool2)
1✔
484

485
        self._obj = sm
1✔
486
        self._BODY = _COMPONENTS_BODY
1✔
487

488
    def tearDown(self):
1✔
489
        clearSite()
1✔
490
        # Make sure our global utility is gone again
491
        gsm = getGlobalSiteManager()
1✔
492
        gsm.unregisterUtility(provided=IComponentsHandlerBlacklist,
1✔
493
                              name='dummy')
494

495

496
class ITestInterface(Interface):
1✔
497
    """interface registered as utility."""
498

499

500
class ITestInterfaceType(Interface):
1✔
501
    """interface provided by ``ITestInterface``."""
502

503

504
if PersistentComponents is not None:
1!
505
    def test_suite():
1✔
506
        # reimport to make sure tests are run from Products
507
        from ..tests.test_components import ComponentRegistryXMLAdapterTests
1✔
508

509
        return unittest.TestSuite((
1✔
510
            unittest.defaultTestLoader.loadTestsFromTestCase(
511
                ComponentRegistryXMLAdapterTests),
512
        ))
513
else:
514
    def test_suite():
×
515
        return unittest.TestSuite()
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc