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

Last change on this file since 3599 was 3599, checked in by vmaksymiv, 11 years ago

PPP fixes

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