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

Last change on this file since 2371 was 2371, checked in by mylan, 14 years ago

Updated tests with new converter by property functionality, fixed bug in converter

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