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

Last change on this file since 3146 was 3146, checked in by vmaksymiv, 9 years ago

pyflakes fixes

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