##// END OF EJS Templates
tests: Add custom header to expected headers
Martin Bornhold -
r611:b6047654 default
parent child Browse files
Show More
@@ -1,186 +1,188 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 RhodeCode GmbH
3 # Copyright (C) 2010-2016 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 from StringIO import StringIO
21 from StringIO import StringIO
22
22
23 import pytest
23 import pytest
24 from mock import patch, Mock
24 from mock import patch, Mock
25
25
26 import rhodecode
26 import rhodecode
27 from rhodecode.lib.middleware.simplesvn import SimpleSvn, SimpleSvnApp
27 from rhodecode.lib.middleware.simplesvn import SimpleSvn, SimpleSvnApp
28
28
29
29
30 class TestSimpleSvn(object):
30 class TestSimpleSvn(object):
31 @pytest.fixture(autouse=True)
31 @pytest.fixture(autouse=True)
32 def simple_svn(self, pylonsapp):
32 def simple_svn(self, pylonsapp):
33 self.app = SimpleSvn(
33 self.app = SimpleSvn(
34 application='None',
34 application='None',
35 config={'auth_ret_code': '',
35 config={'auth_ret_code': '',
36 'base_path': rhodecode.CONFIG['base_path']},
36 'base_path': rhodecode.CONFIG['base_path']},
37 registry=None)
37 registry=None)
38
38
39 def test_get_config(self):
39 def test_get_config(self):
40 extras = {'foo': 'FOO', 'bar': 'BAR'}
40 extras = {'foo': 'FOO', 'bar': 'BAR'}
41 config = self.app._create_config(extras, repo_name='test-repo')
41 config = self.app._create_config(extras, repo_name='test-repo')
42 assert config == extras
42 assert config == extras
43
43
44 @pytest.mark.parametrize(
44 @pytest.mark.parametrize(
45 'method', ['OPTIONS', 'PROPFIND', 'GET', 'REPORT'])
45 'method', ['OPTIONS', 'PROPFIND', 'GET', 'REPORT'])
46 def test_get_action_returns_pull(self, method):
46 def test_get_action_returns_pull(self, method):
47 environment = {'REQUEST_METHOD': method}
47 environment = {'REQUEST_METHOD': method}
48 action = self.app._get_action(environment)
48 action = self.app._get_action(environment)
49 assert action == 'pull'
49 assert action == 'pull'
50
50
51 @pytest.mark.parametrize(
51 @pytest.mark.parametrize(
52 'method', [
52 'method', [
53 'MKACTIVITY', 'PROPPATCH', 'PUT', 'CHECKOUT', 'MKCOL', 'MOVE',
53 'MKACTIVITY', 'PROPPATCH', 'PUT', 'CHECKOUT', 'MKCOL', 'MOVE',
54 'COPY', 'DELETE', 'LOCK', 'UNLOCK', 'MERGE'
54 'COPY', 'DELETE', 'LOCK', 'UNLOCK', 'MERGE'
55 ])
55 ])
56 def test_get_action_returns_push(self, method):
56 def test_get_action_returns_push(self, method):
57 environment = {'REQUEST_METHOD': method}
57 environment = {'REQUEST_METHOD': method}
58 action = self.app._get_action(environment)
58 action = self.app._get_action(environment)
59 assert action == 'push'
59 assert action == 'push'
60
60
61 @pytest.mark.parametrize(
61 @pytest.mark.parametrize(
62 'path, expected_name', [
62 'path, expected_name', [
63 ('/hello-svn', 'hello-svn'),
63 ('/hello-svn', 'hello-svn'),
64 ('/hello-svn/', 'hello-svn'),
64 ('/hello-svn/', 'hello-svn'),
65 ('/group/hello-svn/', 'group/hello-svn'),
65 ('/group/hello-svn/', 'group/hello-svn'),
66 ('/group/hello-svn/!svn/vcc/default', 'group/hello-svn'),
66 ('/group/hello-svn/!svn/vcc/default', 'group/hello-svn'),
67 ])
67 ])
68 def test_get_repository_name(self, path, expected_name):
68 def test_get_repository_name(self, path, expected_name):
69 environment = {'PATH_INFO': path}
69 environment = {'PATH_INFO': path}
70 name = self.app._get_repository_name(environment)
70 name = self.app._get_repository_name(environment)
71 assert name == expected_name
71 assert name == expected_name
72
72
73 def test_get_repository_name_subfolder(self, backend_svn):
73 def test_get_repository_name_subfolder(self, backend_svn):
74 repo = backend_svn.repo
74 repo = backend_svn.repo
75 environment = {
75 environment = {
76 'PATH_INFO': '/{}/path/with/subfolders'.format(repo.repo_name)}
76 'PATH_INFO': '/{}/path/with/subfolders'.format(repo.repo_name)}
77 name = self.app._get_repository_name(environment)
77 name = self.app._get_repository_name(environment)
78 assert name == repo.repo_name
78 assert name == repo.repo_name
79
79
80 def test_create_wsgi_app(self):
80 def test_create_wsgi_app(self):
81 with patch('rhodecode.lib.middleware.simplesvn.SimpleSvnApp') as (
81 with patch('rhodecode.lib.middleware.simplesvn.SimpleSvnApp') as (
82 wsgi_app_mock):
82 wsgi_app_mock):
83 config = Mock()
83 config = Mock()
84 wsgi_app = self.app._create_wsgi_app(
84 wsgi_app = self.app._create_wsgi_app(
85 repo_path='', repo_name='', config=config)
85 repo_path='', repo_name='', config=config)
86
86
87 wsgi_app_mock.assert_called_once_with(config)
87 wsgi_app_mock.assert_called_once_with(config)
88 assert wsgi_app == wsgi_app_mock()
88 assert wsgi_app == wsgi_app_mock()
89
89
90
90
91 class TestSimpleSvnApp(object):
91 class TestSimpleSvnApp(object):
92 data = '<xml></xml>'
92 data = '<xml></xml>'
93 path = '/group/my-repo'
93 path = '/group/my-repo'
94 wsgi_input = StringIO(data)
94 wsgi_input = StringIO(data)
95 environment = {
95 environment = {
96 'HTTP_DAV': (
96 'HTTP_DAV': (
97 'http://subversion.tigris.org/xmlns/dav/svn/depth,'
97 'http://subversion.tigris.org/xmlns/dav/svn/depth,'
98 ' http://subversion.tigris.org/xmlns/dav/svn/mergeinfo'),
98 ' http://subversion.tigris.org/xmlns/dav/svn/mergeinfo'),
99 'HTTP_USER_AGENT': 'SVN/1.8.11 (x86_64-linux) serf/1.3.8',
99 'HTTP_USER_AGENT': 'SVN/1.8.11 (x86_64-linux) serf/1.3.8',
100 'REQUEST_METHOD': 'OPTIONS',
100 'REQUEST_METHOD': 'OPTIONS',
101 'PATH_INFO': path,
101 'PATH_INFO': path,
102 'wsgi.input': wsgi_input,
102 'wsgi.input': wsgi_input,
103 'CONTENT_TYPE': 'text/xml',
103 'CONTENT_TYPE': 'text/xml',
104 'CONTENT_LENGTH': '130'
104 'CONTENT_LENGTH': '130'
105 }
105 }
106
106
107 def setup_method(self, method):
107 def setup_method(self, method):
108 self.host = 'http://localhost/'
108 self.host = 'http://localhost/'
109 self.app = SimpleSvnApp(
109 self.app = SimpleSvnApp(
110 config={'subversion_http_server_url': self.host})
110 config={'subversion_http_server_url': self.host})
111
111
112 def test_get_request_headers_with_content_type(self):
112 def test_get_request_headers_with_content_type(self):
113 expected_headers = {
113 expected_headers = {
114 'Dav': self.environment['HTTP_DAV'],
114 'Dav': self.environment['HTTP_DAV'],
115 'User-Agent': self.environment['HTTP_USER_AGENT'],
115 'User-Agent': self.environment['HTTP_USER_AGENT'],
116 'Content-Type': self.environment['CONTENT_TYPE'],
116 'Content-Type': self.environment['CONTENT_TYPE'],
117 'Content-Length': self.environment['CONTENT_LENGTH']
117 'Content-Length': self.environment['CONTENT_LENGTH']
118 }
118 }
119 headers = self.app._get_request_headers(self.environment)
119 headers = self.app._get_request_headers(self.environment)
120 assert headers == expected_headers
120 assert headers == expected_headers
121
121
122 def test_get_request_headers_without_content_type(self):
122 def test_get_request_headers_without_content_type(self):
123 environment = self.environment.copy()
123 environment = self.environment.copy()
124 environment.pop('CONTENT_TYPE')
124 environment.pop('CONTENT_TYPE')
125 expected_headers = {
125 expected_headers = {
126 'Dav': environment['HTTP_DAV'],
126 'Dav': environment['HTTP_DAV'],
127 'Content-Length': self.environment['CONTENT_LENGTH'],
127 'Content-Length': self.environment['CONTENT_LENGTH'],
128 'User-Agent': environment['HTTP_USER_AGENT'],
128 'User-Agent': environment['HTTP_USER_AGENT'],
129 }
129 }
130 request_headers = self.app._get_request_headers(environment)
130 request_headers = self.app._get_request_headers(environment)
131 assert request_headers == expected_headers
131 assert request_headers == expected_headers
132
132
133 def test_get_response_headers(self):
133 def test_get_response_headers(self):
134 headers = {
134 headers = {
135 'Connection': 'keep-alive',
135 'Connection': 'keep-alive',
136 'Keep-Alive': 'timeout=5, max=100',
136 'Keep-Alive': 'timeout=5, max=100',
137 'Transfer-Encoding': 'chunked',
137 'Transfer-Encoding': 'chunked',
138 'Content-Encoding': 'gzip',
138 'Content-Encoding': 'gzip',
139 'MS-Author-Via': 'DAV',
139 'MS-Author-Via': 'DAV',
140 'SVN-Supported-Posts': 'create-txn-with-props'
140 'SVN-Supported-Posts': 'create-txn-with-props'
141 }
141 }
142 expected_headers = [
142 expected_headers = [
143 ('MS-Author-Via', 'DAV'),
143 ('MS-Author-Via', 'DAV'),
144 ('SVN-Supported-Posts', 'create-txn-with-props')
144 ('SVN-Supported-Posts', 'create-txn-with-props'),
145 ('X-RhodeCode-Backend', 'svn'),
145 ]
146 ]
146 response_headers = self.app._get_response_headers(headers)
147 response_headers = self.app._get_response_headers(headers)
147 assert sorted(response_headers) == sorted(expected_headers)
148 assert sorted(response_headers) == sorted(expected_headers)
148
149
149 def test_get_url(self):
150 def test_get_url(self):
150 url = self.app._get_url(self.path)
151 url = self.app._get_url(self.path)
151 expected_url = '{}{}'.format(self.host.strip('/'), self.path)
152 expected_url = '{}{}'.format(self.host.strip('/'), self.path)
152 assert url == expected_url
153 assert url == expected_url
153
154
154 def test_call(self):
155 def test_call(self):
155 start_response = Mock()
156 start_response = Mock()
156 response_mock = Mock()
157 response_mock = Mock()
157 response_mock.headers = {
158 response_mock.headers = {
158 'Content-Encoding': 'gzip',
159 'Content-Encoding': 'gzip',
159 'MS-Author-Via': 'DAV',
160 'MS-Author-Via': 'DAV',
160 'SVN-Supported-Posts': 'create-txn-with-props'
161 'SVN-Supported-Posts': 'create-txn-with-props'
161 }
162 }
162 response_mock.status_code = 200
163 response_mock.status_code = 200
163 response_mock.reason = 'OK'
164 response_mock.reason = 'OK'
164 with patch('rhodecode.lib.middleware.simplesvn.requests.request') as (
165 with patch('rhodecode.lib.middleware.simplesvn.requests.request') as (
165 request_mock):
166 request_mock):
166 request_mock.return_value = response_mock
167 request_mock.return_value = response_mock
167 self.app(self.environment, start_response)
168 self.app(self.environment, start_response)
168
169
169 expected_url = '{}{}'.format(self.host.strip('/'), self.path)
170 expected_url = '{}{}'.format(self.host.strip('/'), self.path)
170 expected_request_headers = {
171 expected_request_headers = {
171 'Dav': self.environment['HTTP_DAV'],
172 'Dav': self.environment['HTTP_DAV'],
172 'User-Agent': self.environment['HTTP_USER_AGENT'],
173 'User-Agent': self.environment['HTTP_USER_AGENT'],
173 'Content-Type': self.environment['CONTENT_TYPE'],
174 'Content-Type': self.environment['CONTENT_TYPE'],
174 'Content-Length': self.environment['CONTENT_LENGTH']
175 'Content-Length': self.environment['CONTENT_LENGTH']
175 }
176 }
176 expected_response_headers = [
177 expected_response_headers = [
177 ('SVN-Supported-Posts', 'create-txn-with-props'),
178 ('SVN-Supported-Posts', 'create-txn-with-props'),
178 ('MS-Author-Via', 'DAV')
179 ('MS-Author-Via', 'DAV'),
180 ('X-RhodeCode-Backend', 'svn'),
179 ]
181 ]
180 request_mock.assert_called_once_with(
182 request_mock.assert_called_once_with(
181 self.environment['REQUEST_METHOD'], expected_url,
183 self.environment['REQUEST_METHOD'], expected_url,
182 data=self.data, headers=expected_request_headers)
184 data=self.data, headers=expected_request_headers)
183 response_mock.iter_content.assert_called_once_with(chunk_size=1024)
185 response_mock.iter_content.assert_called_once_with(chunk_size=1024)
184 args, _ = start_response.call_args
186 args, _ = start_response.call_args
185 assert args[0] == '200 OK'
187 assert args[0] == '200 OK'
186 assert sorted(args[1]) == sorted(expected_response_headers)
188 assert sorted(args[1]) == sorted(expected_response_headers)
General Comments 0
You need to be logged in to leave comments. Login now