##// END OF EJS Templates
dependencies: dropped nose dependency.
marcink -
r2278:607b09b1 default
parent child Browse files
Show More
@@ -1,137 +1,136 b''
1 ## core
1 ## core
2 setuptools==30.1.0
2 setuptools==30.1.0
3 setuptools-scm==1.15.0
3 setuptools-scm==1.15.0
4
4
5 amqplib==1.0.2
5 amqplib==1.0.2
6 anyjson==0.3.3
6 anyjson==0.3.3
7 authomatic==0.1.0.post1
7 authomatic==0.1.0.post1
8 Babel==1.3
8 Babel==1.3
9 Beaker==1.9.0
9 Beaker==1.9.0
10 celery==2.2.10
10 celery==2.2.10
11 Chameleon==2.24
11 Chameleon==2.24
12 channelstream==0.5.2
12 channelstream==0.5.2
13 click==5.1
13 click==5.1
14 colander==1.3.3
14 colander==1.3.3
15 configobj==5.0.6
15 configobj==5.0.6
16 cssselect==1.0.1
16 cssselect==1.0.1
17 decorator==4.0.11
17 decorator==4.0.11
18 deform==2.0.4
18 deform==2.0.4
19 docutils==0.13.1
19 docutils==0.13.1
20 dogpile.cache==0.6.4
20 dogpile.cache==0.6.4
21 dogpile.core==0.4.1
21 dogpile.core==0.4.1
22 ecdsa==0.13
22 ecdsa==0.13
23 FormEncode==1.2.4
23 FormEncode==1.2.4
24 future==0.14.3
24 future==0.14.3
25 futures==3.0.2
25 futures==3.0.2
26 gnureadline==6.3.3
26 gnureadline==6.3.3
27 infrae.cache==1.0.1
27 infrae.cache==1.0.1
28 iso8601==0.1.11
28 iso8601==0.1.11
29 itsdangerous==0.24
29 itsdangerous==0.24
30 Jinja2==2.7.3
30 Jinja2==2.7.3
31 kombu==1.5.1
31 kombu==1.5.1
32 lxml==3.7.3
32 lxml==3.7.3
33 Mako==1.0.7
33 Mako==1.0.7
34 Markdown==2.6.8
34 Markdown==2.6.8
35 MarkupSafe==0.23
35 MarkupSafe==0.23
36 meld3==1.0.2
36 meld3==1.0.2
37 msgpack-python==0.4.8
37 msgpack-python==0.4.8
38 MySQL-python==1.2.5
38 MySQL-python==1.2.5
39 nose==1.3.6
40 objgraph==3.1.0
39 objgraph==3.1.0
41 packaging==15.2
40 packaging==15.2
42 Paste==2.0.3
41 Paste==2.0.3
43 PasteDeploy==1.5.2
42 PasteDeploy==1.5.2
44 PasteScript==1.7.5
43 PasteScript==1.7.5
45 pathlib2==2.3.0
44 pathlib2==2.3.0
46 peppercorn==0.5
45 peppercorn==0.5
47 psutil==4.3.1
46 psutil==4.3.1
48 psycopg2==2.7.1
47 psycopg2==2.7.1
49 py-bcrypt==0.4
48 py-bcrypt==0.4
50 pycrypto==2.6.1
49 pycrypto==2.6.1
51 pycurl==7.19.5
50 pycurl==7.19.5
52 pyflakes==0.8.1
51 pyflakes==0.8.1
53 pygments-markdown-lexer==0.1.0.dev39
52 pygments-markdown-lexer==0.1.0.dev39
54 Pygments==2.2.0
53 Pygments==2.2.0
55 pyparsing==1.5.7
54 pyparsing==1.5.7
56 pyramid-beaker==0.8
55 pyramid-beaker==0.8
57 pyramid-jinja2==2.5
56 pyramid-jinja2==2.5
58 pyramid-debugtoolbar==4.3.0
57 pyramid-debugtoolbar==4.3.0
59 pyramid-mako==1.0.2
58 pyramid-mako==1.0.2
60 pyramid==1.9.1
59 pyramid==1.9.1
61 pysqlite==2.8.3
60 pysqlite==2.8.3
62 python-dateutil==2.1
61 python-dateutil==2.1
63 python-ldap==2.4.40
62 python-ldap==2.4.40
64 python-memcached==1.58
63 python-memcached==1.58
65 python-pam==1.8.2
64 python-pam==1.8.2
66 pytz==2015.4
65 pytz==2015.4
67 pyzmq==14.6.0
66 pyzmq==14.6.0
68 recaptcha-client==1.0.6
67 recaptcha-client==1.0.6
69 redis==2.10.6
68 redis==2.10.6
70 repoze.lru==0.6
69 repoze.lru==0.6
71 requests==2.9.1
70 requests==2.9.1
72 Routes==1.13
71 Routes==1.13
73 setproctitle==1.1.8
72 setproctitle==1.1.8
74 simplejson==3.11.1
73 simplejson==3.11.1
75 six==1.9.0
74 six==1.9.0
76 SQLAlchemy==1.1.11
75 SQLAlchemy==1.1.11
77 sshpubkeys==2.2.0
76 sshpubkeys==2.2.0
78 subprocess32==3.2.7
77 subprocess32==3.2.7
79 supervisor==3.3.3
78 supervisor==3.3.3
80 Tempita==0.5.2
79 Tempita==0.5.2
81 translationstring==1.3
80 translationstring==1.3
82 trollius==1.0.4
81 trollius==1.0.4
83 urllib3==1.16
82 urllib3==1.16
84 URLObject==2.4.0
83 URLObject==2.4.0
85 venusian==1.1.0
84 venusian==1.1.0
86 WebError==0.10.3
85 WebError==0.10.3
87 WebHelpers2==2.0
86 WebHelpers2==2.0
88 WebHelpers==1.3
87 WebHelpers==1.3
89 WebOb==1.7.3
88 WebOb==1.7.3
90 Whoosh==2.7.4
89 Whoosh==2.7.4
91 wsgiref==0.1.2
90 wsgiref==0.1.2
92 zope.cachedescriptors==4.0.0
91 zope.cachedescriptors==4.0.0
93 zope.deprecation==4.1.2
92 zope.deprecation==4.1.2
94 zope.event==4.0.3
93 zope.event==4.0.3
95 zope.interface==4.1.3
94 zope.interface==4.1.3
96
95
97 ## customized/patched libs
96 ## customized/patched libs
98 # our patched version of Pylons==1.0.2
97 # our patched version of Pylons==1.0.2
99 https://code.rhodecode.com/upstream/pylons/archive/707354ee4261b9c10450404fc9852ccea4fd667d.tar.gz?md5=f26633726fa2cd3a340316ee6a5d218f#egg=Pylons==1.0.2.rhodecode-patch-1
98 https://code.rhodecode.com/upstream/pylons/archive/707354ee4261b9c10450404fc9852ccea4fd667d.tar.gz?md5=f26633726fa2cd3a340316ee6a5d218f#egg=Pylons==1.0.2.rhodecode-patch-1
100 # not released py-gfm==0.1.3
99 # not released py-gfm==0.1.3
101 https://code.rhodecode.com/upstream/py-gfm/archive/0d66a19bc16e3d49de273c0f797d4e4781e8c0f2.tar.gz?md5=0d0d5385bfb629eea636a80b9c2bfd16#egg=py-gfm==0.1.3.rhodecode-upstream1
100 https://code.rhodecode.com/upstream/py-gfm/archive/0d66a19bc16e3d49de273c0f797d4e4781e8c0f2.tar.gz?md5=0d0d5385bfb629eea636a80b9c2bfd16#egg=py-gfm==0.1.3.rhodecode-upstream1
102
101
103 # IPYTHON RENDERING
102 # IPYTHON RENDERING
104 # entrypoints backport, pypi version doesn't support egg installs
103 # entrypoints backport, pypi version doesn't support egg installs
105 https://code.rhodecode.com/upstream/entrypoints/archive/96e6d645684e1af3d7df5b5272f3fe85a546b233.tar.gz?md5=7db37771aea9ac9fefe093e5d6987313#egg=entrypoints==0.2.2.rhodecode-upstream1
104 https://code.rhodecode.com/upstream/entrypoints/archive/96e6d645684e1af3d7df5b5272f3fe85a546b233.tar.gz?md5=7db37771aea9ac9fefe093e5d6987313#egg=entrypoints==0.2.2.rhodecode-upstream1
106 nbconvert==5.1.1
105 nbconvert==5.1.1
107 bleach==1.5.0
106 bleach==1.5.0
108 nbformat==4.3.0
107 nbformat==4.3.0
109 jupyter_client==5.0.0
108 jupyter_client==5.0.0
110
109
111 ## cli tools
110 ## cli tools
112 alembic==0.9.2
111 alembic==0.9.2
113 invoke==0.13.0
112 invoke==0.13.0
114 bumpversion==0.5.3
113 bumpversion==0.5.3
115 transifex-client==0.10
114 transifex-client==0.10
116
115
117 ## http servers
116 ## http servers
118 gevent==1.2.2
117 gevent==1.2.2
119 greenlet==0.4.12
118 greenlet==0.4.12
120 gunicorn==19.7.1
119 gunicorn==19.7.1
121 waitress==1.0.2
120 waitress==1.0.2
122 uWSGI==2.0.15
121 uWSGI==2.0.15
123
122
124 ## debug
123 ## debug
125 ipdb==0.10.3
124 ipdb==0.10.3
126 ipython==5.1.0
125 ipython==5.1.0
127 CProfileV==1.0.7
126 CProfileV==1.0.7
128 bottle==0.12.8
127 bottle==0.12.8
129
128
130 ## rhodecode-tools, special case
129 ## rhodecode-tools, special case
131 https://code.rhodecode.com/rhodecode-tools-ce/archive/v0.13.0.tar.gz?md5=f937b0cb34d0779103895a5ec5689ee4#egg=rhodecode-tools==0.13.0
130 https://code.rhodecode.com/rhodecode-tools-ce/archive/v0.13.0.tar.gz?md5=f937b0cb34d0779103895a5ec5689ee4#egg=rhodecode-tools==0.13.0
132
131
133 ## appenlight
132 ## appenlight
134 appenlight-client==0.6.21
133 appenlight-client==0.6.21
135
134
136 ## test related requirements
135 ## test related requirements
137 -r requirements_test.txt
136 -r requirements_test.txt
@@ -1,202 +1,202 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2017 RhodeCode GmbH
3 # Copyright (C) 2010-2017 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import os
21 import os
22
22
23 import mock
23 import mock
24 import pytest
24 import pytest
25 from whoosh import query
25 from whoosh import query
26
26
27 from rhodecode.tests import (
27 from rhodecode.tests import (
28 TestController, SkipTest, HG_REPO,
28 TestController, HG_REPO,
29 TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS)
29 TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS)
30 from rhodecode.tests.utils import AssertResponse
30 from rhodecode.tests.utils import AssertResponse
31
31
32
32
33 def route_path(name, **kwargs):
33 def route_path(name, **kwargs):
34 from rhodecode.apps._base import ADMIN_PREFIX
34 from rhodecode.apps._base import ADMIN_PREFIX
35 return {
35 return {
36 'search':
36 'search':
37 ADMIN_PREFIX + '/search',
37 ADMIN_PREFIX + '/search',
38 'search_repo':
38 'search_repo':
39 '/{repo_name}/search',
39 '/{repo_name}/search',
40
40
41 }[name].format(**kwargs)
41 }[name].format(**kwargs)
42
42
43
43
44 class TestSearchController(TestController):
44 class TestSearchController(TestController):
45
45
46 def test_index(self):
46 def test_index(self):
47 self.log_user()
47 self.log_user()
48 response = self.app.get(route_path('search'))
48 response = self.app.get(route_path('search'))
49 assert_response = AssertResponse(response)
49 assert_response = AssertResponse(response)
50 assert_response.one_element_exists('input#q')
50 assert_response.one_element_exists('input#q')
51
51
52 def test_search_files_empty_search(self):
52 def test_search_files_empty_search(self):
53 if os.path.isdir(self.index_location):
53 if os.path.isdir(self.index_location):
54 raise SkipTest('skipped due to existing index')
54 pytest.skip('skipped due to existing index')
55 else:
55 else:
56 self.log_user()
56 self.log_user()
57 response = self.app.get(route_path('search'),
57 response = self.app.get(route_path('search'),
58 {'q': HG_REPO})
58 {'q': HG_REPO})
59 response.mustcontain('There is no index to search in. '
59 response.mustcontain('There is no index to search in. '
60 'Please run whoosh indexer')
60 'Please run whoosh indexer')
61
61
62 def test_search_validation(self):
62 def test_search_validation(self):
63 self.log_user()
63 self.log_user()
64 response = self.app.get(route_path('search'),
64 response = self.app.get(route_path('search'),
65 {'q': query, 'type': 'content', 'page_limit': 1000})
65 {'q': query, 'type': 'content', 'page_limit': 1000})
66
66
67 response.mustcontain(
67 response.mustcontain(
68 'page_limit - 1000 is greater than maximum value 500')
68 'page_limit - 1000 is greater than maximum value 500')
69
69
70 @pytest.mark.parametrize("query, expected_hits, expected_paths", [
70 @pytest.mark.parametrize("query, expected_hits, expected_paths", [
71 ('todo', 23, [
71 ('todo', 23, [
72 'vcs/backends/hg/inmemory.py',
72 'vcs/backends/hg/inmemory.py',
73 'vcs/tests/test_git.py']),
73 'vcs/tests/test_git.py']),
74 ('extension:rst installation', 6, [
74 ('extension:rst installation', 6, [
75 'docs/index.rst',
75 'docs/index.rst',
76 'docs/installation.rst']),
76 'docs/installation.rst']),
77 ('def repo', 87, [
77 ('def repo', 87, [
78 'vcs/tests/test_git.py',
78 'vcs/tests/test_git.py',
79 'vcs/tests/test_changesets.py']),
79 'vcs/tests/test_changesets.py']),
80 ('repository:%s def test' % HG_REPO, 18, [
80 ('repository:%s def test' % HG_REPO, 18, [
81 'vcs/tests/test_git.py',
81 'vcs/tests/test_git.py',
82 'vcs/tests/test_changesets.py']),
82 'vcs/tests/test_changesets.py']),
83 ('"def main"', 9, [
83 ('"def main"', 9, [
84 'vcs/__init__.py',
84 'vcs/__init__.py',
85 'vcs/tests/__init__.py',
85 'vcs/tests/__init__.py',
86 'vcs/utils/progressbar.py']),
86 'vcs/utils/progressbar.py']),
87 ('owner:test_admin', 358, [
87 ('owner:test_admin', 358, [
88 'vcs/tests/base.py',
88 'vcs/tests/base.py',
89 'MANIFEST.in',
89 'MANIFEST.in',
90 'vcs/utils/termcolors.py',
90 'vcs/utils/termcolors.py',
91 'docs/theme/ADC/static/documentation.png']),
91 'docs/theme/ADC/static/documentation.png']),
92 ('owner:test_admin def main', 72, [
92 ('owner:test_admin def main', 72, [
93 'vcs/__init__.py',
93 'vcs/__init__.py',
94 'vcs/tests/test_utils_filesize.py',
94 'vcs/tests/test_utils_filesize.py',
95 'vcs/tests/test_cli.py']),
95 'vcs/tests/test_cli.py']),
96 ('owner:michaΕ‚ test', 0, []),
96 ('owner:michaΕ‚ test', 0, []),
97 ])
97 ])
98 def test_search_files(self, query, expected_hits, expected_paths):
98 def test_search_files(self, query, expected_hits, expected_paths):
99 self.log_user()
99 self.log_user()
100 response = self.app.get(route_path('search'),
100 response = self.app.get(route_path('search'),
101 {'q': query, 'type': 'content', 'page_limit': 500})
101 {'q': query, 'type': 'content', 'page_limit': 500})
102
102
103 response.mustcontain('%s results' % expected_hits)
103 response.mustcontain('%s results' % expected_hits)
104 for path in expected_paths:
104 for path in expected_paths:
105 response.mustcontain(path)
105 response.mustcontain(path)
106
106
107 @pytest.mark.parametrize("query, expected_hits, expected_commits", [
107 @pytest.mark.parametrize("query, expected_hits, expected_commits", [
108 ('bother to ask where to fetch repo during tests', 3, [
108 ('bother to ask where to fetch repo during tests', 3, [
109 ('hg', 'a00c1b6f5d7a6ae678fd553a8b81d92367f7ecf1'),
109 ('hg', 'a00c1b6f5d7a6ae678fd553a8b81d92367f7ecf1'),
110 ('git', 'c6eb379775c578a95dad8ddab53f963b80894850'),
110 ('git', 'c6eb379775c578a95dad8ddab53f963b80894850'),
111 ('svn', '98')]),
111 ('svn', '98')]),
112 ('michaΕ‚', 0, []),
112 ('michaΕ‚', 0, []),
113 ('changed:tests/utils.py', 36, [
113 ('changed:tests/utils.py', 36, [
114 ('hg', 'a00c1b6f5d7a6ae678fd553a8b81d92367f7ecf1')]),
114 ('hg', 'a00c1b6f5d7a6ae678fd553a8b81d92367f7ecf1')]),
115 ('changed:vcs/utils/archivers.py', 11, [
115 ('changed:vcs/utils/archivers.py', 11, [
116 ('hg', '25213a5fbb048dff8ba65d21e466a835536e5b70'),
116 ('hg', '25213a5fbb048dff8ba65d21e466a835536e5b70'),
117 ('hg', '47aedd538bf616eedcb0e7d630ea476df0e159c7'),
117 ('hg', '47aedd538bf616eedcb0e7d630ea476df0e159c7'),
118 ('hg', 'f5d23247fad4856a1dabd5838afade1e0eed24fb'),
118 ('hg', 'f5d23247fad4856a1dabd5838afade1e0eed24fb'),
119 ('hg', '04ad456aefd6461aea24f90b63954b6b1ce07b3e'),
119 ('hg', '04ad456aefd6461aea24f90b63954b6b1ce07b3e'),
120 ('git', 'c994f0de03b2a0aa848a04fc2c0d7e737dba31fc'),
120 ('git', 'c994f0de03b2a0aa848a04fc2c0d7e737dba31fc'),
121 ('git', 'd1f898326327e20524fe22417c22d71064fe54a1'),
121 ('git', 'd1f898326327e20524fe22417c22d71064fe54a1'),
122 ('git', 'fe568b4081755c12abf6ba673ba777fc02a415f3'),
122 ('git', 'fe568b4081755c12abf6ba673ba777fc02a415f3'),
123 ('git', 'bafe786f0d8c2ff7da5c1dcfcfa577de0b5e92f1')]),
123 ('git', 'bafe786f0d8c2ff7da5c1dcfcfa577de0b5e92f1')]),
124 ('added:README.rst', 3, [
124 ('added:README.rst', 3, [
125 ('hg', '3803844fdbd3b711175fc3da9bdacfcd6d29a6fb'),
125 ('hg', '3803844fdbd3b711175fc3da9bdacfcd6d29a6fb'),
126 ('git', 'ff7ca51e58c505fec0dd2491de52c622bb7a806b'),
126 ('git', 'ff7ca51e58c505fec0dd2491de52c622bb7a806b'),
127 ('svn', '8')]),
127 ('svn', '8')]),
128 ('changed:lazy.py', 15, [
128 ('changed:lazy.py', 15, [
129 ('hg', 'eaa291c5e6ae6126a203059de9854ccf7b5baa12'),
129 ('hg', 'eaa291c5e6ae6126a203059de9854ccf7b5baa12'),
130 ('git', '17438a11f72b93f56d0e08e7d1fa79a378578a82'),
130 ('git', '17438a11f72b93f56d0e08e7d1fa79a378578a82'),
131 ('svn', '82'),
131 ('svn', '82'),
132 ('svn', '262'),
132 ('svn', '262'),
133 ('hg', 'f5d23247fad4856a1dabd5838afade1e0eed24fb'),
133 ('hg', 'f5d23247fad4856a1dabd5838afade1e0eed24fb'),
134 ('git', '33fa3223355104431402a888fa77a4e9956feb3e')
134 ('git', '33fa3223355104431402a888fa77a4e9956feb3e')
135 ]),
135 ]),
136 ('author:marcin@python-blog.com '
136 ('author:marcin@python-blog.com '
137 'commit_id:b986218ba1c9b0d6a259fac9b050b1724ed8e545', 1, [
137 'commit_id:b986218ba1c9b0d6a259fac9b050b1724ed8e545', 1, [
138 ('hg', 'b986218ba1c9b0d6a259fac9b050b1724ed8e545')]),
138 ('hg', 'b986218ba1c9b0d6a259fac9b050b1724ed8e545')]),
139 ('b986218ba1c9b0d6a259fac9b050b1724ed8e545', 1, [
139 ('b986218ba1c9b0d6a259fac9b050b1724ed8e545', 1, [
140 ('hg', 'b986218ba1c9b0d6a259fac9b050b1724ed8e545')]),
140 ('hg', 'b986218ba1c9b0d6a259fac9b050b1724ed8e545')]),
141 ('b986218b', 1, [
141 ('b986218b', 1, [
142 ('hg', 'b986218ba1c9b0d6a259fac9b050b1724ed8e545')]),
142 ('hg', 'b986218ba1c9b0d6a259fac9b050b1724ed8e545')]),
143 ])
143 ])
144 def test_search_commit_messages(
144 def test_search_commit_messages(
145 self, query, expected_hits, expected_commits, enabled_backends):
145 self, query, expected_hits, expected_commits, enabled_backends):
146 self.log_user()
146 self.log_user()
147 response = self.app.get(route_path('search'),
147 response = self.app.get(route_path('search'),
148 {'q': query, 'type': 'commit', 'page_limit': 500})
148 {'q': query, 'type': 'commit', 'page_limit': 500})
149
149
150 response.mustcontain('%s results' % expected_hits)
150 response.mustcontain('%s results' % expected_hits)
151 for backend, commit_id in expected_commits:
151 for backend, commit_id in expected_commits:
152 if backend in enabled_backends:
152 if backend in enabled_backends:
153 response.mustcontain(commit_id)
153 response.mustcontain(commit_id)
154
154
155 @pytest.mark.parametrize("query, expected_hits, expected_paths", [
155 @pytest.mark.parametrize("query, expected_hits, expected_paths", [
156 ('readme.rst', 3, []),
156 ('readme.rst', 3, []),
157 ('test*', 75, []),
157 ('test*', 75, []),
158 ('*model*', 1, []),
158 ('*model*', 1, []),
159 ('extension:rst', 48, []),
159 ('extension:rst', 48, []),
160 ('extension:rst api', 24, []),
160 ('extension:rst api', 24, []),
161 ])
161 ])
162 def test_search_file_paths(self, query, expected_hits, expected_paths):
162 def test_search_file_paths(self, query, expected_hits, expected_paths):
163 self.log_user()
163 self.log_user()
164 response = self.app.get(route_path('search'),
164 response = self.app.get(route_path('search'),
165 {'q': query, 'type': 'path', 'page_limit': 500})
165 {'q': query, 'type': 'path', 'page_limit': 500})
166
166
167 response.mustcontain('%s results' % expected_hits)
167 response.mustcontain('%s results' % expected_hits)
168 for path in expected_paths:
168 for path in expected_paths:
169 response.mustcontain(path)
169 response.mustcontain(path)
170
170
171 def test_search_commit_message_specific_repo(self, backend):
171 def test_search_commit_message_specific_repo(self, backend):
172 self.log_user()
172 self.log_user()
173 response = self.app.get(
173 response = self.app.get(
174 route_path('search_repo',repo_name=backend.repo_name),
174 route_path('search_repo',repo_name=backend.repo_name),
175 {'q': 'bother to ask where to fetch repo during tests',
175 {'q': 'bother to ask where to fetch repo during tests',
176 'type': 'commit'})
176 'type': 'commit'})
177
177
178 response.mustcontain('1 results')
178 response.mustcontain('1 results')
179
179
180 def test_filters_are_not_applied_for_admin_user(self):
180 def test_filters_are_not_applied_for_admin_user(self):
181 self.log_user()
181 self.log_user()
182 with mock.patch('whoosh.searching.Searcher.search') as search_mock:
182 with mock.patch('whoosh.searching.Searcher.search') as search_mock:
183 self.app.get(route_path('search'),
183 self.app.get(route_path('search'),
184 {'q': 'test query', 'type': 'commit'})
184 {'q': 'test query', 'type': 'commit'})
185 assert search_mock.call_count == 1
185 assert search_mock.call_count == 1
186 _, kwargs = search_mock.call_args
186 _, kwargs = search_mock.call_args
187 assert kwargs['filter'] is None
187 assert kwargs['filter'] is None
188
188
189 def test_filters_are_applied_for_normal_user(self, enabled_backends):
189 def test_filters_are_applied_for_normal_user(self, enabled_backends):
190 self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS)
190 self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS)
191 with mock.patch('whoosh.searching.Searcher.search') as search_mock:
191 with mock.patch('whoosh.searching.Searcher.search') as search_mock:
192 self.app.get(route_path('search'),
192 self.app.get(route_path('search'),
193 {'q': 'test query', 'type': 'commit'})
193 {'q': 'test query', 'type': 'commit'})
194 assert search_mock.call_count == 1
194 assert search_mock.call_count == 1
195 _, kwargs = search_mock.call_args
195 _, kwargs = search_mock.call_args
196 assert isinstance(kwargs['filter'], query.Or)
196 assert isinstance(kwargs['filter'], query.Or)
197 expected_repositories = [
197 expected_repositories = [
198 'vcs_test_{}'.format(b) for b in enabled_backends]
198 'vcs_test_{}'.format(b) for b in enabled_backends]
199 queried_repositories = [
199 queried_repositories = [
200 name for type_, name in kwargs['filter'].all_terms()]
200 name for type_, name in kwargs['filter'].all_terms()]
201 for repository in expected_repositories:
201 for repository in expected_repositories:
202 assert repository in queried_repositories
202 assert repository in queried_repositories
@@ -1,248 +1,247 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2017 RhodeCode GmbH
3 # Copyright (C) 2010-2017 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import os
21 import os
22 import time
22 import time
23 import logging
23 import logging
24 import datetime
24 import datetime
25 import hashlib
25 import hashlib
26 import tempfile
26 import tempfile
27 from os.path import join as jn
27 from os.path import join as jn
28
28
29 from tempfile import _RandomNameSequence
29 from tempfile import _RandomNameSequence
30
30
31 from pylons import url
31 from pylons import url
32
32
33 from nose.plugins.skip import SkipTest
34 import pytest
33 import pytest
35
34
36 from rhodecode.model.db import User
35 from rhodecode.model.db import User
37 from rhodecode.lib import auth
36 from rhodecode.lib import auth
38 from rhodecode.lib import helpers as h
37 from rhodecode.lib import helpers as h
39 from rhodecode.lib.helpers import flash, link_to
38 from rhodecode.lib.helpers import flash, link_to
40 from rhodecode.lib.utils2 import safe_str
39 from rhodecode.lib.utils2 import safe_str
41
40
42
41
43 log = logging.getLogger(__name__)
42 log = logging.getLogger(__name__)
44
43
45 __all__ = [
44 __all__ = [
46 'get_new_dir', 'TestController', 'SkipTest',
45 'get_new_dir', 'TestController',
47 'url', 'link_to', 'ldap_lib_installed', 'clear_all_caches',
46 'url', 'link_to', 'ldap_lib_installed', 'clear_all_caches',
48 'assert_session_flash', 'login_user', 'no_newline_id_generator',
47 'assert_session_flash', 'login_user', 'no_newline_id_generator',
49 'TESTS_TMP_PATH', 'HG_REPO', 'GIT_REPO', 'SVN_REPO',
48 'TESTS_TMP_PATH', 'HG_REPO', 'GIT_REPO', 'SVN_REPO',
50 'NEW_HG_REPO', 'NEW_GIT_REPO',
49 'NEW_HG_REPO', 'NEW_GIT_REPO',
51 'HG_FORK', 'GIT_FORK', 'TEST_USER_ADMIN_LOGIN', 'TEST_USER_ADMIN_PASS',
50 'HG_FORK', 'GIT_FORK', 'TEST_USER_ADMIN_LOGIN', 'TEST_USER_ADMIN_PASS',
52 'TEST_USER_REGULAR_LOGIN', 'TEST_USER_REGULAR_PASS',
51 'TEST_USER_REGULAR_LOGIN', 'TEST_USER_REGULAR_PASS',
53 'TEST_USER_REGULAR_EMAIL', 'TEST_USER_REGULAR2_LOGIN',
52 'TEST_USER_REGULAR_EMAIL', 'TEST_USER_REGULAR2_LOGIN',
54 'TEST_USER_REGULAR2_PASS', 'TEST_USER_REGULAR2_EMAIL', 'TEST_HG_REPO',
53 'TEST_USER_REGULAR2_PASS', 'TEST_USER_REGULAR2_EMAIL', 'TEST_HG_REPO',
55 'TEST_HG_REPO_CLONE', 'TEST_HG_REPO_PULL', 'TEST_GIT_REPO',
54 'TEST_HG_REPO_CLONE', 'TEST_HG_REPO_PULL', 'TEST_GIT_REPO',
56 'TEST_GIT_REPO_CLONE', 'TEST_GIT_REPO_PULL', 'SCM_TESTS',
55 'TEST_GIT_REPO_CLONE', 'TEST_GIT_REPO_PULL', 'SCM_TESTS',
57 ]
56 ]
58
57
59 # Invoke websetup with the current config file
58 # Invoke websetup with the current config file
60 # SetupCommand('setup-app').run([config_file])
59 # SetupCommand('setup-app').run([config_file])
61
60
62 # SOME GLOBALS FOR TESTS
61 # SOME GLOBALS FOR TESTS
63 TEST_DIR = tempfile.gettempdir()
62 TEST_DIR = tempfile.gettempdir()
64
63
65 TESTS_TMP_PATH = jn(TEST_DIR, 'rc_test_%s' % _RandomNameSequence().next())
64 TESTS_TMP_PATH = jn(TEST_DIR, 'rc_test_%s' % _RandomNameSequence().next())
66 TEST_USER_ADMIN_LOGIN = 'test_admin'
65 TEST_USER_ADMIN_LOGIN = 'test_admin'
67 TEST_USER_ADMIN_PASS = 'test12'
66 TEST_USER_ADMIN_PASS = 'test12'
68 TEST_USER_ADMIN_EMAIL = 'test_admin@mail.com'
67 TEST_USER_ADMIN_EMAIL = 'test_admin@mail.com'
69
68
70 TEST_USER_REGULAR_LOGIN = 'test_regular'
69 TEST_USER_REGULAR_LOGIN = 'test_regular'
71 TEST_USER_REGULAR_PASS = 'test12'
70 TEST_USER_REGULAR_PASS = 'test12'
72 TEST_USER_REGULAR_EMAIL = 'test_regular@mail.com'
71 TEST_USER_REGULAR_EMAIL = 'test_regular@mail.com'
73
72
74 TEST_USER_REGULAR2_LOGIN = 'test_regular2'
73 TEST_USER_REGULAR2_LOGIN = 'test_regular2'
75 TEST_USER_REGULAR2_PASS = 'test12'
74 TEST_USER_REGULAR2_PASS = 'test12'
76 TEST_USER_REGULAR2_EMAIL = 'test_regular2@mail.com'
75 TEST_USER_REGULAR2_EMAIL = 'test_regular2@mail.com'
77
76
78 HG_REPO = 'vcs_test_hg'
77 HG_REPO = 'vcs_test_hg'
79 GIT_REPO = 'vcs_test_git'
78 GIT_REPO = 'vcs_test_git'
80 SVN_REPO = 'vcs_test_svn'
79 SVN_REPO = 'vcs_test_svn'
81
80
82 NEW_HG_REPO = 'vcs_test_hg_new'
81 NEW_HG_REPO = 'vcs_test_hg_new'
83 NEW_GIT_REPO = 'vcs_test_git_new'
82 NEW_GIT_REPO = 'vcs_test_git_new'
84
83
85 HG_FORK = 'vcs_test_hg_fork'
84 HG_FORK = 'vcs_test_hg_fork'
86 GIT_FORK = 'vcs_test_git_fork'
85 GIT_FORK = 'vcs_test_git_fork'
87
86
88 ## VCS
87 ## VCS
89 SCM_TESTS = ['hg', 'git']
88 SCM_TESTS = ['hg', 'git']
90 uniq_suffix = str(int(time.mktime(datetime.datetime.now().timetuple())))
89 uniq_suffix = str(int(time.mktime(datetime.datetime.now().timetuple())))
91
90
92 TEST_GIT_REPO = jn(TESTS_TMP_PATH, GIT_REPO)
91 TEST_GIT_REPO = jn(TESTS_TMP_PATH, GIT_REPO)
93 TEST_GIT_REPO_CLONE = jn(TESTS_TMP_PATH, 'vcsgitclone%s' % uniq_suffix)
92 TEST_GIT_REPO_CLONE = jn(TESTS_TMP_PATH, 'vcsgitclone%s' % uniq_suffix)
94 TEST_GIT_REPO_PULL = jn(TESTS_TMP_PATH, 'vcsgitpull%s' % uniq_suffix)
93 TEST_GIT_REPO_PULL = jn(TESTS_TMP_PATH, 'vcsgitpull%s' % uniq_suffix)
95
94
96 TEST_HG_REPO = jn(TESTS_TMP_PATH, HG_REPO)
95 TEST_HG_REPO = jn(TESTS_TMP_PATH, HG_REPO)
97 TEST_HG_REPO_CLONE = jn(TESTS_TMP_PATH, 'vcshgclone%s' % uniq_suffix)
96 TEST_HG_REPO_CLONE = jn(TESTS_TMP_PATH, 'vcshgclone%s' % uniq_suffix)
98 TEST_HG_REPO_PULL = jn(TESTS_TMP_PATH, 'vcshgpull%s' % uniq_suffix)
97 TEST_HG_REPO_PULL = jn(TESTS_TMP_PATH, 'vcshgpull%s' % uniq_suffix)
99
98
100 TEST_REPO_PREFIX = 'vcs-test'
99 TEST_REPO_PREFIX = 'vcs-test'
101
100
102
101
103 # skip ldap tests if LDAP lib is not installed
102 # skip ldap tests if LDAP lib is not installed
104 ldap_lib_installed = False
103 ldap_lib_installed = False
105 try:
104 try:
106 import ldap
105 import ldap
107 ldap_lib_installed = True
106 ldap_lib_installed = True
108 except ImportError:
107 except ImportError:
109 ldap = None
108 ldap = None
110 # means that python-ldap is not installed
109 # means that python-ldap is not installed
111 pass
110 pass
112
111
113
112
114 def clear_all_caches():
113 def clear_all_caches():
115 from beaker.cache import cache_managers
114 from beaker.cache import cache_managers
116 for _cache in cache_managers.values():
115 for _cache in cache_managers.values():
117 _cache.clear()
116 _cache.clear()
118
117
119
118
120 def get_new_dir(title):
119 def get_new_dir(title):
121 """
120 """
122 Returns always new directory path.
121 Returns always new directory path.
123 """
122 """
124 from rhodecode.tests.vcs.utils import get_normalized_path
123 from rhodecode.tests.vcs.utils import get_normalized_path
125 name_parts = [TEST_REPO_PREFIX]
124 name_parts = [TEST_REPO_PREFIX]
126 if title:
125 if title:
127 name_parts.append(title)
126 name_parts.append(title)
128 hex_str = hashlib.sha1('%s %s' % (os.getpid(), time.time())).hexdigest()
127 hex_str = hashlib.sha1('%s %s' % (os.getpid(), time.time())).hexdigest()
129 name_parts.append(hex_str)
128 name_parts.append(hex_str)
130 name = '-'.join(name_parts)
129 name = '-'.join(name_parts)
131 path = os.path.join(TEST_DIR, name)
130 path = os.path.join(TEST_DIR, name)
132 return get_normalized_path(path)
131 return get_normalized_path(path)
133
132
134
133
135 @pytest.mark.usefixtures('app', 'index_location')
134 @pytest.mark.usefixtures('app', 'index_location')
136 class TestController(object):
135 class TestController(object):
137
136
138 maxDiff = None
137 maxDiff = None
139
138
140 def log_user(self, username=TEST_USER_ADMIN_LOGIN,
139 def log_user(self, username=TEST_USER_ADMIN_LOGIN,
141 password=TEST_USER_ADMIN_PASS):
140 password=TEST_USER_ADMIN_PASS):
142 self._logged_username = username
141 self._logged_username = username
143 self._session = login_user_session(self.app, username, password)
142 self._session = login_user_session(self.app, username, password)
144 self.csrf_token = auth.get_csrf_token(self._session)
143 self.csrf_token = auth.get_csrf_token(self._session)
145
144
146 return self._session['rhodecode_user']
145 return self._session['rhodecode_user']
147
146
148 def logout_user(self):
147 def logout_user(self):
149 logout_user_session(self.app, auth.get_csrf_token(self._session))
148 logout_user_session(self.app, auth.get_csrf_token(self._session))
150 self.csrf_token = None
149 self.csrf_token = None
151 self._logged_username = None
150 self._logged_username = None
152 self._session = None
151 self._session = None
153
152
154 def _get_logged_user(self):
153 def _get_logged_user(self):
155 return User.get_by_username(self._logged_username)
154 return User.get_by_username(self._logged_username)
156
155
157
156
158 def login_user_session(
157 def login_user_session(
159 app, username=TEST_USER_ADMIN_LOGIN, password=TEST_USER_ADMIN_PASS):
158 app, username=TEST_USER_ADMIN_LOGIN, password=TEST_USER_ADMIN_PASS):
160
159
161 response = app.post(
160 response = app.post(
162 h.route_path('login'),
161 h.route_path('login'),
163 {'username': username, 'password': password})
162 {'username': username, 'password': password})
164 if 'invalid user name' in response.body:
163 if 'invalid user name' in response.body:
165 pytest.fail('could not login using %s %s' % (username, password))
164 pytest.fail('could not login using %s %s' % (username, password))
166
165
167 assert response.status == '302 Found'
166 assert response.status == '302 Found'
168 response = response.follow()
167 response = response.follow()
169 assert response.status == '200 OK'
168 assert response.status == '200 OK'
170
169
171 session = response.get_session_from_response()
170 session = response.get_session_from_response()
172 assert 'rhodecode_user' in session
171 assert 'rhodecode_user' in session
173 rc_user = session['rhodecode_user']
172 rc_user = session['rhodecode_user']
174 assert rc_user.get('username') == username
173 assert rc_user.get('username') == username
175 assert rc_user.get('is_authenticated')
174 assert rc_user.get('is_authenticated')
176
175
177 return session
176 return session
178
177
179
178
180 def logout_user_session(app, csrf_token):
179 def logout_user_session(app, csrf_token):
181 app.post(h.route_path('logout'), {'csrf_token': csrf_token}, status=302)
180 app.post(h.route_path('logout'), {'csrf_token': csrf_token}, status=302)
182
181
183
182
184 def login_user(app, username=TEST_USER_ADMIN_LOGIN,
183 def login_user(app, username=TEST_USER_ADMIN_LOGIN,
185 password=TEST_USER_ADMIN_PASS):
184 password=TEST_USER_ADMIN_PASS):
186 return login_user_session(app, username, password)['rhodecode_user']
185 return login_user_session(app, username, password)['rhodecode_user']
187
186
188
187
189 def assert_session_flash(response, msg=None, category=None, no_=None):
188 def assert_session_flash(response, msg=None, category=None, no_=None):
190 """
189 """
191 Assert on a flash message in the current session.
190 Assert on a flash message in the current session.
192
191
193 :param response: Response from give calll, it will contain flash
192 :param response: Response from give calll, it will contain flash
194 messages or bound session with them.
193 messages or bound session with them.
195 :param msg: The expected message. Will be evaluated if a
194 :param msg: The expected message. Will be evaluated if a
196 :class:`LazyString` is passed in.
195 :class:`LazyString` is passed in.
197 :param category: Optional. If passed, the message category will be
196 :param category: Optional. If passed, the message category will be
198 checked as well.
197 checked as well.
199 :param no_: Optional. If passed, the message will be checked to NOT
198 :param no_: Optional. If passed, the message will be checked to NOT
200 be in the flash session
199 be in the flash session
201 """
200 """
202 if msg is None and no_ is None:
201 if msg is None and no_ is None:
203 raise ValueError("Parameter msg or no_ is required.")
202 raise ValueError("Parameter msg or no_ is required.")
204
203
205 if msg and no_:
204 if msg and no_:
206 raise ValueError("Please specify either msg or no_, but not both")
205 raise ValueError("Please specify either msg or no_, but not both")
207
206
208 session = response.get_session_from_response()
207 session = response.get_session_from_response()
209 messages = flash.pop_messages(session=session)
208 messages = flash.pop_messages(session=session)
210 msg = _eval_if_lazy(msg)
209 msg = _eval_if_lazy(msg)
211
210
212 assert messages, 'unable to find message `%s` in empty flash list' % msg
211 assert messages, 'unable to find message `%s` in empty flash list' % msg
213 message = messages[0]
212 message = messages[0]
214
213
215 message_text = _eval_if_lazy(message.message) or ''
214 message_text = _eval_if_lazy(message.message) or ''
216
215
217 if no_:
216 if no_:
218 if no_ in message_text:
217 if no_ in message_text:
219 msg = u'msg `%s` found in session flash.' % (no_,)
218 msg = u'msg `%s` found in session flash.' % (no_,)
220 pytest.fail(safe_str(msg))
219 pytest.fail(safe_str(msg))
221 else:
220 else:
222 if msg not in message_text:
221 if msg not in message_text:
223 fail_msg = u'msg `%s` not found in session ' \
222 fail_msg = u'msg `%s` not found in session ' \
224 u'flash: got `%s` (type:%s) instead' % (
223 u'flash: got `%s` (type:%s) instead' % (
225 msg, message_text, type(message_text))
224 msg, message_text, type(message_text))
226
225
227 pytest.fail(safe_str(fail_msg))
226 pytest.fail(safe_str(fail_msg))
228 if category:
227 if category:
229 assert category == message.category
228 assert category == message.category
230
229
231
230
232 def _eval_if_lazy(value):
231 def _eval_if_lazy(value):
233 return value.eval() if hasattr(value, 'eval') else value
232 return value.eval() if hasattr(value, 'eval') else value
234
233
235
234
236 def no_newline_id_generator(test_name):
235 def no_newline_id_generator(test_name):
237 """
236 """
238 Generates a test name without spaces or newlines characters. Used for
237 Generates a test name without spaces or newlines characters. Used for
239 nicer output of progress of test
238 nicer output of progress of test
240 """
239 """
241 org_name = test_name
240 org_name = test_name
242 test_name = test_name\
241 test_name = test_name\
243 .replace('\n', '_N') \
242 .replace('\n', '_N') \
244 .replace('\r', '_N') \
243 .replace('\r', '_N') \
245 .replace('\t', '_T') \
244 .replace('\t', '_T') \
246 .replace(' ', '_S')
245 .replace(' ', '_S')
247
246
248 return test_name or 'test-with-empty-name'
247 return test_name or 'test-with-empty-name'
General Comments 0
You need to be logged in to leave comments. Login now