source: products/quintagroup.canonicalpath/trunk/quintagroup/canonicalpath/tests.py @ 3145

Last change on this file since 3145 was 3145, checked in by vmaksymiv, 13 years ago

pep8 fixes

  • Property svn:eol-style set to native
File size: 19.0 KB
Line 
1import unittest
2
3from zope.testing import doctestunit
4from zope.component import testing
5from zope.component import queryAdapter, queryMultiAdapter, getMultiAdapter
6from zope.schema.interfaces import InvalidValue
7
8#for compatibility with older plone versions
9try:
10    from plone.indexer.interfaces import IIndexableObject
11    IS_NEW = True
12except:
13    from plone.app.content.interfaces import IIndexableObjectWrapper \
14        as _old_IIndexableObjectWrapper
15    IS_NEW = False
16
17
18from OFS.PropertyManager import PropertyManager
19from OFS.Traversable import Traversable
20
21from Testing import ZopeTestCase as ztc
22
23from Products.Five import zcml
24from Products.Five import fiveconfigure
25from Products.CMFCore.utils import getToolByName
26from Products.PloneTestCase import PloneTestCase as ptc
27from Products.PloneTestCase.layer import PloneSite
28
29from Products.Archetypes.tests.utils import makeContent
30
31from quintagroup.canonicalpath.interfaces import ICanonicalPath
32from quintagroup.canonicalpath.interfaces import ICanonicalLink
33from quintagroup.canonicalpath.adapters import PROPERTY_PATH
34from quintagroup.canonicalpath.adapters import PROPERTY_LINK
35from quintagroup.canonicalpath.upgrades import CanonicalConvertor
36
37
38def registerCanonicalPathInReg():
39    import quintagroup.canonicalpath
40    import Products.Five
41    fiveconfigure.debug_mode = True
42    zcml.load_config('meta.zcml', Products.Five)
43    zcml.load_config('configure.zcml', quintagroup.canonicalpath)
44    fiveconfigure.debug_mode = False
45
46
47class TestCase(ptc.PloneTestCase):
48    class layer(PloneSite):
49        @classmethod
50        def setUp(cls):
51            registerCanonicalPathInReg()
52            # import quintagroup.canonicalpath
53            # fiveconfigure.debug_mode = True
54            # zcml.load_config('configure.zcml', quintagroup.canonicalpath)
55            # fiveconfigure.debug_mode = False
56
57ptc.setupPloneSite()
58
59
60class TestIndexerRegistration(TestCase):
61
62    def afterSetUp(self):
63        self.loginAsPortalOwner()
64        self.catalog = getToolByName(self.portal, 'portal_catalog')
65        self.my_doc = makeContent(self.portal, portal_type='Document',
66                                  id='my_doc')
67        self.logout()
68
69    def get_indexable_wrapper(self, obj):
70        if IS_NEW:
71            wrapper = None
72            if not IIndexableObject.providedBy(obj):
73                wrapper = queryMultiAdapter((obj, self.catalog),
74                                            IIndexableObject)
75        else:
76            wf = getattr(self.portal, 'portal_workflow', None)
77            if wf is not None:
78                vars = wf.getCatalogVariablesFor(obj)
79            else:
80                vars = {}
81            wrapper = getMultiAdapter((obj, self.portal),
82                                      _old_IIndexableObjectWrapper)
83            wrapper.update(vars)
84
85        return wrapper and wrapper or obj
86
87    def testForAT(self):
88        wrapper = self.get_indexable_wrapper(self.my_doc)
89        self.assertFalse(wrapper is None,
90                         "No indexer registered for document object")
91
92    def testCanonicalPathForAT(self):
93        wrapper = self.get_indexable_wrapper(self.my_doc)
94        self.assertTrue(hasattr(wrapper, 'canonical_path'),
95                        "'canonical_path' attribute not accessible with "\
96                        "indexer wrapper for Document object")
97
98    def testCanonicalLinkForAT(self):
99        wrapper = self.get_indexable_wrapper(self.my_doc)
100        self.assertTrue(hasattr(wrapper, 'canonical_link'),
101                        "'canonical_link' attribute not accessible with "\
102                        "indexer wrapper for Document object")
103
104
105class TestDefaultCanonicalPathAdapter(TestCase):
106
107    def afterSetUp(self):
108        self.loginAsPortalOwner()
109        self.purl = getToolByName(self.portal, 'portal_url')
110        self.my_doc = makeContent(self.portal, portal_type='Document',
111                                  id='my_doc')
112        self.logout()
113
114        self.mydoc_cp = '/' + '/'.join(self.purl.getRelativeContentPath(
115                                            self.my_doc))
116        self.portal_cp = '/' + '/'.join(self.purl.getRelativeContentPath(
117                                            self.portal))
118
119    def testRegistration4Portal(self):
120        cpadapter = queryAdapter(self.portal, ICanonicalPath)
121        self.assertFalse(cpadapter is None,
122            "Can't get canonical path adapter for the plone site object")
123
124    def testRegistration4AT(self):
125        cpadapter = queryAdapter(self.my_doc, ICanonicalPath)
126        self.assertFalse(cpadapter is None,
127            "Can't get canonical path adapter for the Document object")
128
129    def testGetDefault4Portal(self):
130        cpadapter = queryAdapter(self.portal, ICanonicalPath)
131        self.assertTrue(cpadapter.canonical_path == self.portal_cp,
132            "Canonical path adapter return '%s' for portal, must be: '%s'" % (
133            cpadapter.canonical_path, self.portal_cp))
134
135    def testGetDefault4AT(self):
136        cpadapter = queryAdapter(self.my_doc, ICanonicalPath)
137        self.assertTrue(cpadapter.canonical_path == self.mydoc_cp,
138            "Canonical path adapter return '%s' for document, "\
139            "must be: '%s'" % (cpadapter.canonical_path, self.mydoc_cp))
140
141    def testSet4Portal(self):
142        cpadapter = queryAdapter(self.portal, ICanonicalPath)
143        newcp = self.portal_cp + '/new_portal_canonical'
144
145        cpadapter.canonical_path = newcp
146        prop = self.portal.getProperty(PROPERTY_PATH, None)
147        self.assertTrue(prop == newcp,
148            "Canonical path adapter setter NOT SET new '%s' value to '%s' " \
149            "propery for the portal" % (newcp, PROPERTY_PATH))
150
151        self.assertTrue(cpadapter.canonical_path == newcp,
152            "Canonical path adapter GET '%s' canonical_path, for portal, " \
153            "must be: '%s'" % (cpadapter.canonical_path, newcp))
154
155    def testSet4AT(self):
156        cpadapter = queryAdapter(self.my_doc, ICanonicalPath)
157        newcp = self.mydoc_cp + '/new_mydoc_canonical'
158
159        cpadapter.canonical_path = newcp
160        prop = self.my_doc.getProperty(PROPERTY_PATH, None)
161        self.assertTrue(prop == newcp,
162            "Canonical path adapter setter NOT SET new '%s' value to '%s' " \
163            "propery for the Document" % (newcp, PROPERTY_PATH))
164
165        self.assertTrue(cpadapter.canonical_path == newcp,
166            "Canonical path adapter GET '%s' canonical_path, for Document, " \
167            "must be: '%s'" % (cpadapter.canonical_path, newcp))
168
169    def testValidationWrong(self):
170        cpadapter = queryAdapter(self.my_doc, ICanonicalPath)
171        for wrong in ['new\nline', 's p a c e', 'with\ttabs']:
172            try:
173                cpadapter.canonical_path = wrong
174            except InvalidValue:
175                continue
176            else:
177                raise self.failureException, "InvalidValue not raised when " \
178                      "'%s' wrong value try to set" % wrong
179
180    def testValidationGood(self):
181        cpadapter = queryAdapter(self.my_doc, ICanonicalPath)
182        for good in ['./good', '../good', '/good', 'good']:
183            cpadapter.canonical_path = good
184
185    def testDeleteProperty(self):
186        hasprop = self.portal.hasProperty
187        cpadapter = queryAdapter(self.portal, ICanonicalPath)
188        cpadapter.canonical_path = '/new_portal_canonical'
189        assert hasprop(PROPERTY_PATH)
190
191        del cpadapter.canonical_path
192        self.assertFalse(hasprop(PROPERTY_PATH),
193            "Not deleted Canonical path customization property for the portal")
194
195    def testDelCustomization(self):
196        cpadapter = queryAdapter(self.portal, ICanonicalPath)
197        cpadapter.canonical_path = '/new_portal_canonical'
198        assert cpadapter.canonical_path == '/new_portal_canonical'
199
200        del cpadapter.canonical_path
201        self.assertTrue(cpadapter.canonical_path == self.portal_cp,
202            "After deleted Canonical path customization property not set to "
203            "default value for the portal")
204
205
206class TestDefaultCanonicalLinkAdapter(TestCase):
207
208    def afterSetUp(self):
209        self.loginAsPortalOwner()
210        self.purl = getToolByName(self.portal, 'portal_url')
211        self.my_doc = makeContent(self.portal, portal_type='Document',
212                                  id='my_doc')
213        self.logout()
214
215        self.mydoc_cl = self.my_doc.absolute_url()
216
217    def testRegistration4Portal(self):
218        cladapter = queryAdapter(self.portal, ICanonicalLink)
219        self.assertFalse(cladapter is None,
220            "Can't get canonical link adapter for the plone site object")
221
222    def testRegistration4AT(self):
223        cladapter = queryAdapter(self.my_doc, ICanonicalLink)
224        self.assertFalse(cladapter is None,
225            "Can't get canonical link adapter for the Document object")
226
227    def testGetDefault4Portal(self):
228        cladapter = queryAdapter(self.portal, ICanonicalLink)
229        self.assertTrue(cladapter.canonical_link == self.purl(),
230            "Canonical link adapter return '%s' for portal, must be: '%s'" % (
231            cladapter.canonical_link, self.purl()))
232
233    def testGetDefault4AT(self):
234        cladapter = queryAdapter(self.my_doc, ICanonicalLink)
235        self.assertTrue(cladapter.canonical_link == self.mydoc_cl,
236            "Canonical link adapter return '%s' for document, "\
237            "must be: '%s'" % (cladapter.canonical_link, self.mydoc_cl))
238
239    def testSet4Portal(self):
240        cladapter = queryAdapter(self.portal, ICanonicalLink)
241        newcl = self.purl() + '/new_portal_canonical'
242
243        cladapter.canonical_link = newcl
244        prop = self.portal.getProperty(PROPERTY_LINK, None)
245        self.assertTrue(prop == newcl,
246            "Canonical link adapter setter NOT SET new '%s' value to '%s' " \
247            "propery for the portal" % (newcl, PROPERTY_LINK))
248
249        self.assertTrue(cladapter.canonical_link == newcl,
250            "Canonical link adapter GET '%s' canonical_link, for portal, " \
251            "must be: '%s'" % (cladapter.canonical_link, newcl))
252
253    def testSet4AT(self):
254        cladapter = queryAdapter(self.my_doc, ICanonicalLink)
255        newcl = self.mydoc_cl + '/new_mydoc_canonical'
256
257        cladapter.canonical_link = newcl
258        prop = self.my_doc.getProperty(PROPERTY_LINK, None)
259        self.assertTrue(prop == newcl,
260            "Canonical link adapter setter NOT SET new '%s' value to '%s' " \
261            "propery for the Document" % (newcl, PROPERTY_LINK))
262
263        self.assertTrue(cladapter.canonical_link == newcl,
264            "Canonical link adapter GET '%s' canonical_link, for Document, " \
265            "must be: '%s'" % (cladapter.canonical_link, newcl))
266
267    def testValidationWrong(self):
268        cladapter = queryAdapter(self.my_doc, ICanonicalLink)
269        for wrong in ['http://new\nline', 's p a c e', 'with\ttabs']:
270            try:
271                cladapter.canonical_link = wrong
272            except InvalidValue:
273                continue
274            else:
275                raise self.failureException, "InvalidValue not raised when " \
276                    "'%s' wrong value try to set" % wrong
277
278    def testValidationGood(self):
279        cladapter = queryAdapter(self.my_doc, ICanonicalLink)
280        for good in ['http://', './good', '../good', '/good', 'good']:
281            cladapter.canonical_link = good
282
283    def testDeleteProperty(self):
284        hasprop = self.portal.hasProperty
285        cladapter = queryAdapter(self.portal, ICanonicalLink)
286        cladapter.canonical_link = '/new_portal_canonical'
287        assert hasprop(PROPERTY_LINK)
288
289        del cladapter.canonical_link
290        self.assertFalse(hasprop(PROPERTY_LINK),
291            "Not deleted Canonical link customization property for the portal")
292
293    def test_DelCustomization(self):
294        cladapter = queryAdapter(self.portal, ICanonicalLink)
295        cladapter.canonical_link = '/new_portal_canonical'
296        assert cladapter.canonical_link == '/new_portal_canonical'
297
298        del cladapter.canonical_link
299        self.assertTrue(cladapter.canonical_link == self.purl(),
300            "After deleted Canonical link customization property not set to "
301            "default value for the portal")
302
303##
304## Dummy object for converter tests
305##
306
307
308class PortalURL:
309    def __call__(self):
310        return "http://nohost/plone"
311
312    def getRelativeContentPath(self, context):
313        return ("plone", context.getId())
314
315
316class BaseItem:
317    portal_url = PortalURL()
318
319    def __init__(self, id):
320        self.id = id
321
322    def getId(self):
323        return self.id
324
325    def absolute_url(self):
326        return self.portal_url() + '/' + self.getId()
327
328
329class GoodItem(BaseItem, PropertyManager, Traversable):
330    """Property provider."""
331
332
333class NotPropertyProviderItem(BaseItem, Traversable):
334    """Not property provider."""
335
336
337class NotAdaptableItem(BaseItem):
338    """Not adaptable object."""
339
340
341class TestConvertor(unittest.TestCase):
342
343    def setUp(self):
344        registerCanonicalPathInReg()
345        self.convertor = CanonicalConvertor("http://domain.com")
346
347    def test_convertIPathToLink(self):
348        item = GoodItem("item")
349        item._setProperty(PROPERTY_PATH, "/www/some/path")
350        self.convertor.convertIPathToLink(item)
351        # 1. check canonical link in result object
352        result = ICanonicalLink(item).canonical_link
353        expect = "http://domain.com/www/some/path"
354        self.assertEqual(result, expect, "Got %s canonical link, " \
355                         "expect: %s" % (result, expect))
356        # 2. canonical path propery mast be delete from the object
357        self.assertEqual(item.hasProperty(ICanonicalPath(item).prop), False,
358                         "canonical path property not deleted from the object")
359
360    def test_convertPPathToLink(self):
361        item = GoodItem("item")
362        item._setProperty("custom_property", "/www/some/path")
363        self.convertor.convertPPathToLink(item, prop="custom_property")
364        # 1. check canonical link in result object
365        result = ICanonicalLink(item).canonical_link
366        expect = "http://domain.com/www/some/path"
367        self.assertEqual(result, expect, "Got %s canonical link, " \
368                         "expect: %s" % (result, expect))
369        # 2. custom_property mast be deleted from the object
370        self.assertEqual(item.hasProperty("custom_property"), False,
371                         "custom_property not deleted from the object")
372
373    def test_convertBadItems(self):
374        bad = NotPropertyProviderItem("item")
375        self.convertor.convertIPathToLink(bad)
376        result = self.convertor.getLogs()
377        expect = "NotPropertyProviderItem instance "\
378                 "has no attribute 'hasProperty'"
379        self.assertEqual(expect in result, True, "Wrong log: %s" % result)
380
381        bad = NotAdaptableItem("item")
382        self.convertor.convertIPathToLink(bad)
383        result = self.convertor.getLogs()
384        expect = "zope.component.interfaces.ComponentLookupError"
385        self.assertEqual(expect in result, True, "Wrong log: %s" % result)
386
387    def test_loggingSuccess(self):
388        good = GoodItem("item")
389        self.convertor.convertIPathToLink(good)
390        result = self.convertor.getLogs()
391        expect = "SUCCESS"
392        self.assertEqual(expect in result, True, "Wrong log: %s" % result)
393
394    def test_loggingGet(self):
395        # log must collect new errors
396        # and return full log anytime
397        bad = NotPropertyProviderItem("item")
398        self.convertor.convertIPathToLink(bad)
399        logs = self.convertor.getLogs()
400        logs2 = self.convertor.getLogs()
401        assert logs != ""
402        self.assertEqual(logs == logs2, True,
403             "logs not equal: \"%s\" != \"%s\"" % (logs, logs2))
404        self.convertor.convertIPathToLink(bad)
405        logs3 = self.convertor.getLogs()
406        self.assertEqual(logs3 > logs2, True,
407             "Log was not updated - last: \"%s\", previous: \"%s\"" % (logs3,
408                                                                       logs2))
409
410    def test_loggingCleanup(self):
411        bad = NotPropertyProviderItem("item")
412        self.convertor.convertIPathToLink(bad)
413        assert self.convertor.getLogs() != ""
414        self.convertor.cleanupLogs()
415        logs = self.convertor.getLogs()
416        self.assertEqual(logs, "", "Log not cleand-up: \"%s\"" % logs)
417
418
419class TestAdaptersRegistration(unittest.TestCase):
420    """Test of default adapters registration."""
421
422    def setUp(self):
423        registerCanonicalPathInReg()
424        self.cant = "Can't get \"%s\" adapter for object, which implement: "
425        self.doget = "Get \"%s\" adapter for object, which implement: "
426
427    def test_PropertyManagerAndTraversable(self):
428        class ProperyAndTraverseProvider(BaseItem, PropertyManager,
429                                         Traversable):
430            """Property and Traversable provider."""
431        item = ProperyAndTraverseProvider("test")
432        self.assertNotEqual(queryAdapter(item, ICanonicalLink), None,
433            self.cant % ICanonicalLink.__name__ + "IPropertyManager and "\
434                                                  "ITraversable.")
435        self.assertNotEqual(queryAdapter(item, ICanonicalPath), None,
436            self.cant % ICanonicalPath.__name__ + "IPropertyManager and "\
437                                                  "ITraversable.")
438
439    def test_Traversable(self):
440        """Traversable enough for get adapter"""
441        class TraverseProvider(BaseItem, Traversable):
442            """Only Traversable provider."""
443        item = TraverseProvider("test")
444        self.assertNotEqual(queryAdapter(item, ICanonicalLink), None,
445           self.cant % ICanonicalLink.__name__ + "only ITraversable.")
446        self.assertNotEqual(queryAdapter(item, ICanonicalPath), None,
447           self.cant % ICanonicalPath.__name__ + "only ITraversable.")
448
449    def test_PropertyManager(self):
450        """Implementing only IPropertyManager - not enough, because of
451           the default value need ITraversable.
452        """
453        class PropertyManagerProvider(BaseItem, PropertyManager):
454            """Only PropertyManager provider."""
455        item = PropertyManagerProvider("test")
456        self.assertEqual(queryAdapter(item, ICanonicalLink), None,
457           self.doget % ICanonicalLink.__name__ + "only IPropertyManager.")
458        self.assertEqual(queryAdapter(item, ICanonicalPath), None,
459           self.doget % ICanonicalPath.__name__ + "only IPropertyManager.")
460
461    def test_NotProvider(self):
462        class NotProvider(BaseItem):
463            """Nor Traversable not PropertyManager provider."""
464        item = NotProvider("test")
465        self.assertEqual(queryAdapter(item, ICanonicalLink), None,
466           self.doget % ICanonicalLink.__name__ + "nor ITraversabe not "\
467                                                  "IPropertyManager.")
468        self.assertEqual(queryAdapter(item, ICanonicalPath), None,
469           self.doget % ICanonicalPath.__name__ + "nor ITraversabe not "\
470                                                  "IPropertyManager.")
471
472
473def test_suite():
474    return unittest.TestSuite([
475        unittest.makeSuite(TestIndexerRegistration),
476        unittest.makeSuite(TestDefaultCanonicalPathAdapter),
477        unittest.makeSuite(TestDefaultCanonicalLinkAdapter),
478        unittest.makeSuite(TestConvertor),
479        unittest.makeSuite(TestAdaptersRegistration),
480        ])
481
482if __name__ == '__main__':
483    unittest.main(defaultTest='test_suite')
Note: See TracBrowser for help on using the repository browser.