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

Last change on this file since 3367 was 3367, checked in by kroman0, 12 years ago

typo fix, pyflakes

File size: 11.9 KB
Line 
1import urllib
2from cStringIO import StringIO
3
4from zope.component import queryAdapter, getMultiAdapter
5from zope.interface import directlyProvides
6from zope.viewlet.interfaces import IViewlet, IViewletManager
7
8from quintagroup.seoptimizer.browser.interfaces import IPloneSEOLayer
9from quintagroup.seoptimizer.browser.seo_configlet import ISEOConfigletSchema
10
11from quintagroup.seoptimizer.tests.base import FunctionalTestCase
12from Products.PloneTestCase.PloneTestCase import portal_owner, \
13    default_password
14import re
15from Products.Five import zcml
16
17
18class TestBugs(FunctionalTestCase):
19
20    def afterSetUp(self):
21        self.basic_auth = ':'.join((portal_owner, default_password))
22        self.loginAsPortalOwner()
23        # prepare test document
24        self.portal.invokeFactory('Document', id='my_doc')
25        self.my_doc = self.portal['my_doc']
26        self.mydoc_path = "/%s" % self.my_doc.absolute_url(1)
27
28    def set_title(self, title='', title_override=0, comment='',
29                  comment_override=0):
30        """ Set seo title """
31        portal = self.portal
32        fp = portal['front-page']
33        request = portal.REQUEST
34        view = portal.restrictedTraverse('@@plone')
35        manager = getMultiAdapter((fp, request, view), IViewletManager,
36                        name=u'plone.htmlhead')
37
38        directlyProvides(request, IPloneSEOLayer)
39        viewlet = getMultiAdapter((fp, request, view, manager), IViewlet,
40                        name=u'plone.htmlhead.title')
41
42        form_data = {'seo_title': title,
43                     'seo_title_override:int': title_override,
44                     'seo_html_comment': comment,
45                     'seo_html_comment_override:int': comment_override,
46                     'form.button.Save': "Save",
47                     'form.submitted:int': 1}
48
49        self.publish(path=fp.absolute_url(1) + '/@@seo-context-properties',
50                     basic=self.basic_auth, request_method='POST',
51                     stdin=StringIO(urllib.urlencode(form_data)))
52        viewlet.update()
53        seo_title_comment = viewlet.render()
54        return seo_title_comment
55
56    def test_seo_title(self):
57        """ Test changing title """
58        title = "New Title"
59        new_title = u'<title>%s</title>' % title
60        seo_title = self.set_title(title=title, title_override=1)
61        self.assertEqual(new_title, seo_title)
62
63    def test_seo_comment(self):
64        """ Test changing comment """
65        comment = "New Comment"
66        seo_title_comment = self.set_title(comment=comment, comment_override=1)
67        self.assert_(seo_title_comment.endswith("<!--%s-->" % comment))
68
69    def test_seo_title_comment(self):
70        """ Test changing title and comment """
71        title = "New Title"
72        comment = "New Comment"
73        new_title = u'<title>%s</title>\n<!--%s-->' % (title, comment)
74        seo_title_comment = self.set_title(title=title, title_override=1,
75                                           comment=comment, comment_override=1)
76        self.assertEqual(new_title, seo_title_comment)
77
78    def test_modification_date(self):
79        """ Modification date changing on SEO properties edit """
80        form_data = {'seo_title': 'New Title',
81                     'seo_title_override:int': 1,
82                     'form.button.Save': "Save",
83                     'form.submitted:int': 1}
84
85        md_before = self.my_doc.modification_date
86        self.publish(path=self.mydoc_path + '/@@seo-context-properties',
87                     basic=self.basic_auth, request_method='POST',
88                     stdin=StringIO(urllib.urlencode(form_data)))
89        md_after = self.my_doc.modification_date
90
91        self.assertNotEqual(md_before, md_after)
92
93    def test_bug_20_at_plone_org(self):
94        portal = self.portal
95        fp = portal['front-page']
96        request = portal.REQUEST
97        view = portal.restrictedTraverse('@@plone')
98
99        manager = getMultiAdapter((fp, request, view), IViewletManager,
100                        name=u'plone.htmlhead')
101        viewlet = getMultiAdapter((fp, request, view, manager), IViewlet,
102                        name=u'plone.htmlhead.title')
103        viewlet.update()
104        old_title = viewlet.render()
105
106        # add IPloneSEOLayer
107        directlyProvides(request, IPloneSEOLayer)
108
109        viewlet = getMultiAdapter((fp, request, view, manager), IViewlet,
110                        name=u'plone.htmlhead.title')
111        viewlet.update()
112        new_title = viewlet.render()
113
114        self.assertEqual(old_title, new_title)
115
116    def test_bug_19_23_at_plone_org(self):
117        """overrides.zcml should present in the root of the package"""
118        import quintagroup.seoptimizer
119        try:
120            zcml.load_config('overrides.zcml', quintagroup.seoptimizer)
121        except IOError:
122            self.fail("overrides.zcml removed from the package root")
123
124    def test_escape_characters_title(self):
125        """Change escape characters in title of SEO properties
126           Bug url http://plone.org/products/plone-seo/issues/31
127        """
128        from cgi import escape
129        title = 'New <i>Title</i>'
130        form_data = {'seo_title': title,
131                     'seo_title_override:int': 1,
132                     'form.button.Save': "Save",
133                     'form.submitted:int': 1}
134
135        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('.*<title>\\s*%s\\s*</title>' % escape(title), html,
140                     re.S | re.M)
141        self.assert_(m, 'Title is not escaped properly.')
142
143    def test_escape_characters_desctiption(self):
144        """Change escape characters in desctiption of SEO properties
145        """
146        from cgi import escape
147        description = 'New <i>Description</i>'
148        form_data = {'seo_description': description,
149                     'seo_description_override:int': 1,
150                     'form.button.Save': "Save",
151                     'form.submitted:int': 1}
152
153        self.publish(path=self.mydoc_path + '/@@seo-context-properties',
154                     basic=self.basic_auth, request_method='POST',
155                     stdin=StringIO(urllib.urlencode(form_data)))
156        html = self.publish(self.mydoc_path, self.basic_auth).getBody()
157        m = re.match('.*<meta name="description" content="%s"' %
158                     escape(description), html, re.S | re.M)
159        self.assert_(m, 'Desctiption is not escaped properly.')
160
161    def test_escape_characters_comment(self):
162        """Change escape characters in comment of SEO properties
163        """
164        from cgi import escape
165        comment = 'New <i>comment</i>'
166        form_data = {'seo_title': 'New Title',
167                     'seo_title_override:int': 1,
168                     'seo_html_comment': comment,
169                     'seo_html_comment_override:int': 1,
170                     'form.button.Save': "Save",
171                     'form.submitted:int': 1}
172
173        self.publish(path=self.mydoc_path + '/@@seo-context-properties',
174                     basic=self.basic_auth, request_method='POST',
175                     stdin=StringIO(urllib.urlencode(form_data)))
176        html = self.publish(self.mydoc_path, self.basic_auth).getBody()
177        m = re.match('.*<!--\\s*%s\\s*-->' % escape(comment), html,
178                     re.S | re.M)
179        self.assert_(m, 'Comment is not escaped properly.')
180
181    def test_bug_custom_metatags_update(self):
182        # Prepare a page for the test
183        page = self.portal["front-page"]
184        request = self.portal.REQUEST
185        directlyProvides(request, IPloneSEOLayer)
186        seo_context_props = getMultiAdapter((page, request),
187                                            name="seo-context-properties")
188        # Set default custom meta tag without default value (tag name only)
189        self.gseo = queryAdapter(self.portal, ISEOConfigletSchema)
190        self.gseo.default_custom_metatags = ["test_tag", ]
191        try:
192            # Breakage on updating custom metatag
193            # with seo-context-properties view
194            seo_context_props.updateSEOCustomMetaTagsProperties([])
195        except IndexError:
196            self.fail("Error in calculating of default tag value, when only "\
197                      "tag name set in default_custom_metatags property of "\
198                      "the configlet.")
199
200
201class TestBug24AtPloneOrg(FunctionalTestCase):
202
203    def afterSetUp(self):
204        # Add test users: member, editor
205        member_id = 'test_member'
206        editor_id = 'test_editor'
207        test_pswd = 'pswd'
208        uf = self.portal.acl_users
209        uf.userFolderAddUser(member_id, test_pswd,
210                        ['Member'], [])
211        uf.userFolderAddUser(editor_id, test_pswd,
212                        ['Member', 'Editor'], [])
213
214        self.member_auth = '%s:%s' % (member_id, test_pswd)
215        self.editor_auth = '%s:%s' % (editor_id, test_pswd)
216        self.portal_url = '/'.join(self.portal.getPhysicalPath())
217
218    def test_not_break(self):
219        """Default portal page should not breaks for any user"""
220        # Anonymous
221        resp = self.publish(path=self.portal_url)
222        self.assertEqual(resp.getStatus(), 200)
223        # Member
224        resp = self.publish(path=self.portal_url, basic=self.member_auth)
225        self.assertEqual(resp.getStatus(), 200)
226        # Editor: this fails, althought must pass
227        resp = self.publish(path=self.portal_url, basic=self.editor_auth)
228        self.assertEqual(resp.getStatus(), 200)
229
230    def test_tab_visibility(self):
231        """Only Editor can view seo tab"""
232        rexp = re.compile('<a\s+[^>]*' \
233               'href="[a-zA-Z0-9\:\/_-]*/@@seo-context-properties"[^>]*>'\
234               '\s*SEO Properties\s*</a>', re.I | re.S)
235        # Anonymous: NO SEO Properties link
236        res = self.publish(path=self.portal_url).getBody()
237        self.assertEqual(rexp.search(res), None)
238        # Member: NO 'SEO Properties' link
239        res = self.publish(path=self.portal_url,
240                           basic=self.member_auth).getBody()
241        self.assertEqual(rexp.search(res), None)
242        # Editor: PRESENT 'SEO Properties' link
243        res = self.publish(path=self.portal_url,
244                           basic=self.editor_auth).getBody()
245        self.assertNotEqual(rexp.search(res), None)
246
247    def test_tab_access(self):
248        """Only Editor can access 'SEO Properties' tab"""
249        test_url = self.portal_url + '/front-page/@@seo-context-properties'
250        # Anonymous: can NOT ACCESS
251        headers = self.publish(path=test_url).headers
252        self.assert_('Unauthorized' in headers.get('bobo-exception-type', ""),
253                     "No 'Unauthorized' exception rised for Anonymous on " \
254                     "'@@seo-context-properties' view")
255        # Member: can NOT ACCESS
256        self.publish(path=test_url, basic=self.member_auth).headers
257        self.assert_('Unauthorized' in headers.get('bobo-exception-type', ""),
258                     "No 'Unauthorized' exception rised for Member on " \
259                     "'@@seo-context-properties' view")
260        # Editor: CAN Access
261        res = self.publish(path=test_url, basic=self.editor_auth)
262        self.assertEqual(res.status, 200)
263
264    def test_tab_edit(self):
265        """Editor can change SEO Properties"""
266        test_url = self.portal_url + '/front-page/@@seo-context-properties'
267        form_data = {'seo_title': 'New Title',
268                     'seo_title_override:int': 1,
269                     'form.submitted:int': 1}
270        res = self.publish(path=test_url, basic=self.editor_auth,
271                           request_method='POST',
272                           stdin=StringIO(urllib.urlencode(form_data)))
273        self.assertNotEqual(res.status, 200)
274
275
276def test_suite():
277    from unittest import TestSuite, makeSuite
278    suite = TestSuite()
279    suite.addTest(makeSuite(TestBugs))
280    suite.addTest(makeSuite(TestBug24AtPloneOrg))
281    return suite
Note: See TracBrowser for help on using the repository browser.