source: products/quintagroup.plonegooglesitemaps/trunk/quintagroup/plonegooglesitemaps/tests/testqPloneGoogleSitemaps.py @ 1619

Last change on this file since 1619 was 1619, checked in by mylan, 12 years ago

Prepare package tests infrastructure. Fixed problem with five:registerPackage directive deferred initialization

  • Property svn:eol-style set to native
File size: 17.4 KB
Line 
1#
2# Tests for quintagroup.plonegooglesitemaps
3#
4
5import re, sys
6from urllib import urlencode
7from StringIO import StringIO
8import unittest
9
10from zope.testing import doctestunit
11from zope.component import testing
12from Testing import ZopeTestCase as ztc
13
14from Products.Five import zcml
15from Products.Five import fiveconfigure
16
17from Products.PloneTestCase import PloneTestCase as ptc
18from Products.PloneTestCase.layer import PloneSite
19from Products.CMFPlone.utils import _createObjectByType
20
21from XMLParser import parse, hasURL
22
23import quintagroup.plonegooglesitemaps
24from quintagroup.plonegooglesitemaps.config import ping_googlesitemap
25
26quintagroup.plonegooglesitemaps.config.testing = 1
27
28class MixinTestCase:
29    """ Define layer and common afterSetup method with package installation.
30        Package installation on plone site setup impossible because of
31        five's registerPackage directive not recognized on module initializing.
32    """
33    layer = PloneSite
34
35    def afterSetUp(self):
36        self.loginAsPortalOwner()
37
38
39class TestCase(MixinTestCase, ptc.PloneTestCase):
40    """ For unit tests """
41
42class FunctionalTestCase(MixinTestCase, ptc.FunctionalTestCase):
43    """ For functional tests """
44
45# Initialize all needed zcml directives
46fiveconfigure.debug_mode = True
47from Products import Five, CMFCore, GenericSetup
48zcml.load_config('meta.zcml', Five)
49zcml.load_config('meta.zcml', CMFCore)
50zcml.load_config('meta.zcml', GenericSetup)
51zcml.load_config('permissions.zcml', Five)
52
53# Force quintagroup.plonegooglesitemaps zcml initialization
54zcml.load_config('configure.zcml', quintagroup.plonegooglesitemaps)
55fiveconfigure.debug_mode = False
56
57# Install quintagroup.plonegooglesitemaps package and Plone site
58# with the default profile for the package
59PRODUCT = 'quintagroup.plonegooglesitemaps'
60ptc.installPackage(PRODUCT)
61ptc.setupPloneSite( extension_profiles=("%s:default" % PRODUCT,))
62
63
64class TestGoogleSitemapsInstallation(TestCase):
65
66    def testType(self):
67        pt = self.portal.portal_types
68        self.assert_('Sitemap' in pt.objectIds(), 
69            'No "Sitemap" type after installation')
70        #Test views
71        views = pt.getTypeInfo('Sitemap').view_methods
72        self.assert_('sitemap.xml' in views, 
73            'No "sitemap.xml" view for Sitemap type')
74        self.assert_('mobile-sitemap.xml' in views, 
75            'No "mobile-sitemap.xml" view for Sitemap type')
76        self.assert_('news-sitemap.xml' in views, 
77            'No "news-sitemap.xml" view for Sitemap type')
78
79    def testGSMProperties(self):
80        pp = self.portal.portal_properties
81
82        # Test types_not_searched
83        self.assert_("Sitemap" in pp['site_properties'].getProperty('types_not_searched'), 
84            'No "Sitemap" added to types not searched on installation')
85        # Test metaTypesNotToList
86        self.assert_("Sitemap" in pp['navtree_properties'].getProperty('metaTypesNotToList'), 
87            'No "Sitemap" added to types not to list on installation')
88
89        # Test 'googlesitemap_properties'
90        self.assert_('googlesitemap_properties' in pp.objectIds(), 
91            'No "googlesitemap_properties" after installation')
92        qsmprops = pp['googlesitemap_properties']
93        self.assert_(qsmprops.hasProperty('verification_filenames'),
94            'No "verification_filenames" property added on installation')
95
96    def testSkins(self):
97        ps = self.portal.portal_skins
98        self.assert_('plonegooglesitemaps' in ps.objectIds(), 
99            'No "plonegooglesitemaps" skin layer in portal_skins')
100        self.assert_('plonegooglesitemaps' in ps.getSkinPath(ps.getDefaultSkin()),
101            'No "plonegooglesitemaps" skin layer in default skin')
102
103    def testConfiglet(self):
104        cp = self.portal.portal_controlpanel
105        self.assert_([1 for ai in cp.listActionInfos() if ai['id']=='GoogleSitemaps'], 
106            'No "GoogleSitemaps" configlet added to plone control panel')
107
108    def testCatalog(self):
109        catalog = self.portal.portal_catalog
110        self.assert_('hasMobileContent' in catalog.indexes(),
111            'No "hasMobileContent" index in portal_catalog')
112
113
114class TestSitemapType(FunctionalTestCase):
115
116    def afterSetUp(self):
117        super(TestSitemapType, self).afterSetUp()
118        self.auth = 'admin:admin'
119        self.contentSM = _createObjectByType('Sitemap', self.portal, id='google-sitemaps')
120        self.portal.portal_membership.addMember('admin', 'admin', ('Manager',), [])
121
122    def testFields(self):
123        field_ids = map(lambda x:x.getName(), self.contentSM.Schema().fields())
124        # test old Sitemap settings fields
125        self.assert_('id' in field_ids)
126        self.assert_('portalTypes' in field_ids)
127        self.assert_('states' in field_ids)
128        self.assert_('blackout_list' in field_ids)
129        self.assert_('urls' in field_ids)
130        self.assert_('pingTransitions' in field_ids)
131        # test new sitemap type field
132        self.assert_('sitemapType' in field_ids)
133
134    def testSitemapTypes(self):
135        sitemap_types = self.contentSM.getField('sitemapType').Vocabulary().keys()
136        self.assert_('content' in sitemap_types)
137        self.assert_('mobile' in sitemap_types)
138        self.assert_('news' in sitemap_types)
139
140    def testAutoSetLayout(self):
141        response = self.publish('/%s/createObject?type_name=Sitemap' % \
142                                self.portal.absolute_url(1), basic=self.auth)
143        location = response.getHeader('location')
144        newurl = location[location.find('/'+self.portal.absolute_url(1)):]
145
146        msm_id = 'mobile_sitemap'
147        form = {'id': msm_id,
148                'sitemapType':'mobile',
149                'portalTypes':['Document',],
150                'states':['published'],
151                'form_submit':'Save',
152                'form.submitted':1,
153                }
154        post_data = StringIO(urlencode(form))
155        response = self.publish(newurl, request_method='POST', stdin=post_data, basic=self.auth)
156        msitemap = getattr(self.portal, msm_id)
157
158        self.assertEqual(msitemap.defaultView(), 'mobile-sitemap.xml')
159
160    def txestPingSetting(self):
161        pwf = self.portal.portal_workflow['plone_workflow']
162        self.assertEqual(self.contentSM.getPingTransitions(), ())
163
164        self.contentSM.setPingTransitions(('plone_workflow#publish',))
165        self.assertEqual(self.contentSM.getPingTransitions(), ('plone_workflow#publish',))
166        self.assert_(ping_googlesitemap in pwf.scripts.keys(),"Not add wf script")
167
168
169class TestGoogleSitemaps(FunctionalTestCase):
170
171    def afterSetUp(self):
172        super(TestGoogleSitemaps, self).afterSetUp()
173
174        self.workflow = self.portal.portal_workflow
175        self.auth = 'admin:admin'
176        _createObjectByType('Sitemap', self.portal, id='google-sitemaps')
177        self.sitemapUrl = '/'+self.portal.absolute_url(1) + '/google-sitemaps'
178        self.portal.portal_membership.addMember('admin', 'admin', ('Manager',), [])
179        self.gsm_props = self.portal.portal_properties['googlesitemap_properties']
180
181        # Add testing document to portal
182        my_doc = self.portal.invokeFactory('Document', id='my_doc')
183        self.my_doc = self.portal['my_doc']
184        self.my_doc.edit(text_format='plain', text='hello world')
185
186
187
188    def testSitemap(self):
189        sitemap = self.publish(self.sitemapUrl, self.auth).getBody()
190        parsed_sitemap = parse(sitemap)
191        start = parsed_sitemap['start']
192        data = parsed_sitemap['data']
193        self.assertEqual(len(start.keys()), 1)
194        self.assert_('urlset' in start.keys())
195
196        self.workflow.doActionFor(self.my_doc, 'publish')
197
198        sitemap = self.publish(self.sitemapUrl, self.auth).getBody()
199        parsed_sitemap = parse(sitemap)
200        start = parsed_sitemap['start']
201        data = parsed_sitemap['data']
202        self.assertEqual(len(start.keys()), 4)
203        self.assert_('urlset' in start.keys())
204        self.assert_('url' in start.keys())
205        self.assert_('loc' in start.keys())
206        self.assert_('lastmod' in start.keys())
207
208        self.assert_(data[0] == self.my_doc.absolute_url(0), 'Incorect url')
209
210    def testVerificationFileCreation(self):
211        self.portal.gsm_create_verify_file('verif_file')
212
213        vf_created = hasattr(self.portal, 'verif_file')
214        self.assert_(vf_created, 'Verification file not created')
215
216    def testVerificationForm(self):
217        verifyConfigUrl = '/'+self.portal.absolute_url(1) + '/prefs_gsm_verification'
218        verif_config = self.publish(verifyConfigUrl, self.auth).getBody()
219        rexp_input_acitve = re.compile('<input\s+name="verify_filename"\s+([^>]*)>', re.I|re.S)
220        rexp_button_acitve = re.compile('<input\s+name="form.button.CreateFile"\s+([^>]*)>', re.I|re.S)
221        rexp_delete_button = re.compile('<input\s+name="form.button.DeleteFile"\s+[^>]*>', re.I|re.S)
222
223        input_acitve = rexp_input_acitve.search(verif_config)
224        button_acitve = rexp_button_acitve.search(verif_config)
225        delete_button = rexp_delete_button.match(verif_config)
226
227        self.assert_(input_acitve and not 'disabled' in input_acitve.groups(1))
228        self.assert_(button_acitve and not 'disabled' in button_acitve.groups(1))
229        self.assert_(not delete_button)
230
231        self.portal.gsm_create_verify_file('verif_file')
232
233        input_acitve = rexp_input_acitve.search(verif_config)
234        button_acitve = rexp_button_acitve.search(verif_config)
235        delete_button = rexp_delete_button.match(verif_config)
236
237        verif_config = self.publish(verifyConfigUrl, self.auth).getBody()
238        self.assert_(input_acitve and not 'disabled' in input_acitve.groups(1))
239        self.assert_(not delete_button)
240
241    def testMultiplyVerificationFiles(self):
242        verifyConfigUrl = '/'+self.portal.absolute_url(1) + '/prefs_gsm_verification'
243
244        form = {'verify_filename':'verif_file_1',
245                'form.button.CreateFile': 'Create verification file',
246                'form.submitted':1}
247        post_data = StringIO(urlencode(form))
248        response = self.publish(verifyConfigUrl, request_method='POST',
249                                stdin=post_data, basic=self.auth)
250        self.assertEqual(response.getStatus(), 200)
251        self.assert_('verif_file_1' in self.gsm_props.getProperty('verification_filenames',[]),
252                     self.gsm_props.getProperty('verification_filenames',[]))
253
254        form = {'verify_filename':'verif_file_2',
255                'form.button.CreateFile': 'Create verification file',
256                'form.submitted':1}
257        post_data = StringIO(urlencode(form))
258        response = self.publish(verifyConfigUrl, request_method='POST',
259                                stdin=post_data, basic=self.auth)
260        self.assertEqual(response.getStatus(), 200)
261        self.assert_([1 for vf in ['verif_file','verif_file_2'] \
262                      if vf in self.gsm_props.getProperty('verification_filenames',[])],
263                     self.gsm_props.getProperty('verification_filenames',[]))
264
265
266class TestSettings(FunctionalTestCase):
267
268    def afterSetUp(self):
269        super(TestSettings, self).afterSetUp()
270
271        self.workflow = self.portal.portal_workflow
272        self.gsm_props = self.portal.portal_properties['googlesitemap_properties']
273        self.auth = 'admin:admin'
274        self.contentSM = _createObjectByType('Sitemap', self.portal, id='google-sitemaps')
275
276        self.sitemapUrl = '/'+self.portal.absolute_url(1) + '/google-sitemaps'
277
278        self.portal.portal_membership.addMember('admin', 'admin', ('Manager',), [])
279
280        # Add testing document to portal
281        my_doc = self.portal.invokeFactory('Document', id='my_doc')
282        self.my_doc = self.portal['my_doc']
283        self.my_doc.edit(text_format='plain', text='hello world')
284        self.my_doc_url = self.my_doc.absolute_url()
285
286    def testMetaTypeToDig(self):
287        self.workflow.doActionFor(self.my_doc, 'publish')
288        sitemap = self.publish(self.sitemapUrl, self.auth).getBody()
289        self.assert_(hasURL(sitemap, self.my_doc_url))
290
291        self.contentSM.setPortalTypes([])
292
293        sitemap = self.publish(self.sitemapUrl, self.auth).getBody()
294        self.assert_(not hasURL(sitemap, self.my_doc_url))
295
296        self.contentSM.setPortalTypes(['Document'])
297
298        sitemap = self.publish(self.sitemapUrl, self.auth).getBody()
299        self.assert_(hasURL(sitemap, self.my_doc_url))
300
301    def testStates(self):
302        self.workflow.doActionFor(self.my_doc, 'publish')
303        self.contentSM.setStates(['visible'])
304
305        sitemap = self.publish(self.sitemapUrl, self.auth).getBody()
306        self.assert_(not hasURL(sitemap, self.my_doc_url))
307
308        self.contentSM.setStates(['published'])
309
310        sitemap = self.publish(self.sitemapUrl, self.auth).getBody()
311        self.assert_(hasURL(sitemap, self.my_doc_url))
312
313    def test_blackout_entries(self):
314        self.workflow.doActionFor(self.my_doc, 'publish')
315        self.contentSM.setBlackout_list((self.my_doc.getId(),))
316
317        sitemap = self.publish(self.sitemapUrl, self.auth).getBody()
318        self.assert_(not hasURL(sitemap, self.my_doc_url))
319
320        self.contentSM.setBlackout_list([])
321        sitemap = self.publish(self.sitemapUrl, self.auth).getBody()
322        self.assert_(hasURL(sitemap, self.my_doc_url))
323
324    def test_regexp(self):
325        self.workflow.doActionFor(self.my_doc, 'publish')
326        sitemap = self.publish(self.sitemapUrl, self.auth).getBody()
327        self.assert_(not hasURL(sitemap, self.portal.absolute_url()))
328
329        regexp = "s/\/%s//"%self.my_doc.getId()
330        self.contentSM.setReg_exp([regexp])
331
332        sitemap = self.publish(self.sitemapUrl, self.auth).getBody()
333        self.assert_(hasURL(sitemap, self.portal.absolute_url()))
334
335    def test_add_urls(self):
336        self.contentSM.setUrls(['http://w1', 'w2', '/w3'])
337        w1_url = 'http://w1'
338        w2_url = self.portal.absolute_url() + '/w2'
339        w3_url = self.portal.getPhysicalRoot().absolute_url() + '/w3'
340        sitemap = self.publish(self.sitemapUrl, self.auth).getBody()
341
342        self.assert_(hasURL(sitemap, w1_url))
343        self.assert_(hasURL(sitemap, w2_url))
344        self.assert_(hasURL(sitemap, w3_url))
345
346
347class TestPinging(FunctionalTestCase):
348
349    def afterSetUp(self):
350        super(TestPinging, self).afterSetUp()
351
352        self.workflow = self.portal.portal_workflow
353        self.gsm_props = self.portal.portal_properties['googlesitemap_properties']
354        self.auth = 'admin:admin'
355        self.portal.portal_membership.addMember('admin', 'admin', ('Manager',), [])
356        # Add sitemaps
357        self.contentSM = _createObjectByType('Sitemap', self.portal, id='google-sitemaps')
358        self.contentSM.setPingTransitions(('plone_workflow#publish',))
359        self.newsSM = _createObjectByType('Sitemap', self.portal, id='news-sitemaps')
360        self.newsSM.setPortalTypes(('News Item','Document'))
361        self.newsSM.setPingTransitions(('plone_workflow#publish',))
362        self.sitemapUrl = '/'+self.portal.absolute_url(1) + '/google-sitemaps'
363        # Add testing document to portal
364        my_doc = self.portal.invokeFactory('Document', id='my_doc')
365        self.my_doc = self.portal['my_doc']
366        my_news = self.portal.invokeFactory('News Item', id='my_news')
367        self.my_news = self.portal['my_news']
368
369    def testAutomatePinging(self):
370        # 1. Check for pinging both sitemaps
371        back_out, myout = sys.stdout, StringIO()
372        sys.stdout = myout
373        self.workflow.doActionFor(self.my_doc, 'publish')
374        myout.seek(0)
375        data = myout.read()
376        sys.stdout = back_out
377        self.assert_('Pinged %s sitemap to google' % self.contentSM.absolute_url() in data,
378                     "Not pinged %s: '%s'" % (self.contentSM.id, data))
379        self.assert_('Pinged %s sitemap to google' % self.newsSM.absolute_url() in data,
380                     "Not pinged %s: '%s'" % (self.newsSM.id, data))
381
382        # 2. Check for pinging only news-sitemap sitemaps
383        back_out, myout = sys.stdout, StringIO()
384        sys.stdout = myout
385        self.workflow.doActionFor(self.my_news, 'publish')
386        myout.seek(0)
387        data = myout.read()
388        sys.stdout = back_out
389
390        self.assert_('Pinged %s sitemap to google' % self.newsSM.absolute_url() in data,
391                     "Not pinged %s: '%s'" % (self.newsSM.id, data))
392        self.assert_(not 'Pinged %s sitemap to google' % self.contentSM.absolute_url() in data,
393                     "Pinged %s on news: '%s'" % (self.contentSM.id, data))
394
395    def testPingingWithSetupForm(self):
396        # Ping news and content sitemaps
397        formUrl = '/'+self.portal.absolute_url(1) + '/prefs_gsm_settings'
398        qs = 'smselected:list=%s&smselected:list=%s&form.button.Ping=1&form.submitted=1' % \
399             (self.contentSM.id, self.newsSM.id)
400
401        back_out, myout = sys.stdout, StringIO()
402        sys.stdout = myout
403        response = self.publish("%s?%s" % (formUrl, qs), basic=self.auth)
404        myout.seek(0)
405        data = myout.read()
406        sys.stdout = back_out
407
408        self.assert_('Pinged %s sitemap to google' % self.contentSM.absolute_url() in data,
409                     "Not pinged %s: '%s'" % (self.contentSM.id, data))
410        self.assert_('Pinged %s sitemap to google' % self.newsSM.absolute_url() in data,
411                     "Not pinged %s: '%s'" % (self.newsSM.id, data))
412
413
414
415def test_suite():
416    from unittest import TestSuite, makeSuite
417    suite = TestSuite()
418    suite.addTest(makeSuite(TestGoogleSitemapsInstallation))
419    suite.addTest(makeSuite(TestSitemapType))
420    suite.addTest(makeSuite(TestGoogleSitemaps))
421    suite.addTest(makeSuite(TestSettings))
422    suite.addTest(makeSuite(TestPinging))
423    return suite
424
425if __name__ == '__main__':
426    unittest.main(defaultTest='test_suite')
427#    framework()
Note: See TracBrowser for help on using the repository browser.