##// END OF EJS Templates
tests: change lib tests to use proper pyramid mocks.
marcink -
r2318:03c88275 default
parent child Browse files
Show More
@@ -1,624 +1,623 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
22 22 """
23 23 Package for testing various lib/helper functions in rhodecode
24 24 """
25 25
26 26 import datetime
27 27 import string
28 28 import mock
29 29 import pytest
30 30
31 31 from rhodecode.tests import no_newline_id_generator
32 32 from rhodecode.tests.utils import run_test_concurrently
33 33 from rhodecode.lib.helpers import InitialsGravatar
34 34
35 35 from rhodecode.lib.utils2 import AttributeDict
36 36 from rhodecode.model.db import Repository
37 37
38 38
39 39 def _urls_for_proto(proto):
40 40 return [
41 41 ('%s://127.0.0.1' % proto, ['%s://' % proto, '127.0.0.1'],
42 42 '%s://127.0.0.1' % proto),
43 43 ('%s://marcink@127.0.0.1' % proto, ['%s://' % proto, '127.0.0.1'],
44 44 '%s://127.0.0.1' % proto),
45 45 ('%s://marcink:pass@127.0.0.1' % proto, ['%s://' % proto, '127.0.0.1'],
46 46 '%s://127.0.0.1' % proto),
47 47 ('%s://127.0.0.1:8080' % proto, ['%s://' % proto, '127.0.0.1', '8080'],
48 48 '%s://127.0.0.1:8080' % proto),
49 49 ('%s://domain.org' % proto, ['%s://' % proto, 'domain.org'],
50 50 '%s://domain.org' % proto),
51 51 ('%s://user:pass@domain.org:8080' % proto,
52 52 ['%s://' % proto, 'domain.org', '8080'],
53 53 '%s://domain.org:8080' % proto),
54 54 ]
55 55
56 56 TEST_URLS = _urls_for_proto('http') + _urls_for_proto('https')
57 57
58 58
59 59 @pytest.mark.parametrize("test_url, expected, expected_creds", TEST_URLS)
60 60 def test_uri_filter(test_url, expected, expected_creds):
61 61 from rhodecode.lib.utils2 import uri_filter
62 62 assert uri_filter(test_url) == expected
63 63
64 64
65 65 @pytest.mark.parametrize("test_url, expected, expected_creds", TEST_URLS)
66 66 def test_credentials_filter(test_url, expected, expected_creds):
67 67 from rhodecode.lib.utils2 import credentials_filter
68 68 assert credentials_filter(test_url) == expected_creds
69 69
70 70
71 71 @pytest.mark.parametrize("str_bool, expected", [
72 72 ('t', True),
73 73 ('true', True),
74 74 ('y', True),
75 75 ('yes', True),
76 76 ('on', True),
77 77 ('1', True),
78 78 ('Y', True),
79 79 ('yeS', True),
80 80 ('Y', True),
81 81 ('TRUE', True),
82 82 ('T', True),
83 83 ('False', False),
84 84 ('F', False),
85 85 ('FALSE', False),
86 86 ('0', False),
87 87 ('-1', False),
88 88 ('', False)
89 89 ])
90 90 def test_str2bool(str_bool, expected):
91 91 from rhodecode.lib.utils2 import str2bool
92 92 assert str2bool(str_bool) == expected
93 93
94 94
95 95 @pytest.mark.parametrize("text, expected", reduce(lambda a1,a2:a1+a2, [
96 96 [
97 97 (pref+"", []),
98 98 (pref+"Hi there @marcink", ['marcink']),
99 99 (pref+"Hi there @marcink and @bob", ['bob', 'marcink']),
100 100 (pref+"Hi there @marcink\n", ['marcink']),
101 101 (pref+"Hi there @marcink and @bob\n", ['bob', 'marcink']),
102 102 (pref+"Hi there marcin@rhodecode.com", []),
103 103 (pref+"Hi there @john.malcovic and @bob\n", ['bob', 'john.malcovic']),
104 104 (pref+"This needs to be reviewed: (@marcink,@john)", ["john", "marcink"]),
105 105 (pref+"This needs to be reviewed: (@marcink, @john)", ["john", "marcink"]),
106 106 (pref+"This needs to be reviewed: [@marcink,@john]", ["john", "marcink"]),
107 107 (pref+"This needs to be reviewed: (@marcink @john)", ["john", "marcink"]),
108 108 (pref+"@john @mary, please review", ["john", "mary"]),
109 109 (pref+"@john,@mary, please review", ["john", "mary"]),
110 110 (pref+"Hej @123, @22john,@mary, please review", ['123', '22john', 'mary']),
111 111 (pref+"@first hi there @marcink here's my email marcin@email.com "
112 112 "@lukaszb check @one_more22 it pls @ ttwelve @D[] @one@two@three ", ['first', 'lukaszb', 'marcink', 'one', 'one_more22']),
113 113 (pref+"@MARCIN @maRCiN @2one_more22 @john please see this http://org.pl", ['2one_more22', 'john', 'MARCIN', 'maRCiN']),
114 114 (pref+"@marian.user just do it @marco-polo and next extract @marco_polo", ['marco-polo', 'marco_polo', 'marian.user']),
115 115 (pref+"user.dot hej ! not-needed maril@domain.org", []),
116 116 (pref+"\n@marcin", ['marcin']),
117 117 ]
118 118 for pref in ['', '\n', 'hi !', '\t', '\n\n']]), ids=no_newline_id_generator)
119 119 def test_mention_extractor(text, expected):
120 120 from rhodecode.lib.utils2 import extract_mentioned_users
121 121 got = extract_mentioned_users(text)
122 122 assert sorted(got, key=lambda x: x.lower()) == got
123 123 assert set(expected) == set(got)
124 124
125 125 @pytest.mark.parametrize("age_args, expected, kw", [
126 126 ({}, u'just now', {}),
127 127 ({'seconds': -1}, u'1 second ago', {}),
128 128 ({'seconds': -60 * 2}, u'2 minutes ago', {}),
129 129 ({'hours': -1}, u'1 hour ago', {}),
130 130 ({'hours': -24}, u'1 day ago', {}),
131 131 ({'hours': -24 * 5}, u'5 days ago', {}),
132 132 ({'months': -1}, u'1 month ago', {}),
133 133 ({'months': -1, 'days': -2}, u'1 month and 2 days ago', {}),
134 134 ({'years': -1, 'months': -1}, u'1 year and 1 month ago', {}),
135 135 ({}, u'just now', {'short_format': True}),
136 136 ({'seconds': -1}, u'1sec ago', {'short_format': True}),
137 137 ({'seconds': -60 * 2}, u'2min ago', {'short_format': True}),
138 138 ({'hours': -1}, u'1h ago', {'short_format': True}),
139 139 ({'hours': -24}, u'1d ago', {'short_format': True}),
140 140 ({'hours': -24 * 5}, u'5d ago', {'short_format': True}),
141 141 ({'months': -1}, u'1m ago', {'short_format': True}),
142 142 ({'months': -1, 'days': -2}, u'1m, 2d ago', {'short_format': True}),
143 143 ({'years': -1, 'months': -1}, u'1y, 1m ago', {'short_format': True}),
144 144 ])
145 145 def test_age(age_args, expected, kw, pylonsapp):
146 146 from rhodecode.lib.utils2 import age
147 147 from dateutil import relativedelta
148 148 n = datetime.datetime(year=2012, month=5, day=17)
149 149 delt = lambda *args, **kwargs: relativedelta.relativedelta(*args, **kwargs)
150 150
151 151 def translate(elem):
152 152 return elem.interpolate()
153 153
154 154 assert translate(age(n + delt(**age_args), now=n, **kw)) == expected
155 155
156 156
157 157 @pytest.mark.parametrize("age_args, expected, kw", [
158 158 ({}, u'just now', {}),
159 159 ({'seconds': 1}, u'in 1 second', {}),
160 160 ({'seconds': 60 * 2}, u'in 2 minutes', {}),
161 161 ({'hours': 1}, u'in 1 hour', {}),
162 162 ({'hours': 24}, u'in 1 day', {}),
163 163 ({'hours': 24 * 5}, u'in 5 days', {}),
164 164 ({'months': 1}, u'in 1 month', {}),
165 165 ({'months': 1, 'days': 1}, u'in 1 month and 1 day', {}),
166 166 ({'years': 1, 'months': 1}, u'in 1 year and 1 month', {}),
167 167 ({}, u'just now', {'short_format': True}),
168 168 ({'seconds': 1}, u'in 1sec', {'short_format': True}),
169 169 ({'seconds': 60 * 2}, u'in 2min', {'short_format': True}),
170 170 ({'hours': 1}, u'in 1h', {'short_format': True}),
171 171 ({'hours': 24}, u'in 1d', {'short_format': True}),
172 172 ({'hours': 24 * 5}, u'in 5d', {'short_format': True}),
173 173 ({'months': 1}, u'in 1m', {'short_format': True}),
174 174 ({'months': 1, 'days': 1}, u'in 1m, 1d', {'short_format': True}),
175 175 ({'years': 1, 'months': 1}, u'in 1y, 1m', {'short_format': True}),
176 176 ])
177 177 def test_age_in_future(age_args, expected, kw, pylonsapp):
178 178 from rhodecode.lib.utils2 import age
179 179 from dateutil import relativedelta
180 180 n = datetime.datetime(year=2012, month=5, day=17)
181 181 delt = lambda *args, **kwargs: relativedelta.relativedelta(*args, **kwargs)
182 182
183 183 def translate(elem):
184 184 return elem.interpolate()
185 185
186 186 assert translate(age(n + delt(**age_args), now=n, **kw)) == expected
187 187
188 188
189 189 @pytest.mark.parametrize("sample, expected_tags", [
190 190 ((
191 191 "hello world [stale]"
192 192 ),
193 193 [
194 194 ('state', '[stale]'),
195 195 ]),
196 196 # entry
197 197 ((
198 198 "hello world [v2.0.0] [v1.0.0]"
199 199 ),
200 200 [
201 201 ('generic', '[v2.0.0]'),
202 202 ('generic', '[v1.0.0]'),
203 203 ]),
204 204 # entry
205 205 ((
206 206 "he[ll]o wo[rl]d"
207 207 ),
208 208 [
209 209 ('label', '[ll]'),
210 210 ('label', '[rl]'),
211 211 ]),
212 212 # entry
213 213 ((
214 214 "hello world [stale]\n[featured]\n[stale] [dead] [dev]"
215 215 ),
216 216 [
217 217 ('state', '[stale]'),
218 218 ('state', '[featured]'),
219 219 ('state', '[stale]'),
220 220 ('state', '[dead]'),
221 221 ('state', '[dev]'),
222 222 ]),
223 223 # entry
224 224 ((
225 225 "hello world \n\n [stale] \n [url =&gt; [name](http://rc.com)]"
226 226 ),
227 227 [
228 228 ('state', '[stale]'),
229 229 ('url', '[url =&gt; [name](http://rc.com)]'),
230 230 ]),
231 231 # entry
232 232 ((
233 233 "hello pta[tag] gog [[]] [[] sda ero[or]d [me =&gt;>< sa]"
234 234 "[requires] [stale] [see<>=&gt;] [see =&gt; http://url.com]"
235 235 "[requires =&gt; url] [lang =&gt; python] [just a tag] "
236 236 "<html_tag first='abc' attr=\"my.url?attr=&another=\"></html_tag>"
237 237 "[,d] [ =&gt; ULR ] [obsolete] [desc]]"
238 238 ),
239 239 [
240 240 ('label', '[desc]'),
241 241 ('label', '[obsolete]'),
242 242 ('label', '[or]'),
243 243 ('label', '[requires]'),
244 244 ('label', '[tag]'),
245 245 ('state', '[stale]'),
246 246 ('lang', '[lang =&gt; python]'),
247 247 ('ref', '[requires =&gt; url]'),
248 248 ('see', '[see =&gt; http://url.com]'),
249 249
250 250 ]),
251 251
252 252 ], ids=no_newline_id_generator)
253 253 def test_metatag_extraction(sample, expected_tags):
254 254 from rhodecode.lib.helpers import extract_metatags
255 255 tags, value = extract_metatags(sample)
256 256 assert sorted(tags) == sorted(expected_tags)
257 257
258 258
259 259 @pytest.mark.parametrize("tag_data, expected_html", [
260 260
261 261 (('state', '[stable]'), '<div class="metatag" tag="state stable">stable</div>'),
262 262 (('state', '[stale]'), '<div class="metatag" tag="state stale">stale</div>'),
263 263 (('state', '[featured]'), '<div class="metatag" tag="state featured">featured</div>'),
264 264 (('state', '[dev]'), '<div class="metatag" tag="state dev">dev</div>'),
265 265 (('state', '[dead]'), '<div class="metatag" tag="state dead">dead</div>'),
266 266
267 267 (('label', '[personal]'), '<div class="metatag" tag="label">personal</div>'),
268 268 (('generic', '[v2.0.0]'), '<div class="metatag" tag="generic">v2.0.0</div>'),
269 269
270 270 (('lang', '[lang =&gt; JavaScript]'), '<div class="metatag" tag="lang">JavaScript</div>'),
271 271 (('lang', '[lang =&gt; C++]'), '<div class="metatag" tag="lang">C++</div>'),
272 272 (('lang', '[lang =&gt; C#]'), '<div class="metatag" tag="lang">C#</div>'),
273 273 (('lang', '[lang =&gt; Delphi/Object]'), '<div class="metatag" tag="lang">Delphi/Object</div>'),
274 274 (('lang', '[lang =&gt; Objective-C]'), '<div class="metatag" tag="lang">Objective-C</div>'),
275 275 (('lang', '[lang =&gt; .NET]'), '<div class="metatag" tag="lang">.NET</div>'),
276 276
277 277 (('license', '[license =&gt; BSD 3-clause]'), '<div class="metatag" tag="license"><a href="http:\/\/www.opensource.org/licenses/BSD 3-clause">BSD 3-clause</a></div>'),
278 278 (('license', '[license =&gt; GPLv3]'), '<div class="metatag" tag="license"><a href="http:\/\/www.opensource.org/licenses/GPLv3">GPLv3</a></div>'),
279 279 (('license', '[license =&gt; MIT]'), '<div class="metatag" tag="license"><a href="http:\/\/www.opensource.org/licenses/MIT">MIT</a></div>'),
280 280 (('license', '[license =&gt; AGPLv3]'), '<div class="metatag" tag="license"><a href="http:\/\/www.opensource.org/licenses/AGPLv3">AGPLv3</a></div>'),
281 281
282 282 (('ref', '[requires =&gt; RepoName]'), '<div class="metatag" tag="ref requires">requires: <a href="/RepoName">RepoName</a></div>'),
283 283 (('ref', '[recommends =&gt; GroupName]'), '<div class="metatag" tag="ref recommends">recommends: <a href="/GroupName">GroupName</a></div>'),
284 284 (('ref', '[conflicts =&gt; SomeName]'), '<div class="metatag" tag="ref conflicts">conflicts: <a href="/SomeName">SomeName</a></div>'),
285 285 (('ref', '[base =&gt; SomeName]'), '<div class="metatag" tag="ref base">base: <a href="/SomeName">SomeName</a></div>'),
286 286
287 287 (('see', '[see =&gt; http://rhodecode.com]'), '<div class="metatag" tag="see">see: http://rhodecode.com </div>'),
288 288
289 289 (('url', '[url =&gt; [linkName](https://rhodecode.com)]'), '<div class="metatag" tag="url"> <a href="https://rhodecode.com">linkName</a> </div>'),
290 290 (('url', '[url =&gt; [example link](https://rhodecode.com)]'), '<div class="metatag" tag="url"> <a href="https://rhodecode.com">example link</a> </div>'),
291 291 (('url', '[url =&gt; [v1.0.0](https://rhodecode.com)]'), '<div class="metatag" tag="url"> <a href="https://rhodecode.com">v1.0.0</a> </div>'),
292 292
293 293 ])
294 294 def test_metatags_stylize(tag_data, expected_html):
295 295 from rhodecode.lib.helpers import style_metatag
296 296 tag_type,value = tag_data
297 297 assert style_metatag(tag_type, value) == expected_html
298 298
299 299
300 300 @pytest.mark.parametrize("tmpl_url, email, expected", [
301 301 ('http://test.com/{email}', 'test@foo.com', 'http://test.com/test@foo.com'),
302 302
303 303 ('http://test.com/{md5email}', 'test@foo.com', 'http://test.com/3cb7232fcc48743000cb86d0d5022bd9'),
304 304 ('http://test.com/{md5email}', 'testΔ…Δ‡@foo.com', 'http://test.com/978debb907a3c55cd741872ab293ef30'),
305 305
306 306 ('http://testX.com/{md5email}?s={size}', 'test@foo.com', 'http://testX.com/3cb7232fcc48743000cb86d0d5022bd9?s=24'),
307 307 ('http://testX.com/{md5email}?s={size}', 'testΔ…Δ‡@foo.com', 'http://testX.com/978debb907a3c55cd741872ab293ef30?s=24'),
308 308
309 309 ('{scheme}://{netloc}/{md5email}/{size}', 'test@foo.com', 'https://server.com/3cb7232fcc48743000cb86d0d5022bd9/24'),
310 310 ('{scheme}://{netloc}/{md5email}/{size}', 'testΔ…Δ‡@foo.com', 'https://server.com/978debb907a3c55cd741872ab293ef30/24'),
311 311
312 312 ('http://test.com/{email}', 'testΔ…Δ‡@foo.com', 'http://test.com/testΔ…Δ‡@foo.com'),
313 313 ('http://test.com/{email}?size={size}', 'test@foo.com', 'http://test.com/test@foo.com?size=24'),
314 314 ('http://test.com/{email}?size={size}', 'testΔ…Δ‡@foo.com', 'http://test.com/testΔ…Δ‡@foo.com?size=24'),
315 315 ])
316 316 def test_gravatar_url_builder(tmpl_url, email, expected, request_stub):
317 317 from rhodecode.lib.helpers import gravatar_url
318 318
319 # mock pyramid.threadlocals
320 def fake_get_current_request():
321 request_stub.scheme = 'https'
322 request_stub.host = 'server.com'
323 return request_stub
324
325 # mock pylons.tmpl_context
326 319 def fake_tmpl_context(_url):
327 320 _c = AttributeDict()
328 321 _c.visual = AttributeDict()
329 322 _c.visual.use_gravatar = True
330 323 _c.visual.gravatar_url = _url
324 return _c
331 325
332 return _c
326 # mock pyramid.threadlocals
327 def fake_get_current_request():
328 request_stub.scheme = 'https'
329 request_stub.host = 'server.com'
330
331 request_stub._call_context = fake_tmpl_context(tmpl_url)
332 return request_stub
333 333
334 334 with mock.patch('rhodecode.lib.helpers.get_current_request',
335 335 fake_get_current_request):
336 fake = fake_tmpl_context(_url=tmpl_url)
337 with mock.patch('pylons.tmpl_context', fake):
338 grav = gravatar_url(email_address=email, size=24)
339 assert grav == expected
336
337 grav = gravatar_url(email_address=email, size=24)
338 assert grav == expected
340 339
341 340
342 341 @pytest.mark.parametrize(
343 342 "email, first_name, last_name, expected_initials, expected_color", [
344 343
345 344 ('test@rhodecode.com', '', '', 'TR', '#8a994d'),
346 345 ('marcin.kuzminski@rhodecode.com', '', '', 'MK', '#6559b3'),
347 346 # special cases of email
348 347 ('john.van.dam@rhodecode.com', '', '', 'JD', '#526600'),
349 348 ('Guido.van.Rossum@rhodecode.com', '', '', 'GR', '#990052'),
350 349 ('Guido.van.Rossum@rhodecode.com', 'Guido', 'Van Rossum', 'GR', '#990052'),
351 350
352 351 ('rhodecode+Guido.van.Rossum@rhodecode.com', '', '', 'RR', '#46598c'),
353 352 ('pclouds@rhodecode.com', 'Nguyα»…n ThΓ‘i', 'Tgọc Duy', 'ND', '#665200'),
354 353
355 354 ('john-brown@foo.com', '', '', 'JF', '#73006b'),
356 355 ('admin@rhodecode.com', 'Marcin', 'Kuzminski', 'MK', '#104036'),
357 356 # partials
358 357 ('admin@rhodecode.com', 'Marcin', '', 'MR', '#104036'), # fn+email
359 358 ('admin@rhodecode.com', '', 'Kuzminski', 'AK', '#104036'), # em+ln
360 359 # non-ascii
361 360 ('admin@rhodecode.com', 'Marcin', 'Śuzminski', 'MS', '#104036'),
362 361 ('marcin.Ε›uzminski@rhodecode.com', '', '', 'MS', '#73000f'),
363 362
364 363 # special cases, LDAP can provide those...
365 364 ('admin@', 'Marcin', 'Śuzminski', 'MS', '#aa00ff'),
366 365 ('marcin.Ε›uzminski', '', '', 'MS', '#402020'),
367 366 ('null', '', '', 'NL', '#8c4646'),
368 367 ('some.@abc.com', 'some', '', 'SA', '#664e33')
369 368 ])
370 369 def test_initials_gravatar_pick_of_initials_and_color_algo(
371 370 email, first_name, last_name, expected_initials, expected_color):
372 371 instance = InitialsGravatar(email, first_name, last_name)
373 372 assert instance.get_initials() == expected_initials
374 373 assert instance.str2color(email) == expected_color
375 374
376 375
377 376 def test_initials_gravatar_mapping_algo():
378 377 pos = set()
379 378 instance = InitialsGravatar('', '', '')
380 379 iterations = 0
381 380
382 381 variations = []
383 382 for letter1 in string.ascii_letters:
384 383 for letter2 in string.ascii_letters[::-1][:10]:
385 384 for letter3 in string.ascii_letters[:10]:
386 385 variations.append(
387 386 '%s@rhodecode.com' % (letter1+letter2+letter3))
388 387
389 388 max_variations = 4096
390 389 for email in variations[:max_variations]:
391 390 iterations += 1
392 391 pos.add(
393 392 instance.pick_color_bank_index(email,
394 393 instance.get_color_bank()))
395 394
396 395 # we assume that we have match all 256 possible positions,
397 396 # in reasonable amount of different email addresses
398 397 assert len(pos) == 256
399 398 assert iterations == max_variations
400 399
401 400
402 401 @pytest.mark.parametrize("tmpl, repo_name, overrides, prefix, expected", [
403 402 (Repository.DEFAULT_CLONE_URI, 'group/repo1', {}, '', 'http://vps1:8000/group/repo1'),
404 403 (Repository.DEFAULT_CLONE_URI, 'group/repo1', {'user': 'marcink'}, '', 'http://marcink@vps1:8000/group/repo1'),
405 404 (Repository.DEFAULT_CLONE_URI, 'group/repo1', {}, '/rc', 'http://vps1:8000/rc/group/repo1'),
406 405 (Repository.DEFAULT_CLONE_URI, 'group/repo1', {'user': 'user'}, '/rc', 'http://user@vps1:8000/rc/group/repo1'),
407 406 (Repository.DEFAULT_CLONE_URI, 'group/repo1', {'user': 'marcink'}, '/rc', 'http://marcink@vps1:8000/rc/group/repo1'),
408 407 (Repository.DEFAULT_CLONE_URI, 'group/repo1', {'user': 'user'}, '/rc/', 'http://user@vps1:8000/rc/group/repo1'),
409 408 (Repository.DEFAULT_CLONE_URI, 'group/repo1', {'user': 'marcink'}, '/rc/', 'http://marcink@vps1:8000/rc/group/repo1'),
410 409 ('{scheme}://{user}@{netloc}/_{repoid}', 'group/repo1', {}, '', 'http://vps1:8000/_23'),
411 410 ('{scheme}://{user}@{netloc}/_{repoid}', 'group/repo1', {'user': 'marcink'}, '', 'http://marcink@vps1:8000/_23'),
412 411 ('http://{user}@{netloc}/_{repoid}', 'group/repo1', {'user': 'marcink'}, '', 'http://marcink@vps1:8000/_23'),
413 412 ('http://{netloc}/_{repoid}', 'group/repo1', {'user': 'marcink'}, '', 'http://vps1:8000/_23'),
414 413 ('https://{user}@proxy1.server.com/{repo}', 'group/repo1', {'user': 'marcink'}, '', 'https://marcink@proxy1.server.com/group/repo1'),
415 414 ('https://{user}@proxy1.server.com/{repo}', 'group/repo1', {}, '', 'https://proxy1.server.com/group/repo1'),
416 415 ('https://proxy1.server.com/{user}/{repo}', 'group/repo1', {'user': 'marcink'}, '', 'https://proxy1.server.com/marcink/group/repo1'),
417 416 ])
418 417 def test_clone_url_generator(tmpl, repo_name, overrides, prefix, expected):
419 418 from rhodecode.lib.utils2 import get_clone_url
420 419
421 420 class RequestStub(object):
422 421 def request_url(self, name):
423 422 return 'http://vps1:8000' + prefix
424 423
425 424 def route_url(self, name):
426 425 return self.request_url(name)
427 426
428 427 clone_url = get_clone_url(
429 428 request=RequestStub(),
430 429 uri_tmpl=tmpl,
431 430 repo_name=repo_name, repo_id=23, **overrides)
432 431 assert clone_url == expected
433 432
434 433
435 434 def _quick_url(text, tmpl="""<a class="revision-link" href="%s">%s</a>""", url_=None):
436 435 """
437 436 Changes `some text url[foo]` => `some text <a href="/">foo</a>
438 437
439 438 :param text:
440 439 """
441 440 import re
442 441 # quickly change expected url[] into a link
443 442 URL_PAT = re.compile(r'(?:url\[)(.+?)(?:\])')
444 443
445 444 def url_func(match_obj):
446 445 _url = match_obj.groups()[0]
447 446 return tmpl % (url_ or '/some-url', _url)
448 447 return URL_PAT.sub(url_func, text)
449 448
450 449
451 450 @pytest.mark.parametrize("sample, expected", [
452 451 ("",
453 452 ""),
454 453 ("git-svn-id: https://svn.apache.org/repos/asf/libcloud/trunk@1441655 13f79535-47bb-0310-9956-ffa450edef68",
455 454 "git-svn-id: https://svn.apache.org/repos/asf/libcloud/trunk@1441655 13f79535-47bb-0310-9956-ffa450edef68"),
456 455 ("from rev 000000000000",
457 456 "from rev url[000000000000]"),
458 457 ("from rev 000000000000123123 also rev 000000000000",
459 458 "from rev url[000000000000123123] also rev url[000000000000]"),
460 459 ("this should-000 00",
461 460 "this should-000 00"),
462 461 ("longtextffffffffff rev 123123123123",
463 462 "longtextffffffffff rev url[123123123123]"),
464 463 ("rev ffffffffffffffffffffffffffffffffffffffffffffffffff",
465 464 "rev ffffffffffffffffffffffffffffffffffffffffffffffffff"),
466 465 ("ffffffffffff some text traalaa",
467 466 "url[ffffffffffff] some text traalaa"),
468 467 ("""Multi line
469 468 123123123123
470 469 some text 123123123123
471 470 sometimes !
472 471 """,
473 472 """Multi line
474 473 url[123123123123]
475 474 some text url[123123123123]
476 475 sometimes !
477 476 """)
478 477 ], ids=no_newline_id_generator)
479 478 def test_urlify_commits(sample, expected):
480 479 def fake_url(self, *args, **kwargs):
481 480 return '/some-url'
482 481
483 482 expected = _quick_url(expected)
484 483
485 484 with mock.patch('rhodecode.lib.helpers.route_url', fake_url):
486 485 from rhodecode.lib.helpers import urlify_commits
487 486 assert urlify_commits(sample, 'repo_name') == expected
488 487
489 488
490 489 @pytest.mark.parametrize("sample, expected, url_", [
491 490 ("",
492 491 "",
493 492 ""),
494 493 ("https://svn.apache.org/repos",
495 494 "url[https://svn.apache.org/repos]",
496 495 "https://svn.apache.org/repos"),
497 496 ("http://svn.apache.org/repos",
498 497 "url[http://svn.apache.org/repos]",
499 498 "http://svn.apache.org/repos"),
500 499 ("from rev a also rev http://google.com",
501 500 "from rev a also rev url[http://google.com]",
502 501 "http://google.com"),
503 502 ("""Multi line
504 503 https://foo.bar.com
505 504 some text lalala""",
506 505 """Multi line
507 506 url[https://foo.bar.com]
508 507 some text lalala""",
509 508 "https://foo.bar.com")
510 509 ], ids=no_newline_id_generator)
511 510 def test_urlify_test(sample, expected, url_):
512 511 from rhodecode.lib.helpers import urlify_text
513 512 expected = _quick_url(expected, tmpl="""<a href="%s">%s</a>""", url_=url_)
514 513 assert urlify_text(sample) == expected
515 514
516 515
517 516 @pytest.mark.parametrize("test, expected", [
518 517 ("", None),
519 518 ("/_2", '2'),
520 519 ("_2", '2'),
521 520 ("/_2/", '2'),
522 521 ("_2/", '2'),
523 522
524 523 ("/_21", '21'),
525 524 ("_21", '21'),
526 525 ("/_21/", '21'),
527 526 ("_21/", '21'),
528 527
529 528 ("/_21/foobar", '21'),
530 529 ("_21/121", '21'),
531 530 ("/_21/_12", '21'),
532 531 ("_21/rc/foo", '21'),
533 532
534 533 ])
535 534 def test_get_repo_by_id(test, expected):
536 535 from rhodecode.model.repo import RepoModel
537 536 _test = RepoModel()._extract_id_from_repo_name(test)
538 537 assert _test == expected
539 538
540 539
541 540 @pytest.mark.parametrize("test_repo_name, repo_type", [
542 541 ("test_repo_1", None),
543 542 ("repo_group/foobar", None),
544 543 ("test_non_asci_Δ…Δ‡Δ™", None),
545 544 (u"test_non_asci_unicode_Δ…Δ‡Δ™", None),
546 545 ])
547 546 def test_invalidation_context(pylonsapp, test_repo_name, repo_type):
548 547 from beaker.cache import cache_region
549 548 from rhodecode.lib import caches
550 549 from rhodecode.model.db import CacheKey
551 550
552 551 @cache_region('long_term')
553 552 def _dummy_func(cache_key):
554 553 return 'result'
555 554
556 555 invalidator_context = CacheKey.repo_context_cache(
557 556 _dummy_func, test_repo_name, 'repo')
558 557
559 558 with invalidator_context as context:
560 559 invalidated = context.invalidate()
561 560 result = context.compute()
562 561
563 562 assert invalidated == True
564 563 assert 'result' == result
565 564 assert isinstance(context, caches.FreshRegionCache)
566 565
567 566 assert 'InvalidationContext' in repr(invalidator_context)
568 567
569 568 with invalidator_context as context:
570 569 context.invalidate()
571 570 result = context.compute()
572 571
573 572 assert 'result' == result
574 573 assert isinstance(context, caches.ActiveRegionCache)
575 574
576 575
577 576 def test_invalidation_context_exception_in_compute(pylonsapp):
578 577 from rhodecode.model.db import CacheKey
579 578 from beaker.cache import cache_region
580 579
581 580 @cache_region('long_term')
582 581 def _dummy_func(cache_key):
583 582 # this causes error since it doesn't get any params
584 583 raise Exception('ups')
585 584
586 585 invalidator_context = CacheKey.repo_context_cache(
587 586 _dummy_func, 'test_repo_2', 'repo')
588 587
589 588 with pytest.raises(Exception):
590 589 with invalidator_context as context:
591 590 context.invalidate()
592 591 context.compute()
593 592
594 593
595 594 @pytest.mark.parametrize('execution_number', range(5))
596 595 def test_cache_invalidation_race_condition(execution_number, pylonsapp):
597 596 import time
598 597 from beaker.cache import cache_region
599 598 from rhodecode.model.db import CacheKey
600 599
601 600 if CacheKey.metadata.bind.url.get_backend_name() == "mysql":
602 601 reason = (
603 602 'Fails on MariaDB due to some locking issues. Investigation'
604 603 ' needed')
605 604 pytest.xfail(reason=reason)
606 605
607 606 @run_test_concurrently(25)
608 607 def test_create_and_delete_cache_keys():
609 608 time.sleep(0.2)
610 609
611 610 @cache_region('long_term')
612 611 def _dummy_func(cache_key):
613 612 return 'result'
614 613
615 614 invalidator_context = CacheKey.repo_context_cache(
616 615 _dummy_func, 'test_repo_1', 'repo')
617 616
618 617 with invalidator_context as context:
619 618 context.invalidate()
620 619 context.compute()
621 620
622 621 CacheKey.set_invalidate('test_repo_1', delete=True)
623 622
624 623 test_create_and_delete_cache_keys()
General Comments 0
You need to be logged in to leave comments. Login now