##// END OF EJS Templates
tests: improve debugging of failed flash messages.
marcink -
r1312:c1381149 default
parent child Browse files
Show More
@@ -1,260 +1,262 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2010-2017 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21 import os
22 22 import time
23 23 import logging
24 24 import datetime
25 25 import hashlib
26 26 import tempfile
27 27 from os.path import join as jn
28 28
29 29 from tempfile import _RandomNameSequence
30 30
31 31 from paste.deploy import loadapp
32 32 from paste.script.appinstall import SetupCommand
33 33
34 34 import pylons
35 35 import pylons.test
36 36 from pylons import config, url
37 37 from pylons.i18n.translation import _get_translator
38 38 from pylons.util import ContextObj
39 39
40 40 from routes.util import URLGenerator
41 41 from nose.plugins.skip import SkipTest
42 42 import pytest
43 43
44 44 from rhodecode import is_windows
45 45 from rhodecode.config.routing import ADMIN_PREFIX
46 46 from rhodecode.model.meta import Session
47 47 from rhodecode.model.db import User
48 48 from rhodecode.lib import auth
49 49 from rhodecode.lib.helpers import flash, link_to
50 50 from rhodecode.lib.utils2 import safe_unicode, safe_str
51 51 from rhodecode.tests.utils import get_session_from_response
52 52
53 53 # TODO: johbo: Solve time zone related issues and remove this tweak
54 54 os.environ['TZ'] = 'UTC'
55 55 if not is_windows:
56 56 time.tzset()
57 57
58 58 log = logging.getLogger(__name__)
59 59
60 60 __all__ = [
61 61 'get_new_dir', 'TestController', 'SkipTest',
62 62 'url', 'link_to', 'ldap_lib_installed', 'clear_all_caches',
63 63 'assert_session_flash', 'login_user',
64 64 'TESTS_TMP_PATH', 'HG_REPO', 'GIT_REPO', 'SVN_REPO',
65 65 'NEW_HG_REPO', 'NEW_GIT_REPO',
66 66 'HG_FORK', 'GIT_FORK', 'TEST_USER_ADMIN_LOGIN', 'TEST_USER_ADMIN_PASS',
67 67 'TEST_USER_REGULAR_LOGIN', 'TEST_USER_REGULAR_PASS',
68 68 'TEST_USER_REGULAR_EMAIL', 'TEST_USER_REGULAR2_LOGIN',
69 69 'TEST_USER_REGULAR2_PASS', 'TEST_USER_REGULAR2_EMAIL', 'TEST_HG_REPO',
70 70 'TEST_HG_REPO_CLONE', 'TEST_HG_REPO_PULL', 'TEST_GIT_REPO',
71 71 'TEST_GIT_REPO_CLONE', 'TEST_GIT_REPO_PULL', 'SCM_TESTS',
72 72 ]
73 73
74 74 # Invoke websetup with the current config file
75 75 # SetupCommand('setup-app').run([config_file])
76 76
77 77 # SOME GLOBALS FOR TESTS
78 78 TEST_DIR = tempfile.gettempdir()
79 79
80 80 TESTS_TMP_PATH = jn(TEST_DIR, 'rc_test_%s' % _RandomNameSequence().next())
81 81 TEST_USER_ADMIN_LOGIN = 'test_admin'
82 82 TEST_USER_ADMIN_PASS = 'test12'
83 83 TEST_USER_ADMIN_EMAIL = 'test_admin@mail.com'
84 84
85 85 TEST_USER_REGULAR_LOGIN = 'test_regular'
86 86 TEST_USER_REGULAR_PASS = 'test12'
87 87 TEST_USER_REGULAR_EMAIL = 'test_regular@mail.com'
88 88
89 89 TEST_USER_REGULAR2_LOGIN = 'test_regular2'
90 90 TEST_USER_REGULAR2_PASS = 'test12'
91 91 TEST_USER_REGULAR2_EMAIL = 'test_regular2@mail.com'
92 92
93 93 HG_REPO = 'vcs_test_hg'
94 94 GIT_REPO = 'vcs_test_git'
95 95 SVN_REPO = 'vcs_test_svn'
96 96
97 97 NEW_HG_REPO = 'vcs_test_hg_new'
98 98 NEW_GIT_REPO = 'vcs_test_git_new'
99 99
100 100 HG_FORK = 'vcs_test_hg_fork'
101 101 GIT_FORK = 'vcs_test_git_fork'
102 102
103 103 ## VCS
104 104 SCM_TESTS = ['hg', 'git']
105 105 uniq_suffix = str(int(time.mktime(datetime.datetime.now().timetuple())))
106 106
107 107 TEST_GIT_REPO = jn(TESTS_TMP_PATH, GIT_REPO)
108 108 TEST_GIT_REPO_CLONE = jn(TESTS_TMP_PATH, 'vcsgitclone%s' % uniq_suffix)
109 109 TEST_GIT_REPO_PULL = jn(TESTS_TMP_PATH, 'vcsgitpull%s' % uniq_suffix)
110 110
111 111 TEST_HG_REPO = jn(TESTS_TMP_PATH, HG_REPO)
112 112 TEST_HG_REPO_CLONE = jn(TESTS_TMP_PATH, 'vcshgclone%s' % uniq_suffix)
113 113 TEST_HG_REPO_PULL = jn(TESTS_TMP_PATH, 'vcshgpull%s' % uniq_suffix)
114 114
115 115 TEST_REPO_PREFIX = 'vcs-test'
116 116
117 117
118 118 # skip ldap tests if LDAP lib is not installed
119 119 ldap_lib_installed = False
120 120 try:
121 121 import ldap
122 122 ldap_lib_installed = True
123 123 except ImportError:
124 124 # means that python-ldap is not installed
125 125 pass
126 126
127 127
128 128 def clear_all_caches():
129 129 from beaker.cache import cache_managers
130 130 for _cache in cache_managers.values():
131 131 _cache.clear()
132 132
133 133
134 134 def get_new_dir(title):
135 135 """
136 136 Returns always new directory path.
137 137 """
138 138 from rhodecode.tests.vcs.utils import get_normalized_path
139 139 name_parts = [TEST_REPO_PREFIX]
140 140 if title:
141 141 name_parts.append(title)
142 142 hex_str = hashlib.sha1('%s %s' % (os.getpid(), time.time())).hexdigest()
143 143 name_parts.append(hex_str)
144 144 name = '-'.join(name_parts)
145 145 path = os.path.join(TEST_DIR, name)
146 146 return get_normalized_path(path)
147 147
148 148
149 149 @pytest.mark.usefixtures('app', 'index_location')
150 150 class TestController(object):
151 151
152 152 maxDiff = None
153 153
154 154 def log_user(self, username=TEST_USER_ADMIN_LOGIN,
155 155 password=TEST_USER_ADMIN_PASS):
156 156 self._logged_username = username
157 157 self._session = login_user_session(self.app, username, password)
158 158 self.csrf_token = auth.get_csrf_token(self._session)
159 159
160 160 return self._session['rhodecode_user']
161 161
162 162 def logout_user(self):
163 163 logout_user_session(self.app, auth.get_csrf_token(self._session))
164 164 self.csrf_token = None
165 165 self._logged_username = None
166 166 self._session = None
167 167
168 168 def _get_logged_user(self):
169 169 return User.get_by_username(self._logged_username)
170 170
171 171 # TODO: remove, use plain assert in tests
172 172 def assertEqual(self, a, b, msg=None):
173 173 if msg:
174 174 assert a == b, msg
175 175 else:
176 176 assert a == b
177 177
178 178
179 179 def login_user_session(
180 180 app, username=TEST_USER_ADMIN_LOGIN, password=TEST_USER_ADMIN_PASS):
181 181 from rhodecode.tests.functional.test_login import login_url
182 182 response = app.post(
183 183 login_url,
184 184 {'username': username, 'password': password})
185 185 if 'invalid user name' in response.body:
186 186 pytest.fail('could not login using %s %s' % (username, password))
187 187
188 188 assert response.status == '302 Found'
189 189 response = response.follow()
190 190 assert response.status == '200 OK'
191 191
192 192 session = get_session_from_response(response)
193 193 assert 'rhodecode_user' in session
194 194 rc_user = session['rhodecode_user']
195 195 assert rc_user.get('username') == username
196 196 assert rc_user.get('is_authenticated')
197 197
198 198 return session
199 199
200 200
201 201 def logout_user_session(app, csrf_token):
202 202 from rhodecode.tests.functional.test_login import logut_url
203 203 app.post(logut_url, {'csrf_token': csrf_token}, status=302)
204 204
205 205
206 206 def login_user(app, username=TEST_USER_ADMIN_LOGIN,
207 207 password=TEST_USER_ADMIN_PASS):
208 208 return login_user_session(app, username, password)['rhodecode_user']
209 209
210 210
211 211 def assert_session_flash(response=None, msg=None, category=None):
212 212 """
213 213 Assert on a flash message in the current session.
214 214
215 215 :param msg: Required. The expected message. Will be evaluated if a
216 216 :class:`LazyString` is passed in.
217 217 :param response: Optional. For functional testing, pass in the response
218 218 object. Otherwise don't pass in any value.
219 219 :param category: Optional. If passed, the message category will be
220 220 checked as well.
221 221 """
222 222 if msg is None:
223 223 raise ValueError("Parameter msg is required.")
224 224
225 225 messages = flash.pop_messages()
226 226 msg = _eval_if_lazy(msg)
227 227
228 228 assert messages, 'unable to find message `%s` in empty flash list' % msg
229 229 message = messages[0]
230 230
231 231 message_text = _eval_if_lazy(message.message)
232 232
233 233 if msg not in message_text:
234 msg = u'msg `%s` not found in session flash: got `%s` instead' % (
235 msg, message_text)
236 pytest.fail(safe_str(msg))
234 fail_msg = u'msg `%s` not found in session ' \
235 u'flash: got `%s` (type:%s) instead' % (
236 msg, message_text, type(message_text))
237
238 pytest.fail(safe_str(fail_msg))
237 239 if category:
238 240 assert category == message.category
239 241
240 242
241 243 def _eval_if_lazy(value):
242 244 return value.eval() if hasattr(value, 'eval') else value
243 245
244 246
245 247 def assert_not_in_session_flash(response, msg, category=None):
246 248 assert 'flash' in response.session, 'Response session has no flash key'
247 249 message_category, message_text = response.session['flash'][0]
248 250 if msg in message_text:
249 251 msg = u'msg `%s` found in session flash: got `%s` instead' % (
250 252 msg, message_text)
251 253 pytest.fail(safe_str(msg))
252 254 if category:
253 255 assert category == message_category
254 256
255 257
256 258 def assert_session_flash_is_empty(response):
257 259 if 'flash' in response.session:
258 260 msg = 'flash messages are present in session:%s' % \
259 261 response.session['flash'][0]
260 262 pytest.fail(safe_str(msg))
General Comments 0
You need to be logged in to leave comments. Login now