##// END OF EJS Templates
tests: use common test route generator.
milka -
r4614:0e8f3a20 default
parent child Browse files
Show More
@@ -1,111 +1,111 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2010-2020 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 pytest
22 22
23 23 from rhodecode.apps._base import ADMIN_PREFIX
24 24 from rhodecode.model.db import User
25 25 from rhodecode.tests import (
26 TestController, TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS,
27 TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS, assert_session_flash)
26 TestController, route_path_generator, assert_session_flash)
28 27 from rhodecode.tests.fixture import Fixture
29 28 from rhodecode.tests.utils import AssertResponse
30 29
31 30 fixture = Fixture()
32 31
33 32
34 def route_path(name, **kwargs):
35 return {
33 def route_path(name, params=None, **kwargs):
34 url_defs = {
36 35 'my_account_auth_tokens':
37 36 ADMIN_PREFIX + '/my_account/auth_tokens',
38 37 'my_account_auth_tokens_add':
39 38 ADMIN_PREFIX + '/my_account/auth_tokens/new',
40 39 'my_account_auth_tokens_delete':
41 40 ADMIN_PREFIX + '/my_account/auth_tokens/delete',
42 }[name].format(**kwargs)
41 }
42 return route_path_generator(url_defs, name=name, params=params, **kwargs)
43 43
44 44
45 45 class TestMyAccountAuthTokens(TestController):
46 46
47 47 def test_my_account_auth_tokens(self):
48 48 usr = self.log_user('test_regular2', 'test12')
49 49 user = User.get(usr['user_id'])
50 50 response = self.app.get(route_path('my_account_auth_tokens'))
51 51 for token in user.auth_tokens:
52 52 response.mustcontain(token[:4])
53 53 response.mustcontain('never')
54 54
55 55 def test_my_account_add_auth_tokens_wrong_csrf(self, user_util):
56 56 user = user_util.create_user(password='qweqwe')
57 57 self.log_user(user.username, 'qweqwe')
58 58
59 59 self.app.post(
60 60 route_path('my_account_auth_tokens_add'),
61 61 {'description': 'desc', 'lifetime': -1}, status=403)
62 62
63 63 @pytest.mark.parametrize("desc, lifetime", [
64 64 ('forever', -1),
65 65 ('5mins', 60*5),
66 66 ('30days', 60*60*24*30),
67 67 ])
68 68 def test_my_account_add_auth_tokens(self, desc, lifetime, user_util):
69 69 user = user_util.create_user(password='qweqwe')
70 70 user_id = user.user_id
71 71 self.log_user(user.username, 'qweqwe')
72 72
73 73 response = self.app.post(
74 74 route_path('my_account_auth_tokens_add'),
75 75 {'description': desc, 'lifetime': lifetime,
76 76 'csrf_token': self.csrf_token})
77 77 assert_session_flash(response, 'Auth token successfully created')
78 78
79 79 response = response.follow()
80 80 user = User.get(user_id)
81 81 for auth_token in user.auth_tokens:
82 82 response.mustcontain(auth_token[:4])
83 83
84 84 def test_my_account_delete_auth_token(self, user_util):
85 85 user = user_util.create_user(password='qweqwe')
86 86 user_id = user.user_id
87 87 self.log_user(user.username, 'qweqwe')
88 88
89 89 user = User.get(user_id)
90 90 keys = user.get_auth_tokens()
91 91 assert 2 == len(keys)
92 92
93 93 response = self.app.post(
94 94 route_path('my_account_auth_tokens_add'),
95 95 {'description': 'desc', 'lifetime': -1,
96 96 'csrf_token': self.csrf_token})
97 97 assert_session_flash(response, 'Auth token successfully created')
98 98 response.follow()
99 99
100 100 user = User.get(user_id)
101 101 keys = user.get_auth_tokens()
102 102 assert 3 == len(keys)
103 103
104 104 response = self.app.post(
105 105 route_path('my_account_auth_tokens_delete'),
106 106 {'del_auth_token': keys[0].user_api_key_id, 'csrf_token': self.csrf_token})
107 107 assert_session_flash(response, 'Auth token successfully deleted')
108 108
109 109 user = User.get(user_id)
110 110 keys = user.auth_tokens
111 111 assert 2 == len(keys)
@@ -1,202 +1,202 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2010-2020 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
23 23 import mock
24 24 import pytest
25 25 from whoosh import query
26 26
27 27 from rhodecode.tests import (
28 TestController, HG_REPO,
28 TestController, route_path_generator, HG_REPO,
29 29 TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS)
30 30 from rhodecode.tests.utils import AssertResponse
31 31
32 32
33 def route_path(name, **kwargs):
33 def route_path(name, params=None, **kwargs):
34 34 from rhodecode.apps._base import ADMIN_PREFIX
35 return {
35 url_defs = {
36 36 'search':
37 37 ADMIN_PREFIX + '/search',
38 38 'search_repo':
39 39 '/{repo_name}/search',
40
41 }[name].format(**kwargs)
40 }
41 return route_path_generator(url_defs, name=name, params=params, **kwargs)
42 42
43 43
44 44 class TestSearchController(TestController):
45 45
46 46 def test_index(self):
47 47 self.log_user()
48 48 response = self.app.get(route_path('search'))
49 49 assert_response = response.assert_response()
50 50 assert_response.one_element_exists('input#q')
51 51
52 52 def test_search_files_empty_search(self):
53 53 if os.path.isdir(self.index_location):
54 54 pytest.skip('skipped due to existing index')
55 55 else:
56 56 self.log_user()
57 57 response = self.app.get(route_path('search'),
58 58 {'q': HG_REPO})
59 59 response.mustcontain('There is no index to search in. '
60 60 'Please run whoosh indexer')
61 61
62 62 def test_search_validation(self):
63 63 self.log_user()
64 64 response = self.app.get(route_path('search'),
65 65 {'q': query, 'type': 'content', 'page_limit': 1000})
66 66
67 67 response.mustcontain(
68 68 'page_limit - 1000 is greater than maximum value 500')
69 69
70 70 @pytest.mark.parametrize("query, expected_hits, expected_paths", [
71 71 ('todo', 23, [
72 72 'vcs/backends/hg/inmemory.py',
73 73 'vcs/tests/test_git.py']),
74 74 ('extension:rst installation', 6, [
75 75 'docs/index.rst',
76 76 'docs/installation.rst']),
77 77 ('def repo', 87, [
78 78 'vcs/tests/test_git.py',
79 79 'vcs/tests/test_changesets.py']),
80 80 ('repository:%s def test' % HG_REPO, 18, [
81 81 'vcs/tests/test_git.py',
82 82 'vcs/tests/test_changesets.py']),
83 83 ('"def main"', 9, [
84 84 'vcs/__init__.py',
85 85 'vcs/tests/__init__.py',
86 86 'vcs/utils/progressbar.py']),
87 87 ('owner:test_admin', 358, [
88 88 'vcs/tests/base.py',
89 89 'MANIFEST.in',
90 90 'vcs/utils/termcolors.py',
91 91 'docs/theme/ADC/static/documentation.png']),
92 92 ('owner:test_admin def main', 72, [
93 93 'vcs/__init__.py',
94 94 'vcs/tests/test_utils_filesize.py',
95 95 'vcs/tests/test_cli.py']),
96 96 ('owner:michaΕ‚ test', 0, []),
97 97 ])
98 98 def test_search_files(self, query, expected_hits, expected_paths):
99 99 self.log_user()
100 100 response = self.app.get(route_path('search'),
101 101 {'q': query, 'type': 'content', 'page_limit': 500})
102 102
103 103 response.mustcontain('%s results' % expected_hits)
104 104 for path in expected_paths:
105 105 response.mustcontain(path)
106 106
107 107 @pytest.mark.parametrize("query, expected_hits, expected_commits", [
108 108 ('bother to ask where to fetch repo during tests', 3, [
109 109 ('hg', 'a00c1b6f5d7a6ae678fd553a8b81d92367f7ecf1'),
110 110 ('git', 'c6eb379775c578a95dad8ddab53f963b80894850'),
111 111 ('svn', '98')]),
112 112 ('michaΕ‚', 0, []),
113 113 ('changed:tests/utils.py', 36, [
114 114 ('hg', 'a00c1b6f5d7a6ae678fd553a8b81d92367f7ecf1')]),
115 115 ('changed:vcs/utils/archivers.py', 11, [
116 116 ('hg', '25213a5fbb048dff8ba65d21e466a835536e5b70'),
117 117 ('hg', '47aedd538bf616eedcb0e7d630ea476df0e159c7'),
118 118 ('hg', 'f5d23247fad4856a1dabd5838afade1e0eed24fb'),
119 119 ('hg', '04ad456aefd6461aea24f90b63954b6b1ce07b3e'),
120 120 ('git', 'c994f0de03b2a0aa848a04fc2c0d7e737dba31fc'),
121 121 ('git', 'd1f898326327e20524fe22417c22d71064fe54a1'),
122 122 ('git', 'fe568b4081755c12abf6ba673ba777fc02a415f3'),
123 123 ('git', 'bafe786f0d8c2ff7da5c1dcfcfa577de0b5e92f1')]),
124 124 ('added:README.rst', 3, [
125 125 ('hg', '3803844fdbd3b711175fc3da9bdacfcd6d29a6fb'),
126 126 ('git', 'ff7ca51e58c505fec0dd2491de52c622bb7a806b'),
127 127 ('svn', '8')]),
128 128 ('changed:lazy.py', 15, [
129 129 ('hg', 'eaa291c5e6ae6126a203059de9854ccf7b5baa12'),
130 130 ('git', '17438a11f72b93f56d0e08e7d1fa79a378578a82'),
131 131 ('svn', '82'),
132 132 ('svn', '262'),
133 133 ('hg', 'f5d23247fad4856a1dabd5838afade1e0eed24fb'),
134 134 ('git', '33fa3223355104431402a888fa77a4e9956feb3e')
135 135 ]),
136 136 ('author:marcin@python-blog.com '
137 137 'commit_id:b986218ba1c9b0d6a259fac9b050b1724ed8e545', 1, [
138 138 ('hg', 'b986218ba1c9b0d6a259fac9b050b1724ed8e545')]),
139 139 ('b986218ba1c9b0d6a259fac9b050b1724ed8e545', 1, [
140 140 ('hg', 'b986218ba1c9b0d6a259fac9b050b1724ed8e545')]),
141 141 ('b986218b', 1, [
142 142 ('hg', 'b986218ba1c9b0d6a259fac9b050b1724ed8e545')]),
143 143 ])
144 144 def test_search_commit_messages(
145 145 self, query, expected_hits, expected_commits, enabled_backends):
146 146 self.log_user()
147 147 response = self.app.get(route_path('search'),
148 148 {'q': query, 'type': 'commit', 'page_limit': 500})
149 149
150 150 response.mustcontain('%s results' % expected_hits)
151 151 for backend, commit_id in expected_commits:
152 152 if backend in enabled_backends:
153 153 response.mustcontain(commit_id)
154 154
155 155 @pytest.mark.parametrize("query, expected_hits, expected_paths", [
156 156 ('readme.rst', 3, []),
157 157 ('test*', 75, []),
158 158 ('*model*', 1, []),
159 159 ('extension:rst', 48, []),
160 160 ('extension:rst api', 24, []),
161 161 ])
162 162 def test_search_file_paths(self, query, expected_hits, expected_paths):
163 163 self.log_user()
164 164 response = self.app.get(route_path('search'),
165 165 {'q': query, 'type': 'path', 'page_limit': 500})
166 166
167 167 response.mustcontain('%s results' % expected_hits)
168 168 for path in expected_paths:
169 169 response.mustcontain(path)
170 170
171 171 def test_search_commit_message_specific_repo(self, backend):
172 172 self.log_user()
173 173 response = self.app.get(
174 174 route_path('search_repo',repo_name=backend.repo_name),
175 175 {'q': 'bother to ask where to fetch repo during tests',
176 176 'type': 'commit'})
177 177
178 178 response.mustcontain('1 results')
179 179
180 180 def test_filters_are_not_applied_for_admin_user(self):
181 181 self.log_user()
182 182 with mock.patch('whoosh.searching.Searcher.search') as search_mock:
183 183 self.app.get(route_path('search'),
184 184 {'q': 'test query', 'type': 'commit'})
185 185 assert search_mock.call_count == 1
186 186 _, kwargs = search_mock.call_args
187 187 assert kwargs['filter'] is None
188 188
189 189 def test_filters_are_applied_for_normal_user(self, enabled_backends):
190 190 self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS)
191 191 with mock.patch('whoosh.searching.Searcher.search') as search_mock:
192 192 self.app.get(route_path('search'),
193 193 {'q': 'test query', 'type': 'commit'})
194 194 assert search_mock.call_count == 1
195 195 _, kwargs = search_mock.call_args
196 196 assert isinstance(kwargs['filter'], query.Or)
197 197 expected_repositories = [
198 198 'vcs_test_{}'.format(b) for b in enabled_backends]
199 199 queried_repositories = [
200 200 name for type_, name in kwargs['filter'].all_terms()]
201 201 for repository in expected_repositories:
202 202 assert repository in queried_repositories
@@ -1,245 +1,255 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2010-2020 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 import pytest
32 32
33 33 from rhodecode.model.db import User
34 34 from rhodecode.lib import auth
35 35 from rhodecode.lib import helpers as h
36 from rhodecode.lib.helpers import flash, link_to
36 from rhodecode.lib.helpers import flash
37 37 from rhodecode.lib.utils2 import safe_str
38 38
39 39
40 40 log = logging.getLogger(__name__)
41 41
42 42 __all__ = [
43 'get_new_dir', 'TestController',
44 'link_to', 'clear_cache_regions',
43 'get_new_dir', 'TestController', 'route_path_generator',
44 'clear_cache_regions',
45 45 'assert_session_flash', 'login_user', 'no_newline_id_generator',
46 46 'TESTS_TMP_PATH', 'HG_REPO', 'GIT_REPO', 'SVN_REPO',
47 47 'NEW_HG_REPO', 'NEW_GIT_REPO',
48 48 'HG_FORK', 'GIT_FORK', 'TEST_USER_ADMIN_LOGIN', 'TEST_USER_ADMIN_PASS',
49 49 'TEST_USER_REGULAR_LOGIN', 'TEST_USER_REGULAR_PASS',
50 50 'TEST_USER_REGULAR_EMAIL', 'TEST_USER_REGULAR2_LOGIN',
51 51 'TEST_USER_REGULAR2_PASS', 'TEST_USER_REGULAR2_EMAIL', 'TEST_HG_REPO',
52 52 'TEST_HG_REPO_CLONE', 'TEST_HG_REPO_PULL', 'TEST_GIT_REPO',
53 53 'TEST_GIT_REPO_CLONE', 'TEST_GIT_REPO_PULL', 'SCM_TESTS',
54 54 ]
55 55
56 56
57 57 # SOME GLOBALS FOR TESTS
58 58 TEST_DIR = tempfile.gettempdir()
59 59
60 60 TESTS_TMP_PATH = jn(TEST_DIR, 'rc_test_%s' % _RandomNameSequence().next())
61 61 TEST_USER_ADMIN_LOGIN = 'test_admin'
62 62 TEST_USER_ADMIN_PASS = 'test12'
63 63 TEST_USER_ADMIN_EMAIL = 'test_admin@mail.com'
64 64
65 65 TEST_USER_REGULAR_LOGIN = 'test_regular'
66 66 TEST_USER_REGULAR_PASS = 'test12'
67 67 TEST_USER_REGULAR_EMAIL = 'test_regular@mail.com'
68 68
69 69 TEST_USER_REGULAR2_LOGIN = 'test_regular2'
70 70 TEST_USER_REGULAR2_PASS = 'test12'
71 71 TEST_USER_REGULAR2_EMAIL = 'test_regular2@mail.com'
72 72
73 73 HG_REPO = 'vcs_test_hg'
74 74 GIT_REPO = 'vcs_test_git'
75 75 SVN_REPO = 'vcs_test_svn'
76 76
77 77 NEW_HG_REPO = 'vcs_test_hg_new'
78 78 NEW_GIT_REPO = 'vcs_test_git_new'
79 79
80 80 HG_FORK = 'vcs_test_hg_fork'
81 81 GIT_FORK = 'vcs_test_git_fork'
82 82
83 83 ## VCS
84 84 SCM_TESTS = ['hg', 'git']
85 85 uniq_suffix = str(int(time.mktime(datetime.datetime.now().timetuple())))
86 86
87 87 TEST_GIT_REPO = jn(TESTS_TMP_PATH, GIT_REPO)
88 88 TEST_GIT_REPO_CLONE = jn(TESTS_TMP_PATH, 'vcsgitclone%s' % uniq_suffix)
89 89 TEST_GIT_REPO_PULL = jn(TESTS_TMP_PATH, 'vcsgitpull%s' % uniq_suffix)
90 90
91 91 TEST_HG_REPO = jn(TESTS_TMP_PATH, HG_REPO)
92 92 TEST_HG_REPO_CLONE = jn(TESTS_TMP_PATH, 'vcshgclone%s' % uniq_suffix)
93 93 TEST_HG_REPO_PULL = jn(TESTS_TMP_PATH, 'vcshgpull%s' % uniq_suffix)
94 94
95 95 TEST_REPO_PREFIX = 'vcs-test'
96 96
97 97
98 98 def clear_cache_regions(regions=None):
99 99 # dogpile
100 100 from rhodecode.lib.rc_cache import region_meta
101 101 for region_name, region in region_meta.dogpile_cache_regions.items():
102 102 if not regions or region_name in regions:
103 103 region.invalidate()
104 104
105 105
106 106 def get_new_dir(title):
107 107 """
108 108 Returns always new directory path.
109 109 """
110 110 from rhodecode.tests.vcs.utils import get_normalized_path
111 111 name_parts = [TEST_REPO_PREFIX]
112 112 if title:
113 113 name_parts.append(title)
114 114 hex_str = hashlib.sha1('%s %s' % (os.getpid(), time.time())).hexdigest()
115 115 name_parts.append(hex_str)
116 116 name = '-'.join(name_parts)
117 117 path = os.path.join(TEST_DIR, name)
118 118 return get_normalized_path(path)
119 119
120 120
121 121 def repo_id_generator(name):
122 122 numeric_hash = 0
123 123 for char in name:
124 124 numeric_hash += (ord(char))
125 125 return numeric_hash
126 126
127 127
128 128 @pytest.mark.usefixtures('app', 'index_location')
129 129 class TestController(object):
130 130
131 131 maxDiff = None
132 132
133 133 def log_user(self, username=TEST_USER_ADMIN_LOGIN,
134 134 password=TEST_USER_ADMIN_PASS):
135 135 self._logged_username = username
136 136 self._session = login_user_session(self.app, username, password)
137 137 self.csrf_token = auth.get_csrf_token(self._session)
138 138
139 139 return self._session['rhodecode_user']
140 140
141 141 def logout_user(self):
142 142 logout_user_session(self.app, auth.get_csrf_token(self._session))
143 143 self.csrf_token = None
144 144 self._logged_username = None
145 145 self._session = None
146 146
147 147 def _get_logged_user(self):
148 148 return User.get_by_username(self._logged_username)
149 149
150 150
151 151 def login_user_session(
152 152 app, username=TEST_USER_ADMIN_LOGIN, password=TEST_USER_ADMIN_PASS):
153 153
154 154 response = app.post(
155 155 h.route_path('login'),
156 156 {'username': username, 'password': password})
157 157 if 'invalid user name' in response.body:
158 158 pytest.fail('could not login using %s %s' % (username, password))
159 159
160 160 assert response.status == '302 Found'
161 161 response = response.follow()
162 162 assert response.status == '200 OK'
163 163
164 164 session = response.get_session_from_response()
165 165 assert 'rhodecode_user' in session
166 166 rc_user = session['rhodecode_user']
167 167 assert rc_user.get('username') == username
168 168 assert rc_user.get('is_authenticated')
169 169
170 170 return session
171 171
172 172
173 173 def logout_user_session(app, csrf_token):
174 174 app.post(h.route_path('logout'), {'csrf_token': csrf_token}, status=302)
175 175
176 176
177 177 def login_user(app, username=TEST_USER_ADMIN_LOGIN,
178 178 password=TEST_USER_ADMIN_PASS):
179 179 return login_user_session(app, username, password)['rhodecode_user']
180 180
181 181
182 182 def assert_session_flash(response, msg=None, category=None, no_=None):
183 183 """
184 184 Assert on a flash message in the current session.
185 185
186 186 :param response: Response from give calll, it will contain flash
187 187 messages or bound session with them.
188 188 :param msg: The expected message. Will be evaluated if a
189 189 :class:`LazyString` is passed in.
190 190 :param category: Optional. If passed, the message category will be
191 191 checked as well.
192 192 :param no_: Optional. If passed, the message will be checked to NOT
193 193 be in the flash session
194 194 """
195 195 if msg is None and no_ is None:
196 196 raise ValueError("Parameter msg or no_ is required.")
197 197
198 198 if msg and no_:
199 199 raise ValueError("Please specify either msg or no_, but not both")
200 200
201 201 session = response.get_session_from_response()
202 202 messages = flash.pop_messages(session=session)
203 203 msg = _eval_if_lazy(msg)
204 204
205 205 if no_:
206 206 error_msg = 'unable to detect no_ message `%s` in empty flash list' % no_
207 207 else:
208 208 error_msg = 'unable to find message `%s` in empty flash list' % msg
209 209 assert messages, error_msg
210 210 message = messages[0]
211 211
212 212 message_text = _eval_if_lazy(message.message) or ''
213 213
214 214 if no_:
215 215 if no_ in message_text:
216 216 msg = u'msg `%s` found in session flash.' % (no_,)
217 217 pytest.fail(safe_str(msg))
218 218 else:
219 219 if msg not in message_text:
220 220 fail_msg = u'msg `%s` not found in session ' \
221 221 u'flash: got `%s` (type:%s) instead' % (
222 222 msg, message_text, type(message_text))
223 223
224 224 pytest.fail(safe_str(fail_msg))
225 225 if category:
226 226 assert category == message.category
227 227
228 228
229 229 def _eval_if_lazy(value):
230 230 return value.eval() if hasattr(value, 'eval') else value
231 231
232 232
233 233 def no_newline_id_generator(test_name):
234 234 """
235 235 Generates a test name without spaces or newlines characters. Used for
236 236 nicer output of progress of test
237 237 """
238 238 org_name = test_name
239 239 test_name = safe_str(test_name)\
240 240 .replace('\n', '_N') \
241 241 .replace('\r', '_N') \
242 242 .replace('\t', '_T') \
243 243 .replace(' ', '_S')
244 244
245 245 return test_name or 'test-with-empty-name'
246
247
248 def route_path_generator(url_defs, name, params=None, **kwargs):
249 import urllib
250
251 base_url = url_defs[name].format(**kwargs)
252
253 if params:
254 base_url = '{}?{}'.format(base_url, urllib.urlencode(params))
255 return base_url
General Comments 0
You need to be logged in to leave comments. Login now