PageRenderTime 73ms CodeModel.GetById 33ms RepoModel.GetById 0ms app.codeStats 0ms

/common/test/base.py

https://github.com/2dpodcast/jaikuenginepatch
Python | 209 lines | 166 code | 22 blank | 21 comment | 8 complexity | 48bd89b89fca197a55b05c4caff74ff0 MD5 | raw file
Possible License(s): LGPL-2.0, Apache-2.0
  1. # Copyright 2009 Google Inc.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. import urlparse
  15. import sys
  16. from beautifulsoup import BeautifulSoup
  17. from django import http
  18. from django import test
  19. from django.conf import settings
  20. from django.test import client
  21. from common import clean
  22. from common import memcache
  23. from common import profile
  24. from common import util
  25. from common.protocol import sms
  26. from common.protocol import xmpp
  27. from common.test import util as test_util
  28. try:
  29. import xml.etree.ElementTree as etree
  30. import xml.parsers.expat
  31. except ImportError:
  32. etree = None
  33. class FixturesTestCase(test.TestCase):
  34. fixtures = ['actors', 'streams', 'contacts', 'streamentries',
  35. 'inboxentries', 'subscriptions', 'oauthconsumers',
  36. 'invites', 'emails', 'ims', 'activations',
  37. 'oauthaccesstokens']
  38. passwords = {'obligated@example.com': 'bar',
  39. 'popular@example.com': 'baz',
  40. 'celebrity@example.com': 'baz',
  41. 'boyfriend@example.com': 'baz',
  42. 'girlfriend@example.com': 'baz',
  43. 'annoying@example.com': 'foo',
  44. 'unpopular@example.com': 'foo',
  45. 'hermit@example.com': 'baz',
  46. 'broken@example.com': 'baz',
  47. 'CapitalPunishment@example.com': 'baz',
  48. 'root@example.com': 'fakepassword',
  49. 'hotness@example.com': 'fakepassword'};
  50. def setUp(self):
  51. settings.DEBUG = False
  52. xmpp.XmppConnection = test_util.TestXmppConnection
  53. xmpp.outbox = []
  54. sms.SmsConnection = test_util.TestSmsConnection
  55. sms.outbox = []
  56. memcache.client = test_util.FakeMemcache()
  57. if profile.PROFILE_ALL_TESTS:
  58. profile.start()
  59. self.client = client.Client(SERVER_NAME=settings.DOMAIN)
  60. def tearDown(self):
  61. if profile.PROFILE_ALL_TESTS:
  62. profile.stop()
  63. if hasattr(self, 'override'):
  64. self.override.reset()
  65. del self.override
  66. def exhaust_queue(self, nick):
  67. test_util.exhaust_queue(nick)
  68. def exhaust_queue_any(self):
  69. test_util.exhaust_queue_any()
  70. class ViewTestCase(FixturesTestCase):
  71. def login(self, nick, password=None):
  72. if not password:
  73. password = self.passwords[clean.nick(nick)]
  74. r = self.client.post('/login', {'log': nick, 'pwd': password})
  75. return
  76. def logout(self):
  77. self.client.cookies.pop(settings.USER_COOKIE)
  78. self.client.cookies.pop(settings.PASSWORD_COOKIE)
  79. def login_and_get(self, nick, path, *args, **kw):
  80. if nick:
  81. self.login(nick, kw.get('password', None))
  82. return self.client.get(path, *args, **kw)
  83. def assert_error_contains(self, response, content, code=200):
  84. self.assertContains(response, content, 1, code);
  85. # TODO(teemu): propose this to appengine_django project, when best submit path (Google-internal or
  86. # public) is decided.
  87. def assertRedirectsPrefix(self, response, expected_url_prefix,
  88. status_code=302, target_status_code=200,
  89. host=None):
  90. """Asserts that a response redirected to an URL with specified prefix,
  91. and that the redirect URL can be loaded. Return redirected response, so
  92. that further asserts can be performed on it.
  93. Note that assertRedirects won't work for external links since it uses
  94. TestClient to do a request.
  95. """
  96. self.assertEqual(response.status_code, status_code,
  97. ("Response didn't redirect as expected: Response code was"
  98. " %d (expected %d) content %s" % (
  99. response.status_code, status_code, response.content)))
  100. url = response['Location']
  101. scheme, netloc, path, query, fragment = urlparse.urlsplit(url)
  102. e_scheme, e_netloc, e_path, e_query, e_fragment = (
  103. urlparse.urlsplit(expected_url_prefix))
  104. if not (e_scheme or e_netloc):
  105. expected_url_prefix = urlparse.urlunsplit(
  106. ('http', host or settings.DOMAIN, e_path, e_query, e_fragment))
  107. self.assertEqual(url.find(expected_url_prefix), 0,
  108. "Response redirected to '%s',"
  109. " expected prefix url '%s'" % (url, expected_url_prefix))
  110. # Get the redirection page, using the same client that was used
  111. # to obtain the original response.
  112. params = {'path': path,
  113. 'data': http.QueryDict(query),
  114. 'SERVER_NAME': netloc,
  115. }
  116. if scheme == 'https':
  117. params['wsgi.url_scheme'] = 'https'
  118. params['SERVER_PORT'] = '443'
  119. redirect_response = response.client.get(**params)
  120. self.assertEqual(redirect_response.status_code,
  121. target_status_code,
  122. "Couldn't retrieve redirection page '%s': response code"
  123. " was %d (expected %d)" % (url,
  124. redirect_response.status_code,
  125. target_status_code)
  126. )
  127. return redirect_response
  128. def assertWellformed(self, r):
  129. """Tries to parse the xhmtl content in r, fails the test if not wellformed,
  130. returns the ElementTree object if it is.
  131. Not run if elementtree is not available (e.g., plain 2.4).
  132. """
  133. if not etree:
  134. return None
  135. try:
  136. parsed = etree.fromstring(r.content)
  137. return parsed
  138. except xml.parsers.expat.ExpatError, e:
  139. # TODO(mikie): this should save the output to a file for inspection.
  140. line = ''
  141. lineno = -1
  142. if getattr(e, 'lineno', None):
  143. lines = r.content.splitlines()
  144. line = lines[e.lineno - 1]
  145. line = "'" + line + "'"
  146. lineno = e.lineno
  147. codestr = ''
  148. if getattr(e, 'code', None):
  149. codestr = xml.parsers.expat.ErrorString(e.code)
  150. self.assertTrue(False,
  151. 'failed to parse response, error %s on line %d %s (%s)' %
  152. (codestr, lineno, line, str(e)))
  153. except:
  154. self.assertTrue(False, 'failed to parse response, error %s' %
  155. str(sys.exc_info()[0]))
  156. def assertGetLink(self, response, link_class, link_no,
  157. of_count=-1, msg=''):
  158. """Tries to find an anchor element with the given class from the response.
  159. Checks that there are of_count total links of that class
  160. (unless of_count==-1). Gets the page from that link.
  161. """
  162. self.assertWellformed(response)
  163. parsed = BeautifulSoup.BeautifulSoup(response.content)
  164. found = parsed.findAll('a', attrs = { 'class': link_class})
  165. anchors = [a for a in found]
  166. if of_count > -1:
  167. self.assertEqual(len(anchors), of_count, msg)
  168. a = anchors[link_no]
  169. href = a['href']
  170. # 2.4 sgmllib/HTMLParser doesn't decode HTML entities, this
  171. # fixes the query parameter separator.
  172. # TODO(mikie): how do we properly detect the sgmllib version?
  173. if int(sys.version.split(' ')[0].split('.')[1]) < 5:
  174. href = href.replace('&amp;', '&')
  175. args = util.href_to_queryparam_dict(href)
  176. args['confirm'] = 1
  177. url = response.request['PATH_INFO']
  178. return self.client.get(url, args)