source: products/quintagroup.seoptimizer/trunk/quintagroup/seoptimizer/tests/testBugs.py @ 3125

Last change on this file since 3125 was 3125, checked in by zidane, 13 years ago

added tests replace escape characters in title and comment

File size: 10.2 KB
RevLine 
[1958]1import urllib
[1493]2from cStringIO import StringIO
[2205]3
[2237]4from OFS.interfaces import ITraversable
5
[2205]6from zope.component import providedBy
[2237]7from zope.component import getGlobalSiteManager
8from zope.component import queryAdapter, getMultiAdapter
[2205]9from zope.interface import directlyProvides
10from zope.viewlet.interfaces import IViewlet, IViewletManager
11from zope.publisher.browser import TestRequest
12
13from quintagroup.seoptimizer.browser.interfaces import IPloneSEOLayer
[2440]14from quintagroup.seoptimizer.browser.views import PROP_CUSTOM_PREFIX
15from quintagroup.seoptimizer.browser.seo_configlet import ISEOConfigletSchema
[2237]16from quintagroup.canonicalpath.interfaces import ICanonicalLink
17from quintagroup.canonicalpath.adapters import DefaultCanonicalLinkAdapter
[1877]18from base import *
[1493]19
[2205]20
[1493]21class TestBugs(FunctionalTestCase):
22
23    def afterSetUp(self):
[1894]24        self.basic_auth = ':'.join((portal_owner,default_password))
25        self.loginAsPortalOwner()
26        # prepare test document
27        my_doc = self.portal.invokeFactory('Document', id='my_doc')
28        self.my_doc = self.portal['my_doc']
[2237]29        self.mydoc_path = "/%s" % self.my_doc.absolute_url(1)
[1493]30
31    def test_modification_date(self):
32        """ Modification date changing on SEO properties edit """
[1894]33        form_data = {'seo_title': 'New Title',
34                     'seo_title_override:int': 1,
[3012]35                     'form.button.Save': "Save",
[1894]36                     'form.submitted:int': 1}
[1493]37
[1894]38        md_before = self.my_doc.modification_date
[2237]39        self.publish(path=self.mydoc_path+'/@@seo-context-properties',
[1894]40                     basic=self.basic_auth, request_method='POST',
41                     stdin=StringIO(urllib.urlencode(form_data)))
42        md_after = self.my_doc.modification_date
43
[1493]44        self.assertNotEqual(md_before, md_after)
45
[2205]46    def test_bug_20_at_plone_org(self):
47        portal = self.portal
48        fp = portal['front-page']
49        request = portal.REQUEST
50        view = portal.restrictedTraverse('@@plone')
[1894]51
[2205]52        manager = getMultiAdapter((fp, request, view), IViewletManager,
53                        name=u'plone.htmlhead')
54        viewlet = getMultiAdapter((fp, request, view, manager), IViewlet,
55                        name=u'plone.htmlhead.title')
56        viewlet.update()
57        old_title = viewlet.render()
58
59        # add IPloneSEOLayer
60        directlyProvides(request, IPloneSEOLayer)
61
62        viewlet = getMultiAdapter((fp, request, view, manager), IViewlet,
63                        name=u'plone.htmlhead.title')
64        viewlet.update()
65        new_title = viewlet.render()
66
67        self.assertEqual(old_title, new_title)
68
[2237]69    def test_bug_22_at_plone_org(self):
70        """If ICanonicalLink adapter is not found for the context object
[2239]71           - page rendering should not break, but only canonical link
[2237]72           should disappear.
73        """
74        curl = re.compile('<link\srel\s*=\s*"canonical"\s+' \
75                         '[^>]*href\s*=\s*\"([^\"]*)\"[^>]*>', re.S|re.M)
76        # When adapter registered for the object - canoncal link present on the page
77        self.assertNotEqual( queryAdapter(self.my_doc, ICanonicalLink), None)
[2205]78
[2237]79        res = self.publish(path=self.mydoc_path, basic=self.basic_auth)
80        self.assertNotEqual(curl.search(res.getBody()), None)
[2205]81
[2237]82        # Now remove adapter from the registry -> this should :
83        #     - not break page on rendering;
84        #     - canonical link will be absent on the page
85        gsm = getGlobalSiteManager()
86        gsm.unregisterAdapter(DefaultCanonicalLinkAdapter, [ITraversable,],
87                              ICanonicalLink)
88        self.assertEqual( queryAdapter(self.my_doc, ICanonicalLink), None)
89
90        res = self.publish(path=self.mydoc_path, basic=self.basic_auth)
91        self.assertEqual(curl.search(res.getBody()), None)
92
93        # register adapter back in the global site manager
94        gsm.registerAdapter(DefaultCanonicalLinkAdapter, [ITraversable,],
95                            ICanonicalLink)
[2239]96
97    def test_bug_19_23_at_plone_org(self):
98        """overrides.zcml should present in the root of the package"""
99        import quintagroup.seoptimizer
100        try:
101            zcml.load_config('overrides.zcml', quintagroup.seoptimizer)
102        except IOError:
103            self.fail("overrides.zcml removed from the package root")
104
[3125]105    def test_escape_characters_title(self):
106        """Change escape characters in title of SEO properties
107           Bug url http://plone.org/products/plone-seo/issues/31
108        """       
109        from cgi import escape
110        title = 'New <i>Title</i>'
111        form_data = {'seo_title': title,
112                     'seo_title_override:int': 1,
113                     'form.button.Save': "Save",
114                     'form.submitted:int': 1}
115           
116        res = self.publish(path=self.mydoc_path+'/@@seo-context-properties',
117                     basic=self.basic_auth, request_method='POST',
118                     stdin=StringIO(urllib.urlencode(form_data)))
119        html = self.publish(self.mydoc_path, self.basic_auth).getBody()
120        m = re.match('.*<title>\\s*%s\\s*</title>' % escape(title), html, re.S|re.M)
121        self.assert_(m, 'Title is not escaped properly.')       
122
123    def test_escape_characters_comment(self):
124        """Change escape characters in comment of SEO properties
125        """       
126        from cgi import escape
127        comment = 'New <i>comment</i>'
128        form_data = {'seo_title': 'New Title',
129                     'seo_title_override:int': 1,
130                     'seo_html_comment': comment,
131                     'seo_html_comment_override:int': 1,
132                     'form.button.Save': "Save",
133                     'form.submitted:int': 1}
134           
135        res = self.publish(path=self.mydoc_path+'/@@seo-context-properties',
136                     basic=self.basic_auth, request_method='POST',
137                     stdin=StringIO(urllib.urlencode(form_data)))
138        html = self.publish(self.mydoc_path, self.basic_auth).getBody()
139        m = re.match('.*<!--\\s*%s\\s*-->' % escape(comment), html, re.S|re.M)
140        self.assert_(m, 'Comment is not escaped properly.')       
141
[2440]142    def test_bug_custom_metatags_update(self):
143        # Prepare a page for the test
144        page = self.portal["front-page"]
145        request = self.portal.REQUEST
146        directlyProvides(request, IPloneSEOLayer)
147        seo_context_props = getMultiAdapter((page, request), name="seo-context-properties")
148        # Set default custom meta tag without default value (tag name only)
149        self.gseo = queryAdapter(self.portal, ISEOConfigletSchema)
150        self.gseo.default_custom_metatags = ["test_tag",]
151        try:
152            # Breakage on updating custom metatag with seo-context-properties view
153            seo_context_props.updateSEOCustomMetaTagsProperties([])
154        except IndexError:
155            self.fail("Error in calculating of default tag value, when only tag name set "\
156                      "in default_custom_metatags property of the configlet.")
[2247]157
[2440]158
[2252]159class TestBug24AtPloneOrg(FunctionalTestCase):
160
161    def afterSetUp(self):
162        # Add test users: member, editor
[2247]163        member_id = 'test_member'
164        editor_id = 'test_editor'
165        test_pswd = 'pswd'
166        uf = self.portal.acl_users
167        uf.userFolderAddUser(member_id, test_pswd,
168                        ['Member'], [])
169        uf.userFolderAddUser(editor_id, test_pswd,
170                        ['Member','Editor'], [])
171
[2252]172        self.member_auth = '%s:%s'%(member_id, test_pswd)
173        self.editor_auth = '%s:%s'%(editor_id, test_pswd)
174        self.portal_url = '/'.join(self.portal.getPhysicalPath())
[2247]175
[2252]176    def test_not_break(self):
177        """Default portal page should not breaks for any user"""
178        # Anonymous
179        resp = self.publish(path=self.portal_url)
[2247]180        self.assertEqual(resp.getStatus(), 200)
[2252]181        # Member
182        resp = self.publish(path=self.portal_url, basic=self.member_auth)
183        self.assertEqual(resp.getStatus(), 200)
184        # Editor: this fails, althought must pass
185        resp = self.publish(path=self.portal_url, basic=self.editor_auth)
186        self.assertEqual(resp.getStatus(), 200)
[2237]187
[2252]188    def test_tab_visibility(self):
189        """Only Editor can view seo tab"""
190        rexp = re.compile('<a\s+[^>]*' \
191               'href="[a-zA-Z0-9\:\/_-]*/@@seo-context-properties"[^>]*>'\
192               '\s*SEO Properties\s*</a>', re.I|re.S)
193        # Anonymous: NO SEO Properties link
194        res = self.publish(path=self.portal_url).getBody()
195        self.assertEqual(rexp.search(res), None)
196        # Member: NO 'SEO Properties' link
197        res = self.publish(path=self.portal_url, basic=self.member_auth).getBody()
198        self.assertEqual(rexp.search(res), None)
199        # Editor: PRESENT 'SEO Properties' link
200        res = self.publish(path=self.portal_url, basic=self.editor_auth).getBody()
201        self.assertNotEqual(rexp.search(res), None)
[2249]202
[2252]203    def test_tab_access(self):
204        """Only Editor can access 'SEO Properties' tab"""
205        test_url = self.portal_url + '/front-page/@@seo-context-properties'
206        # Anonymous: can NOT ACCESS
207        headers = self.publish(path=test_url).headers
208        self.assertEqual( headers.get('bobo-exception-type',""), 'Unauthorized',
209            "No 'Unauthorized' exception rised for Anonymous on '@@seo-context-properties' view")
210        # Member: can NOT ACCESS
211        status = self.publish(path=test_url, basic=self.member_auth).headers
212        self.assertEqual( headers.get('bobo-exception-type',""), 'Unauthorized',
213            "No 'Unauthorized' exception rised for Member on '@@seo-context-properties' view")
214        # Editor: CAN Access
215        res = self.publish(path=test_url, basic=self.editor_auth)
216        self.assertEqual(res.status, 200)
[2249]217
[2252]218
219    def test_tab_edit(self):
220        """Editor can change SEO Properties"""
221        test_url = self.portal_url + '/front-page/@@seo-context-properties'
222        form_data = {'seo_title': 'New Title',
223                     'seo_title_override:int': 1,
224                     'form.submitted:int': 1}
225        res = self.publish(path=test_url, basic=self.editor_auth,
226                  request_method='POST', stdin=StringIO(urllib.urlencode(form_data)))
227        self.assertNotEqual(res.status, 200)
228
229
[1493]230def test_suite():
231    from unittest import TestSuite, makeSuite
232    suite = TestSuite()
233    suite.addTest(makeSuite(TestBugs))
[2252]234    suite.addTest(makeSuite(TestBug24AtPloneOrg))
[1493]235    return suite
[2247]236
Note: See TracBrowser for help on using the repository browser.