Files @ 6a9f82696750
Branch filter:

Location: kallithea/kallithea/tests/other/test_libs.py

Thomas De Schampheleire
tests: introduce test_context to handle internationalization

As preparation to the migration to Turbogears2, introduce a test_context
context manager to wrap certain tests. The context manager provides a
translator for tests that need it. This translator was previously provided
globally to all tests via the TestController.

When swapping Pylons with Turbogears2, the new file
kallithea/tests/test_context.py can be removed, and the test_context from
tg2/tg/util/webtest.py should be used.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
# -*- coding: utf-8 -*-
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
"""
kallithea.tests.other.test_libs
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Package for testing various lib/helper functions in kallithea

This file was forked by the Kallithea project in July 2014.
Original author and date, and relevant copyright and licensing information is below:
:created_on: Jun 9, 2011
:author: marcink
:copyright: (c) 2013 RhodeCode GmbH, and others.
:license: GPLv3, see LICENSE.md for more details.
"""

import datetime
import hashlib
import mock
from kallithea.tests.base import *
from kallithea.lib.utils2 import AttributeDict
from kallithea.model.db import Repository

proto = 'http'
TEST_URLS = [
    ('%s://127.0.0.1' % proto, ['%s://' % proto, '127.0.0.1'],
     '%s://127.0.0.1' % proto),
    ('%s://username@127.0.0.1' % proto, ['%s://' % proto, '127.0.0.1'],
     '%s://127.0.0.1' % proto),
    ('%s://username:pass@127.0.0.1' % proto, ['%s://' % proto, '127.0.0.1'],
     '%s://127.0.0.1' % proto),
    ('%s://127.0.0.1:8080' % proto, ['%s://' % proto, '127.0.0.1', '8080'],
     '%s://127.0.0.1:8080' % proto),
    ('%s://example.com' % proto, ['%s://' % proto, 'example.com'],
     '%s://example.com' % proto),
    ('%s://user:pass@example.com:8080' % proto, ['%s://' % proto, 'example.com',
                                                '8080'],
     '%s://example.com:8080' % proto),
]

proto = 'https'
TEST_URLS += [
    ('%s://127.0.0.1' % proto, ['%s://' % proto, '127.0.0.1'],
     '%s://127.0.0.1' % proto),
    ('%s://username@127.0.0.1' % proto, ['%s://' % proto, '127.0.0.1'],
     '%s://127.0.0.1' % proto),
    ('%s://username:pass@127.0.0.1' % proto, ['%s://' % proto, '127.0.0.1'],
     '%s://127.0.0.1' % proto),
    ('%s://127.0.0.1:8080' % proto, ['%s://' % proto, '127.0.0.1', '8080'],
     '%s://127.0.0.1:8080' % proto),
    ('%s://example.com' % proto, ['%s://' % proto, 'example.com'],
     '%s://example.com' % proto),
    ('%s://user:pass@example.com:8080' % proto, ['%s://' % proto, 'example.com',
                                                '8080'],
     '%s://example.com:8080' % proto),
]

class FakeUrlGenerator(object):

    def __init__(self, current_url=None, default_route=None, **routes):
        """Initialize using specified 'current' URL template,
        default route template, and all other aguments describing known
        routes (format: route=template)"""
        self.current_url = current_url
        self.default_route = default_route
        self.routes = routes

    def __call__(self, route_name, *args, **kwargs):
        if route_name in self.routes:
            return self.routes[route_name] % kwargs

        return self.default_route % kwargs

    def current(self, *args, **kwargs):
        return self.current_url % kwargs

