source: products/quintagroup.seoptimizer/branches/plone4/quintagroup/seoptimizer/tests/testUsageKeywords.py @ 2958

Last change on this file since 2958 was 2958, checked in by mylan, 14 years ago

Merged 3.0.5 to 3.0.7 changes from trunk into plone-4 branch version.

Merged revisions 3942-3945,3966-3976,3982-3983,3994 via svnmerge from
http://svn.quintagroup.com/products/quintagroup.seoptimizer/trunk

........

r3942 | mylan | 2010-10-20 17:06:46 +0300 (Wed, 20 Oct 2010) | 1 line


#233: Bump version to 3.0.7, updated history

........

r3943 | olha | 2010-10-20 17:14:52 +0300 (Wed, 20 Oct 2010) | 1 line


HISTORY.txt checked

........

r3944 | olha | 2010-10-20 17:20:15 +0300 (Wed, 20 Oct 2010) | 1 line


internal README file updated

........

r3945 | mylan | 2010-10-20 18:16:14 +0300 (Wed, 20 Oct 2010) | 1 line


#233: Updated list of supported version in README.txt to 3.1+

........

r3966 | mylan | 2010-10-26 17:33:27 +0300 (Tue, 26 Oct 2010) | 1 line


#233: Reduce catch exceptions to URLError and HTTPError, log error to error_log, return link to error_log

........

r3967 | mylan | 2010-10-26 17:34:03 +0300 (Tue, 26 Oct 2010) | 1 line


#233: Update tests for catching errors on keywords calculation

........

r3968 | mylan | 2010-10-26 17:55:15 +0300 (Tue, 26 Oct 2010) | 1 line


#233: Make code more readable

........

r3969 | mylan | 2010-10-26 18:08:15 +0300 (Tue, 26 Oct 2010) | 1 line


#233: Force to get portal_transforms as utility

........

r3970 | mylan | 2010-10-26 18:14:46 +0300 (Tue, 26 Oct 2010) | 1 line


#233: little cleanup

........

r3971 | mylan | 2010-10-26 20:35:28 +0300 (Tue, 26 Oct 2010) | 1 line


#233: Force logging keywords calculation to nearest to context error_log object. Other minor fixes

........

r3972 | mylan | 2010-10-26 21:08:06 +0300 (Tue, 26 Oct 2010) | 1 line


#233: Return getting error_log with getToolByName as more flexible and accurate

........

r3973 | mylan | 2010-10-27 18:09:31 +0300 (Wed, 27 Oct 2010) | 1 line


#233: Correct HISTORY information

........

r3974 | mylan | 2010-10-27 18:16:40 +0300 (Wed, 27 Oct 2010) | 1 line


#233: Added plone.browserlayer to requirements for Plone-3.0 support

........

r3975 | mylan | 2010-10-27 18:18:13 +0300 (Wed, 27 Oct 2010) | 1 line


#233: Fixed testcases to emulate proper test environment for plone-3.0

........

r3976 | mylan | 2010-10-27 18:21:55 +0300 (Wed, 27 Oct 2010) | 1 line


#233: Described steps for use the package with plone-3.0.

........

r3982 | olha | 2010-10-29 13:16:55 +0300 (Fri, 29 Oct 2010) | 1 line


doc files corrected a bit

........

r3983 | olha | 2010-10-29 13:20:45 +0300 (Fri, 29 Oct 2010) | 1 line


wrong line spacing corrected

........

r3994 | mylan | 2010-11-01 16:59:34 +0200 (Mon, 01 Nov 2010) | 1 line


Removed devloper settings of the package configuration

........

