#
# Tests for quintagroup.plonegooglesitemaps
#
import re, sys
from urllib import urlencode
from StringIO import StringIO
import unittest
from zope.testing import doctestunit
from zope.component import testing
from Testing import ZopeTestCase as ztc
from Products.Five import zcml
from Products.Five import fiveconfigure
from Products.PloneTestCase import PloneTestCase as ptc
from Products.PloneTestCase.layer import PloneSite
from Products.CMFPlone.utils import _createObjectByType
from XMLParser import parse, hasURL
import quintagroup.plonegooglesitemaps
from quintagroup.plonegooglesitemaps.config import ping_googlesitemap
quintagroup.plonegooglesitemaps.config.testing = 1
quintagroup.plonegooglesitemaps.config.UPDATE_CATALOG = True
class MixinTestCase:
""" Define layer and common afterSetup method with package installation.
Package installation on plone site setup impossible because of
five's registerPackage directive not recognized on module initializing.
"""
layer = PloneSite
def afterSetUp(self):
self.loginAsPortalOwner()
class TestCase(MixinTestCase, ptc.PloneTestCase):
""" For unit tests """
class FunctionalTestCase(MixinTestCase, ptc.FunctionalTestCase):
""" For functional tests """
# Initialize all needed zcml directives
fiveconfigure.debug_mode = True
from Products import Five, CMFCore, GenericSetup
zcml.load_config('meta.zcml', Five)
zcml.load_config('meta.zcml', CMFCore)
zcml.load_config('meta.zcml', GenericSetup)
zcml.load_config('permissions.zcml', Five)
# Force quintagroup.plonegooglesitemaps zcml initialization
zcml.load_config('configure.zcml', quintagroup.plonegooglesitemaps)
fiveconfigure.debug_mode = False
# Install quintagroup.plonegooglesitemaps package and Plone site
# with the default profile for the package
PRODUCT = 'quintagroup.plonegooglesitemaps'
ptc.installPackage(PRODUCT)
ptc.setupPloneSite( extension_profiles=("%s:default" % PRODUCT,))
class TestGoogleSitemapsInstallation(TestCase):
def testType(self):
pt = self.portal.portal_types
self.assert_('Sitemap' in pt.objectIds(),
'No "Sitemap" type after installation')
#Test views
views = pt.getTypeInfo('Sitemap').view_methods
self.assert_('sitemap.xml' in views,
'No "sitemap.xml" view for Sitemap type')
self.assert_('mobile-sitemap.xml' in views,
'No "mobile-sitemap.xml" view for Sitemap type')
self.assert_('news-sitemap.xml' in views,
'No "news-sitemap.xml" view for Sitemap type')
def testGSMProperties(self):
pp = self.portal.portal_properties
# Test types_not_searched
self.assert_("Sitemap" in pp['site_properties'].getProperty('types_not_searched'),
'No "Sitemap" added to types not searched on installation')
# Test metaTypesNotToList
self.assert_("Sitemap" in pp['navtree_properties'].getProperty('metaTypesNotToList'),
'No "Sitemap" added to types not to list on installation')
# Test 'googlesitemap_properties'
self.assert_('googlesitemap_properties' in pp.objectIds(),
'No "googlesitemap_properties" after installation')
qsmprops = pp['googlesitemap_properties']
self.assert_(qsmprops.hasProperty('verification_filenames'),
'No "verification_filenames" property added on installation')
def testSkins(self):
ps = self.portal.portal_skins
self.assert_('plonegooglesitemaps' in ps.objectIds(),
'No "plonegooglesitemaps" skin layer in portal_skins')
self.assert_('plonegooglesitemaps' in ps.getSkinPath(ps.getDefaultSkin()),
'No "plonegooglesitemaps" skin layer in default skin')
def testConfiglet(self):
cp = self.portal.portal_controlpanel
self.assert_([1 for ai in cp.listActionInfos() if ai['id']=='GoogleSitemaps'],
'No "GoogleSitemaps" configlet added to plone control panel')
class TestSitemapType(FunctionalTestCase):
def afterSetUp(self):
super(TestSitemapType, self).afterSetUp()
self.auth = 'admin:admin'
self.contentSM = _createObjectByType('Sitemap', self.portal, id='google-sitemaps')
self.portal.portal_membership.addMember('admin', 'admin', ('Manager',), [])
def testFields(self):
field_ids = map(lambda x:x.getName(), self.contentSM.Schema().fields())
# test old Sitemap settings fields
self.assert_('id' in field_ids)
self.assert_('portalTypes' in field_ids)
self.assert_('states' in field_ids)
self.assert_('blackout_list' in field_ids)
self.assert_('urls' in field_ids)
self.assert_('pingTransitions' in field_ids)
# test new sitemap type field
self.assert_('sitemapType' in field_ids)
def testSitemapTypes(self):
sitemap_types = self.contentSM.getField('sitemapType').Vocabulary().keys()
self.assert_('content' in sitemap_types)
self.assert_('mobile' in sitemap_types)
self.assert_('news' in sitemap_types)
def testAutoSetLayout(self):
response = self.publish('/%s/createObject?type_name=Sitemap' % \
self.portal.absolute_url(1), basic=self.auth)
location = response.getHeader('location')
newurl = location[location.find('/'+self.portal.absolute_url(1)):]
msm_id = 'mobile_sitemap'
form = {'id': msm_id,
'sitemapType':'mobile',
'portalTypes':['Document',],
'states':['published'],
'form_submit':'Save',
'form.submitted':1,
}
post_data = StringIO(urlencode(form))
response = self.publish(newurl, request_method='POST', stdin=post_data, basic=self.auth)
msitemap = getattr(self.portal, msm_id)
self.assertEqual(msitemap.defaultView(), 'mobile-sitemap.xml')
def txestPingSetting(self):
pwf = self.portal.portal_workflow['plone_workflow']
self.assertEqual(self.contentSM.getPingTransitions(), ())
self.contentSM.setPingTransitions(('plone_workflow#publish',))
self.assertEqual(self.contentSM.getPingTransitions(), ('plone_workflow#publish',))
self.assert_(ping_googlesitemap in pwf.scripts.keys(),"Not add wf script")
class TestGoogleSitemaps(FunctionalTestCase):
def afterSetUp(self):
super(TestGoogleSitemaps, self).afterSetUp()
self.workflow = self.portal.portal_workflow
self.auth = 'admin:admin'
_createObjectByType('Sitemap', self.portal, id='google-sitemaps')
self.sitemapUrl = '/'+self.portal.absolute_url(1) + '/google-sitemaps'
self.portal.portal_membership.addMember('admin', 'admin', ('Manager',), [])
self.gsm_props = self.portal.portal_properties['googlesitemap_properties']
# Add testing document to portal
my_doc = self.portal.invokeFactory('Document', id='my_doc')
self.my_doc = self.portal['my_doc']
self.my_doc.edit(text_format='plain', text='hello world')
def testSitemap(self):
sitemap = self.publish(self.sitemapUrl, self.auth).getBody()
parsed_sitemap = parse(sitemap)
start = parsed_sitemap['start']
data = parsed_sitemap['data']
self.assert_('urlset' in start.keys())
self.assertFalse(self.my_doc.absolute_url(0) in data,
'Wrong content present in the sitemap')
self.workflow.doActionFor(self.my_doc, 'publish')
sitemap = self.publish(self.sitemapUrl, self.auth).getBody()
parsed_sitemap = parse(sitemap)
start = parsed_sitemap['start']
data = parsed_sitemap['data']
self.assertEqual(len(start.keys()), 4)
self.assert_('urlset' in start.keys())
self.assert_('url' in start.keys())
self.assert_('loc' in start.keys())
self.assert_('lastmod' in start.keys())
self.assertTrue(self.my_doc.absolute_url(0) in data, 'Incorect url')
def testVerificationFileCreation(self):
self.portal.gsm_create_verify_file('verif_file')
vf_created = hasattr(self.portal, 'verif_file')
self.assert_(vf_created, 'Verification file not created')
def testVerificationForm(self):
verifyConfigUrl = '/'+self.portal.absolute_url(1) + '/prefs_gsm_verification'
verif_config = self.publish(verifyConfigUrl, self.auth).getBody()
rexp_input_acitve = re.compile(']*)>', re.I|re.S)
rexp_button_acitve = re.compile(']*)>', re.I|re.S)
rexp_delete_button = re.compile(']*>', re.I|re.S)
input_acitve = rexp_input_acitve.search(verif_config)
button_acitve = rexp_button_acitve.search(verif_config)
delete_button = rexp_delete_button.match(verif_config)
self.assert_(input_acitve and not 'disabled' in input_acitve.groups(1))
self.assert_(button_acitve and not 'disabled' in button_acitve.groups(1))
self.assert_(not delete_button)
self.portal.gsm_create_verify_file('verif_file')
input_acitve = rexp_input_acitve.search(verif_config)
button_acitve = rexp_button_acitve.search(verif_config)
delete_button = rexp_delete_button.match(verif_config)
verif_config = self.publish(verifyConfigUrl, self.auth).getBody()
self.assert_(input_acitve and not 'disabled' in input_acitve.groups(1))
self.assert_(not delete_button)
def testMultiplyVerificationFiles(self):
verifyConfigUrl = '/'+self.portal.absolute_url(1) + '/prefs_gsm_verification'
form = {'verify_filename':'verif_file_1',
'form.button.CreateFile': 'Create verification file',
'form.submitted':1}
post_data = StringIO(urlencode(form))
response = self.publish(verifyConfigUrl, request_method='POST',
stdin=post_data, basic=self.auth)
self.assertEqual(response.getStatus(), 200)
self.assert_('verif_file_1' in self.gsm_props.getProperty('verification_filenames',[]),
self.gsm_props.getProperty('verification_filenames',[]))
form = {'verify_filename':'verif_file_2',
'form.button.CreateFile': 'Create verification file',
'form.submitted':1}
post_data = StringIO(urlencode(form))
response = self.publish(verifyConfigUrl, request_method='POST',
stdin=post_data, basic=self.auth)
self.assertEqual(response.getStatus(), 200)
self.assert_([1 for vf in ['verif_file','verif_file_2'] \
if vf in self.gsm_props.getProperty('verification_filenames',[])],
self.gsm_props.getProperty('verification_filenames',[]))
class TestSettings(FunctionalTestCase):
def afterSetUp(self):
super(TestSettings, self).afterSetUp()
self.workflow = self.portal.portal_workflow
self.gsm_props = self.portal.portal_properties['googlesitemap_properties']
self.auth = 'admin:admin'
self.contentSM = _createObjectByType('Sitemap', self.portal, id='google-sitemaps')
self.sitemapUrl = '/'+self.portal.absolute_url(1) + '/google-sitemaps'
self.portal.portal_membership.addMember('admin', 'admin', ('Manager',), [])
# Add testing document to portal
my_doc = self.portal.invokeFactory('Document', id='my_doc')
self.my_doc = self.portal['my_doc']
self.my_doc.edit(text_format='plain', text='hello world')
self.my_doc_url = self.my_doc.absolute_url()
def testMetaTypeToDig(self):
self.workflow.doActionFor(self.my_doc, 'publish')
sitemap = self.publish(self.sitemapUrl, self.auth).getBody()
self.assert_(hasURL(sitemap, self.my_doc_url))
self.contentSM.setPortalTypes([])
sitemap = self.publish(self.sitemapUrl, self.auth).getBody()
self.assert_(not hasURL(sitemap, self.my_doc_url))
self.contentSM.setPortalTypes(['Document'])
sitemap = self.publish(self.sitemapUrl, self.auth).getBody()
self.assert_(hasURL(sitemap, self.my_doc_url))
def testStates(self):
self.workflow.doActionFor(self.my_doc, 'publish')
self.contentSM.setStates(['visible'])
sitemap = self.publish(self.sitemapUrl, self.auth).getBody()
self.assert_(not hasURL(sitemap, self.my_doc_url))
self.contentSM.setStates(['published'])
sitemap = self.publish(self.sitemapUrl, self.auth).getBody()
self.assert_(hasURL(sitemap, self.my_doc_url))
def test_blackout_entries(self):
self.workflow.doActionFor(self.my_doc, 'publish')
self.contentSM.setBlackout_list((self.my_doc.getId(),))
sitemap = self.publish(self.sitemapUrl, self.auth).getBody()
self.assert_(not hasURL(sitemap, self.my_doc_url))
self.contentSM.setBlackout_list([])
sitemap = self.publish(self.sitemapUrl, self.auth).getBody()
self.assert_(hasURL(sitemap, self.my_doc_url))
def test_regexp(self):
self.workflow.doActionFor(self.my_doc, 'publish')
sitemap = self.publish(self.sitemapUrl, self.auth).getBody()
self.assert_(not hasURL(sitemap, self.portal.absolute_url()))
regexp = "s/\/%s//"%self.my_doc.getId()
self.contentSM.setReg_exp([regexp])
sitemap = self.publish(self.sitemapUrl, self.auth).getBody()
self.assert_(hasURL(sitemap, self.portal.absolute_url()))
def test_add_urls(self):
self.contentSM.setUrls(['http://w1', 'w2', '/w3'])
w1_url = 'http://w1'
w2_url = self.portal.absolute_url() + '/w2'
w3_url = self.portal.getPhysicalRoot().absolute_url() + '/w3'
sitemap = self.publish(self.sitemapUrl, self.auth).getBody()
self.assert_(hasURL(sitemap, w1_url))
self.assert_(hasURL(sitemap, w2_url))
self.assert_(hasURL(sitemap, w3_url))
class TestPinging(FunctionalTestCase):
def afterSetUp(self):
super(TestPinging, self).afterSetUp()
self.workflow = self.portal.portal_workflow
self.workflow.setChainForPortalTypes(pt_names=('News Item','Document'),
chain="simple_publication_workflow")
self.gsm_props = self.portal.portal_properties['googlesitemap_properties']
self.auth = 'admin:admin'
self.portal.portal_membership.addMember('admin', 'admin', ('Manager',), [])
# Add sitemaps
self.contentSM = _createObjectByType('Sitemap', self.portal, id='google-sitemaps')
self.contentSM.setPingTransitions(('simple_publication_workflow#publish',))
self.newsSM = _createObjectByType('Sitemap', self.portal, id='news-sitemaps')
self.newsSM.setPortalTypes(('News Item','Document'))
self.newsSM.setPingTransitions(('simple_publication_workflow#publish',))
self.sitemapUrl = '/'+self.portal.absolute_url(1) + '/google-sitemaps'
# Add testing document to portal
my_doc = self.portal.invokeFactory('Document', id='my_doc')
self.my_doc = self.portal['my_doc']
my_news = self.portal.invokeFactory('News Item', id='my_news')
self.my_news = self.portal['my_news']
def testAutomatePinging(self):
# 1. Check for pinging both sitemaps
back_out, myout = sys.stdout, StringIO()
sys.stdout = myout
try:
self.workflow.doActionFor(self.my_doc, 'publish')
myout.seek(0)
data = myout.read()
finally:
sys.stdout = back_out
self.assert_('Pinged %s sitemap to Google' % self.contentSM.absolute_url() in data,
"Not pinged %s: '%s'" % (self.contentSM.id, data))
self.assert_('Pinged %s sitemap to Google' % self.newsSM.absolute_url() in data,
"Not pinged %s: '%s'" % (self.newsSM.id, data))
# 2. Check for pinging only news-sitemap sitemaps
back_out, myout = sys.stdout, StringIO()
sys.stdout = myout
try:
self.workflow.doActionFor(self.my_news, 'publish')
myout.seek(0)
data = myout.read()
finally:
sys.stdout = back_out
self.assert_('Pinged %s sitemap to Google' % self.newsSM.absolute_url() in data,
"Not pinged %s: '%s'" % (self.newsSM.id, data))
self.assert_(not 'Pinged %s sitemap to Google' % self.contentSM.absolute_url() in data,
"Pinged %s on news: '%s'" % (self.contentSM.id, data))
def testPingingWithSetupForm(self):
# Ping news and content sitemaps
formUrl = '/'+self.portal.absolute_url(1) + '/prefs_gsm_settings'
qs = 'smselected:list=%s&smselected:list=%s&form.button.Ping=1&form.submitted=1' % \
(self.contentSM.id, self.newsSM.id)
back_out, myout = sys.stdout, StringIO()
sys.stdout = myout
try:
response = self.publish("%s?%s" % (formUrl, qs), basic=self.auth)
myout.seek(0)
data = myout.read()
finally:
sys.stdout = back_out
self.assert_('Pinged %s sitemap to Google' % self.contentSM.absolute_url() in data,
"Not pinged %s: '%s'" % (self.contentSM.id, data))
self.assert_('Pinged %s sitemap to Google' % self.newsSM.absolute_url() in data,
"Not pinged %s: '%s'" % (self.newsSM.id, data))
def test_suite():
from unittest import TestSuite, makeSuite
suite = TestSuite()
suite.addTest(makeSuite(TestGoogleSitemapsInstallation))
suite.addTest(makeSuite(TestSitemapType))
suite.addTest(makeSuite(TestGoogleSitemaps))
suite.addTest(makeSuite(TestSettings))
suite.addTest(makeSuite(TestPinging))
return suite
if __name__ == '__main__':
unittest.main(defaultTest='test_suite')
# framework()