class TestLibs(TestController):

    @parametrize('test_url,expected,expected_creds', TEST_URLS)
    def test_uri_filter(self, test_url, expected, expected_creds):
        from kallithea.lib.utils2 import uri_filter
        assert uri_filter(test_url) == expected

    @parametrize('test_url,expected,expected_creds', TEST_URLS)
    def test_credentials_filter(self, test_url, expected, expected_creds):
        from kallithea.lib.utils2 import credentials_filter
        assert credentials_filter(test_url) == expected_creds

    @parametrize('str_bool,expected', [
                           ('t', True),
                           ('true', True),
                           ('y', True),
                           ('yes', True),
                           ('on', True),
                           ('1', True),
                           ('Y', True),
                           ('yeS', True),
                           ('Y', True),
                           ('TRUE', True),
                           ('T', True),
                           ('False', False),
                           ('F', False),
                           ('FALSE', False),
                           ('0', False),
                           ('-1', False),
                           ('', False)
    ])
    def test_str2bool(self, str_bool, expected):
        from kallithea.lib.utils2 import str2bool
        assert str2bool(str_bool) == expected

    def test_mention_extractor(self):
        from kallithea.lib.utils2 import extract_mentioned_usernames
        sample = (
            "@first hi there @world here's my email username@example.com "
            "@lukaszb check @one_more22 it pls @ ttwelve @D[] @one@two@three "
            "@UPPER    @cAmEL @2one_more22 @john please see this http://org.pl "
            "@marian.user just do it @marco-polo and next extract @marco_polo "
            "user.dot  hej ! not-needed maril@example.com"
        )

        expected = set([
            '2one_more22', 'first', 'lukaszb', 'one', 'one_more22', 'UPPER', 'cAmEL', 'john',
            'marian.user', 'marco-polo', 'marco_polo', 'world'])
        assert expected == set(extract_mentioned_usernames(sample))

    @parametrize('age_args,expected', [
        (dict(), u'just now'),
        (dict(seconds= -1), u'1 second ago'),
        (dict(seconds= -60 * 2), u'2 minutes ago'),
        (dict(hours= -1), u'1 hour ago'),
        (dict(hours= -24), u'1 day ago'),
        (dict(hours= -24 * 5), u'5 days ago'),
        (dict(months= -1), u'1 month ago'),
        (dict(months= -1, days= -2), u'1 month and 2 days ago'),
        (dict(months= -1, days= -20), u'1 month and 19 days ago'),
        (dict(years= -1, months= -1), u'1 year and 1 month ago'),
        (dict(years= -1, months= -10), u'1 year and 10 months ago'),
        (dict(years= -2, months= -4), u'2 years and 4 months ago'),
        (dict(years= -2, months= -11), u'2 years and 11 months ago'),
        (dict(years= -3, months= -2), u'3 years and 2 months ago'),
    ])
    def test_age(self, age_args, expected):
        from kallithea.lib.utils2 import age
        from dateutil import relativedelta
        n = datetime.datetime(year=2012, month=5, day=17)
        delt = lambda *args, **kwargs: relativedelta.relativedelta(*args, **kwargs)
        assert age(n + delt(**age_args), now=n) == expected

    @parametrize('age_args,expected', [
        (dict(), u'just now'),
        (dict(seconds= -1), u'1 second ago'),
        (dict(seconds= -60 * 2), u'2 minutes ago'),
        (dict(hours= -1), u'1 hour ago'),
        (dict(hours= -24), u'1 day ago'),
        (dict(hours= -24 * 5), u'5 days ago'),
        (dict(months= -1), u'1 month ago'),
        (dict(months= -1, days= -2), u'1 month ago'),
        (dict(months= -1, days= -20), u'1 month ago'),
        (dict(years= -1, months= -1), u'13 months ago'),
        (dict(years= -1, months= -10), u'22 months ago'),
        (dict(years= -2, months= -4), u'2 years ago'),
        (dict(years= -2, months= -11), u'3 years ago'),
        (dict(years= -3, months= -2), u'3 years ago'),
        (dict(years= -4, months= -8), u'5 years ago'),
    ])
    def test_age_short(self, age_args, expected):
        from kallithea.lib.utils2 import age
        from dateutil import relativedelta
        n = datetime.datetime(year=2012, month=5, day=17)
        delt = lambda *args, **kwargs: relativedelta.relativedelta(*args, **kwargs)
        assert age(n + delt(**age_args), show_short_version=True, now=n) == expected

    @parametrize('age_args,expected', [
        (dict(), u'just now'),
        (dict(seconds=1), u'in 1 second'),
        (dict(seconds=60 * 2), u'in 2 minutes'),
        (dict(hours=1), u'in 1 hour'),
        (dict(hours=24), u'in 1 day'),
        (dict(hours=24 * 5), u'in 5 days'),
        (dict(months=1), u'in 1 month'),
        (dict(months=1, days=1), u'in 1 month and 1 day'),
        (dict(years=1, months=1), u'in 1 year and 1 month')
    ])
    def test_age_in_future(self, age_args, expected):
        from kallithea.lib.utils2 import age
        from dateutil import relativedelta
        n = datetime.datetime(year=2012, month=5, day=17)
        delt = lambda *args, **kwargs: relativedelta.relativedelta(*args, **kwargs)
        assert age(n + delt(**age_args), now=n) == expected

    def test_tag_extractor(self):
        sample = (
            "hello pta[tag] gog [[]] [[] sda ero[or]d [me =>>< sa]"
            "[requires] [stale] [see<>=>] [see => http://example.com]"
            "[requires => url] [lang => python] [just a tag]"
            "[,d] [ => ULR ] [obsolete] [desc]]"
        )
        from kallithea.lib.helpers import urlify_text
        res = urlify_text(sample, stylize=True)
        assert '<div class="metatag" tag="tag">tag</div>' in res
        assert '<div class="metatag" tag="obsolete">obsolete</div>' in res
        assert '<div class="metatag" tag="stale">stale</div>' in res
        assert '<div class="metatag" tag="lang">python</div>' in res
        assert '<div class="metatag" tag="requires">requires =&gt; <a href="/url">url</a></div>' in res
        assert '<div class="metatag" tag="tag">tag</div>' in res

    def test_alternative_gravatar(self):
        from kallithea.lib.helpers import gravatar_url
        _md5 = lambda s: hashlib.md5(s).hexdigest()

        #mock pylons.tmpl_context
        def fake_tmpl_context(_url):
            _c = AttributeDict()
            _c.visual = AttributeDict()
            _c.visual.use_gravatar = True
            _c.visual.gravatar_url = _url

            return _c

        fake_url = FakeUrlGenerator(current_url='https://example.com')
        with mock.patch('kallithea.config.routing.url', fake_url):
            fake = fake_tmpl_context(_url='http://example.com/{email}')
            with mock.patch('pylons.tmpl_context', fake):
                    from kallithea.config.routing import url
                    assert url.current() == 'https://example.com'
                    grav = gravatar_url(email_address='test@example.com', size=24)
                    assert grav == 'http://example.com/test@example.com'

            fake = fake_tmpl_context(_url='http://example.com/{email}')
            with mock.patch('pylons.tmpl_context', fake):
                grav = gravatar_url(email_address='test@example.com', size=24)
                assert grav == 'http://example.com/test@example.com'

            fake = fake_tmpl_context(_url='http://example.com/{md5email}')
            with mock.patch('pylons.tmpl_context', fake):
                em = 'test@example.com'
                grav = gravatar_url(email_address=em, size=24)
                assert grav == 'http://example.com/%s' % (_md5(em))

            fake = fake_tmpl_context(_url='http://example.com/{md5email}/{size}')
            with mock.patch('pylons.tmpl_context', fake):
                em = 'test@example.com'
                grav = gravatar_url(email_address=em, size=24)
                assert grav == 'http://example.com/%s/%s' % (_md5(em), 24)

            fake = fake_tmpl_context(_url='{scheme}://{netloc}/{md5email}/{size}')
            with mock.patch('pylons.tmpl_context', fake):
                em = 'test@example.com'
                grav = gravatar_url(email_address=em, size=24)
                assert grav == 'https://example.com/%s/%s' % (_md5(em), 24)

    @parametrize('tmpl,repo_name,overrides,prefix,expected', [
        (Repository.DEFAULT_CLONE_URI, 'group/repo1', {}, '', 'http://vps1:8000/group/repo1'),
        (Repository.DEFAULT_CLONE_URI, 'group/repo1', {'user': 'username'}, '', 'http://username@vps1:8000/group/repo1'),
        (Repository.DEFAULT_CLONE_URI, 'group/repo1', {}, '/prefix', 'http://vps1:8000/prefix/group/repo1'),
        (Repository.DEFAULT_CLONE_URI, 'group/repo1', {'user': 'user'}, '/prefix', 'http://user@vps1:8000/prefix/group/repo1'),
        (Repository.DEFAULT_CLONE_URI, 'group/repo1', {'user': 'username'}, '/prefix', 'http://username@vps1:8000/prefix/group/repo1'),
        (Repository.DEFAULT_CLONE_URI, 'group/repo1', {'user': 'user'}, '/prefix/', 'http://user@vps1:8000/prefix/group/repo1'),
        (Repository.DEFAULT_CLONE_URI, 'group/repo1', {'user': 'username'}, '/prefix/', 'http://username@vps1:8000/prefix/group/repo1'),
        ('{scheme}://{user}@{netloc}/_{repoid}', 'group/repo1', {}, '', 'http://vps1:8000/_23'),
        ('{scheme}://{user}@{netloc}/_{repoid}', 'group/repo1', {'user': 'username'}, '', 'http://username@vps1:8000/_23'),
        ('http://{user}@{netloc}/_{repoid}', 'group/repo1', {'user': 'username'}, '', 'http://username@vps1:8000/_23'),
        ('http://{netloc}/_{repoid}', 'group/repo1', {'user': 'username'}, '', 'http://vps1:8000/_23'),
        ('https://{user}@proxy1.example.com/{repo}', 'group/repo1', {'user': 'username'}, '', 'https://username@proxy1.example.com/group/repo1'),
        ('https://{user}@proxy1.example.com/{repo}', 'group/repo1', {}, '', 'https://proxy1.example.com/group/repo1'),
        ('https://proxy1.example.com/{user}/{repo}', 'group/repo1', {'user': 'username'}, '', 'https://proxy1.example.com/username/group/repo1'),
    ])
    def test_clone_url_generator(self, tmpl, repo_name, overrides, prefix, expected):
        from kallithea.lib.utils2 import get_clone_url
        clone_url = get_clone_url(uri_tmpl=tmpl, qualified_home_url='http://vps1:8000'+prefix,
                                  repo_name=repo_name, repo_id=23, **overrides)
        assert clone_url == expected

    def _quick_url(self, text, tmpl="""<a class="revision-link" href="%s">%s</a>""", url_=None):
        """
        Changes `some text url[foo]` => `some text <a href="/">foo</a>

        :param text:
        """
        import re
        # quickly change expected url[] into a link
        URL_PAT = re.compile(r'(?:url\[)(.+?)(?:\])')

        def url_func(match_obj):
            _url = match_obj.groups()[0]
            return tmpl % (url_ or '/repo_name/changeset/%s' % _url, _url)
        return URL_PAT.sub(url_func, text)

    @parametrize('sample,expected', [
      ("",
       ""),
      ("git-svn-id: https://svn.apache.org/repos/asf/libcloud/trunk@1441655 13f79535-47bb-0310-9956-ffa450edef68",
       """git-svn-id: <a href="https://svn.apache.org/repos/asf/libcloud/trunk@1441655">https://svn.apache.org/repos/asf/libcloud/trunk@1441655</a> 13f79535-47bb-0310-9956-ffa450edef68"""),
      ("from rev 000000000000",
       """from rev url[000000000000]"""),
      ("from rev 000000000000123123 also rev 000000000000",
       """from rev url[000000000000123123] also rev url[000000000000]"""),
      ("this should-000 00",
       """this should-000 00"""),
      ("longtextffffffffff rev 123123123123",
       """longtextffffffffff rev url[123123123123]"""),
      ("rev ffffffffffffffffffffffffffffffffffffffffffffffffff",
       """rev ffffffffffffffffffffffffffffffffffffffffffffffffff"""),
      ("ffffffffffff some text traalaa",
       """url[ffffffffffff] some text traalaa"""),
       ("""Multi line
       123123123123
       some text 123123123123
       sometimes !
       """,
       """Multi line<br/>"""
       """       url[123123123123]<br/>"""
       """       some text url[123123123123]<br/>"""
       """       sometimes !"""),
    ])
    def test_urlify_text(self, sample, expected):
        expected = self._quick_url(expected)
        fake_url = FakeUrlGenerator(changeset_home='/%(repo_name)s/changeset/%(revision)s')
        with mock.patch('kallithea.config.routing.url', fake_url):
            from kallithea.lib.helpers import urlify_text
            assert urlify_text(sample, 'repo_name') == expected

    @parametrize('sample,expected,url_', [
      ("",
       "",
       ""),
      ("https://svn.apache.org/repos",
       """url[https://svn.apache.org/repos]""",
       "https://svn.apache.org/repos"),
      ("http://svn.apache.org/repos",
       """url[http://svn.apache.org/repos]""",
       "http://svn.apache.org/repos"),
      ("from rev a also rev http://google.com",
       """from rev a also rev url[http://google.com]""",
       "http://google.com"),
      ("http://imgur.com/foo.gif inline http://imgur.com/foo.gif ending http://imgur.com/foo.gif",
       """url[http://imgur.com/foo.gif] inline url[http://imgur.com/foo.gif] ending url[http://imgur.com/foo.gif]""",
       "http://imgur.com/foo.gif"),
      ("""Multi line
       https://foo.bar.example.com
       some text lalala""",
       """Multi line<br/>"""
       """       url[https://foo.bar.example.com]<br/>"""
       """       some text lalala""",
       "https://foo.bar.example.com"),
      ("@mention @someone",
       """<b>@mention</b> <b>@someone</b>""",
       ""),
      ("deadbeefcafe 123412341234",
       """<a class="revision-link" href="/repo_name/changeset/deadbeefcafe">deadbeefcafe</a> <a class="revision-link" href="/repo_name/changeset/123412341234">123412341234</a>""",
       ""),
      ("We support * markup for *bold* markup of *single or multiple* words, "
       "*a bit @like http://slack.com*. "
       "The first * must come after whitespace and not be followed by whitespace, "
       "contain anything but * and newline until the next *, "
       "which must not come after whitespace "
       "and not be followed by * or alphanumerical *characters*.",
       """We support * markup for <b>*bold*</b> markup of <b>*single or multiple*</b> words, """
       """<b>*a bit <b>@like</b> <a href="http://slack.com">http://slack.com</a>*</b>. """
       """The first * must come after whitespace and not be followed by whitespace, """
       """contain anything but * and newline until the next *, """
       """which must not come after whitespace """
       """and not be followed by * or alphanumerical <b>*characters*</b>.""",
       "-"),
      # tags are covered by test_tag_extractor
    ])
    def test_urlify_test(self, sample, expected, url_):
        expected = self._quick_url(expected,
                                   tmpl="""<a href="%s">%s</a>""", url_=url_)
        fake_url = FakeUrlGenerator(changeset_home='/%(repo_name)s/changeset/%(revision)s')
        with mock.patch('kallithea.config.routing.url', fake_url):
            from kallithea.lib.helpers import urlify_text
            assert urlify_text(sample, 'repo_name', stylize=True) == expected

    @parametrize('sample,expected', [
      ("deadbeefcafe @mention, and http://foo.bar/ yo",
       """<a class="revision-link" href="/repo_name/changeset/deadbeefcafe">deadbeefcafe</a>"""
       """<a class="message-link" href="#the-link"> <b>@mention</b>, and </a>"""
       """<a href="http://foo.bar/">http://foo.bar/</a>"""
       """<a class="message-link" href="#the-link"> yo</a>"""),
    ])
    def test_urlify_link(self, sample, expected):
        fake_url = FakeUrlGenerator(changeset_home='/%(repo_name)s/changeset/%(revision)s')
        with mock.patch('kallithea.config.routing.url', fake_url):
            from kallithea.lib.helpers import urlify_text
            assert urlify_text(sample, 'repo_name', link_='#the-link') == expected

    @parametrize('test,expected', [
      ("", None),
      ("/_2", '2'),
      ("_2", '2'),
      ("/_2/", '2'),
      ("_2/", '2'),

      ("/_21", '21'),
      ("_21", '21'),
      ("/_21/", '21'),
      ("_21/", '21'),

      ("/_21/foobar", '21'),
      ("_21/121", '21'),
      ("/_21/_12", '21'),
      ("_21/prefix/foo", '21'),
    ])
    def test_get_repo_by_id(self, test, expected):
        from kallithea.lib.utils import _extract_id_from_repo_name
        _test = _extract_id_from_repo_name(test)
        assert _test == expected, 'url:%s, got:`%s` expected: `%s`' % (test, _test, expected)