File size: 6.9 KB
Line 
1from base import *
2import urllib2
3from StringIO import StringIO
4from zope.component import queryMultiAdapter
5from zope.interface import alsoProvides
6from quintagroup.seoptimizer.browser.interfaces import IPloneSEOLayer
7
8KWSTMPL = '.*(<meta\s+(?:(?:name="keywords"\s*)|(?:content="%s"\s*)){2}/>)'
9
10class TestUsageKeywords(FunctionalTestCase):
11
12    def afterSetUp(self):
13        self.sp = self.portal.portal_properties.seo_properties
14        self.pu = self.portal.plone_utils
15        self.basic_auth = ':'.join((portal_owner,default_password))
16        self.loginAsPortalOwner()
17        #Preparation for functional testing
18        self.my_doc = self.portal.invokeFactory('Document', id='my_doc')
19        self.my_doc = self.portal['my_doc']
20
21    def test_noDefaultKeywords(self):
22        """No keywords added for the content by default"""
23        metatags = self.pu.listMetaTags(self.my_doc)
24        self.assert_('keywords' not in metatags)
25
26    def testrender_SEOKeywords(self):
27        """ """
28        self.my_doc.setText('<p>foo bar</p>')
29        self.my_doc.manage_addProperty('qSEO_keywords', [], 'lines')
30
31        for seokws in [('foo',), ('foo', 'bar')]:
32            self.my_doc._updateProperty('qSEO_keywords', seokws)
33            html = str(self.publish(self.portal.id+'/my_doc', self.basic_auth))
34            expect = ',\s*'.join(seokws)
35            open('/tmp/testrender_SEOKeywords','w').write(html)
36            self.assert_(re.match(KWSTMPL % expect, html, re.S|re.M),
37                         "No '%s' keyword found" % str(seokws))
38
39    def testbehave_NoSEOKeywordsOnlySubject(self):
40        self.my_doc.setText('<p>local subject</p>')
41        self.my_doc.setSubject('subject')
42        html = str(self.publish(self.portal.id+'/my_doc', self.basic_auth))
43
44        expect = "subject"
45        self.assert_(re.match(KWSTMPL % expect, html, re.S|re.M),
46                     "No '%s' keyword find" % expect)
47
48    def testbehave_SEOKeywordsOverrideSubject(self):
49        SEOKWS = ('local',)
50        self.my_doc.setText('<p>local subject</p>')
51        self.my_doc.setSubject('subject')
52        self.my_doc.manage_addProperty('qSEO_keywords', SEOKWS, 'lines')
53        html = str(self.publish(self.portal.id+'/my_doc', self.basic_auth))
54
55        expect = ',\s*'.join(SEOKWS)
56        self.assert_(re.match(KWSTMPL % expect, html, re.S|re.M),
57                     "No '%s' keywords find" % SEOKWS)
58
59    def testbehave_noSEOKeywordsNoSubject(self):
60        """Nor seo keywords not subject added"""
61        html = str(self.publish(self.portal.id+'/my_doc', self.basic_auth))
62        self.assertFalse(re.match('.*(<meta\s[^\>]*name="keywords"[^\>]*>)',
63                                  html, re.S|re.M), "'keyword' meta tag found")
64
65
66class TestCalcKeywords(FunctionalTestCase):
67
68    def afterSetUp(self):
69        self.loginAsPortalOwner()
70        self.seo = self.portal.portal_properties.seo_properties
71        #Preparation for functional testing
72        self.key = "SEO_KEYWORD "
73        self.portal.invokeFactory('Document', id='my_doc')
74        self.my_doc = getattr(self.portal, 'my_doc')
75        self.my_doc.setText(self.key * 2)
76        # Emulate JS request
77        self.app.REQUEST.set("text", self.key)
78        # Mark request with IPloneSEOLayer browser layer interface
79        alsoProvides(self.app.REQUEST, IPloneSEOLayer)
80        # Get checkSEOKeywords view
81        self.chckView = queryMultiAdapter((self.my_doc, self.app.REQUEST),
82            name="checkSEOKeywords")
83       
84    def patchURLLib(self, fnc):
85        self.orig_urlopen = urllib2.urlopen
86        self.urlfd = StringIO()
87        urllib2.urlopen = fnc
88   
89    def unpatchURLLib(self):
90        urllib2.urlopen = self.orig_urlopen
91        self.urlfd.close()
92
93    def test_InternalPageRendering(self):
94        self.assertTrue(not self.seo.external_keywords_test)
95        # Only keywords from content must present in check view
96        self.assertTrue('2' in self.chckView())
97
98    def test_ExternalPageRendering(self):
99        def patch_urlopen(*args, **kwargs):
100            if args[0] == self.my_doc.absolute_url():
101                self.urlfd.write(unicode(self.my_doc() + self.key).encode("utf-8"))
102                self.urlfd.seek(0)
103                return self.urlfd
104            else:
105                return self.orig_urlopen(*args, **kwargs)
106        self.seo._updateProperty("external_keywords_test", True)
107        self.patchURLLib(fnc=patch_urlopen)
108        self.assertTrue(self.seo.external_keywords_test)
109        # 1. Extra keyword must present in check view
110        self.assertTrue('3' in self.chckView())
111        # 2. Opened urllib file descriptor must be closed
112        self.assertTrue(self.urlfd.closed, "Opened file descriptor was not closed.")
113        self.unpatchURLLib()
114       
115    def test_ExternalURLError(self):
116        def patch_urlopen(*args, **kwargs):
117            if args[0] == self.my_doc.absolute_url():
118                raise urllib2.URLError("Some URL Error occured")
119            else:
120                return self.orig_urlopen(*args, **kwargs)
121        self.seo._updateProperty("external_keywords_test", True)
122        self.patchURLLib(fnc=patch_urlopen)
123        self.assertTrue(self.seo.external_keywords_test)
124        # 1. Information about problem must present in check view
125        msg = self.chckView()
126        rematch = re.match(
127            ".*Problem with page retrieval.*error_log/showEntry\?id=",
128             msg, re.S)
129        self.assertTrue(rematch, "Return message has incomplete information "
130            "about problem with page retrieval: %s" % msg)
131        # 2. Opened urllib file descriptor should not be closed because
132        #    it even not returned to the view
133        self.assertFalse(self.urlfd.closed, "Opened file descriptor was closed.")
134        self.unpatchURLLib()
135   
136    def test_ExternalIOError(self):
137        def patch_urlopen(*args, **kwargs):
138            if args[0] == self.my_doc.absolute_url():
139                self.urlfd.write(unicode(self.my_doc() + self.key).encode("utf-8"))
140                self.urlfd.seek(0)
141                return self.urlfd
142            else:
143                return self.orig_urlopen(*args, **kwargs)
144        def patch_read(*args, **kwargs):
145            raise Exception("General exception")
146        # Patch urllib2.urlopen to emulate external url retrieval
147        self.patchURLLib(fnc=patch_urlopen)
148        # Patch opened by urllib2 file descriptor to emulate IOError during reading
149        self.urlfd.read = patch_read
150        self.seo._updateProperty("external_keywords_test", True)
151        self.assertTrue(self.seo.external_keywords_test)
152        # 1. General exception must be raised.
153        self.assertRaises(Exception, self.chckView)
154        # 2. Opened urllib file descriptor must be closed
155        self.assertTrue(self.urlfd.closed, "Opened file descriptor was not closed.")
156        self.unpatchURLLib()
157       
158
159def test_suite():
160    from unittest import TestSuite, makeSuite
161    suite = TestSuite()
162    suite.addTest(makeSuite(TestUsageKeywords))
163    suite.addTest(makeSuite(TestCalcKeywords))
164    return suite
165
Note: See TracBrowser for help on using the repository browser.