import urllib
from cStringIO import StringIO
from OFS.interfaces import ITraversable
from zope.component import providedBy
from zope.component import getGlobalSiteManager
from zope.component import queryAdapter, getMultiAdapter
from zope.interface import directlyProvides, alsoProvides
from zope.viewlet.interfaces import IViewlet, IViewletManager
from zope.publisher.browser import TestRequest
from quintagroup.seoptimizer.browser.interfaces import IPloneSEOLayer
from quintagroup.seoptimizer.browser.views import PROP_CUSTOM_PREFIX
from quintagroup.seoptimizer.browser.seo_configlet import ISEOConfigletSchema
from quintagroup.canonicalpath.interfaces import ICanonicalLink
from quintagroup.canonicalpath.adapters import DefaultCanonicalLinkAdapter
from base import *
class TestBugs(FunctionalTestCase):
def afterSetUp(self):
self.basic_auth = ':'.join((portal_owner,default_password))
self.loginAsPortalOwner()
# prepare test document
my_doc = self.portal.invokeFactory('Document', id='my_doc')
self.my_doc = self.portal['my_doc']
self.mydoc_path = "/%s" % self.my_doc.absolute_url(1)
def test_modification_date(self):
""" Modification date changing on SEO properties edit """
form_data = {'seo_title': 'New Title',
'seo_title_override:int': 1,
'form.submitted:int': 1}
md_before = self.my_doc.modification_date
self.publish(path=self.mydoc_path+'/@@seo-context-properties',
basic=self.basic_auth, request_method='POST',
stdin=StringIO(urllib.urlencode(form_data)))
md_after = self.my_doc.modification_date
self.assertNotEqual(md_before, md_after)
def test_bug_20_at_plone_org(self):
portal = self.portal
fp = portal['front-page']
request = portal.REQUEST
view = portal.restrictedTraverse('@@plone')
manager = getMultiAdapter((fp, request, view), IViewletManager,
name=u'plone.htmlhead')
viewlet = getMultiAdapter((fp, request, view, manager), IViewlet,
name=u'plone.htmlhead.title')
viewlet.update()
old_title = viewlet.render()
# add IPloneSEOLayer
directlyProvides(request, IPloneSEOLayer)
viewlet = getMultiAdapter((fp, request, view, manager), IViewlet,
name=u'plone.htmlhead.title')
viewlet.update()
new_title = viewlet.render()
self.assertEqual(old_title, new_title)
def test_bug_22_at_plone_org(self):
"""If ICanonicalLink adapter is not found for the context object
- page rendering should not break, but only canonical link
should disappear.
"""
curl = re.compile(']*href\s*=\s*\"([^\"]*)\"[^>]*>', re.S|re.M)
# When adapter registered for the object - canoncal link present on the page
self.assertNotEqual( queryAdapter(self.my_doc, ICanonicalLink), None)
res = self.publish(path=self.mydoc_path, basic=self.basic_auth)
self.assertNotEqual(curl.search(res.getBody()), None)
# Now remove adapter from the registry -> this should :
# - not break page on rendering;
# - canonical link will be absent on the page
gsm = getGlobalSiteManager()
gsm.unregisterAdapter(DefaultCanonicalLinkAdapter, [ITraversable,],
ICanonicalLink)
self.assertEqual( queryAdapter(self.my_doc, ICanonicalLink), None)
res = self.publish(path=self.mydoc_path, basic=self.basic_auth)
self.assertEqual(curl.search(res.getBody()), None)
# register adapter back in the global site manager
gsm.registerAdapter(DefaultCanonicalLinkAdapter, [ITraversable,],
ICanonicalLink)
def test_bug_19_23_at_plone_org(self):
"""overrides.zcml should present in the root of the package"""
import quintagroup.seoptimizer
try:
zcml.load_config('overrides.zcml', quintagroup.seoptimizer)
except IOError:
self.fail("overrides.zcml removed from the package root")
def test_bug_custom_metatags_update(self):
# Prepare a page for the test
page = self.portal["front-page"]
request = self.portal.REQUEST
directlyProvides(request, IPloneSEOLayer)
seo_context_props = getMultiAdapter((page, request), name="seo-context-properties")
# Set default custom meta tag without default value (tag name only)
self.gseo = queryAdapter(self.portal, ISEOConfigletSchema)
self.gseo.default_custom_metatags = ["test_tag",]
try:
# Breakage on updating custom metatag with seo-context-properties view
seo_context_props.updateSEOCustomMetaTagsProperties([])
except IndexError:
self.fail("Error in calculating of default tag value, when only tag name set "\
"in default_custom_metatags property of the configlet.")
class TestBug24AtPloneOrg(FunctionalTestCase):
def afterSetUp(self):
super(TestBug24AtPloneOrg, self).afterSetUp()
self.loginAsPortalOwner()
self.portal.error_log.setProperties(20)
# Add test users: member, editor
member_id = 'test_member'
editor_id = 'test_editor'
test_pswd = 'pswd'
uf = self.portal.acl_users
uf.userFolderAddUser(member_id, test_pswd,
['Member'], [])
uf.userFolderAddUser(editor_id, test_pswd,
['Member','Editor'], [])
self.member_auth = '%s:%s'%(member_id, test_pswd)
self.editor_auth = '%s:%s'%(editor_id, test_pswd)
self.portal_url = '/'.join(self.portal.getPhysicalPath())
#alsoProvides(self.app.REQUEST, IPloneSEOLayer)
# add IPloneSEOLayer
directlyProvides(self.portal.REQUEST, IPloneSEOLayer)
def test_not_break(self):
"""Default portal page should not breaks for any user"""
# Anonymous
resp = self.publish(path=self.portal_url)
file("/tmp/b24.0.1.html","wb").write(resp.getBody())
#self.assertEqual(resp.getStatus(), 200)
# Member
resp = self.publish(path=self.portal_url, basic=self.member_auth)
file("/tmp/b24.0.2.html","wb").write(resp.getBody())
#self.assertEqual(resp.getStatus(), 200)
# Editor: this fails, althought must pass
resp = self.publish(path=self.portal_url, basic=self.editor_auth)
file("/tmp/b24.0.3.html","wb").write(resp.getBody())
self.assertEqual(resp.getStatus(), 200)
def test_tab_visibility(self):
"""Only Editor can view seo tab"""
rexp = re.compile(']*' \
'href="[a-zA-Z0-9\:\/_-]*/@@seo-context-properties"[^>]*>'\
'\s*SEO Properties\s*', re.I|re.S)
# Anonymous: NO SEO Properties link
res = self.publish(path=self.portal_url).getBody()
file("/tmp/b24.1.1.html","wb").write(res)
# self.assertEqual(rexp.search(res), None)
# Member: NO 'SEO Properties' link
res = self.publish(path=self.portal_url, basic=self.member_auth).getBody()
file("/tmp/b24.1.2.html","wb").write(res)
# self.assertEqual(rexp.search(res), None)
# Editor: PRESENT 'SEO Properties' link
res = self.publish(path=self.portal_url, basic=self.editor_auth).getBody()
file("/tmp/b24.1.3.html","wb").write(res)
# self.assertNotEqual(rexp.search(res), None)
def test_tab_access(self):
"""Only Editor can access 'SEO Properties' tab"""
test_url = self.portal_url + '/front-page/@@seo-context-properties'
# Anonymous: can NOT ACCESS
headers = self.publish(path=test_url).headers
# self.assertEqual( headers.get('bobo-exception-type',""), 'Unauthorized',
# "No 'Unauthorized' exception rised for Anonymous on '@@seo-context-properties' view")
# Member: can NOT ACCESS
status = self.publish(path=test_url, basic=self.member_auth).headers
# self.assertEqual( headers.get('bobo-exception-type',""), 'Unauthorized',
# "No 'Unauthorized' exception rised for Member on '@@seo-context-properties' view")
# Editor: CAN Access
res = self.publish(path=test_url, basic=self.editor_auth)
file("/tmp/b24.2.1.html","wb").write(res.getBody())
# self.assertEqual(res.status, 200)
def test_tab_edit(self):
"""Editor can change SEO Properties"""
test_url = self.portal_url + '/front-page/@@seo-context-properties'
form_data = {'seo_title': 'New Title',
'seo_title_override:int': 1,
'form.submitted:int': 1}
res = self.publish(path=test_url, basic=self.editor_auth,
request_method='POST', stdin=StringIO(urllib.urlencode(form_data)))
file("/tmp/b24.3.1.html","wb").write(res.getBody())
# self.assertNotEqual(res.status, 200)
def test_suite():
from unittest import TestSuite, makeSuite
suite = TestSuite()
suite.addTest(makeSuite(TestBugs))
suite.addTest(makeSuite(TestBug24AtPloneOrg))
return suite