##// END OF EJS Templates
api: make all tests for API pass
super-admin -
r5048:a6860778 default
parent child Browse files
Show More
@@ -1,390 +1,380 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20 import pytest
22 21
23 22 from rhodecode.model.comment import CommentsModel
24 23 from rhodecode.model.db import UserLog, User, ChangesetComment
25 24 from rhodecode.model.pull_request import PullRequestModel
26 25 from rhodecode.tests import TEST_USER_ADMIN_LOGIN
27 26 from rhodecode.api.tests.utils import (
28 27 build_data, api_call, assert_error, assert_ok)
29 28
30 29
31 30 @pytest.mark.usefixtures("testuser_api", "app")
32 31 class TestCommentPullRequest(object):
33 32 finalizers = []
34 33
35 34 def teardown_method(self, method):
36 35 if self.finalizers:
37 36 for finalizer in self.finalizers:
38 37 finalizer()
39 38 self.finalizers = []
40 39
41 40 @pytest.mark.backends("git", "hg")
42 41 def test_api_comment_pull_request(self, pr_util, no_notifications):
43 42 pull_request = pr_util.create_pull_request()
44 43 pull_request_id = pull_request.pull_request_id
45 44 author = pull_request.user_id
46 45 repo = pull_request.target_repo.repo_id
47 46 id_, params = build_data(
48 47 self.apikey, 'comment_pull_request',
49 48 repoid=pull_request.target_repo.repo_name,
50 49 pullrequestid=pull_request.pull_request_id,
51 50 message='test message')
52 51 response = api_call(self.app, params)
53 52 pull_request = PullRequestModel().get(pull_request.pull_request_id)
54 53
55 54 comments = CommentsModel().get_comments(
56 55 pull_request.target_repo.repo_id, pull_request=pull_request)
57 56
58 57 expected = {
59 58 'pull_request_id': pull_request.pull_request_id,
60 59 'comment_id': comments[-1].comment_id,
61 60 'status': {'given': None, 'was_changed': None}
62 61 }
63 62 assert_ok(id_, expected, response.body)
64 63
65 64 journal = UserLog.query()\
66 65 .filter(UserLog.user_id == author)\
67 66 .filter(UserLog.repository_id == repo) \
68 67 .order_by(UserLog.user_log_id.asc()) \
69 68 .all()
70 69 assert journal[-1].action == 'repo.pull_request.comment.create'
71 70
72 71 @pytest.mark.backends("git", "hg")
73 72 def test_api_comment_pull_request_with_extra_recipients(self, pr_util, user_util):
74 73 pull_request = pr_util.create_pull_request()
75 74
76 75 user1 = user_util.create_user()
77 76 user1_id = user1.user_id
78 77 user2 = user_util.create_user()
79 78 user2_id = user2.user_id
80 79
81 80 id_, params = build_data(
82 81 self.apikey, 'comment_pull_request',
83 82 repoid=pull_request.target_repo.repo_name,
84 83 pullrequestid=pull_request.pull_request_id,
85 84 message='test message',
86 85 extra_recipients=[user1.user_id, user2.username]
87 86 )
88 87 response = api_call(self.app, params)
89 88 pull_request = PullRequestModel().get(pull_request.pull_request_id)
90 89
91 90 comments = CommentsModel().get_comments(
92 91 pull_request.target_repo.repo_id, pull_request=pull_request)
93 92
94 93 expected = {
95 94 'pull_request_id': pull_request.pull_request_id,
96 95 'comment_id': comments[-1].comment_id,
97 96 'status': {'given': None, 'was_changed': None}
98 97 }
99 98 assert_ok(id_, expected, response.body)
100 99 # check user1/user2 inbox for notification
101 100 user1 = User.get(user1_id)
102 101 assert 1 == len(user1.notifications)
103 102 assert 'test message' in user1.notifications[0].notification.body
104 103
105 104 user2 = User.get(user2_id)
106 105 assert 1 == len(user2.notifications)
107 106 assert 'test message' in user2.notifications[0].notification.body
108 107
109 108 @pytest.mark.backends("git", "hg")
110 109 def test_api_comment_pull_request_change_status(
111 110 self, pr_util, no_notifications):
112 111 pull_request = pr_util.create_pull_request()
113 112 pull_request_id = pull_request.pull_request_id
114 113 id_, params = build_data(
115 114 self.apikey, 'comment_pull_request',
116 115 repoid=pull_request.target_repo.repo_name,
117 116 pullrequestid=pull_request.pull_request_id,
118 117 status='rejected')
119 118 response = api_call(self.app, params)
120 119 pull_request = PullRequestModel().get(pull_request_id)
121 120
122 121 comments = CommentsModel().get_comments(
123 122 pull_request.target_repo.repo_id, pull_request=pull_request)
124 123 expected = {
125 124 'pull_request_id': pull_request.pull_request_id,
126 125 'comment_id': comments[-1].comment_id,
127 126 'status': {'given': 'rejected', 'was_changed': True}
128 127 }
129 128 assert_ok(id_, expected, response.body)
130 129
131 130 @pytest.mark.backends("git", "hg")
132 def test_api_comment_pull_request_change_status_with_specific_commit_id(
131 def test_api_comment_pull_request_change_status_with_specific_commit_id_and_test_commit(
133 132 self, pr_util, no_notifications):
134 133 pull_request = pr_util.create_pull_request()
135 134 pull_request_id = pull_request.pull_request_id
136 135 latest_commit_id = 'test_commit'
136
137 137 # inject additional revision, to fail test the status change on
138 138 # non-latest commit
139 139 pull_request.revisions = pull_request.revisions + ['test_commit']
140 140
141 141 id_, params = build_data(
142 142 self.apikey, 'comment_pull_request',
143 message='test-change-of-status-not-allowed',
143 144 repoid=pull_request.target_repo.repo_name,
144 145 pullrequestid=pull_request.pull_request_id,
145 146 status='approved', commit_id=latest_commit_id)
146 147 response = api_call(self.app, params)
147 148 pull_request = PullRequestModel().get(pull_request_id)
149 comments = CommentsModel().get_comments(
150 pull_request.target_repo.repo_id, pull_request=pull_request)
148 151
149 152 expected = {
150 153 'pull_request_id': pull_request.pull_request_id,
151 'comment_id': None,
154 'comment_id': comments[-1].comment_id,
152 155 'status': {'given': 'approved', 'was_changed': False}
153 156 }
154 157 assert_ok(id_, expected, response.body)
155 158
156 159 @pytest.mark.backends("git", "hg")
157 160 def test_api_comment_pull_request_change_status_with_specific_commit_id(
158 161 self, pr_util, no_notifications):
159 162 pull_request = pr_util.create_pull_request()
160 163 pull_request_id = pull_request.pull_request_id
161 164 latest_commit_id = pull_request.revisions[0]
162 165
163 166 id_, params = build_data(
164 167 self.apikey, 'comment_pull_request',
165 168 repoid=pull_request.target_repo.repo_name,
166 169 pullrequestid=pull_request.pull_request_id,
167 170 status='approved', commit_id=latest_commit_id)
168 171 response = api_call(self.app, params)
169 172 pull_request = PullRequestModel().get(pull_request_id)
170 173
171 174 comments = CommentsModel().get_comments(
172 175 pull_request.target_repo.repo_id, pull_request=pull_request)
173 176 expected = {
174 177 'pull_request_id': pull_request.pull_request_id,
175 178 'comment_id': comments[-1].comment_id,
176 179 'status': {'given': 'approved', 'was_changed': True}
177 180 }
178 181 assert_ok(id_, expected, response.body)
179 182
180 183 @pytest.mark.backends("git", "hg")
181 184 def test_api_comment_pull_request_missing_params_error(self, pr_util):
182 185 pull_request = pr_util.create_pull_request()
183 186 pull_request_id = pull_request.pull_request_id
184 187 pull_request_repo = pull_request.target_repo.repo_name
185 188 id_, params = build_data(
186 189 self.apikey, 'comment_pull_request',
187 190 repoid=pull_request_repo,
188 191 pullrequestid=pull_request_id)
189 192 response = api_call(self.app, params)
190 193
191 194 expected = 'Both message and status parameters are missing. At least one is required.'
192 195 assert_error(id_, expected, given=response.body)
193 196
194 197 @pytest.mark.backends("git", "hg")
195 198 def test_api_comment_pull_request_unknown_status_error(self, pr_util):
196 199 pull_request = pr_util.create_pull_request()
197 200 pull_request_id = pull_request.pull_request_id
198 201 pull_request_repo = pull_request.target_repo.repo_name
199 202 id_, params = build_data(
200 203 self.apikey, 'comment_pull_request',
201 204 repoid=pull_request_repo,
202 205 pullrequestid=pull_request_id,
203 206 status='42')
204 207 response = api_call(self.app, params)
205 208
206 209 expected = 'Unknown comment status: `42`'
207 210 assert_error(id_, expected, given=response.body)
208 211
209 212 @pytest.mark.backends("git", "hg")
210 213 def test_api_comment_pull_request_repo_error(self, pr_util):
211 214 pull_request = pr_util.create_pull_request()
212 215 id_, params = build_data(
213 216 self.apikey, 'comment_pull_request',
214 217 repoid=666, pullrequestid=pull_request.pull_request_id)
215 218 response = api_call(self.app, params)
216 219
217 220 expected = 'repository `666` does not exist'
218 221 assert_error(id_, expected, given=response.body)
219 222
220 223 @pytest.mark.backends("git", "hg")
221 224 def test_api_comment_pull_request_non_admin_with_userid_error(self, pr_util):
222 225 pull_request = pr_util.create_pull_request()
223 226 id_, params = build_data(
224 227 self.apikey_regular, 'comment_pull_request',
225 228 repoid=pull_request.target_repo.repo_name,
226 229 pullrequestid=pull_request.pull_request_id,
227 230 userid=TEST_USER_ADMIN_LOGIN)
228 231 response = api_call(self.app, params)
229 232
230 233 expected = 'userid is not the same as your user'
231 234 assert_error(id_, expected, given=response.body)
232 235
233 236 @pytest.mark.backends("git", "hg")
234 def test_api_comment_pull_request_non_admin_with_userid_error(self, pr_util):
235 pull_request = pr_util.create_pull_request()
236 id_, params = build_data(
237 self.apikey_regular, 'comment_pull_request',
238 repoid=pull_request.target_repo.repo_name,
239 pullrequestid=pull_request.pull_request_id,
240 userid=TEST_USER_ADMIN_LOGIN)
241 response = api_call(self.app, params)
242
243 expected = 'userid is not the same as your user'
244 assert_error(id_, expected, given=response.body)
245
246 @pytest.mark.backends("git", "hg")
247 237 def test_api_comment_pull_request_wrong_commit_id_error(self, pr_util):
248 238 pull_request = pr_util.create_pull_request()
249 239 id_, params = build_data(
250 240 self.apikey_regular, 'comment_pull_request',
251 241 repoid=pull_request.target_repo.repo_name,
252 242 status='approved',
253 243 pullrequestid=pull_request.pull_request_id,
254 244 commit_id='XXX')
255 245 response = api_call(self.app, params)
256 246
257 247 expected = 'Invalid commit_id `XXX` for this pull request.'
258 248 assert_error(id_, expected, given=response.body)
259 249
260 250 @pytest.mark.backends("git", "hg")
261 251 def test_api_edit_comment(self, pr_util):
262 252 pull_request = pr_util.create_pull_request()
263 253
264 254 id_, params = build_data(
265 255 self.apikey,
266 256 'comment_pull_request',
267 257 repoid=pull_request.target_repo.repo_name,
268 258 pullrequestid=pull_request.pull_request_id,
269 259 message='test message',
270 260 )
271 261 response = api_call(self.app, params)
272 262 json_response = response.json
273 263 comment_id = json_response['result']['comment_id']
274 264
275 265 message_after_edit = 'just message'
276 266 id_, params = build_data(
277 267 self.apikey,
278 268 'edit_comment',
279 269 comment_id=comment_id,
280 270 message=message_after_edit,
281 271 version=0,
282 272 )
283 273 response = api_call(self.app, params)
284 274 json_response = response.json
285 275 assert json_response['result']['version'] == 1
286 276
287 277 text_form_db = ChangesetComment.get(comment_id).text
288 278 assert message_after_edit == text_form_db
289 279
290 280 @pytest.mark.backends("git", "hg")
291 def test_api_edit_comment_wrong_version(self, pr_util):
281 def test_api_edit_comment_wrong_version_mismatch(self, pr_util):
292 282 pull_request = pr_util.create_pull_request()
293 283
294 284 id_, params = build_data(
295 285 self.apikey, 'comment_pull_request',
296 286 repoid=pull_request.target_repo.repo_name,
297 287 pullrequestid=pull_request.pull_request_id,
298 288 message='test message')
299 289 response = api_call(self.app, params)
300 290 json_response = response.json
301 291 comment_id = json_response['result']['comment_id']
302 292
303 293 message_after_edit = 'just message'
304 294 id_, params = build_data(
305 self.apikey_regular,
295 self.apikey,
306 296 'edit_comment',
307 297 comment_id=comment_id,
308 298 message=message_after_edit,
309 299 version=1,
310 300 )
311 301 response = api_call(self.app, params)
312 302 expected = 'comment ({}) version ({}) mismatch'.format(comment_id, 1)
313 303 assert_error(id_, expected, given=response.body)
314 304
315 305 @pytest.mark.backends("git", "hg")
316 306 def test_api_edit_comment_wrong_version(self, pr_util):
317 307 pull_request = pr_util.create_pull_request()
318 308
319 309 id_, params = build_data(
320 310 self.apikey, 'comment_pull_request',
321 311 repoid=pull_request.target_repo.repo_name,
322 312 pullrequestid=pull_request.pull_request_id,
323 313 message='test message')
324 314 response = api_call(self.app, params)
325 315 json_response = response.json
326 316 comment_id = json_response['result']['comment_id']
327 317
328 318 id_, params = build_data(
329 319 self.apikey,
330 320 'edit_comment',
331 321 comment_id=comment_id,
332 322 message='',
333 323 version=0,
334 324 )
335 325 response = api_call(self.app, params)
336 expected = "comment ({}) can't be changed with empty string".format(comment_id, 1)
326 expected = f"comment ({comment_id}) can't be changed with empty string"
337 327 assert_error(id_, expected, given=response.body)
338 328
339 329 @pytest.mark.backends("git", "hg")
340 330 def test_api_edit_comment_wrong_user_set_by_non_admin(self, pr_util):
341 331 pull_request = pr_util.create_pull_request()
342 332 pull_request_id = pull_request.pull_request_id
343 333 id_, params = build_data(
344 334 self.apikey,
345 335 'comment_pull_request',
346 336 repoid=pull_request.target_repo.repo_name,
347 337 pullrequestid=pull_request_id,
348 338 message='test message'
349 339 )
350 340 response = api_call(self.app, params)
351 341 json_response = response.json
352 342 comment_id = json_response['result']['comment_id']
353 343
354 344 id_, params = build_data(
355 345 self.apikey_regular,
356 346 'edit_comment',
357 347 comment_id=comment_id,
358 348 message='just message',
359 349 version=0,
360 350 userid=TEST_USER_ADMIN_LOGIN
361 351 )
362 352 response = api_call(self.app, params)
363 353 expected = 'userid is not the same as your user'
364 354 assert_error(id_, expected, given=response.body)
365 355
366 356 @pytest.mark.backends("git", "hg")
367 357 def test_api_edit_comment_wrong_user_with_permissions_to_edit_comment(self, pr_util):
368 358 pull_request = pr_util.create_pull_request()
369 359 pull_request_id = pull_request.pull_request_id
370 360 id_, params = build_data(
371 361 self.apikey,
372 362 'comment_pull_request',
373 363 repoid=pull_request.target_repo.repo_name,
374 364 pullrequestid=pull_request_id,
375 365 message='test message'
376 366 )
377 367 response = api_call(self.app, params)
378 368 json_response = response.json
379 369 comment_id = json_response['result']['comment_id']
380 370
381 371 id_, params = build_data(
382 372 self.apikey_regular,
383 373 'edit_comment',
384 374 comment_id=comment_id,
385 375 message='just message',
386 376 version=0,
387 377 )
388 378 response = api_call(self.app, params)
389 379 expected = "you don't have access to edit this comment"
390 380 assert_error(id_, expected, given=response.body)
@@ -1,102 +1,101 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20 import mock
22 21 import pytest
23 22
24 23 from rhodecode.model.db import Gist
25 24 from rhodecode.model.gist import GistModel
26 25 from rhodecode.api.tests.utils import (
27 26 build_data, api_call, assert_error, assert_ok, crash)
28 27 from rhodecode.tests.fixture import Fixture
29 28
30 29
31 30 @pytest.mark.usefixtures("testuser_api", "app")
32 31 class TestApiCreateGist(object):
33 32 @pytest.mark.parametrize("lifetime, gist_type, gist_acl_level", [
34 33 (10, Gist.GIST_PUBLIC, Gist.ACL_LEVEL_PUBLIC),
35 34 (20, Gist.GIST_PUBLIC, Gist.ACL_LEVEL_PRIVATE),
36 35 (40, Gist.GIST_PRIVATE, Gist.ACL_LEVEL_PUBLIC),
37 36 (80, Gist.GIST_PRIVATE, Gist.ACL_LEVEL_PRIVATE),
38 37 ])
39 38 def test_api_create_gist(self, lifetime, gist_type, gist_acl_level):
40 39 id_, params = build_data(
41 40 self.apikey_regular, 'create_gist',
42 41 lifetime=lifetime,
43 42 description='foobar-gist',
44 43 gist_type=gist_type,
45 44 acl_level=gist_acl_level,
46 45 files={'foobar_ąć': {'content': 'foo'}})
47 46 response = api_call(self.app, params)
48 47 response_json = response.json
49 48 gist = response_json['result']['gist']
50 49 expected = {
51 50 'gist': {
52 51 'access_id': gist['access_id'],
53 52 'created_on': gist['created_on'],
54 53 'modified_at': gist['modified_at'],
55 54 'description': 'foobar-gist',
56 55 'expires': gist['expires'],
57 56 'gist_id': gist['gist_id'],
58 57 'type': gist_type,
59 58 'url': gist['url'],
60 59 # content is empty since we don't show it here
61 60 'content': None,
62 61 'acl_level': gist_acl_level,
63 62 },
64 63 'msg': 'created new gist'
65 64 }
66 65 try:
67 66 assert_ok(id_, expected, given=response.body)
68 67 finally:
69 68 Fixture().destroy_gists()
70 69
71 70 @pytest.mark.parametrize("expected, lifetime, gist_type, gist_acl_level, files", [
72 71 ({'gist_type': '"ups" is not one of private, public'},
73 72 10, 'ups', Gist.ACL_LEVEL_PUBLIC, {'f': {'content': 'f'}}),
74 73
75 74 ({'lifetime': '-120 is less than minimum value -1'},
76 75 -120, Gist.GIST_PUBLIC, Gist.ACL_LEVEL_PUBLIC, {'f': {'content': 'f'}}),
77 76
78 77 ({'0.content': 'Required'},
79 78 10, Gist.GIST_PUBLIC, Gist.ACL_LEVEL_PUBLIC, {'f': {'x': 'f'}}),
80 79 ])
81 80 def test_api_try_create_gist(
82 81 self, expected, lifetime, gist_type, gist_acl_level, files):
83 82 id_, params = build_data(
84 83 self.apikey_regular, 'create_gist',
85 84 lifetime=lifetime,
86 85 description='foobar-gist',
87 86 gist_type=gist_type,
88 87 acl_level=gist_acl_level,
89 88 files=files)
90 89 response = api_call(self.app, params)
91 90
92 91 try:
93 92 assert_error(id_, expected, given=response.body)
94 93 finally:
95 94 Fixture().destroy_gists()
96 95
97 96 @mock.patch.object(GistModel, 'create', crash)
98 97 def test_api_create_gist_exception_occurred(self):
99 98 id_, params = build_data(self.apikey_regular, 'create_gist', files={})
100 99 response = api_call(self.app, params)
101 100 expected = 'failed to create gist'
102 101 assert_error(id_, expected, given=response.body)
@@ -1,368 +1,367 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20 import pytest
22 21
23 22 from rhodecode.model.db import User
24 23 from rhodecode.model.pull_request import PullRequestModel
25 24 from rhodecode.model.repo import RepoModel
26 25 from rhodecode.model.user import UserModel
27 26 from rhodecode.tests import TEST_USER_ADMIN_LOGIN, TEST_USER_REGULAR_LOGIN
28 27 from rhodecode.api.tests.utils import build_data, api_call, assert_error
29 28
30 29
31 30 @pytest.mark.usefixtures("testuser_api", "app")
32 31 class TestCreatePullRequestApi(object):
33 32 finalizers = []
34 33
35 34 def teardown_method(self, method):
36 35 if self.finalizers:
37 36 for finalizer in self.finalizers:
38 37 finalizer()
39 38 self.finalizers = []
40 39
41 40 def test_create_with_wrong_data(self):
42 41 required_data = {
43 42 'source_repo': 'tests/source_repo',
44 43 'target_repo': 'tests/target_repo',
45 44 'source_ref': 'branch:default:initial',
46 45 'target_ref': 'branch:default:new-feature',
47 46 }
48 47 for key in required_data:
49 48 data = required_data.copy()
50 49 data.pop(key)
51 50 id_, params = build_data(
52 51 self.apikey, 'create_pull_request', **data)
53 52 response = api_call(self.app, params)
54 53
55 54 expected = 'Missing non optional `{}` arg in JSON DATA'.format(key)
56 55 assert_error(id_, expected, given=response.body)
57 56
58 57 @pytest.mark.backends("git", "hg")
59 58 @pytest.mark.parametrize('source_ref', [
60 59 'bookmarg:default:initial'
61 60 ])
62 61 def test_create_with_wrong_refs_data(self, backend, source_ref):
63 62
64 63 data = self._prepare_data(backend)
65 64 data['source_ref'] = source_ref
66 65
67 66 id_, params = build_data(
68 67 self.apikey_regular, 'create_pull_request', **data)
69 68
70 69 response = api_call(self.app, params)
71 70
72 71 expected = "Ref `{}` type is not allowed. " \
73 72 "Only:['bookmark', 'book', 'tag', 'branch'] " \
74 73 "are possible.".format(source_ref)
75 74 assert_error(id_, expected, given=response.body)
76 75
77 76 @pytest.mark.backends("git", "hg")
78 77 def test_create_with_correct_data(self, backend):
79 78 data = self._prepare_data(backend)
80 79 RepoModel().revoke_user_permission(
81 80 self.source.repo_name, User.DEFAULT_USER)
82 81 id_, params = build_data(
83 82 self.apikey_regular, 'create_pull_request', **data)
84 83 response = api_call(self.app, params)
85 84 expected_message = "Created new pull request `{title}`".format(
86 85 title=data['title'])
87 86 result = response.json
88 87 assert result['error'] is None
89 88 assert result['result']['msg'] == expected_message
90 89 pull_request_id = result['result']['pull_request_id']
91 90 pull_request = PullRequestModel().get(pull_request_id)
92 91 assert pull_request.title == data['title']
93 92 assert pull_request.description == data['description']
94 93 assert pull_request.source_ref == data['source_ref']
95 94 assert pull_request.target_ref == data['target_ref']
96 95 assert pull_request.source_repo.repo_name == data['source_repo']
97 96 assert pull_request.target_repo.repo_name == data['target_repo']
98 97 assert pull_request.revisions == [self.commit_ids['change']]
99 98 assert len(pull_request.reviewers) == 1
100 99
101 100 @pytest.mark.backends("git", "hg")
102 101 def test_create_with_empty_description(self, backend):
103 102 data = self._prepare_data(backend)
104 103 data.pop('description')
105 104 id_, params = build_data(
106 105 self.apikey_regular, 'create_pull_request', **data)
107 106 response = api_call(self.app, params)
108 107 expected_message = "Created new pull request `{title}`".format(
109 108 title=data['title'])
110 109 result = response.json
111 110 assert result['error'] is None
112 111 assert result['result']['msg'] == expected_message
113 112 pull_request_id = result['result']['pull_request_id']
114 113 pull_request = PullRequestModel().get(pull_request_id)
115 114 assert pull_request.description == ''
116 115
117 116 @pytest.mark.backends("git", "hg")
118 117 def test_create_with_empty_title(self, backend):
119 118 data = self._prepare_data(backend)
120 119 data.pop('title')
121 120 id_, params = build_data(
122 121 self.apikey_regular, 'create_pull_request', **data)
123 122 response = api_call(self.app, params)
124 123 result = response.json
125 124 pull_request_id = result['result']['pull_request_id']
126 125 pull_request = PullRequestModel().get(pull_request_id)
127 126 data['ref'] = backend.default_branch_name
128 127 title = '{source_repo}#{ref} to {target_repo}'.format(**data)
129 128 assert pull_request.title == title
130 129
131 130 @pytest.mark.backends("git", "hg")
132 131 def test_create_with_reviewers_specified_by_names(
133 132 self, backend, no_notifications):
134 133 data = self._prepare_data(backend)
135 134 reviewers = [
136 135 {'username': TEST_USER_REGULAR_LOGIN,
137 136 'reasons': ['{} added manually'.format(TEST_USER_REGULAR_LOGIN)]},
138 137 {'username': TEST_USER_ADMIN_LOGIN,
139 138 'reasons': ['{} added manually'.format(TEST_USER_ADMIN_LOGIN)],
140 139 'mandatory': True},
141 140 ]
142 141 data['reviewers'] = reviewers
143 142
144 143 id_, params = build_data(
145 144 self.apikey_regular, 'create_pull_request', **data)
146 145 response = api_call(self.app, params)
147 146
148 147 expected_message = "Created new pull request `{title}`".format(
149 148 title=data['title'])
150 149 result = response.json
151 150 assert result['error'] is None
152 151 assert result['result']['msg'] == expected_message
153 152 pull_request_id = result['result']['pull_request_id']
154 153 pull_request = PullRequestModel().get(pull_request_id)
155 154
156 155 actual_reviewers = []
157 156 for rev in pull_request.reviewers:
158 157 entry = {
159 158 'username': rev.user.username,
160 159 'reasons': rev.reasons,
161 160 }
162 161 if rev.mandatory:
163 162 entry['mandatory'] = rev.mandatory
164 163 actual_reviewers.append(entry)
165 164
166 165 owner_username = pull_request.target_repo.user.username
167 166 for spec_reviewer in reviewers[::]:
168 167 # default reviewer will be added who is an owner of the repo
169 168 # this get's overridden by a add owner to reviewers rule
170 169 if spec_reviewer['username'] == owner_username:
171 170 spec_reviewer['reasons'] = [u'Default reviewer', u'Repository owner']
172 171 # since owner is more important, we don't inherit mandatory flag
173 172 del spec_reviewer['mandatory']
174 173
175 174 assert sorted(actual_reviewers, key=lambda e: e['username']) \
176 175 == sorted(reviewers, key=lambda e: e['username'])
177 176
178 177 @pytest.mark.backends("git", "hg")
179 178 def test_create_with_reviewers_specified_by_ids(
180 179 self, backend, no_notifications):
181 180 data = self._prepare_data(backend)
182 181 reviewers = [
183 182 {'username': UserModel().get_by_username(
184 183 TEST_USER_REGULAR_LOGIN).user_id,
185 184 'reasons': ['added manually']},
186 185 {'username': UserModel().get_by_username(
187 186 TEST_USER_ADMIN_LOGIN).user_id,
188 187 'reasons': ['added manually']},
189 188 ]
190 189
191 190 data['reviewers'] = reviewers
192 191 id_, params = build_data(
193 192 self.apikey_regular, 'create_pull_request', **data)
194 193 response = api_call(self.app, params)
195 194
196 195 expected_message = "Created new pull request `{title}`".format(
197 196 title=data['title'])
198 197 result = response.json
199 198 assert result['error'] is None
200 199 assert result['result']['msg'] == expected_message
201 200 pull_request_id = result['result']['pull_request_id']
202 201 pull_request = PullRequestModel().get(pull_request_id)
203 202
204 203 actual_reviewers = []
205 204 for rev in pull_request.reviewers:
206 205 entry = {
207 206 'username': rev.user.user_id,
208 207 'reasons': rev.reasons,
209 208 }
210 209 if rev.mandatory:
211 210 entry['mandatory'] = rev.mandatory
212 211 actual_reviewers.append(entry)
213 212
214 213 owner_user_id = pull_request.target_repo.user.user_id
215 214 for spec_reviewer in reviewers[::]:
216 215 # default reviewer will be added who is an owner of the repo
217 216 # this get's overridden by a add owner to reviewers rule
218 217 if spec_reviewer['username'] == owner_user_id:
219 218 spec_reviewer['reasons'] = [u'Default reviewer', u'Repository owner']
220 219
221 220 assert sorted(actual_reviewers, key=lambda e: e['username']) \
222 221 == sorted(reviewers, key=lambda e: e['username'])
223 222
224 223 @pytest.mark.backends("git", "hg")
225 224 def test_create_fails_when_the_reviewer_is_not_found(self, backend):
226 225 data = self._prepare_data(backend)
227 226 data['reviewers'] = [{'username': 'somebody'}]
228 227 id_, params = build_data(
229 228 self.apikey_regular, 'create_pull_request', **data)
230 229 response = api_call(self.app, params)
231 230 expected_message = 'user `somebody` does not exist'
232 231 assert_error(id_, expected_message, given=response.body)
233 232
234 233 @pytest.mark.backends("git", "hg")
235 234 def test_cannot_create_with_reviewers_in_wrong_format(self, backend):
236 235 data = self._prepare_data(backend)
237 236 reviewers = ','.join([TEST_USER_REGULAR_LOGIN, TEST_USER_ADMIN_LOGIN])
238 237 data['reviewers'] = reviewers
239 238 id_, params = build_data(
240 239 self.apikey_regular, 'create_pull_request', **data)
241 240 response = api_call(self.app, params)
242 241 expected_message = {u'': '"test_regular,test_admin" is not iterable'}
243 242 assert_error(id_, expected_message, given=response.body)
244 243
245 244 @pytest.mark.backends("git", "hg")
246 245 def test_create_with_no_commit_hashes(self, backend):
247 246 data = self._prepare_data(backend)
248 247 expected_source_ref = data['source_ref']
249 248 expected_target_ref = data['target_ref']
250 249 data['source_ref'] = 'branch:{}'.format(backend.default_branch_name)
251 250 data['target_ref'] = 'branch:{}'.format(backend.default_branch_name)
252 251 id_, params = build_data(
253 252 self.apikey_regular, 'create_pull_request', **data)
254 253 response = api_call(self.app, params)
255 254 expected_message = "Created new pull request `{title}`".format(
256 255 title=data['title'])
257 256 result = response.json
258 257 assert result['result']['msg'] == expected_message
259 258 pull_request_id = result['result']['pull_request_id']
260 259 pull_request = PullRequestModel().get(pull_request_id)
261 260 assert pull_request.source_ref == expected_source_ref
262 261 assert pull_request.target_ref == expected_target_ref
263 262
264 263 @pytest.mark.backends("git", "hg")
265 264 @pytest.mark.parametrize("data_key", ["source_repo", "target_repo"])
266 265 def test_create_fails_with_wrong_repo(self, backend, data_key):
267 266 repo_name = 'fake-repo'
268 267 data = self._prepare_data(backend)
269 268 data[data_key] = repo_name
270 269 id_, params = build_data(
271 270 self.apikey_regular, 'create_pull_request', **data)
272 271 response = api_call(self.app, params)
273 272 expected_message = 'repository `{}` does not exist'.format(repo_name)
274 273 assert_error(id_, expected_message, given=response.body)
275 274
276 275 @pytest.mark.backends("git", "hg")
277 276 @pytest.mark.parametrize("data_key", ["source_ref", "target_ref"])
278 277 def test_create_fails_with_non_existing_branch(self, backend, data_key):
279 278 branch_name = 'test-branch'
280 279 data = self._prepare_data(backend)
281 280 data[data_key] = "branch:{}".format(branch_name)
282 281 id_, params = build_data(
283 282 self.apikey_regular, 'create_pull_request', **data)
284 283 response = api_call(self.app, params)
285 284 expected_message = 'The specified value:{type}:`{name}` ' \
286 285 'does not exist, or is not allowed.'.format(type='branch',
287 286 name=branch_name)
288 287 assert_error(id_, expected_message, given=response.body)
289 288
290 289 @pytest.mark.backends("git", "hg")
291 290 @pytest.mark.parametrize("data_key", ["source_ref", "target_ref"])
292 291 def test_create_fails_with_ref_in_a_wrong_format(self, backend, data_key):
293 292 data = self._prepare_data(backend)
294 293 ref = 'stange-ref'
295 294 data[data_key] = ref
296 295 id_, params = build_data(
297 296 self.apikey_regular, 'create_pull_request', **data)
298 297 response = api_call(self.app, params)
299 298 expected_message = (
300 299 'Ref `{ref}` given in a wrong format. Please check the API'
301 300 ' documentation for more details'.format(ref=ref))
302 301 assert_error(id_, expected_message, given=response.body)
303 302
304 303 @pytest.mark.backends("git", "hg")
305 304 @pytest.mark.parametrize("data_key", ["source_ref", "target_ref"])
306 305 def test_create_fails_with_non_existing_ref(self, backend, data_key):
307 306 commit_id = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa10'
308 307 ref = self._get_full_ref(backend, commit_id)
309 308 data = self._prepare_data(backend)
310 309 data[data_key] = ref
311 310 id_, params = build_data(
312 311 self.apikey_regular, 'create_pull_request', **data)
313 312 response = api_call(self.app, params)
314 313 expected_message = 'Ref `{}` does not exist'.format(ref)
315 314 assert_error(id_, expected_message, given=response.body)
316 315
317 316 @pytest.mark.backends("git", "hg")
318 317 def test_create_fails_when_no_revisions(self, backend):
319 318 data = self._prepare_data(backend, source_head='initial')
320 319 id_, params = build_data(
321 320 self.apikey_regular, 'create_pull_request', **data)
322 321 response = api_call(self.app, params)
323 322 expected_message = 'no commits found for merge between specified references'
324 323 assert_error(id_, expected_message, given=response.body)
325 324
326 325 @pytest.mark.backends("git", "hg")
327 326 def test_create_fails_when_no_permissions(self, backend):
328 327 data = self._prepare_data(backend)
329 328 RepoModel().revoke_user_permission(
330 329 self.source.repo_name, self.test_user)
331 330 RepoModel().revoke_user_permission(
332 331 self.source.repo_name, User.DEFAULT_USER)
333 332
334 333 id_, params = build_data(
335 334 self.apikey_regular, 'create_pull_request', **data)
336 335 response = api_call(self.app, params)
337 336 expected_message = 'repository `{}` does not exist'.format(
338 337 self.source.repo_name)
339 338 assert_error(id_, expected_message, given=response.body)
340 339
341 340 def _prepare_data(
342 341 self, backend, source_head='change', target_head='initial'):
343 342 commits = [
344 343 {'message': 'initial'},
345 344 {'message': 'change'},
346 345 {'message': 'new-feature', 'parents': ['initial']},
347 346 ]
348 347 self.commit_ids = backend.create_master_repo(commits)
349 348 self.source = backend.create_repo(heads=[source_head])
350 349 self.target = backend.create_repo(heads=[target_head])
351 350
352 351 data = {
353 352 'source_repo': self.source.repo_name,
354 353 'target_repo': self.target.repo_name,
355 354 'source_ref': self._get_full_ref(
356 355 backend, self.commit_ids[source_head]),
357 356 'target_ref': self._get_full_ref(
358 357 backend, self.commit_ids[target_head]),
359 358 'title': 'Test PR 1',
360 359 'description': 'Test'
361 360 }
362 361 RepoModel().grant_user_permission(
363 362 self.source.repo_name, self.TEST_USER_LOGIN, 'repository.read')
364 363 return data
365 364
366 365 def _get_full_ref(self, backend, commit_id):
367 366 return 'branch:{branch}:{commit_id}'.format(
368 367 branch=backend.default_branch_name, commit_id=commit_id)
@@ -1,350 +1,348 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 import json
22
23 20 import mock
24 21 import pytest
25 22
26 from rhodecode.lib.utils2 import safe_unicode
27 23 from rhodecode.lib.vcs import settings
28 24 from rhodecode.model.meta import Session
29 25 from rhodecode.model.repo import RepoModel
30 26 from rhodecode.model.user import UserModel
31 27 from rhodecode.tests import TEST_USER_ADMIN_LOGIN
32 28 from rhodecode.api.tests.utils import (
33 29 build_data, api_call, assert_ok, assert_error, crash)
34 30 from rhodecode.tests.fixture import Fixture
31 from rhodecode.lib.ext_json import json
32 from rhodecode.lib.str_utils import safe_str
35 33
36 34
37 35 fixture = Fixture()
38 36
39 37
40 38 @pytest.mark.usefixtures("testuser_api", "app")
41 39 class TestCreateRepo(object):
42 40
43 41 @pytest.mark.parametrize('given, expected_name, expected_exc', [
44 42 ('api repo-1', 'api-repo-1', False),
45 43 ('api-repo 1-ąć', 'api-repo-1-ąć', False),
46 44 (u'unicode-ąć', u'unicode-ąć', False),
47 45 ('some repo v1.2', 'some-repo-v1.2', False),
48 46 ('v2.0', 'v2.0', False),
49 47 ])
50 48 def test_api_create_repo(self, backend, given, expected_name, expected_exc):
51 49
52 50 id_, params = build_data(
53 51 self.apikey,
54 52 'create_repo',
55 53 repo_name=given,
56 54 owner=TEST_USER_ADMIN_LOGIN,
57 55 repo_type=backend.alias,
58 56 )
59 57 response = api_call(self.app, params)
60 58
61 59 ret = {
62 60 'msg': 'Created new repository `%s`' % (expected_name,),
63 61 'success': True,
64 62 'task': None,
65 63 }
66 64 expected = ret
67 65 assert_ok(id_, expected, given=response.body)
68 66
69 repo = RepoModel().get_by_repo_name(safe_unicode(expected_name))
67 repo = RepoModel().get_by_repo_name(safe_str(expected_name))
70 68 assert repo is not None
71 69
72 70 id_, params = build_data(self.apikey, 'get_repo', repoid=expected_name)
73 71 response = api_call(self.app, params)
74 72 body = json.loads(response.body)
75 73
76 74 assert body['result']['enable_downloads'] is False
77 75 assert body['result']['enable_locking'] is False
78 76 assert body['result']['enable_statistics'] is False
79 77
80 fixture.destroy_repo(safe_unicode(expected_name))
78 fixture.destroy_repo(safe_str(expected_name))
81 79
82 80 def test_api_create_restricted_repo_type(self, backend):
83 81 repo_name = 'api-repo-type-{0}'.format(backend.alias)
84 82 id_, params = build_data(
85 83 self.apikey,
86 84 'create_repo',
87 85 repo_name=repo_name,
88 86 owner=TEST_USER_ADMIN_LOGIN,
89 87 repo_type=backend.alias,
90 88 )
91 89 git_backend = settings.BACKENDS['git']
92 90 with mock.patch(
93 91 'rhodecode.lib.vcs.settings.BACKENDS', {'git': git_backend}):
94 92 response = api_call(self.app, params)
95 93
96 94 repo = RepoModel().get_by_repo_name(repo_name)
97 95
98 96 if backend.alias == 'git':
99 97 assert repo is not None
100 98 expected = {
101 99 'msg': 'Created new repository `{0}`'.format(repo_name,),
102 100 'success': True,
103 101 'task': None,
104 102 }
105 103 assert_ok(id_, expected, given=response.body)
106 104 else:
107 105 assert repo is None
108 106
109 107 fixture.destroy_repo(repo_name)
110 108
111 109 def test_api_create_repo_with_booleans(self, backend):
112 110 repo_name = 'api-repo-2'
113 111 id_, params = build_data(
114 112 self.apikey,
115 113 'create_repo',
116 114 repo_name=repo_name,
117 115 owner=TEST_USER_ADMIN_LOGIN,
118 116 repo_type=backend.alias,
119 117 enable_statistics=True,
120 118 enable_locking=True,
121 119 enable_downloads=True
122 120 )
123 121 response = api_call(self.app, params)
124 122
125 123 repo = RepoModel().get_by_repo_name(repo_name)
126 124
127 125 assert repo is not None
128 126 ret = {
129 127 'msg': 'Created new repository `%s`' % (repo_name,),
130 128 'success': True,
131 129 'task': None,
132 130 }
133 131 expected = ret
134 132 assert_ok(id_, expected, given=response.body)
135 133
136 134 id_, params = build_data(self.apikey, 'get_repo', repoid=repo_name)
137 135 response = api_call(self.app, params)
138 136 body = json.loads(response.body)
139 137
140 138 assert body['result']['enable_downloads'] is True
141 139 assert body['result']['enable_locking'] is True
142 140 assert body['result']['enable_statistics'] is True
143 141
144 142 fixture.destroy_repo(repo_name)
145 143
146 144 def test_api_create_repo_in_group(self, backend):
147 145 repo_group_name = 'my_gr'
148 146 # create the parent
149 147 fixture.create_repo_group(repo_group_name)
150 148
151 149 repo_name = '%s/api-repo-gr' % (repo_group_name,)
152 150 id_, params = build_data(
153 151 self.apikey, 'create_repo',
154 152 repo_name=repo_name,
155 153 owner=TEST_USER_ADMIN_LOGIN,
156 154 repo_type=backend.alias,)
157 155 response = api_call(self.app, params)
158 156 repo = RepoModel().get_by_repo_name(repo_name)
159 157 assert repo is not None
160 158 assert repo.group is not None
161 159
162 160 ret = {
163 161 'msg': 'Created new repository `%s`' % (repo_name,),
164 162 'success': True,
165 163 'task': None,
166 164 }
167 165 expected = ret
168 166 assert_ok(id_, expected, given=response.body)
169 167 fixture.destroy_repo(repo_name)
170 168 fixture.destroy_repo_group(repo_group_name)
171 169
172 170 def test_create_repo_in_group_that_doesnt_exist(self, backend, user_util):
173 171 repo_group_name = 'fake_group'
174 172
175 173 repo_name = '%s/api-repo-gr' % (repo_group_name,)
176 174 id_, params = build_data(
177 175 self.apikey, 'create_repo',
178 176 repo_name=repo_name,
179 177 owner=TEST_USER_ADMIN_LOGIN,
180 178 repo_type=backend.alias,)
181 179 response = api_call(self.app, params)
182 180
183 181 expected = {'repo_group': 'Repository group `{}` does not exist'.format(
184 182 repo_group_name)}
185 183 assert_error(id_, expected, given=response.body)
186 184
187 185 def test_api_create_repo_unknown_owner(self, backend):
188 186 repo_name = 'api-repo-2'
189 187 owner = 'i-dont-exist'
190 188 id_, params = build_data(
191 189 self.apikey, 'create_repo',
192 190 repo_name=repo_name,
193 191 owner=owner,
194 192 repo_type=backend.alias)
195 193 response = api_call(self.app, params)
196 194 expected = 'user `%s` does not exist' % (owner,)
197 195 assert_error(id_, expected, given=response.body)
198 196
199 197 def test_api_create_repo_dont_specify_owner(self, backend):
200 198 repo_name = 'api-repo-3'
201 199 id_, params = build_data(
202 200 self.apikey, 'create_repo',
203 201 repo_name=repo_name,
204 202 repo_type=backend.alias)
205 203 response = api_call(self.app, params)
206 204
207 205 repo = RepoModel().get_by_repo_name(repo_name)
208 206 assert repo is not None
209 207 ret = {
210 208 'msg': 'Created new repository `%s`' % (repo_name,),
211 209 'success': True,
212 210 'task': None,
213 211 }
214 212 expected = ret
215 213 assert_ok(id_, expected, given=response.body)
216 214 fixture.destroy_repo(repo_name)
217 215
218 216 def test_api_create_repo_by_non_admin(self, backend):
219 217 repo_name = 'api-repo-4'
220 218 id_, params = build_data(
221 219 self.apikey_regular, 'create_repo',
222 220 repo_name=repo_name,
223 221 repo_type=backend.alias)
224 222 response = api_call(self.app, params)
225 223
226 224 repo = RepoModel().get_by_repo_name(repo_name)
227 225 assert repo is not None
228 226 ret = {
229 227 'msg': 'Created new repository `%s`' % (repo_name,),
230 228 'success': True,
231 229 'task': None,
232 230 }
233 231 expected = ret
234 232 assert_ok(id_, expected, given=response.body)
235 233 fixture.destroy_repo(repo_name)
236 234
237 235 def test_api_create_repo_by_non_admin_specify_owner(self, backend):
238 236 repo_name = 'api-repo-5'
239 237 owner = 'i-dont-exist'
240 238 id_, params = build_data(
241 239 self.apikey_regular, 'create_repo',
242 240 repo_name=repo_name,
243 241 repo_type=backend.alias,
244 242 owner=owner)
245 243 response = api_call(self.app, params)
246 244
247 245 expected = 'Only RhodeCode super-admin can specify `owner` param'
248 246 assert_error(id_, expected, given=response.body)
249 247 fixture.destroy_repo(repo_name)
250 248
251 249 def test_api_create_repo_by_non_admin_no_parent_group_perms(self, backend):
252 250 repo_group_name = 'no-access'
253 251 fixture.create_repo_group(repo_group_name)
254 252 repo_name = 'no-access/api-repo'
255 253
256 254 id_, params = build_data(
257 255 self.apikey_regular, 'create_repo',
258 256 repo_name=repo_name,
259 257 repo_type=backend.alias)
260 258 response = api_call(self.app, params)
261 259
262 260 expected = {'repo_group': 'Repository group `{}` does not exist'.format(
263 261 repo_group_name)}
264 262 assert_error(id_, expected, given=response.body)
265 263 fixture.destroy_repo_group(repo_group_name)
266 264 fixture.destroy_repo(repo_name)
267 265
268 266 def test_api_create_repo_non_admin_no_permission_to_create_to_root_level(
269 267 self, backend, user_util):
270 268
271 269 regular_user = user_util.create_user()
272 270 regular_user_api_key = regular_user.api_key
273 271
274 272 usr = UserModel().get_by_username(regular_user.username)
275 273 usr.inherit_default_permissions = False
276 274 Session().add(usr)
277 275
278 276 repo_name = backend.new_repo_name()
279 277 id_, params = build_data(
280 278 regular_user_api_key, 'create_repo',
281 279 repo_name=repo_name,
282 280 repo_type=backend.alias)
283 281 response = api_call(self.app, params)
284 282 expected = {
285 283 "repo_name": "You do not have the permission to "
286 284 "store repositories in the root location."}
287 285 assert_error(id_, expected, given=response.body)
288 286
289 287 def test_api_create_repo_exists(self, backend):
290 288 repo_name = backend.repo_name
291 289 id_, params = build_data(
292 290 self.apikey, 'create_repo',
293 291 repo_name=repo_name,
294 292 owner=TEST_USER_ADMIN_LOGIN,
295 293 repo_type=backend.alias,)
296 294 response = api_call(self.app, params)
297 295 expected = {
298 296 'unique_repo_name': 'Repository with name `{}` already exists'.format(
299 297 repo_name)}
300 298 assert_error(id_, expected, given=response.body)
301 299
302 300 @mock.patch.object(RepoModel, 'create', crash)
303 301 def test_api_create_repo_exception_occurred(self, backend):
304 302 repo_name = 'api-repo-6'
305 303 id_, params = build_data(
306 304 self.apikey, 'create_repo',
307 305 repo_name=repo_name,
308 306 owner=TEST_USER_ADMIN_LOGIN,
309 307 repo_type=backend.alias,)
310 308 response = api_call(self.app, params)
311 309 expected = 'failed to create repository `%s`' % (repo_name,)
312 310 assert_error(id_, expected, given=response.body)
313 311
314 312 @pytest.mark.parametrize('parent_group, dirty_name, expected_name', [
315 313 (None, 'foo bar x', 'foo-bar-x'),
316 314 ('foo', '/foo//bar x', 'foo/bar-x'),
317 315 ('foo-bar', 'foo-bar //bar x', 'foo-bar/bar-x'),
318 316 ])
319 317 def test_create_repo_with_extra_slashes_in_name(
320 318 self, backend, parent_group, dirty_name, expected_name):
321 319
322 320 if parent_group:
323 321 gr = fixture.create_repo_group(parent_group)
324 322 assert gr.group_name == parent_group
325 323
326 324 id_, params = build_data(
327 325 self.apikey, 'create_repo',
328 326 repo_name=dirty_name,
329 327 repo_type=backend.alias,
330 328 owner=TEST_USER_ADMIN_LOGIN,)
331 329 response = api_call(self.app, params)
332 330 expected ={
333 331 "msg": "Created new repository `{}`".format(expected_name),
334 332 "task": None,
335 333 "success": True
336 334 }
337 335 assert_ok(id_, expected, response.body)
338 336
339 337 repo = RepoModel().get_by_repo_name(expected_name)
340 338 assert repo is not None
341 339
342 340 expected = {
343 341 'msg': 'Created new repository `%s`' % (expected_name,),
344 342 'success': True,
345 343 'task': None,
346 344 }
347 345 assert_ok(id_, expected, given=response.body)
348 346 fixture.destroy_repo(expected_name)
349 347 if parent_group:
350 348 fixture.destroy_repo_group(parent_group)
@@ -1,289 +1,288 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20 import mock
22 21 import pytest
23 22
24 23 from rhodecode.model.meta import Session
25 24 from rhodecode.model.repo_group import RepoGroupModel
26 25 from rhodecode.model.user import UserModel
27 26 from rhodecode.tests import TEST_USER_ADMIN_LOGIN
28 27 from rhodecode.api.tests.utils import (
29 28 build_data, api_call, assert_ok, assert_error, crash)
30 29 from rhodecode.tests.fixture import Fixture
31 30
32 31
33 32 fixture = Fixture()
34 33
35 34
36 35 @pytest.mark.usefixtures("testuser_api", "app")
37 36 class TestCreateRepoGroup(object):
38 37 def test_api_create_repo_group(self):
39 38 repo_group_name = 'api-repo-group'
40 39
41 40 repo_group = RepoGroupModel.cls.get_by_group_name(repo_group_name)
42 41 assert repo_group is None
43 42
44 43 id_, params = build_data(
45 44 self.apikey, 'create_repo_group',
46 45 group_name=repo_group_name,
47 46 owner=TEST_USER_ADMIN_LOGIN,)
48 47 response = api_call(self.app, params)
49 48
50 49 repo_group = RepoGroupModel.cls.get_by_group_name(repo_group_name)
51 50 assert repo_group is not None
52 51 ret = {
53 52 'msg': 'Created new repo group `%s`' % (repo_group_name,),
54 53 'repo_group': repo_group.get_api_data()
55 54 }
56 55 expected = ret
57 56 try:
58 57 assert_ok(id_, expected, given=response.body)
59 58 finally:
60 59 fixture.destroy_repo_group(repo_group_name)
61 60
62 61 def test_api_create_repo_group_in_another_group(self):
63 62 repo_group_name = 'api-repo-group'
64 63
65 64 repo_group = RepoGroupModel.cls.get_by_group_name(repo_group_name)
66 65 assert repo_group is None
67 66 # create the parent
68 67 fixture.create_repo_group(repo_group_name)
69 68
70 69 full_repo_group_name = repo_group_name+'/'+repo_group_name
71 70 id_, params = build_data(
72 71 self.apikey, 'create_repo_group',
73 72 group_name=full_repo_group_name,
74 73 owner=TEST_USER_ADMIN_LOGIN,
75 74 copy_permissions=True)
76 75 response = api_call(self.app, params)
77 76
78 77 repo_group = RepoGroupModel.cls.get_by_group_name(full_repo_group_name)
79 78 assert repo_group is not None
80 79 ret = {
81 80 'msg': 'Created new repo group `%s`' % (full_repo_group_name,),
82 81 'repo_group': repo_group.get_api_data()
83 82 }
84 83 expected = ret
85 84 try:
86 85 assert_ok(id_, expected, given=response.body)
87 86 finally:
88 87 fixture.destroy_repo_group(full_repo_group_name)
89 88 fixture.destroy_repo_group(repo_group_name)
90 89
91 90 def test_api_create_repo_group_in_another_group_not_existing(self):
92 91 repo_group_name = 'api-repo-group-no'
93 92
94 93 repo_group = RepoGroupModel.cls.get_by_group_name(repo_group_name)
95 94 assert repo_group is None
96 95
97 96 full_repo_group_name = repo_group_name+'/'+repo_group_name
98 97 id_, params = build_data(
99 98 self.apikey, 'create_repo_group',
100 99 group_name=full_repo_group_name,
101 100 owner=TEST_USER_ADMIN_LOGIN,
102 101 copy_permissions=True)
103 102 response = api_call(self.app, params)
104 103 expected = {
105 104 'repo_group':
106 105 'Parent repository group `{}` does not exist'.format(
107 106 repo_group_name)}
108 107 assert_error(id_, expected, given=response.body)
109 108
110 109 def test_api_create_repo_group_that_exists(self):
111 110 repo_group_name = 'api-repo-group'
112 111
113 112 repo_group = RepoGroupModel.cls.get_by_group_name(repo_group_name)
114 113 assert repo_group is None
115 114
116 115 fixture.create_repo_group(repo_group_name)
117 116 id_, params = build_data(
118 117 self.apikey, 'create_repo_group',
119 118 group_name=repo_group_name,
120 119 owner=TEST_USER_ADMIN_LOGIN,)
121 120 response = api_call(self.app, params)
122 121 expected = {
123 122 'unique_repo_group_name':
124 123 'Repository group with name `{}` already exists'.format(
125 124 repo_group_name)}
126 125 try:
127 126 assert_error(id_, expected, given=response.body)
128 127 finally:
129 128 fixture.destroy_repo_group(repo_group_name)
130 129
131 130 def test_api_create_repo_group_regular_user_wit_root_location_perms(
132 131 self, user_util):
133 132 regular_user = user_util.create_user()
134 133 regular_user_api_key = regular_user.api_key
135 134
136 135 repo_group_name = 'api-repo-group-by-regular-user'
137 136
138 137 usr = UserModel().get_by_username(regular_user.username)
139 138 usr.inherit_default_permissions = False
140 139 Session().add(usr)
141 140
142 141 UserModel().grant_perm(
143 142 regular_user.username, 'hg.repogroup.create.true')
144 143 Session().commit()
145 144
146 145 repo_group = RepoGroupModel.cls.get_by_group_name(repo_group_name)
147 146 assert repo_group is None
148 147
149 148 id_, params = build_data(
150 149 regular_user_api_key, 'create_repo_group',
151 150 group_name=repo_group_name)
152 151 response = api_call(self.app, params)
153 152
154 153 repo_group = RepoGroupModel.cls.get_by_group_name(repo_group_name)
155 154 assert repo_group is not None
156 155 expected = {
157 156 'msg': 'Created new repo group `%s`' % (repo_group_name,),
158 157 'repo_group': repo_group.get_api_data()
159 158 }
160 159 try:
161 160 assert_ok(id_, expected, given=response.body)
162 161 finally:
163 162 fixture.destroy_repo_group(repo_group_name)
164 163
165 164 def test_api_create_repo_group_regular_user_with_admin_perms_to_parent(
166 165 self, user_util):
167 166
168 167 repo_group_name = 'api-repo-group-parent'
169 168
170 169 repo_group = RepoGroupModel.cls.get_by_group_name(repo_group_name)
171 170 assert repo_group is None
172 171 # create the parent
173 172 fixture.create_repo_group(repo_group_name)
174 173
175 174 # user perms
176 175 regular_user = user_util.create_user()
177 176 regular_user_api_key = regular_user.api_key
178 177
179 178 usr = UserModel().get_by_username(regular_user.username)
180 179 usr.inherit_default_permissions = False
181 180 Session().add(usr)
182 181
183 182 RepoGroupModel().grant_user_permission(
184 183 repo_group_name, regular_user.username, 'group.admin')
185 184 Session().commit()
186 185
187 186 full_repo_group_name = repo_group_name + '/' + repo_group_name
188 187 id_, params = build_data(
189 188 regular_user_api_key, 'create_repo_group',
190 189 group_name=full_repo_group_name)
191 190 response = api_call(self.app, params)
192 191
193 192 repo_group = RepoGroupModel.cls.get_by_group_name(full_repo_group_name)
194 193 assert repo_group is not None
195 194 expected = {
196 195 'msg': 'Created new repo group `{}`'.format(full_repo_group_name),
197 196 'repo_group': repo_group.get_api_data()
198 197 }
199 198 try:
200 199 assert_ok(id_, expected, given=response.body)
201 200 finally:
202 201 fixture.destroy_repo_group(full_repo_group_name)
203 202 fixture.destroy_repo_group(repo_group_name)
204 203
205 204 def test_api_create_repo_group_regular_user_no_permission_to_create_to_root_level(self):
206 205 repo_group_name = 'api-repo-group'
207 206
208 207 id_, params = build_data(
209 208 self.apikey_regular, 'create_repo_group',
210 209 group_name=repo_group_name)
211 210 response = api_call(self.app, params)
212 211
213 212 expected = {
214 213 'repo_group':
215 214 u'You do not have the permission to store '
216 215 u'repository groups in the root location.'}
217 216 assert_error(id_, expected, given=response.body)
218 217
219 218 def test_api_create_repo_group_regular_user_no_parent_group_perms(self):
220 219 repo_group_name = 'api-repo-group-regular-user'
221 220
222 221 repo_group = RepoGroupModel.cls.get_by_group_name(repo_group_name)
223 222 assert repo_group is None
224 223 # create the parent
225 224 fixture.create_repo_group(repo_group_name)
226 225
227 226 full_repo_group_name = repo_group_name+'/'+repo_group_name
228 227
229 228 id_, params = build_data(
230 229 self.apikey_regular, 'create_repo_group',
231 230 group_name=full_repo_group_name)
232 231 response = api_call(self.app, params)
233 232
234 233 expected = {
235 234 'repo_group':
236 235 u"You do not have the permissions to store "
237 236 u"repository groups inside repository group `{}`".format(repo_group_name)}
238 237 try:
239 238 assert_error(id_, expected, given=response.body)
240 239 finally:
241 240 fixture.destroy_repo_group(repo_group_name)
242 241
243 242 def test_api_create_repo_group_regular_user_no_permission_to_specify_owner(
244 243 self):
245 244 repo_group_name = 'api-repo-group'
246 245
247 246 id_, params = build_data(
248 247 self.apikey_regular, 'create_repo_group',
249 248 group_name=repo_group_name,
250 249 owner=TEST_USER_ADMIN_LOGIN,)
251 250 response = api_call(self.app, params)
252 251
253 252 expected = "Only RhodeCode super-admin can specify `owner` param"
254 253 assert_error(id_, expected, given=response.body)
255 254
256 255 @mock.patch.object(RepoGroupModel, 'create', crash)
257 256 def test_api_create_repo_group_exception_occurred(self):
258 257 repo_group_name = 'api-repo-group'
259 258
260 259 repo_group = RepoGroupModel.cls.get_by_group_name(repo_group_name)
261 260 assert repo_group is None
262 261
263 262 id_, params = build_data(
264 263 self.apikey, 'create_repo_group',
265 264 group_name=repo_group_name,
266 265 owner=TEST_USER_ADMIN_LOGIN,)
267 266 response = api_call(self.app, params)
268 267 expected = 'failed to create repo group `%s`' % (repo_group_name,)
269 268 assert_error(id_, expected, given=response.body)
270 269
271 270 def test_create_group_with_extra_slashes_in_name(self, user_util):
272 271 existing_repo_group = user_util.create_repo_group()
273 272 dirty_group_name = '//{}//group2//'.format(
274 273 existing_repo_group.group_name)
275 274 cleaned_group_name = '{}/group2'.format(
276 275 existing_repo_group.group_name)
277 276
278 277 id_, params = build_data(
279 278 self.apikey, 'create_repo_group',
280 279 group_name=dirty_group_name,
281 280 owner=TEST_USER_ADMIN_LOGIN,)
282 281 response = api_call(self.app, params)
283 282 repo_group = RepoGroupModel.cls.get_by_group_name(cleaned_group_name)
284 283 expected = {
285 284 'msg': 'Created new repo group `%s`' % (cleaned_group_name,),
286 285 'repo_group': repo_group.get_api_data()
287 286 }
288 287 assert_ok(id_, expected, given=response.body)
289 288 fixture.destroy_repo_group(cleaned_group_name)
@@ -1,207 +1,206 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20 import mock
22 21 import pytest
23 22
24 23 from rhodecode.lib.auth import check_password
25 24 from rhodecode.model.user import UserModel
26 25 from rhodecode.tests import (
27 26 TEST_USER_ADMIN_LOGIN, TEST_USER_REGULAR_EMAIL)
28 27 from rhodecode.api.tests.utils import (
29 28 build_data, api_call, assert_ok, assert_error, jsonify, crash)
30 29 from rhodecode.tests.fixture import Fixture
31 30 from rhodecode.model.db import RepoGroup
32 31
33 32
34 33 # TODO: mikhail: remove fixture from here
35 34 fixture = Fixture()
36 35
37 36
38 37 @pytest.mark.usefixtures("testuser_api", "app")
39 38 class TestCreateUser(object):
40 39 def test_api_create_existing_user(self):
41 40 id_, params = build_data(
42 41 self.apikey, 'create_user',
43 42 username=TEST_USER_ADMIN_LOGIN,
44 43 email='test@foo.com',
45 44 password='trololo')
46 45 response = api_call(self.app, params)
47 46
48 47 expected = "user `%s` already exist" % (TEST_USER_ADMIN_LOGIN,)
49 48 assert_error(id_, expected, given=response.body)
50 49
51 50 def test_api_create_user_with_existing_email(self):
52 51 id_, params = build_data(
53 52 self.apikey, 'create_user',
54 53 username=TEST_USER_ADMIN_LOGIN + 'new',
55 54 email=TEST_USER_REGULAR_EMAIL,
56 55 password='trololo')
57 56 response = api_call(self.app, params)
58 57
59 58 expected = "email `%s` already exist" % (TEST_USER_REGULAR_EMAIL,)
60 59 assert_error(id_, expected, given=response.body)
61 60
62 61 def test_api_create_user_with_wrong_username(self):
63 62 bad_username = '<> HELLO WORLD <>'
64 63 id_, params = build_data(
65 64 self.apikey, 'create_user',
66 65 username=bad_username,
67 66 email='new@email.com',
68 67 password='trololo')
69 68 response = api_call(self.app, params)
70 69
71 70 expected = {'username':
72 71 "Username may only contain alphanumeric characters "
73 72 "underscores, periods or dashes and must begin with "
74 73 "alphanumeric character or underscore"}
75 74 assert_error(id_, expected, given=response.body)
76 75
77 76 def test_api_create_user(self):
78 77 username = 'test_new_api_user'
79 78 email = username + "@foo.com"
80 79
81 80 id_, params = build_data(
82 81 self.apikey, 'create_user',
83 82 username=username,
84 83 email=email,
85 84 description='CTO of Things',
86 85 password='example')
87 86 response = api_call(self.app, params)
88 87
89 88 usr = UserModel().get_by_username(username)
90 89 ret = {
91 90 'msg': 'created new user `%s`' % (username,),
92 91 'user': jsonify(usr.get_api_data(include_secrets=True)),
93 92 }
94 93 try:
95 94 expected = ret
96 95 assert check_password('example', usr.password)
97 96 assert_ok(id_, expected, given=response.body)
98 97 finally:
99 98 fixture.destroy_user(usr.user_id)
100 99
101 100 def test_api_create_user_without_password(self):
102 101 username = 'test_new_api_user_passwordless'
103 102 email = username + "@foo.com"
104 103
105 104 id_, params = build_data(
106 105 self.apikey, 'create_user',
107 106 username=username,
108 107 email=email)
109 108 response = api_call(self.app, params)
110 109
111 110 usr = UserModel().get_by_username(username)
112 111 ret = {
113 112 'msg': 'created new user `%s`' % (username,),
114 113 'user': jsonify(usr.get_api_data(include_secrets=True)),
115 114 }
116 115 try:
117 116 expected = ret
118 117 assert_ok(id_, expected, given=response.body)
119 118 finally:
120 119 fixture.destroy_user(usr.user_id)
121 120
122 121 def test_api_create_user_with_extern_name(self):
123 122 username = 'test_new_api_user_passwordless'
124 123 email = username + "@foo.com"
125 124
126 125 id_, params = build_data(
127 126 self.apikey, 'create_user',
128 127 username=username,
129 128 email=email, extern_name='rhodecode')
130 129 response = api_call(self.app, params)
131 130
132 131 usr = UserModel().get_by_username(username)
133 132 ret = {
134 133 'msg': 'created new user `%s`' % (username,),
135 134 'user': jsonify(usr.get_api_data(include_secrets=True)),
136 135 }
137 136 try:
138 137 expected = ret
139 138 assert_ok(id_, expected, given=response.body)
140 139 finally:
141 140 fixture.destroy_user(usr.user_id)
142 141
143 142 def test_api_create_user_with_password_change(self):
144 143 username = 'test_new_api_user_password_change'
145 144 email = username + "@foo.com"
146 145
147 146 id_, params = build_data(
148 147 self.apikey, 'create_user',
149 148 username=username,
150 149 email=email, extern_name='rhodecode',
151 150 force_password_change=True)
152 151 response = api_call(self.app, params)
153 152
154 153 usr = UserModel().get_by_username(username)
155 154 ret = {
156 155 'msg': 'created new user `%s`' % (username,),
157 156 'user': jsonify(usr.get_api_data(include_secrets=True)),
158 157 }
159 158 try:
160 159 expected = ret
161 160 assert_ok(id_, expected, given=response.body)
162 161 finally:
163 162 fixture.destroy_user(usr.user_id)
164 163
165 164 def test_api_create_user_with_personal_repo_group(self):
166 165 username = 'test_new_api_user_personal_group'
167 166 email = username + "@foo.com"
168 167
169 168 id_, params = build_data(
170 169 self.apikey, 'create_user',
171 170 username=username,
172 171 email=email, extern_name='rhodecode',
173 172 create_personal_repo_group=True)
174 173 response = api_call(self.app, params)
175 174
176 175 usr = UserModel().get_by_username(username)
177 176 ret = {
178 177 'msg': 'created new user `%s`' % (username,),
179 178 'user': jsonify(usr.get_api_data(include_secrets=True)),
180 179 }
181 180
182 181 personal_group = RepoGroup.get_by_group_name(username)
183 182 assert personal_group
184 183 assert personal_group.personal == True
185 184 assert personal_group.user.username == username
186 185
187 186 try:
188 187 expected = ret
189 188 assert_ok(id_, expected, given=response.body)
190 189 finally:
191 190 fixture.destroy_repo_group(username)
192 191 fixture.destroy_user(usr.user_id)
193 192
194 193 @mock.patch.object(UserModel, 'create_or_update', crash)
195 194 def test_api_create_user_when_exception_happened(self):
196 195
197 196 username = 'test_new_api_user'
198 197 email = username + "@foo.com"
199 198
200 199 id_, params = build_data(
201 200 self.apikey, 'create_user',
202 201 username=username,
203 202 email=email,
204 203 password='trololo')
205 204 response = api_call(self.app, params)
206 205 expected = 'failed to create user `%s`' % (username,)
207 206 assert_error(id_, expected, given=response.body)
@@ -1,127 +1,126 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20 import mock
22 21 import pytest
23 22
24 23 from rhodecode.model.meta import Session
25 24 from rhodecode.model.user import UserModel
26 25 from rhodecode.model.user_group import UserGroupModel
27 26 from rhodecode.api.tests.utils import (
28 27 build_data, api_call, assert_error, assert_ok, crash, jsonify)
29 28 from rhodecode.tests.fixture import Fixture
30 29
31 30
32 31 @pytest.mark.usefixtures("testuser_api", "app")
33 32 class TestCreateUserGroup(object):
34 33 fixture = Fixture()
35 34
36 35 def test_api_create_user_group(self):
37 36 group_name = 'some_new_group'
38 37 id_, params = build_data(
39 38 self.apikey, 'create_user_group', group_name=group_name)
40 39 response = api_call(self.app, params)
41 40
42 41 ret = {
43 42 'msg': 'created new user group `%s`' % (group_name,),
44 43 'user_group': jsonify(
45 44 UserGroupModel()
46 45 .get_by_name(group_name)
47 46 .get_api_data()
48 47 )
49 48 }
50 49 expected = ret
51 50 assert_ok(id_, expected, given=response.body)
52 51 self.fixture.destroy_user_group(group_name)
53 52
54 53 def test_api_create_user_group_regular_user(self):
55 54 group_name = 'some_new_group'
56 55
57 56 usr = UserModel().get_by_username(self.TEST_USER_LOGIN)
58 57 usr.inherit_default_permissions = False
59 58 Session().add(usr)
60 59 UserModel().grant_perm(
61 60 self.TEST_USER_LOGIN, 'hg.usergroup.create.true')
62 61 Session().commit()
63 62
64 63 id_, params = build_data(
65 64 self.apikey_regular, 'create_user_group', group_name=group_name)
66 65 response = api_call(self.app, params)
67 66
68 67 expected = {
69 68 'msg': 'created new user group `%s`' % (group_name,),
70 69 'user_group': jsonify(
71 70 UserGroupModel()
72 71 .get_by_name(group_name)
73 72 .get_api_data()
74 73 )
75 74 }
76 75 try:
77 76 assert_ok(id_, expected, given=response.body)
78 77 finally:
79 78 self.fixture.destroy_user_group(group_name)
80 79 UserModel().revoke_perm(
81 80 self.TEST_USER_LOGIN, 'hg.usergroup.create.true')
82 81 usr = UserModel().get_by_username(self.TEST_USER_LOGIN)
83 82 usr.inherit_default_permissions = True
84 83 Session().add(usr)
85 84 Session().commit()
86 85
87 86 def test_api_create_user_group_regular_user_no_permission(self):
88 87 group_name = 'some_new_group'
89 88 id_, params = build_data(
90 89 self.apikey_regular, 'create_user_group', group_name=group_name)
91 90 response = api_call(self.app, params)
92 91 expected = "Access was denied to this resource."
93 92 assert_error(id_, expected, given=response.body)
94 93
95 94 def test_api_create_user_group_that_exist(self, user_util):
96 95 group = user_util.create_user_group()
97 96 group_name = group.users_group_name
98 97
99 98 id_, params = build_data(
100 99 self.apikey, 'create_user_group', group_name=group_name)
101 100 response = api_call(self.app, params)
102 101
103 102 expected = "user group `%s` already exist" % (group_name,)
104 103 assert_error(id_, expected, given=response.body)
105 104
106 105 @mock.patch.object(UserGroupModel, 'create', crash)
107 106 def test_api_create_user_group_exception_occurred(self):
108 107 group_name = 'exception_happens'
109 108 id_, params = build_data(
110 109 self.apikey, 'create_user_group', group_name=group_name)
111 110 response = api_call(self.app, params)
112 111
113 112 expected = 'failed to create group `%s`' % (group_name,)
114 113 assert_error(id_, expected, given=response.body)
115 114
116 115 def test_api_create_user_group_with_wrong_name(self, user_util):
117 116
118 117 group_name = 'wrong NAME <>'
119 118 id_, params = build_data(
120 119 self.apikey, 'create_user_group', group_name=group_name)
121 120 response = api_call(self.app, params)
122 121
123 122 expected = {"user_group_name":
124 123 "Allowed in name are letters, numbers, and `-`, `_`, "
125 124 "`.` Name must start with a letter or number. "
126 125 "Got `{}`".format(group_name)}
127 126 assert_error(id_, expected, given=response.body)
@@ -1,61 +1,60 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20 import mock
22 21 import pytest
23 22
24 23 from rhodecode.model.gist import GistModel
25 24 from rhodecode.api.tests.utils import (
26 25 build_data, api_call, assert_error, assert_ok, crash)
27 26
28 27
29 28 @pytest.mark.usefixtures("testuser_api", "app")
30 29 class TestApiDeleteGist(object):
31 30 def test_api_delete_gist(self, gist_util):
32 31 gist_id = gist_util.create_gist().gist_access_id
33 32 id_, params = build_data(self.apikey, 'delete_gist', gistid=gist_id)
34 33 response = api_call(self.app, params)
35 34 expected = {'gist': None, 'msg': 'deleted gist ID:%s' % (gist_id,)}
36 35 assert_ok(id_, expected, given=response.body)
37 36
38 37 def test_api_delete_gist_regular_user(self, gist_util):
39 38 gist_id = gist_util.create_gist(
40 39 owner=self.TEST_USER_LOGIN).gist_access_id
41 40 id_, params = build_data(
42 41 self.apikey_regular, 'delete_gist', gistid=gist_id)
43 42 response = api_call(self.app, params)
44 43 expected = {'gist': None, 'msg': 'deleted gist ID:%s' % (gist_id,)}
45 44 assert_ok(id_, expected, given=response.body)
46 45
47 46 def test_api_delete_gist_regular_user_no_permission(self, gist_util):
48 47 gist_id = gist_util.create_gist().gist_access_id
49 48 id_, params = build_data(
50 49 self.apikey_regular, 'delete_gist', gistid=gist_id)
51 50 response = api_call(self.app, params)
52 51 expected = 'gist `%s` does not exist' % (gist_id,)
53 52 assert_error(id_, expected, given=response.body)
54 53
55 54 @mock.patch.object(GistModel, 'delete', crash)
56 55 def test_api_delete_gist_exception_occurred(self, gist_util):
57 56 gist_id = gist_util.create_gist().gist_access_id
58 57 id_, params = build_data(self.apikey, 'delete_gist', gistid=gist_id)
59 58 response = api_call(self.app, params)
60 59 expected = 'failed to delete gist ID:%s' % (gist_id,)
61 60 assert_error(id_, expected, given=response.body)
@@ -1,74 +1,73 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20 import mock
22 21 import pytest
23 22
24 23 from rhodecode.model.repo import RepoModel
25 24 from rhodecode.api.tests.utils import (
26 25 build_data, api_call, assert_error, assert_ok, crash)
27 26
28 27
29 28 @pytest.mark.usefixtures("testuser_api", "app")
30 29 class TestApiDeleteRepo(object):
31 30 def test_api_delete_repo(self, backend):
32 31 repo = backend.create_repo()
33 32 repo_name = repo.repo_name
34 33 id_, params = build_data(
35 34 self.apikey, 'delete_repo', repoid=repo.repo_name, )
36 35 response = api_call(self.app, params)
37 36
38 37 expected = {
39 38 'msg': 'Deleted repository `%s`' % (repo_name,),
40 39 'success': True
41 40 }
42 41 assert_ok(id_, expected, given=response.body)
43 42
44 43 def test_api_delete_repo_by_non_admin(self, backend, user_regular):
45 44 repo = backend.create_repo(cur_user=user_regular.username)
46 45 repo_name = repo.repo_name
47 46 id_, params = build_data(
48 47 user_regular.api_key, 'delete_repo', repoid=repo.repo_name, )
49 48 response = api_call(self.app, params)
50 49
51 50 expected = {
52 51 'msg': 'Deleted repository `%s`' % (repo_name,),
53 52 'success': True
54 53 }
55 54 assert_ok(id_, expected, given=response.body)
56 55
57 56 def test_api_delete_repo_by_non_admin_no_permission(self, backend):
58 57 repo = backend.create_repo()
59 58 repo_name = repo.repo_name
60 59 id_, params = build_data(
61 60 self.apikey_regular, 'delete_repo', repoid=repo.repo_name, )
62 61 response = api_call(self.app, params)
63 62 expected = 'repository `%s` does not exist' % (repo_name)
64 63 assert_error(id_, expected, given=response.body)
65 64
66 65 def test_api_delete_repo_exception_occurred(self, backend):
67 66 repo = backend.create_repo()
68 67 repo_name = repo.repo_name
69 68 id_, params = build_data(
70 69 self.apikey, 'delete_repo', repoid=repo.repo_name, )
71 70 with mock.patch.object(RepoModel, 'delete', crash):
72 71 response = api_call(self.app, params)
73 72 expected = 'failed to delete repository `%s`' % (repo_name,)
74 73 assert_error(id_, expected, given=response.body)
@@ -1,86 +1,85 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20
22 21 import pytest
23 22
24 23 from rhodecode.model.repo_group import RepoGroupModel
25 24 from rhodecode.model.user import UserModel
26 25 from rhodecode.api.tests.utils import (
27 26 build_data, api_call, assert_error, assert_ok)
28 27
29 28
30 29 @pytest.mark.usefixtures("testuser_api", "app")
31 30 class TestApiDeleteRepoGroup(object):
32 31 def test_api_delete_repo_group(self, user_util):
33 32 repo_group = user_util.create_repo_group(auto_cleanup=False)
34 33 repo_group_name = repo_group.group_name
35 34 repo_group_id = repo_group.group_id
36 35 id_, params = build_data(
37 36 self.apikey, 'delete_repo_group', repogroupid=repo_group_name, )
38 37 response = api_call(self.app, params)
39 38
40 39 ret = {
41 40 'msg': 'deleted repo group ID:%s %s' % (
42 41 repo_group_id, repo_group_name
43 42 ),
44 43 'repo_group': None
45 44 }
46 45 expected = ret
47 46 assert_ok(id_, expected, given=response.body)
48 47 gr = RepoGroupModel()._get_repo_group(repo_group_name)
49 48 assert gr is None
50 49
51 50 def test_api_delete_repo_group_regular_user(self, user_util):
52 51 repo_group = user_util.create_repo_group(auto_cleanup=False)
53 52 repo_group_name = repo_group.group_name
54 53 repo_group_id = repo_group.group_id
55 54
56 55 user = UserModel().get_by_username(self.TEST_USER_LOGIN)
57 56 user_util.grant_user_permission_to_repo_group(
58 57 repo_group, user, 'group.admin')
59 58
60 59 id_, params = build_data(
61 60 self.apikey, 'delete_repo_group', repogroupid=repo_group_name, )
62 61 response = api_call(self.app, params)
63 62
64 63 ret = {
65 64 'msg': 'deleted repo group ID:%s %s' % (
66 65 repo_group_id, repo_group_name
67 66 ),
68 67 'repo_group': None
69 68 }
70 69 expected = ret
71 70 assert_ok(id_, expected, given=response.body)
72 71 gr = RepoGroupModel()._get_repo_group(repo_group_name)
73 72 assert gr is None
74 73
75 74 def test_api_delete_repo_group_regular_user_no_permission(self, user_util):
76 75 repo_group = user_util.create_repo_group()
77 76 repo_group_name = repo_group.group_name
78 77
79 78 id_, params = build_data(
80 79 self.apikey_regular, 'delete_repo_group',
81 80 repogroupid=repo_group_name, )
82 81 response = api_call(self.app, params)
83 82
84 83 expected = 'repository group `%s` does not exist' % (
85 84 repo_group_name,)
86 85 assert_error(id_, expected, given=response.body)
@@ -1,57 +1,56 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20
22 21 import mock
23 22 import pytest
24 23
25 24 from rhodecode.model.user import UserModel
26 25 from rhodecode.api.tests.utils import (
27 26 build_data, api_call, assert_ok, assert_error, crash)
28 27
29 28
30 29 @pytest.mark.usefixtures("testuser_api", "app")
31 30 class TestDeleteUser(object):
32 31 def test_api_delete_user(self, user_util):
33 32 usr = user_util.create_user(auto_cleanup=False)
34 33
35 34 username = usr.username
36 35 usr_id = usr.user_id
37 36
38 37 id_, params = build_data(self.apikey, 'delete_user', userid=username)
39 38 response = api_call(self.app, params)
40 39
41 40 ret = {'msg': 'deleted user ID:%s %s' % (usr_id, username),
42 41 'user': None}
43 42 expected = ret
44 43 assert_ok(id_, expected, given=response.body)
45 44
46 45 @mock.patch.object(UserModel, 'delete', crash)
47 46 def test_api_delete_user_when_exception_happened(self, user_util):
48 47 usr = user_util.create_user()
49 48 username = usr.username
50 49
51 50 id_, params = build_data(
52 51 self.apikey, 'delete_user', userid=username, )
53 52 response = api_call(self.app, params)
54 53 ret = 'failed to delete user ID:%s %s' % (usr.user_id,
55 54 usr.username)
56 55 expected = ret
57 56 assert_error(id_, expected, given=response.body)
@@ -1,106 +1,105 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20
22 21 import mock
23 22 import pytest
24 23
25 24 from rhodecode.model.user import UserModel
26 25 from rhodecode.model.user_group import UserGroupModel
27 26 from rhodecode.api.tests.utils import (
28 27 build_data, api_call, assert_error, assert_ok, crash)
29 28
30 29
31 30 @pytest.mark.usefixtures("testuser_api", "app")
32 31 class TestDeleteUserGroup(object):
33 32 def test_api_delete_user_group(self, user_util):
34 33 user_group = user_util.create_user_group(auto_cleanup=False)
35 34 group_name = user_group.users_group_name
36 35 group_id = user_group.users_group_id
37 36 id_, params = build_data(
38 37 self.apikey, 'delete_user_group', usergroupid=group_name)
39 38 response = api_call(self.app, params)
40 39
41 40 expected = {
42 41 'user_group': None,
43 42 'msg': 'deleted user group ID:%s %s' % (group_id, group_name)
44 43 }
45 44 assert_ok(id_, expected, given=response.body)
46 45
47 46 def test_api_delete_user_group_regular_user(self, user_util):
48 47 ugroup = user_util.create_user_group(auto_cleanup=False)
49 48 group_name = ugroup.users_group_name
50 49 group_id = ugroup.users_group_id
51 50 user = UserModel().get_by_username(self.TEST_USER_LOGIN)
52 51
53 52 user_util.grant_user_permission_to_user_group(
54 53 ugroup, user, 'usergroup.admin')
55 54
56 55 id_, params = build_data(
57 56 self.apikey_regular, 'delete_user_group', usergroupid=group_name)
58 57 response = api_call(self.app, params)
59 58
60 59 expected = {
61 60 'user_group': None,
62 61 'msg': 'deleted user group ID:%s %s' % (group_id, group_name)
63 62 }
64 63 assert_ok(id_, expected, given=response.body)
65 64
66 65 def test_api_delete_user_group_regular_user_no_permission(self, user_util):
67 66 user_group = user_util.create_user_group()
68 67 group_name = user_group.users_group_name
69 68
70 69 id_, params = build_data(
71 70 self.apikey_regular, 'delete_user_group', usergroupid=group_name)
72 71 response = api_call(self.app, params)
73 72
74 73 expected = 'user group `%s` does not exist' % (group_name)
75 74 assert_error(id_, expected, given=response.body)
76 75
77 76 def test_api_delete_user_group_that_is_assigned(self, backend, user_util):
78 77 ugroup = user_util.create_user_group()
79 78 group_name = ugroup.users_group_name
80 79 repo = backend.create_repo()
81 80
82 81 ugr_to_perm = user_util.grant_user_group_permission_to_repo(
83 82 repo, ugroup, 'repository.write')
84 83 msg = 'UserGroup assigned to %s' % (ugr_to_perm.repository)
85 84
86 85 id_, params = build_data(
87 86 self.apikey, 'delete_user_group',
88 87 usergroupid=group_name)
89 88 response = api_call(self.app, params)
90 89
91 90 expected = msg
92 91 assert_error(id_, expected, given=response.body)
93 92
94 93 def test_api_delete_user_group_exception_occurred(self, user_util):
95 94 ugroup = user_util.create_user_group()
96 95 group_name = ugroup.users_group_name
97 96 group_id = ugroup.users_group_id
98 97 id_, params = build_data(
99 98 self.apikey, 'delete_user_group',
100 99 usergroupid=group_name)
101 100
102 101 with mock.patch.object(UserGroupModel, 'delete', crash):
103 102 response = api_call(self.app, params)
104 103 expected = 'failed to delete user group ID:%s %s' % (
105 104 group_id, group_name)
106 105 assert_error(id_, expected, given=response.body)
@@ -1,79 +1,78 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20
22 21 import pytest
23 22
24 23 from rhodecode.api.views import deprecated_api
25 24 from rhodecode.lib.ext_json import json
26 25 from rhodecode.api.tests.utils import (
27 26 build_data, api_call)
28 27
29 28
30 29 @pytest.mark.usefixtures("testuser_api", "app")
31 30 class TestCommitComment(object):
32 31 def test_deprecated_message_in_docstring(self):
33 32 docstring = deprecated_api.changeset_comment.__doc__
34 33 assert '.. deprecated:: 3.4.0' in docstring
35 34 assert 'Please use method `comment_commit` instead.' in docstring
36 35
37 36 def test_deprecated_message_in_retvalue(self):
38 37
39 38 id_, params = build_data(
40 39 self.apikey, 'show_ip')
41 40 response = api_call(self.app, params)
42 41
43 42 expected = {
44 43 'id': id_,
45 44 'error': None,
46 45 'result': json.loads(response.body)['result'],
47 46 'DEPRECATION_WARNING':
48 47 'DEPRECATED METHOD Please use method `get_ip` instead.'
49 48 }
50 49 assert expected == json.loads(response.body)
51 50
52 51 # def test_calls_comment_commit(self, backend, no_notifications):
53 52 # data = {
54 53 # 'repoid': backend.repo_name,
55 54 # 'status': ChangesetStatus.STATUS_APPROVED,
56 55 # 'message': 'Approved',
57 56 # 'revision': 'tip'
58 57 # }
59 58 # with patch.object(repo_api, 'changeset_commit') as comment_mock:
60 59 # id_, params = build_data(self.apikey, 'comment_commit', **data)
61 60 # api_call(self.app, params)
62 61 #
63 62 # _, call_args = comment_mock.call_args
64 63 # data['commit_id'] = data.pop('revision')
65 64 # for key in data:
66 65 # assert call_args[key] == data[key]
67 66
68 67 # def test_warning_log_contains_deprecation_message(self):
69 68 # api = self.SampleApi()
70 69 # with patch.object(utils, 'log') as log_mock:
71 70 # api.api_method()
72 71 #
73 72 # assert log_mock.warning.call_count == 1
74 73 # call_args = log_mock.warning.call_args[0]
75 74 # assert (
76 75 # call_args[0] ==
77 76 # 'DEPRECATED API CALL on function %s, please use `%s` instead')
78 77 # assert call_args[1].__name__ == 'api_method'
79 78 # assert call_args[2] == 'new_method' No newline at end of file
@@ -1,279 +1,278 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20
22 21 import mock
23 22 import pytest
24 23
25 24 from rhodecode.model.meta import Session
26 25 from rhodecode.model.repo import RepoModel
27 26 from rhodecode.model.repo_group import RepoGroupModel
28 27 from rhodecode.model.user import UserModel
29 28 from rhodecode.tests import TEST_USER_ADMIN_LOGIN
30 29 from rhodecode.api.tests.utils import (
31 30 build_data, api_call, assert_error, assert_ok, crash)
32 31 from rhodecode.tests.fixture import Fixture
33 32
34 33
35 34 fixture = Fixture()
36 35
37 36
38 37 @pytest.mark.usefixtures("testuser_api", "app")
39 38 class TestApiForkRepo(object):
40 39 def test_api_fork_repo(self, backend):
41 40 source_name = backend['minimal'].repo_name
42 41 fork_name = backend.new_repo_name()
43 42
44 43 id_, params = build_data(
45 44 self.apikey, 'fork_repo',
46 45 repoid=source_name,
47 46 fork_name=fork_name,
48 47 owner=TEST_USER_ADMIN_LOGIN)
49 48 response = api_call(self.app, params)
50 49
51 50 expected = {
52 51 'msg': 'Created fork of `%s` as `%s`' % (source_name, fork_name),
53 52 'success': True,
54 53 'task': None,
55 54 }
56 55 try:
57 56 assert_ok(id_, expected, given=response.body)
58 57 finally:
59 58 fixture.destroy_repo(fork_name)
60 59
61 60 def test_api_fork_repo_into_group(self, backend, user_util):
62 61 source_name = backend['minimal'].repo_name
63 62 repo_group = user_util.create_repo_group()
64 63 fork_name = '%s/api-repo-fork' % repo_group.group_name
65 64 id_, params = build_data(
66 65 self.apikey, 'fork_repo',
67 66 repoid=source_name,
68 67 fork_name=fork_name,
69 68 owner=TEST_USER_ADMIN_LOGIN)
70 69 response = api_call(self.app, params)
71 70
72 71 ret = {
73 72 'msg': 'Created fork of `%s` as `%s`' % (source_name, fork_name),
74 73 'success': True,
75 74 'task': None,
76 75 }
77 76 expected = ret
78 77 try:
79 78 assert_ok(id_, expected, given=response.body)
80 79 finally:
81 80 fixture.destroy_repo(fork_name)
82 81
83 82 def test_api_fork_repo_non_admin(self, backend):
84 83 source_name = backend['minimal'].repo_name
85 84 fork_name = backend.new_repo_name()
86 85
87 86 id_, params = build_data(
88 87 self.apikey_regular, 'fork_repo',
89 88 repoid=source_name,
90 89 fork_name=fork_name)
91 90 response = api_call(self.app, params)
92 91
93 92 expected = {
94 93 'msg': 'Created fork of `%s` as `%s`' % (source_name, fork_name),
95 94 'success': True,
96 95 'task': None,
97 96 }
98 97 try:
99 98 assert_ok(id_, expected, given=response.body)
100 99 finally:
101 100 fixture.destroy_repo(fork_name)
102 101
103 102 def test_api_fork_repo_non_admin_into_group_no_permission(self, backend, user_util):
104 103 source_name = backend['minimal'].repo_name
105 104 repo_group = user_util.create_repo_group()
106 105 repo_group_name = repo_group.group_name
107 106 fork_name = '%s/api-repo-fork' % repo_group_name
108 107
109 108 id_, params = build_data(
110 109 self.apikey_regular, 'fork_repo',
111 110 repoid=source_name,
112 111 fork_name=fork_name)
113 112 response = api_call(self.app, params)
114 113
115 114 expected = {
116 115 'repo_group': 'Repository group `{}` does not exist'.format(
117 116 repo_group_name)}
118 117 try:
119 118 assert_error(id_, expected, given=response.body)
120 119 finally:
121 120 fixture.destroy_repo(fork_name)
122 121
123 122 def test_api_fork_repo_non_admin_into_group(self, backend, user_util):
124 123 source_name = backend['minimal'].repo_name
125 124 repo_group = user_util.create_repo_group()
126 125 fork_name = '%s/api-repo-fork' % repo_group.group_name
127 126
128 127 RepoGroupModel().grant_user_permission(
129 128 repo_group, self.TEST_USER_LOGIN, 'group.admin')
130 129 Session().commit()
131 130
132 131 id_, params = build_data(
133 132 self.apikey_regular, 'fork_repo',
134 133 repoid=source_name,
135 134 fork_name=fork_name)
136 135 response = api_call(self.app, params)
137 136
138 137 expected = {
139 138 'msg': 'Created fork of `%s` as `%s`' % (source_name, fork_name),
140 139 'success': True,
141 140 'task': None,
142 141 }
143 142 try:
144 143 assert_ok(id_, expected, given=response.body)
145 144 finally:
146 145 fixture.destroy_repo(fork_name)
147 146
148 147 def test_api_fork_repo_non_admin_specify_owner(self, backend):
149 148 source_name = backend['minimal'].repo_name
150 149 fork_name = backend.new_repo_name()
151 150 id_, params = build_data(
152 151 self.apikey_regular, 'fork_repo',
153 152 repoid=source_name,
154 153 fork_name=fork_name,
155 154 owner=TEST_USER_ADMIN_LOGIN)
156 155 response = api_call(self.app, params)
157 156 expected = 'Only RhodeCode super-admin can specify `owner` param'
158 157 assert_error(id_, expected, given=response.body)
159 158
160 159 def test_api_fork_repo_non_admin_no_permission_of_source_repo(
161 160 self, backend):
162 161 source_name = backend['minimal'].repo_name
163 162 RepoModel().grant_user_permission(repo=source_name,
164 163 user=self.TEST_USER_LOGIN,
165 164 perm='repository.none')
166 165 fork_name = backend.new_repo_name()
167 166 id_, params = build_data(
168 167 self.apikey_regular, 'fork_repo',
169 168 repoid=backend.repo_name,
170 169 fork_name=fork_name)
171 170 response = api_call(self.app, params)
172 171 expected = 'repository `%s` does not exist' % (backend.repo_name)
173 172 assert_error(id_, expected, given=response.body)
174 173
175 174 def test_api_fork_repo_non_admin_no_permission_to_fork_to_root_level(
176 175 self, backend, user_util):
177 176
178 177 regular_user = user_util.create_user()
179 178 regular_user_api_key = regular_user.api_key
180 179 usr = UserModel().get_by_username(regular_user.username)
181 180 usr.inherit_default_permissions = False
182 181 Session().add(usr)
183 182 UserModel().grant_perm(regular_user.username, 'hg.fork.repository')
184 183
185 184 source_name = backend['minimal'].repo_name
186 185 fork_name = backend.new_repo_name()
187 186 id_, params = build_data(
188 187 regular_user_api_key, 'fork_repo',
189 188 repoid=source_name,
190 189 fork_name=fork_name)
191 190 response = api_call(self.app, params)
192 191 expected = {
193 192 "repo_name": "You do not have the permission to "
194 193 "store repositories in the root location."}
195 194 assert_error(id_, expected, given=response.body)
196 195
197 196 def test_api_fork_repo_non_admin_no_permission_to_fork(
198 197 self, backend, user_util):
199 198
200 199 regular_user = user_util.create_user()
201 200 regular_user_api_key = regular_user.api_key
202 201 usr = UserModel().get_by_username(regular_user.username)
203 202 usr.inherit_default_permissions = False
204 203 Session().add(usr)
205 204
206 205 source_name = backend['minimal'].repo_name
207 206 fork_name = backend.new_repo_name()
208 207 id_, params = build_data(
209 208 regular_user_api_key, 'fork_repo',
210 209 repoid=source_name,
211 210 fork_name=fork_name)
212 211 response = api_call(self.app, params)
213 212
214 213 expected = "Access was denied to this resource."
215 214 assert_error(id_, expected, given=response.body)
216 215
217 216 def test_api_fork_repo_unknown_owner(self, backend):
218 217 source_name = backend['minimal'].repo_name
219 218 fork_name = backend.new_repo_name()
220 219 owner = 'i-dont-exist'
221 220 id_, params = build_data(
222 221 self.apikey, 'fork_repo',
223 222 repoid=source_name,
224 223 fork_name=fork_name,
225 224 owner=owner)
226 225 response = api_call(self.app, params)
227 226 expected = 'user `%s` does not exist' % (owner,)
228 227 assert_error(id_, expected, given=response.body)
229 228
230 229 def test_api_fork_repo_fork_exists(self, backend):
231 230 source_name = backend['minimal'].repo_name
232 231 fork_name = backend.new_repo_name()
233 232 fork_repo = fixture.create_fork(source_name, fork_name)
234 233
235 234 id_, params = build_data(
236 235 self.apikey, 'fork_repo',
237 236 repoid=source_name,
238 237 fork_name=fork_name,
239 238 owner=TEST_USER_ADMIN_LOGIN)
240 239 response = api_call(self.app, params)
241 240
242 241 try:
243 242 expected = {
244 243 'unique_repo_name': 'Repository with name `{}` already exists'.format(
245 244 fork_name)}
246 245 assert_error(id_, expected, given=response.body)
247 246 finally:
248 247 fixture.destroy_repo(fork_repo.repo_name)
249 248
250 249 def test_api_fork_repo_repo_exists(self, backend):
251 250 source_name = backend['minimal'].repo_name
252 251 fork_name = source_name
253 252
254 253 id_, params = build_data(
255 254 self.apikey, 'fork_repo',
256 255 repoid=source_name,
257 256 fork_name=fork_name,
258 257 owner=TEST_USER_ADMIN_LOGIN)
259 258 response = api_call(self.app, params)
260 259
261 260 expected = {
262 261 'unique_repo_name': 'Repository with name `{}` already exists'.format(
263 262 fork_name)}
264 263 assert_error(id_, expected, given=response.body)
265 264
266 265 @mock.patch.object(RepoModel, 'create_fork', crash)
267 266 def test_api_fork_repo_exception_occurred(self, backend):
268 267 source_name = backend['minimal'].repo_name
269 268 fork_name = backend.new_repo_name()
270 269 id_, params = build_data(
271 270 self.apikey, 'fork_repo',
272 271 repoid=source_name,
273 272 fork_name=fork_name,
274 273 owner=TEST_USER_ADMIN_LOGIN)
275 274 response = api_call(self.app, params)
276 275
277 276 expected = 'failed to fork repository `%s` as `%s`' % (source_name,
278 277 fork_name)
279 278 assert_error(id_, expected, given=response.body)
@@ -1,115 +1,114 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20 import pytest
22 21 from rhodecode.tests import HG_REPO
23 22 from rhodecode.api.tests.utils import (
24 23 build_data, api_call, assert_error, assert_ok)
25 24
26 25
27 26 @pytest.mark.usefixtures("testuser_api", "app")
28 27 class TestApiSearch(object):
29 28
30 29 @pytest.mark.parametrize("sort_dir", [
31 30 "asc",
32 31 "desc",
33 32 ])
34 33 @pytest.mark.parametrize("sort", [
35 34 "xxx",
36 35 "author_email",
37 36 "date",
38 37 "message",
39 38 ])
40 39 @pytest.mark.parametrize("query, expected_hits, expected_paths", [
41 40 ('todo', 23, [
42 41 'vcs/backends/hg/inmemory.py',
43 42 'vcs/tests/test_git.py']),
44 43 ('extension:rst installation', 6, [
45 44 'docs/index.rst',
46 45 'docs/installation.rst']),
47 46 ('def repo', 87, [
48 47 'vcs/tests/test_git.py',
49 48 'vcs/tests/test_changesets.py']),
50 49 ('repository:%s def test' % HG_REPO, 18, [
51 50 'vcs/tests/test_git.py',
52 51 'vcs/tests/test_changesets.py']),
53 52 ('"def main"', 9, [
54 53 'vcs/__init__.py',
55 54 'vcs/tests/__init__.py',
56 55 'vcs/utils/progressbar.py']),
57 56 ('owner:test_admin', 358, [
58 57 'vcs/tests/base.py',
59 58 'MANIFEST.in',
60 59 'vcs/utils/termcolors.py',
61 60 'docs/theme/ADC/static/documentation.png']),
62 61 ('owner:test_admin def main', 72, [
63 62 'vcs/__init__.py',
64 63 'vcs/tests/test_utils_filesize.py',
65 64 'vcs/tests/test_cli.py']),
66 65 ('owner:michał test', 0, []),
67 66 ])
68 67 def test_search_content_results(self, sort_dir, sort, query, expected_hits, expected_paths):
69 68 id_, params = build_data(
70 69 self.apikey_regular, 'search',
71 70 search_query=query,
72 71 search_sort='{}:{}'.format(sort_dir, sort),
73 72 search_type='content')
74 73
75 74 response = api_call(self.app, params)
76 75 json_response = response.json
77 76
78 77 assert json_response['result']['item_count'] == expected_hits
79 78 paths = [x['f_path'] for x in json_response['result']['results']]
80 79
81 80 for expected_path in expected_paths:
82 81 assert expected_path in paths
83 82
84 83 @pytest.mark.parametrize("sort_dir", [
85 84 "asc",
86 85 "desc",
87 86 ])
88 87 @pytest.mark.parametrize("sort", [
89 88 "xxx",
90 89 "date",
91 90 "file",
92 91 "size",
93 92 ])
94 93 @pytest.mark.parametrize("query, expected_hits, expected_paths", [
95 94 ('readme.rst', 3, []),
96 95 ('test*', 75, []),
97 96 ('*model*', 1, []),
98 97 ('extension:rst', 48, []),
99 98 ('extension:rst api', 24, []),
100 99 ])
101 100 def test_search_file_paths(self, sort_dir, sort, query, expected_hits, expected_paths):
102 101 id_, params = build_data(
103 102 self.apikey_regular, 'search',
104 103 search_query=query,
105 104 search_sort='{}:{}'.format(sort_dir, sort),
106 105 search_type='path')
107 106
108 107 response = api_call(self.app, params)
109 108 json_response = response.json
110 109
111 110 assert json_response['result']['item_count'] == expected_hits
112 111 paths = [x['f_path'] for x in json_response['result']['results']]
113 112
114 113 for expected_path in expected_paths:
115 114 assert expected_path in paths
@@ -1,101 +1,101 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20
22 21 import pytest
23 22
23 from rhodecode.lib.str_utils import safe_bytes
24 24 from rhodecode.model.db import Gist
25 25 from rhodecode.api.tests.utils import (
26 26 build_data, api_call, assert_error, assert_ok)
27 27
28 28
29 29 @pytest.mark.usefixtures("testuser_api", "app")
30 30 class TestApiGetGist(object):
31 31 def test_api_get_gist(self, gist_util, http_host_only_stub):
32 32 gist = gist_util.create_gist()
33 33 gist_id = gist.gist_access_id
34 34 gist_created_on = gist.created_on
35 35 gist_modified_at = gist.modified_at
36 36 id_, params = build_data(
37 37 self.apikey, 'get_gist', gistid=gist_id, )
38 38 response = api_call(self.app, params)
39 39
40 40 expected = {
41 41 'access_id': gist_id,
42 42 'created_on': gist_created_on,
43 43 'modified_at': gist_modified_at,
44 44 'description': 'new-gist',
45 45 'expires': -1.0,
46 46 'gist_id': int(gist_id),
47 47 'type': 'public',
48 48 'url': 'http://%s/_admin/gists/%s' % (http_host_only_stub, gist_id,),
49 49 'acl_level': Gist.ACL_LEVEL_PUBLIC,
50 50 'content': None,
51 51 }
52 52
53 53 assert_ok(id_, expected, given=response.body)
54 54
55 55 def test_api_get_gist_with_content(self, gist_util, http_host_only_stub):
56 56 mapping = {
57 u'filename1.txt': {'content': u'hello world'},
58 u'filename1Ä….txt': {'content': u'hello worldÄ™'}
57 b'filename1.txt': {'content': b'hello world'},
58 safe_bytes('filename1Ä….txt'): {'content': safe_bytes('hello worldÄ™')}
59 59 }
60 60 gist = gist_util.create_gist(gist_mapping=mapping)
61 61 gist_id = gist.gist_access_id
62 62 gist_created_on = gist.created_on
63 63 gist_modified_at = gist.modified_at
64 64 id_, params = build_data(
65 65 self.apikey, 'get_gist', gistid=gist_id, content=True)
66 66 response = api_call(self.app, params)
67 67
68 68 expected = {
69 69 'access_id': gist_id,
70 70 'created_on': gist_created_on,
71 71 'modified_at': gist_modified_at,
72 72 'description': 'new-gist',
73 73 'expires': -1.0,
74 74 'gist_id': int(gist_id),
75 75 'type': 'public',
76 76 'url': 'http://%s/_admin/gists/%s' % (http_host_only_stub, gist_id,),
77 77 'acl_level': Gist.ACL_LEVEL_PUBLIC,
78 78 'content': {
79 79 u'filename1.txt': u'hello world',
80 80 u'filename1Ä….txt': u'hello worldÄ™'
81 81 },
82 82 }
83 83
84 84 assert_ok(id_, expected, given=response.body)
85 85
86 86 def test_api_get_gist_not_existing(self):
87 87 id_, params = build_data(
88 88 self.apikey_regular, 'get_gist', gistid='12345', )
89 89 response = api_call(self.app, params)
90 90 expected = 'gist `%s` does not exist' % ('12345',)
91 91 assert_error(id_, expected, given=response.body)
92 92
93 93 def test_api_get_gist_private_gist_without_permission(self, gist_util):
94 94 gist = gist_util.create_gist()
95 95 gist_id = gist.gist_access_id
96 96 id_, params = build_data(
97 97 self.apikey_regular, 'get_gist', gistid=gist_id, )
98 98 response = api_call(self.app, params)
99 99
100 100 expected = 'gist `%s` does not exist' % (gist_id,)
101 101 assert_error(id_, expected, given=response.body)
@@ -1,74 +1,73 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20
22 21 import pytest
23 22
24 23 from rhodecode.tests import TEST_USER_ADMIN_LOGIN
25 24 from rhodecode.api.tests.utils import (
26 25 build_data, api_call, assert_error)
27 26
28 27
29 28 @pytest.mark.usefixtures("testuser_api", "app")
30 29 class TestApiGetGist(object):
31 30 def test_api_get_gists(self, gist_util):
32 31 gist_util.create_gist()
33 32 gist_util.create_gist()
34 33
35 34 id_, params = build_data(self.apikey, 'get_gists')
36 35 response = api_call(self.app, params)
37 36 assert len(response.json['result']) == 2
38 37
39 38 def test_api_get_gists_regular_user(self, gist_util):
40 39 # by admin
41 40 gist_util.create_gist()
42 41 gist_util.create_gist()
43 42
44 43 # by reg user
45 44 gist_util.create_gist(owner=self.TEST_USER_LOGIN)
46 45 gist_util.create_gist(owner=self.TEST_USER_LOGIN)
47 46 gist_util.create_gist(owner=self.TEST_USER_LOGIN)
48 47
49 48 id_, params = build_data(self.apikey_regular, 'get_gists')
50 49 response = api_call(self.app, params)
51 50 assert len(response.json['result']) == 3
52 51
53 52 def test_api_get_gists_only_for_regular_user(self, gist_util):
54 53 # by admin
55 54 gist_util.create_gist()
56 55 gist_util.create_gist()
57 56
58 57 # by reg user
59 58 gist_util.create_gist(owner=self.TEST_USER_LOGIN)
60 59 gist_util.create_gist(owner=self.TEST_USER_LOGIN)
61 60 gist_util.create_gist(owner=self.TEST_USER_LOGIN)
62 61
63 62 id_, params = build_data(
64 63 self.apikey, 'get_gists', userid=self.TEST_USER_LOGIN)
65 64 response = api_call(self.app, params)
66 65 assert len(response.json['result']) == 3
67 66
68 67 def test_api_get_gists_regular_user_with_different_userid(self):
69 68 id_, params = build_data(
70 69 self.apikey_regular, 'get_gists',
71 70 userid=TEST_USER_ADMIN_LOGIN)
72 71 response = api_call(self.app, params)
73 72 expected = 'userid is not the same as your user'
74 73 assert_error(id_, expected, given=response.body)
@@ -1,36 +1,35 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20
22 21 import pytest
23 22
24 23 from rhodecode.api.tests.utils import build_data, api_call, assert_ok
25 24
26 25
27 26 @pytest.mark.usefixtures("testuser_api", "app")
28 27 class TestGetIp(object):
29 28 def test_api_get_ip(self):
30 29 id_, params = build_data(self.apikey, 'get_ip')
31 30 response = api_call(self.app, params)
32 31 expected = {
33 32 'server_ip_addr': '0.0.0.0',
34 33 'user_ips': []
35 34 }
36 35 assert_ok(id_, expected, given=response.body)
@@ -1,91 +1,90 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20
22 21 import pytest
23 22
24 23 from rhodecode.model.db import Repository, User
25 24 from rhodecode.tests import TEST_USER_ADMIN_LOGIN, TEST_USER_REGULAR_LOGIN
26 25 from rhodecode.api.tests.utils import (
27 26 build_data, api_call, assert_ok, assert_error)
28 27
29 28
30 29 @pytest.mark.usefixtures("testuser_api", "app")
31 30 class TestGetLocks(object):
32 31 def test_api_get_user_locks_regular_user(self):
33 32 id_, params = build_data(self.apikey_regular, 'get_user_locks')
34 33 response = api_call(self.app, params)
35 34 expected = []
36 35 assert_ok(id_, expected, given=response.body)
37 36
38 37 def test_api_get_user_locks_with_userid_regular_user(self):
39 38 id_, params = build_data(
40 39 self.apikey_regular, 'get_user_locks', userid=TEST_USER_ADMIN_LOGIN)
41 40 response = api_call(self.app, params)
42 41 expected = 'userid is not the same as your user'
43 42 assert_error(id_, expected, given=response.body)
44 43
45 44 def test_api_get_user_locks(self):
46 45 id_, params = build_data(self.apikey, 'get_user_locks')
47 46 response = api_call(self.app, params)
48 47 expected = []
49 48 assert_ok(id_, expected, given=response.body)
50 49
51 50 @pytest.mark.parametrize("apikey_attr, expect_secrets", [
52 51 ('apikey', True),
53 52 ('apikey_regular', False),
54 53 ])
55 54 def test_api_get_user_locks_with_one_locked_repo(
56 55 self, apikey_attr, expect_secrets, backend):
57 56
58 57 repo = backend.create_repo(cur_user=self.TEST_USER_LOGIN)
59 58 Repository.lock(
60 59 repo, User.get_by_username(self.TEST_USER_LOGIN).user_id)
61 60
62 61 apikey = getattr(self, apikey_attr)
63 62
64 63 id_, params = build_data(apikey, 'get_user_locks')
65 64 if apikey_attr == 'apikey':
66 65 # super-admin should call in specific user
67 66 id_, params = build_data(apikey, 'get_user_locks',
68 67 userid=self.TEST_USER_LOGIN)
69 68
70 69 response = api_call(self.app, params)
71 70 expected = [repo.get_api_data(include_secrets=expect_secrets)]
72 71 assert_ok(id_, expected, given=response.body)
73 72
74 73 def test_api_get_user_locks_with_one_locked_repo_for_specific_user(
75 74 self, backend):
76 75 repo = backend.create_repo(cur_user=self.TEST_USER_LOGIN)
77 76
78 77 Repository.lock(repo, User.get_by_username(
79 78 self.TEST_USER_LOGIN).user_id)
80 79 id_, params = build_data(
81 80 self.apikey, 'get_user_locks', userid=self.TEST_USER_LOGIN)
82 81 response = api_call(self.app, params)
83 82 expected = [repo.get_api_data(include_secrets=True)]
84 83 assert_ok(id_, expected, given=response.body)
85 84
86 85 def test_api_get_user_locks_with_userid(self):
87 86 id_, params = build_data(
88 87 self.apikey, 'get_user_locks', userid=TEST_USER_REGULAR_LOGIN)
89 88 response = api_call(self.app, params)
90 89 expected = []
91 90 assert_ok(id_, expected, given=response.body)
@@ -1,63 +1,62 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20
22 21 import pytest
23 22
24 23 from rhodecode.api.tests.utils import build_data, api_call, assert_ok
25 24
26 25
27 26 @pytest.mark.usefixtures("testuser_api", "app")
28 27 class TestGetMethod(object):
29 28 def test_get_methods_no_matches(self):
30 29 id_, params = build_data(self.apikey, 'get_method', pattern='hello')
31 30 response = api_call(self.app, params)
32 31
33 32 expected = []
34 33 assert_ok(id_, expected, given=response.body)
35 34
36 35 def test_get_methods(self):
37 36 id_, params = build_data(self.apikey, 'get_method', pattern='*comment*')
38 37 response = api_call(self.app, params)
39 38
40 39 expected = [
41 40 'changeset_comment', 'comment_pull_request', 'get_pull_request_comments',
42 41 'comment_commit', 'edit_comment', 'get_comment', 'get_repo_comments'
43 42 ]
44 43 assert_ok(id_, expected, given=response.body)
45 44
46 45 def test_get_methods_on_single_match(self):
47 46 id_, params = build_data(self.apikey, 'get_method',
48 47 pattern='*comment_commit*')
49 48 response = api_call(self.app, params)
50 49
51 50 expected = ['comment_commit',
52 51 {'apiuser': '<RequiredType>',
53 'comment_type': "<Optional:u'note'>",
52 'comment_type': "<Optional:'note'>",
54 53 'commit_id': '<RequiredType>',
55 54 'extra_recipients': '<Optional:[]>',
56 55 'message': '<RequiredType>',
57 56 'repoid': '<RequiredType>',
58 57 'request': '<RequiredType>',
59 58 'resolves_comment_id': '<Optional:None>',
60 59 'status': '<Optional:None>',
61 60 'userid': '<Optional:<OptionalAttr:apiuser>>',
62 61 'send_email': '<Optional:True>'}]
63 62 assert_ok(id_, expected, given=response.body)
@@ -1,143 +1,143 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20
22 21 import pytest
23 22 import urlobject
24 23
25 24 from rhodecode.api.tests.utils import (
26 25 build_data, api_call, assert_error, assert_ok)
27 26 from rhodecode.lib import helpers as h
28 from rhodecode.lib.utils2 import safe_unicode
27 from rhodecode.lib.str_utils import safe_str
28
29 29
30 30 pytestmark = pytest.mark.backends("git", "hg")
31 31
32 32
33 33 @pytest.mark.usefixtures("testuser_api", "app")
34 34 class TestGetPullRequest(object):
35 35
36 36 def test_api_get_pull_request(self, pr_util, http_host_only_stub):
37 37 from rhodecode.model.pull_request import PullRequestModel
38 38 pull_request = pr_util.create_pull_request(mergeable=True)
39 39 id_, params = build_data(
40 40 self.apikey, 'get_pull_request',
41 41 pullrequestid=pull_request.pull_request_id, merge_state=True)
42 42
43 43 response = api_call(self.app, params)
44 44
45 45 assert response.status == '200 OK'
46 46
47 47 url_obj = urlobject.URLObject(
48 48 h.route_url(
49 49 'pullrequest_show',
50 50 repo_name=pull_request.target_repo.repo_name,
51 51 pull_request_id=pull_request.pull_request_id))
52 52
53 pr_url = safe_unicode(
53 pr_url = safe_str(
54 54 url_obj.with_netloc(http_host_only_stub))
55 source_url = safe_unicode(
55 source_url = safe_str(
56 56 pull_request.source_repo.clone_url().with_netloc(http_host_only_stub))
57 target_url = safe_unicode(
57 target_url = safe_str(
58 58 pull_request.target_repo.clone_url().with_netloc(http_host_only_stub))
59 shadow_url = safe_unicode(
59 shadow_url = safe_str(
60 60 PullRequestModel().get_shadow_clone_url(pull_request))
61 61
62 62 expected = {
63 63 'pull_request_id': pull_request.pull_request_id,
64 64 'url': pr_url,
65 65 'title': pull_request.title,
66 66 'description': pull_request.description,
67 67 'status': pull_request.status,
68 68 'state': pull_request.pull_request_state,
69 69 'created_on': pull_request.created_on,
70 70 'updated_on': pull_request.updated_on,
71 71 'commit_ids': pull_request.revisions,
72 72 'review_status': pull_request.calculated_review_status(),
73 73 'mergeable': {
74 74 'status': True,
75 75 'message': 'This pull request can be automatically merged.',
76 76 },
77 77 'source': {
78 78 'clone_url': source_url,
79 79 'repository': pull_request.source_repo.repo_name,
80 80 'reference': {
81 81 'name': pull_request.source_ref_parts.name,
82 82 'type': pull_request.source_ref_parts.type,
83 83 'commit_id': pull_request.source_ref_parts.commit_id,
84 84 },
85 85 },
86 86 'target': {
87 87 'clone_url': target_url,
88 88 'repository': pull_request.target_repo.repo_name,
89 89 'reference': {
90 90 'name': pull_request.target_ref_parts.name,
91 91 'type': pull_request.target_ref_parts.type,
92 92 'commit_id': pull_request.target_ref_parts.commit_id,
93 93 },
94 94 },
95 95 'merge': {
96 96 'clone_url': shadow_url,
97 97 'reference': {
98 98 'name': pull_request.shadow_merge_ref.name,
99 99 'type': pull_request.shadow_merge_ref.type,
100 100 'commit_id': pull_request.shadow_merge_ref.commit_id,
101 101 },
102 102 },
103 103 'author': pull_request.author.get_api_data(include_secrets=False,
104 104 details='basic'),
105 105 'reviewers': [
106 106 {
107 107 'user': reviewer.get_api_data(include_secrets=False,
108 108 details='basic'),
109 109 'reasons': reasons,
110 110 'review_status': st[0][1].status if st else 'not_reviewed',
111 111 }
112 112 for obj, reviewer, reasons, mandatory, st in
113 113 pull_request.reviewers_statuses()
114 114 ]
115 115 }
116 116 assert_ok(id_, expected, response.body)
117 117
118 118 def test_api_get_pull_request_repo_error(self, pr_util):
119 119 pull_request = pr_util.create_pull_request()
120 120 id_, params = build_data(
121 121 self.apikey, 'get_pull_request',
122 122 repoid=666, pullrequestid=pull_request.pull_request_id)
123 123 response = api_call(self.app, params)
124 124
125 125 expected = 'repository `666` does not exist'
126 126 assert_error(id_, expected, given=response.body)
127 127
128 128 def test_api_get_pull_request_pull_request_error(self):
129 129 id_, params = build_data(
130 130 self.apikey, 'get_pull_request', pullrequestid=666)
131 131 response = api_call(self.app, params)
132 132
133 133 expected = 'pull request `666` does not exist'
134 134 assert_error(id_, expected, given=response.body)
135 135
136 136 def test_api_get_pull_request_pull_request_error_just_pr_id(self):
137 137 id_, params = build_data(
138 138 self.apikey, 'get_pull_request',
139 139 pullrequestid=666)
140 140 response = api_call(self.app, params)
141 141
142 142 expected = 'pull request `666` does not exist'
143 143 assert_error(id_, expected, given=response.body)
@@ -1,87 +1,83 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20
22 21 import pytest
23 import urlobject
24 22
25 23 from rhodecode.api.tests.utils import (
26 24 build_data, api_call, assert_error, assert_ok)
27 from rhodecode.lib import helpers as h
28 from rhodecode.lib.utils2 import safe_unicode
29 25
30 26 pytestmark = pytest.mark.backends("git", "hg")
31 27
32 28
33 29 @pytest.mark.usefixtures("testuser_api", "app")
34 30 class TestGetPullRequestComments(object):
35 31
36 32 def test_api_get_pull_request_comments(self, pr_util, http_host_only_stub):
37 33 from rhodecode.model.pull_request import PullRequestModel
38 34
39 35 pull_request = pr_util.create_pull_request(mergeable=True)
40 36 id_, params = build_data(
41 37 self.apikey, 'get_pull_request_comments',
42 38 pullrequestid=pull_request.pull_request_id)
43 39
44 40 response = api_call(self.app, params)
45 41
46 42 assert response.status == '200 OK'
47 43 resp_date = response.json['result'][0]['comment_created_on']
48 44 resp_comment_id = response.json['result'][0]['comment_id']
49 45
50 46 expected = [
51 47 {'comment_author': {'active': True,
52 48 'full_name_or_username': 'RhodeCode Admin',
53 49 'username': 'test_admin'},
54 50 'comment_created_on': resp_date,
55 51 'comment_f_path': None,
56 52 'comment_id': resp_comment_id,
57 53 'comment_lineno': None,
58 54 'comment_status': {'status': 'under_review',
59 55 'status_lbl': 'Under Review'},
60 56 'comment_text': 'Auto status change to |new_status|\n\n.. |new_status| replace:: *"Under Review"*',
61 57 'comment_type': 'note',
62 58 'comment_resolved_by': None,
63 59 'pull_request_version': None,
64 60 'comment_last_version': 0,
65 61 'comment_commit_id': None,
66 62 'comment_pull_request_id': pull_request.pull_request_id
67 63 }
68 64 ]
69 65 assert_ok(id_, expected, response.body)
70 66
71 67 def test_api_get_pull_request_comments_repo_error(self, pr_util):
72 68 pull_request = pr_util.create_pull_request()
73 69 id_, params = build_data(
74 70 self.apikey, 'get_pull_request_comments',
75 71 repoid=666, pullrequestid=pull_request.pull_request_id)
76 72 response = api_call(self.app, params)
77 73
78 74 expected = 'repository `666` does not exist'
79 75 assert_error(id_, expected, given=response.body)
80 76
81 77 def test_api_get_pull_request_comments_pull_request_error(self):
82 78 id_, params = build_data(
83 79 self.apikey, 'get_pull_request_comments', pullrequestid=666)
84 80 response = api_call(self.app, params)
85 81
86 82 expected = 'pull request `666` does not exist'
87 83 assert_error(id_, expected, given=response.body)
@@ -1,82 +1,81 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20
22 21 import pytest
23 22
24 23 from rhodecode.model.meta import Session
25 24 from rhodecode.model.pull_request import PullRequestModel
26 25 from rhodecode.api.tests.utils import (
27 26 build_data, api_call, assert_error)
28 27
29 28
30 29 @pytest.mark.usefixtures("testuser_api", "app")
31 30 class TestGetPullRequest(object):
32 31
33 32 @pytest.mark.backends("git", "hg")
34 33 def test_api_get_pull_requests(self, pr_util):
35 34 pull_request = pr_util.create_pull_request()
36 35 pull_request_2 = PullRequestModel().create(
37 36 created_by=pull_request.author,
38 37 source_repo=pull_request.source_repo,
39 38 source_ref=pull_request.source_ref,
40 39 target_repo=pull_request.target_repo,
41 40 target_ref=pull_request.target_ref,
42 41 revisions=pull_request.revisions,
43 42 reviewers=(),
44 43 observers=(),
45 44 title=pull_request.title,
46 45 description=pull_request.description,
47 46 )
48 47 Session().commit()
49 48 id_, params = build_data(
50 49 self.apikey, 'get_pull_requests',
51 50 repoid=pull_request.target_repo.repo_name)
52 51 response = api_call(self.app, params)
53 52 assert response.status == '200 OK'
54 53 assert len(response.json['result']) == 2
55 54
56 55 PullRequestModel().close_pull_request(
57 56 pull_request_2, pull_request_2.author)
58 57 Session().commit()
59 58
60 59 id_, params = build_data(
61 60 self.apikey, 'get_pull_requests',
62 61 repoid=pull_request.target_repo.repo_name,
63 62 status='new')
64 63 response = api_call(self.app, params)
65 64 assert response.status == '200 OK'
66 65 assert len(response.json['result']) == 1
67 66
68 67 id_, params = build_data(
69 68 self.apikey, 'get_pull_requests',
70 69 repoid=pull_request.target_repo.repo_name,
71 70 status='closed')
72 71 response = api_call(self.app, params)
73 72 assert response.status == '200 OK'
74 73 assert len(response.json['result']) == 1
75 74
76 75 @pytest.mark.backends("git", "hg")
77 76 def test_api_get_pull_requests_repo_error(self):
78 77 id_, params = build_data(self.apikey, 'get_pull_requests', repoid=666)
79 78 response = api_call(self.app, params)
80 79
81 80 expected = 'repository `666` does not exist'
82 81 assert_error(id_, expected, given=response.body)
@@ -1,143 +1,142 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20
22 21 import pytest
23 22
24 23 from rhodecode.model.meta import Session
25 24 from rhodecode.model.repo import RepoModel
26 25 from rhodecode.model.user import UserModel
27 26 from rhodecode.tests import TEST_USER_ADMIN_LOGIN
28 27 from rhodecode.api.tests.utils import (
29 28 build_data, api_call, assert_ok, assert_error, expected_permissions)
30 29
31 30
32 31 @pytest.mark.usefixtures("testuser_api", "app")
33 32 class TestGetRepo(object):
34 33 @pytest.mark.parametrize("apikey_attr, expect_secrets", [
35 34 ('apikey', True),
36 35 ('apikey_regular', False),
37 36 ])
38 37 @pytest.mark.parametrize("cache_param", [
39 38 True,
40 39 False,
41 40 None,
42 41 ])
43 42 def test_api_get_repo(
44 43 self, apikey_attr, expect_secrets, cache_param, backend,
45 44 user_util):
46 45 repo = backend.create_repo()
47 46 repo_id = repo.repo_id
48 47 usr = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN)
49 48 group = user_util.create_user_group(members=[usr])
50 49 user_util.grant_user_group_permission_to_repo(
51 50 repo=repo, user_group=group, permission_name='repository.read')
52 51 Session().commit()
53 52 kwargs = {
54 53 'repoid': repo.repo_name,
55 54 }
56 55 if cache_param is not None:
57 56 kwargs['cache'] = cache_param
58 57
59 58 apikey = getattr(self, apikey_attr)
60 59 id_, params = build_data(apikey, 'get_repo', **kwargs)
61 60 response = api_call(self.app, params)
62 61
63 62 ret = repo.get_api_data()
64 63
65 64 permissions = expected_permissions(repo)
66 65
67 66 followers = []
68 67
69 68 repo = RepoModel().get(repo_id)
70 69 for user in repo.followers:
71 70 followers.append(user.user.get_api_data(
72 71 include_secrets=expect_secrets))
73 72
74 73 ret['permissions'] = permissions
75 74 ret['followers'] = followers
76 75
77 76 expected = ret
78 77
79 78 assert_ok(id_, expected, given=response.body)
80 79
81 80 @pytest.mark.parametrize("grant_perm", [
82 81 'repository.admin',
83 82 'repository.write',
84 83 'repository.read',
85 84 ])
86 85 def test_api_get_repo_by_non_admin(self, grant_perm, backend):
87 86 # TODO: Depending on which tests are running before this one, we
88 87 # start with a different number of permissions in the database.
89 88 repo = RepoModel().get_by_repo_name(backend.repo_name)
90 89 repo_id = repo.repo_id
91 90 permission_count = len(repo.repo_to_perm)
92 91
93 92 RepoModel().grant_user_permission(repo=backend.repo_name,
94 93 user=self.TEST_USER_LOGIN,
95 94 perm=grant_perm)
96 95 Session().commit()
97 96 id_, params = build_data(
98 97 self.apikey_regular, 'get_repo', repoid=backend.repo_name)
99 98 response = api_call(self.app, params)
100 99
101 100 repo = RepoModel().get_by_repo_name(backend.repo_name)
102 101 ret = repo.get_api_data()
103 102
104 103 assert permission_count + 1, len(repo.repo_to_perm)
105 104
106 105 permissions = expected_permissions(repo)
107 106
108 107 followers = []
109 108
110 109 repo = RepoModel().get(repo_id)
111 110 for user in repo.followers:
112 111 followers.append(user.user.get_api_data())
113 112
114 113 ret['permissions'] = permissions
115 114 ret['followers'] = followers
116 115
117 116 expected = ret
118 117 try:
119 118 assert_ok(id_, expected, given=response.body)
120 119 finally:
121 120 RepoModel().revoke_user_permission(
122 121 backend.repo_name, self.TEST_USER_LOGIN)
123 122
124 123 def test_api_get_repo_by_non_admin_no_permission_to_repo(self, backend):
125 124 RepoModel().grant_user_permission(repo=backend.repo_name,
126 125 user=self.TEST_USER_LOGIN,
127 126 perm='repository.none')
128 127
129 128 id_, params = build_data(
130 129 self.apikey_regular, 'get_repo', repoid=backend.repo_name)
131 130 response = api_call(self.app, params)
132 131
133 132 expected = 'repository `%s` does not exist' % (backend.repo_name)
134 133 assert_error(id_, expected, given=response.body)
135 134
136 135 def test_api_get_repo_not_existing(self):
137 136 id_, params = build_data(
138 137 self.apikey, 'get_repo', repoid='no-such-repo')
139 138 response = api_call(self.app, params)
140 139
141 140 ret = 'repository `%s` does not exist' % 'no-such-repo'
142 141 expected = ret
143 142 assert_error(id_, expected, given=response.body)
@@ -1,141 +1,140 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20
22 21 import pytest
23 22
24 23 from rhodecode.api.tests.utils import build_data, api_call, assert_error
25 24
26 25
27 26 @pytest.mark.usefixtures("testuser_api", "app")
28 27 class TestGetRepoChangeset(object):
29 28 @pytest.mark.parametrize("details", ['basic', 'extended', 'full'])
30 29 def test_get_repo_changeset(self, details, backend):
31 30 commit = backend.repo.get_commit(commit_idx=0)
32 31 __, params = build_data(
33 32 self.apikey, 'get_repo_changeset',
34 33 repoid=backend.repo_name, revision=commit.raw_id,
35 34 details=details,
36 35 )
37 36 response = api_call(self.app, params)
38 37 result = response.json['result']
39 38 assert result['revision'] == 0
40 39 assert result['raw_id'] == commit.raw_id
41 40
42 41 if details == 'full':
43 42 assert result['refs']['bookmarks'] == getattr(
44 43 commit, 'bookmarks', [])
45 44 branches = [commit.branch] if commit.branch else []
46 45 assert result['refs']['branches'] == branches
47 46 assert result['refs']['tags'] == commit.tags
48 47
49 48 @pytest.mark.parametrize("details", ['basic', 'extended', 'full'])
50 49 def test_get_repo_changeset_bad_type(self, details, backend):
51 50 id_, params = build_data(
52 51 self.apikey, 'get_repo_changeset',
53 52 repoid=backend.repo_name, revision=0,
54 53 details=details,
55 54 )
56 55 response = api_call(self.app, params)
57 expected = "commit_id must be a string value got <type 'int'> instead"
56 expected = "commit_id must be a string value got <class 'int'> instead"
58 57 assert_error(id_, expected, given=response.body)
59 58
60 59 @pytest.mark.parametrize("details", ['basic', 'extended', 'full'])
61 60 def test_get_repo_changesets(self, details, backend):
62 61 limit = 2
63 62 commit = backend.repo.get_commit(commit_idx=0)
64 63 __, params = build_data(
65 64 self.apikey, 'get_repo_changesets',
66 65 repoid=backend.repo_name, start_rev=commit.raw_id, limit=limit,
67 66 details=details,
68 67 )
69 68 response = api_call(self.app, params)
70 69 result = response.json['result']
71 70 assert result
72 71 assert len(result) == limit
73 72 for x in range(limit):
74 73 assert result[x]['revision'] == x
75 74
76 75 if details == 'full':
77 76 for x in range(limit):
78 77 assert 'bookmarks' in result[x]['refs']
79 78 assert 'branches' in result[x]['refs']
80 79 assert 'tags' in result[x]['refs']
81 80
82 81 @pytest.mark.parametrize("details", ['basic', 'extended', 'full'])
83 82 @pytest.mark.parametrize("start_rev, expected_revision", [
84 83 ("0", 0),
85 84 ("10", 10),
86 85 ("20", 20),
87 86 ])
88 87 @pytest.mark.backends("hg", "git")
89 88 def test_get_repo_changesets_commit_range(
90 89 self, details, backend, start_rev, expected_revision):
91 90 limit = 10
92 91 __, params = build_data(
93 92 self.apikey, 'get_repo_changesets',
94 93 repoid=backend.repo_name, start_rev=start_rev, limit=limit,
95 94 details=details,
96 95 )
97 96 response = api_call(self.app, params)
98 97 result = response.json['result']
99 98 assert result
100 99 assert len(result) == limit
101 100 for i in range(limit):
102 101 assert result[i]['revision'] == int(expected_revision) + i
103 102
104 103 @pytest.mark.parametrize("details", ['basic', 'extended', 'full'])
105 104 @pytest.mark.parametrize("start_rev, expected_revision", [
106 105 ("0", 0),
107 106 ("10", 9),
108 107 ("20", 19),
109 108 ])
110 109 def test_get_repo_changesets_commit_range_svn(
111 110 self, details, backend_svn, start_rev, expected_revision):
112 111
113 112 # TODO: johbo: SVN showed a problem here: The parameter "start_rev"
114 113 # in our API allows to pass in a "Commit ID" as well as a
115 114 # "Commit Index". In the case of Subversion it is not possible to
116 115 # distinguish these cases. As a workaround we implemented this
117 116 # behavior which gives a preference to see it as a "Commit ID".
118 117
119 118 limit = 10
120 119 __, params = build_data(
121 120 self.apikey, 'get_repo_changesets',
122 121 repoid=backend_svn.repo_name, start_rev=start_rev, limit=limit,
123 122 details=details,
124 123 )
125 124 response = api_call(self.app, params)
126 125 result = response.json['result']
127 126 assert result
128 127 assert len(result) == limit
129 128 for i in range(limit):
130 129 assert result[i]['revision'] == int(expected_revision) + i
131 130
132 131 @pytest.mark.parametrize("details", ['basic', 'extended', 'full'])
133 132 def test_get_repo_changesets_bad_type(self, details, backend):
134 133 id_, params = build_data(
135 134 self.apikey, 'get_repo_changesets',
136 135 repoid=backend.repo_name, start_rev=0, limit=2,
137 136 details=details,
138 137 )
139 138 response = api_call(self.app, params)
140 expected = "commit_id must be a string value got <type 'int'> instead"
139 expected = "commit_id must be a string value got <class 'int'> instead"
141 140 assert_error(id_, expected, given=response.body)
@@ -1,142 +1,141 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20
22 21 import pytest
23 22
24 23 from rhodecode.model.db import User, ChangesetComment
25 24 from rhodecode.model.meta import Session
26 25 from rhodecode.model.comment import CommentsModel
27 26 from rhodecode.api.tests.utils import (
28 27 build_data, api_call, assert_error, assert_call_ok)
29 28
30 29
31 30 @pytest.fixture()
32 31 def make_repo_comments_factory(request):
33 32
34 33 class Make(object):
35 34
36 35 def make_comments(self, repo):
37 36 user = User.get_first_super_admin()
38 37 commit = repo.scm_instance()[0]
39 38
40 39 commit_id = commit.raw_id
41 40 file_0 = commit.affected_files[0]
42 41 comments = []
43 42
44 43 # general
45 44 comment = CommentsModel().create(
46 45 text='General Comment', repo=repo, user=user, commit_id=commit_id,
47 46 comment_type=ChangesetComment.COMMENT_TYPE_NOTE, send_email=False)
48 47 comments.append(comment)
49 48
50 49 # inline
51 50 comment = CommentsModel().create(
52 51 text='Inline Comment', repo=repo, user=user, commit_id=commit_id,
53 52 f_path=file_0, line_no='n1',
54 53 comment_type=ChangesetComment.COMMENT_TYPE_NOTE, send_email=False)
55 54 comments.append(comment)
56 55
57 56 # todo
58 57 comment = CommentsModel().create(
59 58 text='INLINE TODO Comment', repo=repo, user=user, commit_id=commit_id,
60 59 f_path=file_0, line_no='n1',
61 60 comment_type=ChangesetComment.COMMENT_TYPE_TODO, send_email=False)
62 61 comments.append(comment)
63 62
64 63 return comments
65 64
66 65 return Make()
67 66
68 67
69 68 @pytest.mark.usefixtures("testuser_api", "app")
70 69 class TestGetRepo(object):
71 70
72 71 @pytest.mark.parametrize('filters, expected_count', [
73 72 ({}, 3),
74 73 ({'comment_type': ChangesetComment.COMMENT_TYPE_NOTE}, 2),
75 74 ({'comment_type': ChangesetComment.COMMENT_TYPE_TODO}, 1),
76 75 ({'commit_id': 'FILLED DYNAMIC'}, 3),
77 76 ])
78 77 def test_api_get_repo_comments(self, backend, user_util,
79 78 make_repo_comments_factory, filters, expected_count):
80 79 commits = [{'message': 'A'}, {'message': 'B'}]
81 80 repo = backend.create_repo(commits=commits)
82 81 make_repo_comments_factory.make_comments(repo)
83 82
84 83 api_call_params = {'repoid': repo.repo_name,}
85 84 api_call_params.update(filters)
86 85
87 86 if 'commit_id' in api_call_params:
88 87 commit = repo.scm_instance()[0]
89 88 commit_id = commit.raw_id
90 89 api_call_params['commit_id'] = commit_id
91 90
92 91 id_, params = build_data(self.apikey, 'get_repo_comments', **api_call_params)
93 92 response = api_call(self.app, params)
94 93 result = assert_call_ok(id_, given=response.body)
95 94
96 95 assert len(result) == expected_count
97 96
98 97 def test_api_get_repo_comments_wrong_comment_type(
99 98 self, make_repo_comments_factory, backend_hg):
100 99 commits = [{'message': 'A'}, {'message': 'B'}]
101 100 repo = backend_hg.create_repo(commits=commits)
102 101 make_repo_comments_factory.make_comments(repo)
103 102
104 103 api_call_params = {'repoid': repo.repo_name}
105 104 api_call_params.update({'comment_type': 'bogus'})
106 105
107 106 expected = 'comment_type must be one of `{}` got {}'.format(
108 107 ChangesetComment.COMMENT_TYPES, 'bogus')
109 108 id_, params = build_data(self.apikey, 'get_repo_comments', **api_call_params)
110 109 response = api_call(self.app, params)
111 110 assert_error(id_, expected, given=response.body)
112 111
113 112 def test_api_get_comment(self, make_repo_comments_factory, backend_hg):
114 113 commits = [{'message': 'A'}, {'message': 'B'}]
115 114 repo = backend_hg.create_repo(commits=commits)
116 115
117 116 comments = make_repo_comments_factory.make_comments(repo)
118 117 comment_ids = [x.comment_id for x in comments]
119 118 Session().commit()
120 119
121 120 for comment_id in comment_ids:
122 121 id_, params = build_data(self.apikey, 'get_comment',
123 122 **{'comment_id': comment_id})
124 123 response = api_call(self.app, params)
125 124 result = assert_call_ok(id_, given=response.body)
126 125 assert result['comment_id'] == comment_id
127 126
128 127 def test_api_get_comment_no_access(self, make_repo_comments_factory, backend_hg, user_util):
129 128 commits = [{'message': 'A'}, {'message': 'B'}]
130 129 repo = backend_hg.create_repo(commits=commits)
131 130 comments = make_repo_comments_factory.make_comments(repo)
132 131 comment_id = comments[0].comment_id
133 132
134 133 test_user = user_util.create_user()
135 134 user_util.grant_user_permission_to_repo(repo, test_user, 'repository.none')
136 135
137 136 id_, params = build_data(test_user.api_key, 'get_comment',
138 137 **{'comment_id': comment_id})
139 138 response = api_call(self.app, params)
140 139 assert_error(id_,
141 140 expected='comment `{}` does not exist'.format(comment_id),
142 141 given=response.body)
@@ -1,55 +1,54 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20
22 21 import pytest
23 22
24 23 from rhodecode.model.repo_group import RepoGroupModel
25 24 from rhodecode.api.tests.utils import (
26 25 build_data, api_call, assert_ok, assert_error, expected_permissions)
27 26
28 27
29 28 @pytest.mark.usefixtures("testuser_api", "app")
30 29 class TestApiGetRepoGroup(object):
31 30 def test_api_get_repo_group(self, user_util):
32 31 repo_group = user_util.create_repo_group()
33 32 repo_group_name = repo_group.group_name
34 33
35 34 id_, params = build_data(
36 35 self.apikey, 'get_repo_group', repogroupid=repo_group_name)
37 36 response = api_call(self.app, params)
38 37
39 38 repo_group = RepoGroupModel()._get_repo_group(repo_group_name)
40 39 ret = repo_group.get_api_data()
41 40
42 41 permissions = expected_permissions(repo_group)
43 42
44 43 ret['permissions'] = permissions
45 44 expected = ret
46 45 assert_ok(id_, expected, given=response.body)
47 46
48 47 def test_api_get_repo_group_not_existing(self):
49 48 id_, params = build_data(
50 49 self.apikey, 'get_repo_group', repogroupid='no-such-repo-group')
51 50 response = api_call(self.app, params)
52 51
53 52 ret = 'repository group `%s` does not exist' % 'no-such-repo-group'
54 53 expected = ret
55 54 assert_error(id_, expected, given=response.body)
@@ -1,40 +1,39 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20
22 21 import pytest
23 22
24 23 from rhodecode.model.repo_group import RepoGroupModel
25 24 from rhodecode.api.tests.utils import build_data, api_call, assert_ok, jsonify
26 25
27 26
28 27 @pytest.mark.usefixtures("testuser_api", "app")
29 28 class TestApiGetRepoGroups(object):
30 29 def test_api_get_repo_groups(self):
31 30 id_, params = build_data(self.apikey, 'get_repo_groups')
32 31 response = api_call(self.app, params)
33 32
34 33 result = []
35 34 for repo in RepoGroupModel().get_all():
36 35 result.append(repo.get_api_data())
37 36 ret = jsonify(result)
38 37
39 38 expected = ret
40 39 assert_ok(id_, expected, given=response.body)
@@ -1,142 +1,141 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20
22 21 import pytest
23 22
24 23 from rhodecode.model.meta import Session
25 24 from rhodecode.model.repo import RepoModel
26 25 from rhodecode.api.tests.utils import (
27 26 build_data, api_call, assert_error, assert_ok)
28 27
29 28
30 29 @pytest.mark.usefixtures("testuser_api", "app")
31 30 class TestGetRepoNodes(object):
32 31 @pytest.mark.parametrize("name, ret_type", [
33 32 ('all', 'all'),
34 33 ('dirs', 'dirs'),
35 34 ('files', 'files'),
36 35 ])
37 36 def test_api_get_repo_nodes(self, name, ret_type, backend):
38 37 commit_id = 'tip'
39 38 path = '/'
40 39 id_, params = build_data(
41 40 self.apikey, 'get_repo_nodes',
42 41 repoid=backend.repo_name, revision=commit_id,
43 42 root_path=path,
44 43 ret_type=ret_type)
45 44 response = api_call(self.app, params)
46 45
47 46 # we don't the actual return types here since it's tested somewhere
48 47 # else
49 48 expected = response.json['result']
50 49 assert_ok(id_, expected, given=response.body)
51 50
52 51 def test_api_get_repo_nodes_bad_commits(self, backend):
53 52 commit_id = 'i-dont-exist'
54 53 path = '/'
55 54 id_, params = build_data(
56 55 self.apikey, 'get_repo_nodes',
57 56 repoid=backend.repo_name, revision=commit_id,
58 57 root_path=path, )
59 58 response = api_call(self.app, params)
60 59
61 60 expected = 'failed to get repo: `%s` nodes' % (backend.repo_name,)
62 61 assert_error(id_, expected, given=response.body)
63 62
64 63 def test_api_get_repo_nodes_bad_path(self, backend):
65 64 commit_id = 'tip'
66 65 path = '/idontexits'
67 66 id_, params = build_data(
68 67 self.apikey, 'get_repo_nodes',
69 68 repoid=backend.repo_name, revision=commit_id,
70 69 root_path=path, )
71 70 response = api_call(self.app, params)
72 71
73 72 expected = 'failed to get repo: `%s` nodes' % (backend.repo_name,)
74 73 assert_error(id_, expected, given=response.body)
75 74
76 75 def test_api_get_repo_nodes_max_file_bytes(self, backend):
77 76 commit_id = 'tip'
78 77 path = '/'
79 78 max_file_bytes = 500
80 79
81 80 id_, params = build_data(
82 81 self.apikey, 'get_repo_nodes',
83 82 repoid=backend.repo_name, revision=commit_id, details='full',
84 83 root_path=path)
85 84 response = api_call(self.app, params)
86 85 assert any(file['content'] and len(file['content']) > max_file_bytes
87 86 for file in response.json['result'])
88 87
89 88 id_, params = build_data(
90 89 self.apikey, 'get_repo_nodes',
91 90 repoid=backend.repo_name, revision=commit_id,
92 91 root_path=path, details='full',
93 92 max_file_bytes=max_file_bytes)
94 93 response = api_call(self.app, params)
95 94 assert all(
96 95 file['content'] is None if file['size'] > max_file_bytes else True
97 96 for file in response.json['result'])
98 97
99 98 def test_api_get_repo_nodes_bad_ret_type(self, backend):
100 99 commit_id = 'tip'
101 100 path = '/'
102 101 ret_type = 'error'
103 102 id_, params = build_data(
104 103 self.apikey, 'get_repo_nodes',
105 104 repoid=backend.repo_name, revision=commit_id,
106 105 root_path=path,
107 106 ret_type=ret_type)
108 107 response = api_call(self.app, params)
109 108
110 109 expected = ('ret_type must be one of %s'
111 110 % (','.join(['all', 'dirs', 'files'])))
112 111 assert_error(id_, expected, given=response.body)
113 112
114 113 @pytest.mark.parametrize("name, ret_type, grant_perm", [
115 114 ('all', 'all', 'repository.write'),
116 115 ('dirs', 'dirs', 'repository.admin'),
117 116 ('files', 'files', 'repository.read'),
118 117 ])
119 118 def test_api_get_repo_nodes_by_regular_user(
120 119 self, name, ret_type, grant_perm, backend):
121 120 RepoModel().grant_user_permission(repo=backend.repo_name,
122 121 user=self.TEST_USER_LOGIN,
123 122 perm=grant_perm)
124 123 Session().commit()
125 124
126 125 commit_id = 'tip'
127 126 path = '/'
128 127 id_, params = build_data(
129 128 self.apikey_regular, 'get_repo_nodes',
130 129 repoid=backend.repo_name, revision=commit_id,
131 130 root_path=path,
132 131 ret_type=ret_type)
133 132 response = api_call(self.app, params)
134 133
135 134 # we don't the actual return types here since it's tested somewhere
136 135 # else
137 136 expected = response.json['result']
138 137 try:
139 138 assert_ok(id_, expected, given=response.body)
140 139 finally:
141 140 RepoModel().revoke_user_permission(
142 141 backend.repo_name, self.TEST_USER_LOGIN)
@@ -1,40 +1,39 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20
22 21 import pytest
23 22
24 23 from rhodecode.model.meta import Session
25 24 from rhodecode.model.repo import RepoModel
26 25 from rhodecode.model.user import UserModel
27 26 from rhodecode.tests import TEST_USER_ADMIN_LOGIN
28 27 from rhodecode.api.tests.utils import (
29 28 build_data, api_call, assert_ok, assert_error, expected_permissions)
30 29
31 30
32 31 @pytest.mark.usefixtures("testuser_api", "app")
33 32 class TestGetRepo(object):
34 33 def test_api_get_repo_refs(self, backend, user_util):
35 34 repo = backend.create_repo()
36 35 id_, params = build_data(self.apikey, 'get_repo_refs',
37 36 **{'repoid': repo.repo_name,})
38 37 response = api_call(self.app, params)
39 38 expected = repo.scm_instance().refs()
40 39 assert_ok(id_, expected, given=response.body)
@@ -1,129 +1,128 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20
22 21 import pytest
23 22
24 23 from rhodecode.model.repo import RepoModel
25 24 from rhodecode.api.tests.utils import (
26 25 build_data, api_call, assert_ok, assert_error, jsonify)
27 26 from rhodecode.model.db import User
28 27
29 28
30 29 @pytest.mark.usefixtures("testuser_api", "app")
31 30 class TestGetRepos(object):
32 31 def test_api_get_repos(self):
33 32 id_, params = build_data(self.apikey, 'get_repos')
34 33 response = api_call(self.app, params)
35 34
36 35 result = []
37 36 for repo in RepoModel().get_all():
38 37 result.append(repo.get_api_data(include_secrets=True))
39 38 ret = jsonify(result)
40 39
41 40 expected = ret
42 41 assert_ok(id_, expected, given=response.body)
43 42
44 43 def test_api_get_repos_only_toplevel(self, user_util):
45 44 repo_group = user_util.create_repo_group(auto_cleanup=True)
46 45 user_util.create_repo(parent=repo_group)
47 46
48 47 id_, params = build_data(self.apikey, 'get_repos', traverse=0)
49 48 response = api_call(self.app, params)
50 49
51 50 result = []
52 51 for repo in RepoModel().get_repos_for_root(root=None):
53 52 result.append(repo.get_api_data(include_secrets=True))
54 53 expected = jsonify(result)
55 54
56 55 assert_ok(id_, expected, given=response.body)
57 56
58 57 def test_api_get_repos_with_wrong_root(self):
59 58 id_, params = build_data(self.apikey, 'get_repos', root='abracadabra')
60 59 response = api_call(self.app, params)
61 60
62 61 expected = 'Root repository group `abracadabra` does not exist'
63 62 assert_error(id_, expected, given=response.body)
64 63
65 64 def test_api_get_repos_with_root(self, user_util):
66 65 repo_group = user_util.create_repo_group(auto_cleanup=True)
67 66 repo_group_name = repo_group.group_name
68 67
69 68 user_util.create_repo(parent=repo_group)
70 69 user_util.create_repo(parent=repo_group)
71 70
72 71 # nested, should not show up
73 72 user_util._test_name = '{}/'.format(repo_group_name)
74 73 sub_repo_group = user_util.create_repo_group(auto_cleanup=True)
75 74 user_util.create_repo(parent=sub_repo_group)
76 75
77 76 id_, params = build_data(self.apikey, 'get_repos',
78 77 root=repo_group_name, traverse=0)
79 78 response = api_call(self.app, params)
80 79
81 80 result = []
82 81 for repo in RepoModel().get_repos_for_root(repo_group):
83 82 result.append(repo.get_api_data(include_secrets=True))
84 83
85 84 assert len(result) == 2
86 85 expected = jsonify(result)
87 86 assert_ok(id_, expected, given=response.body)
88 87
89 88 def test_api_get_repos_with_root_and_traverse(self, user_util):
90 89 repo_group = user_util.create_repo_group(auto_cleanup=True)
91 90 repo_group_name = repo_group.group_name
92 91
93 92 user_util.create_repo(parent=repo_group)
94 93 user_util.create_repo(parent=repo_group)
95 94
96 95 # nested, should not show up
97 96 user_util._test_name = '{}/'.format(repo_group_name)
98 97 sub_repo_group = user_util.create_repo_group(auto_cleanup=True)
99 98 user_util.create_repo(parent=sub_repo_group)
100 99
101 100 id_, params = build_data(self.apikey, 'get_repos',
102 101 root=repo_group_name, traverse=1)
103 102 response = api_call(self.app, params)
104 103
105 104 result = []
106 105 for repo in RepoModel().get_repos_for_root(
107 106 repo_group_name, traverse=True):
108 107 result.append(repo.get_api_data(include_secrets=True))
109 108
110 109 assert len(result) == 3
111 110 expected = jsonify(result)
112 111 assert_ok(id_, expected, given=response.body)
113 112
114 113 def test_api_get_repos_non_admin(self):
115 114 id_, params = build_data(self.apikey_regular, 'get_repos')
116 115 response = api_call(self.app, params)
117 116
118 117 user = User.get_by_username(self.TEST_USER_LOGIN)
119 118 allowed_repos = user.AuthUser().permissions['repositories']
120 119
121 120 result = []
122 121 for repo in RepoModel().get_all():
123 122 perm = allowed_repos[repo.repo_name]
124 123 if perm in ['repository.read', 'repository.write', 'repository.admin']:
125 124 result.append(repo.get_api_data())
126 125 ret = jsonify(result)
127 126
128 127 expected = ret
129 128 assert_ok(id_, expected, given=response.body)
@@ -1,84 +1,83 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20
22 21 import pytest
23 22
24 23 from rhodecode.model.scm import ScmModel
25 24 from rhodecode.api.tests.utils import build_data, api_call, assert_ok
26 25
27 26
28 27 @pytest.fixture()
29 28 def http_host_stub():
30 29 """
31 30 To ensure that we can get an IP address, this test shall run with a
32 31 hostname set to "localhost".
33 32 """
34 33 return 'localhost:80'
35 34
36 35
37 36 @pytest.mark.usefixtures("testuser_api", "app")
38 37 class TestGetServerInfo(object):
39 38 def test_api_get_server_info(self):
40 39 id_, params = build_data(self.apikey, 'get_server_info')
41 40 response = api_call(self.app, params)
42 41 resp = response.json
43 42 expected = ScmModel().get_server_info()
44 43 expected['memory'] = resp['result']['memory']
45 44 expected['uptime'] = resp['result']['uptime']
46 45 expected['load'] = resp['result']['load']
47 46 expected['cpu'] = resp['result']['cpu']
48 47 expected['storage'] = resp['result']['storage']
49 48 expected['storage_temp'] = resp['result']['storage_temp']
50 49 expected['storage_inodes'] = resp['result']['storage_inodes']
51 50 expected['server'] = resp['result']['server']
52 51
53 52 expected['index_storage'] = resp['result']['index_storage']
54 53 expected['storage'] = resp['result']['storage']
55 54
56 55 assert_ok(id_, expected, given=response.body)
57 56
58 57 def test_api_get_server_info_ip(self):
59 58 id_, params = build_data(self.apikey, 'get_server_info')
60 59 response = api_call(self.app, params)
61 60 resp = response.json
62 61 expected = ScmModel().get_server_info({'SERVER_NAME': 'unknown'})
63 62 expected['memory'] = resp['result']['memory']
64 63 expected['uptime'] = resp['result']['uptime']
65 64 expected['load'] = resp['result']['load']
66 65 expected['cpu'] = resp['result']['cpu']
67 66 expected['storage'] = resp['result']['storage']
68 67 expected['storage_temp'] = resp['result']['storage_temp']
69 68 expected['storage_inodes'] = resp['result']['storage_inodes']
70 69 expected['server'] = resp['result']['server']
71 70
72 71 expected['index_storage'] = resp['result']['index_storage']
73 72 expected['storage'] = resp['result']['storage']
74 73
75 74 assert_ok(id_, expected, given=response.body)
76 75
77 76 def test_api_get_server_info_data_for_search_index_build(self):
78 77 id_, params = build_data(self.apikey, 'get_server_info')
79 78 response = api_call(self.app, params)
80 79 resp = response.json
81 80
82 81 # required by indexer
83 82 assert resp['result']['index_storage']
84 83 assert resp['result']['storage']
@@ -1,86 +1,85 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20 import pytest
22 21
23 22 from rhodecode.lib.auth import AuthUser
24 23 from rhodecode.model.user import UserModel
25 24 from rhodecode.tests import TEST_USER_ADMIN_LOGIN
26 25 from rhodecode.api.tests.utils import (
27 26 build_data, api_call, assert_ok, assert_error)
28 27
29 28
30 29 @pytest.mark.usefixtures("testuser_api", "app")
31 30 class TestGetUser(object):
32 31 def test_api_get_user(self):
33 32 id_, params = build_data(
34 33 self.apikey, 'get_user', userid=TEST_USER_ADMIN_LOGIN)
35 34 response = api_call(self.app, params)
36 35
37 36 usr = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN)
38 37 ret = usr.get_api_data(include_secrets=True)
39 38 permissions = AuthUser(usr.user_id).permissions
40 39 ret['permissions'] = permissions
41 40 ret['permissions_summary'] = permissions
42 41
43 42 expected = ret
44 43 assert_ok(id_, expected, given=response.body)
45 44
46 45 def test_api_get_user_not_existing(self):
47 46 id_, params = build_data(self.apikey, 'get_user', userid='trololo')
48 47 response = api_call(self.app, params)
49 48
50 49 expected = "user `%s` does not exist" % 'trololo'
51 50 assert_error(id_, expected, given=response.body)
52 51
53 52 def test_api_get_user_without_giving_userid(self):
54 53 id_, params = build_data(self.apikey, 'get_user')
55 54 response = api_call(self.app, params)
56 55
57 56 usr = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN)
58 57 ret = usr.get_api_data(include_secrets=True)
59 58 permissions = AuthUser(usr.user_id).permissions
60 59 ret['permissions'] = permissions
61 60 ret['permissions_summary'] = permissions
62 61
63 62 expected = ret
64 63 assert_ok(id_, expected, given=response.body)
65 64
66 65 def test_api_get_user_without_giving_userid_non_admin(self):
67 66 id_, params = build_data(self.apikey_regular, 'get_user')
68 67 response = api_call(self.app, params)
69 68
70 69 usr = UserModel().get_by_username(self.TEST_USER_LOGIN)
71 70 ret = usr.get_api_data(include_secrets=True)
72 71 permissions = AuthUser(usr.user_id).permissions
73 72 ret['permissions'] = permissions
74 73 ret['permissions_summary'] = permissions
75 74
76 75 expected = ret
77 76 assert_ok(id_, expected, given=response.body)
78 77
79 78 def test_api_get_user_with_giving_userid_non_admin(self):
80 79 id_, params = build_data(
81 80 self.apikey_regular, 'get_user',
82 81 userid=self.TEST_USER_LOGIN)
83 82 response = api_call(self.app, params)
84 83
85 84 expected = 'userid is not the same as your user'
86 85 assert_error(id_, expected, given=response.body)
@@ -1,76 +1,75 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20 import pytest
22 21
23 22 from rhodecode.model.user import UserModel
24 23 from rhodecode.api.tests.utils import (
25 24 build_data, api_call, assert_ok, assert_error, expected_permissions)
26 25
27 26
28 27 @pytest.mark.usefixtures("testuser_api", "app")
29 28 class TestGetUserGroups(object):
30 29 def test_api_get_user_group(self, user_util):
31 30 user, group = user_util.create_user_with_group()
32 31 id_, params = build_data(
33 32 self.apikey, 'get_user_group', usergroupid=group.users_group_name)
34 33 response = api_call(self.app, params)
35 34
36 35 ret = group.get_api_data()
37 36 ret['users'] = [user.get_api_data()]
38 37
39 38 permissions = expected_permissions(group)
40 39
41 40 ret['permissions'] = permissions
42 41 ret['permissions_summary'] = response.json['result']['permissions_summary']
43 42 expected = ret
44 43 assert_ok(id_, expected, given=response.body)
45 44
46 45 def test_api_get_user_group_regular_user(self, user_util):
47 46 user, group = user_util.create_user_with_group()
48 47 id_, params = build_data(
49 48 self.apikey_regular, 'get_user_group',
50 49 usergroupid=group.users_group_name)
51 50 response = api_call(self.app, params)
52 51
53 52 ret = group.get_api_data()
54 53 ret['users'] = [user.get_api_data()]
55 54
56 55 permissions = expected_permissions(group)
57 56
58 57 ret['permissions'] = permissions
59 58 ret['permissions_summary'] = response.json['result']['permissions_summary']
60 59 expected = ret
61 60 assert_ok(id_, expected, given=response.body)
62 61
63 62 def test_api_get_user_group_regular_user_permission_denied(
64 63 self, user_util):
65 64 group = user_util.create_user_group()
66 65 user = UserModel().get_by_username(self.TEST_USER_LOGIN)
67 66 group_name = group.users_group_name
68 67 user_util.grant_user_permission_to_user_group(
69 68 group, user, 'usergroup.none')
70 69
71 70 id_, params = build_data(
72 71 self.apikey_regular, 'get_user_group', usergroupid=group_name)
73 72 response = api_call(self.app, params)
74 73
75 74 expected = 'user group `%s` does not exist' % (group_name,)
76 75 assert_error(id_, expected, given=response.body)
@@ -1,71 +1,69 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20
22 import json
23
24 21 import pytest
25 22
26 23 from rhodecode.model.user import UserModel
27 24 from rhodecode.api.tests.utils import build_data, api_call
25 from rhodecode.lib.ext_json import json
28 26
29 27
30 28 @pytest.mark.usefixtures("testuser_api", "app")
31 29 class TestGetUserGroups(object):
32 30 @pytest.mark.parametrize("apikey_attr, expect_secrets", [
33 31 ('apikey', True),
34 32 ('apikey_regular', False),
35 33 ])
36 34 def test_api_get_user_groups(self, apikey_attr, expect_secrets, user_util):
37 35 first_group = user_util.create_user_group()
38 36 second_group = user_util.create_user_group()
39 37 expected = [
40 38 g.get_api_data(include_secrets=expect_secrets)
41 39 for g in (first_group, second_group)]
42 40
43 41 apikey = getattr(self, apikey_attr)
44 42 id_, params = build_data(apikey, 'get_user_groups', )
45 43 response = api_call(self.app, params)
46 44 self._assert_ok(id_, expected, response)
47 45
48 46 def test_api_get_user_groups_regular_user(self, user_util):
49 47 first_group = user_util.create_user_group()
50 48 second_group = user_util.create_user_group()
51 49 expected = [g.get_api_data() for g in (first_group, second_group)]
52 50
53 51 id_, params = build_data(self.apikey_regular, 'get_user_groups', )
54 52 response = api_call(self.app, params)
55 53 self._assert_ok(id_, expected, response)
56 54
57 55 def test_api_get_user_groups_regular_user_no_permission(self, user_util):
58 56 group = user_util.create_user_group()
59 57 user = UserModel().get_by_username(self.TEST_USER_LOGIN)
60 58 user_util.grant_user_permission_to_user_group(
61 59 group, user, 'usergroup.none')
62 60 id_, params = build_data(self.apikey_regular, 'get_user_groups', )
63 61 response = api_call(self.app, params)
64 62 expected = []
65 63 self._assert_ok(id_, expected, response)
66 64
67 65 def _assert_ok(self, id_, expected_list, response):
68 66 result = json.loads(response.body)
69 67 assert result['id'] == id_
70 68 assert result['error'] is None
71 assert sorted(result['result']) == sorted(expected_list)
69 assert result['result'] == expected_list
@@ -1,40 +1,39 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20 import pytest
22 21
23 22 from rhodecode.model.db import User
24 23 from rhodecode.api.tests.utils import (
25 24 build_data, api_call, assert_ok, jsonify)
26 25
27 26
28 27 @pytest.mark.usefixtures("testuser_api", "app")
29 28 class TestGetUsers(object):
30 29 def test_api_get_users(self):
31 30 id_, params = build_data(self.apikey, 'get_users', )
32 31 response = api_call(self.app, params)
33 32 ret_all = []
34 33 _users = User.query().filter(User.username != User.DEFAULT_USER) \
35 34 .order_by(User.username).all()
36 35 for usr in _users:
37 36 ret = usr.get_api_data(include_secrets=True)
38 37 ret_all.append(jsonify(ret))
39 38 expected = ret_all
40 39 assert_ok(id_, expected, given=response.body)
@@ -1,90 +1,89 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20 import mock
22 21 import pytest
23 22
24 23 from rhodecode.model.repo import RepoModel
25 24 from rhodecode.api.tests.utils import (
26 25 build_data, api_call, assert_error, assert_ok, crash)
27 26
28 27
29 28 @pytest.mark.usefixtures("testuser_api", "app")
30 29 class TestGrantUserGroupPermission(object):
31 30 @pytest.mark.parametrize("name, perm", [
32 31 ('none', 'repository.none'),
33 32 ('read', 'repository.read'),
34 33 ('write', 'repository.write'),
35 34 ('admin', 'repository.admin')
36 35 ])
37 36 def test_api_grant_user_group_permission(
38 37 self, name, perm, backend, user_util):
39 38 user_group = user_util.create_user_group()
40 39 id_, params = build_data(
41 40 self.apikey,
42 41 'grant_user_group_permission',
43 42 repoid=backend.repo_name,
44 43 usergroupid=user_group.users_group_name,
45 44 perm=perm)
46 45 response = api_call(self.app, params)
47 46
48 47 ret = {
49 48 'msg': 'Granted perm: `%s` for user group: `%s` in repo: `%s`' % (
50 49 perm, user_group.users_group_name, backend.repo_name
51 50 ),
52 51 'success': True
53 52 }
54 53 expected = ret
55 54 assert_ok(id_, expected, given=response.body)
56 55
57 56 def test_api_grant_user_group_permission_wrong_permission(
58 57 self, backend, user_util):
59 58 perm = 'haha.no.permission'
60 59 user_group = user_util.create_user_group()
61 60 id_, params = build_data(
62 61 self.apikey,
63 62 'grant_user_group_permission',
64 63 repoid=backend.repo_name,
65 64 usergroupid=user_group.users_group_name,
66 65 perm=perm)
67 66 response = api_call(self.app, params)
68 67
69 68 expected = 'permission `%s` does not exist.' % (perm,)
70 69 assert_error(id_, expected, given=response.body)
71 70
72 71 @mock.patch.object(RepoModel, 'grant_user_group_permission', crash)
73 72 def test_api_grant_user_group_permission_exception_when_adding(
74 73 self, backend, user_util):
75 74 perm = 'repository.read'
76 75 user_group = user_util.create_user_group()
77 76 id_, params = build_data(
78 77 self.apikey,
79 78 'grant_user_group_permission',
80 79 repoid=backend.repo_name,
81 80 usergroupid=user_group.users_group_name,
82 81 perm=perm)
83 82 response = api_call(self.app, params)
84 83
85 84 expected = (
86 85 'failed to edit permission for user group: `%s` in repo: `%s`' % (
87 86 user_group.users_group_name, backend.repo_name
88 87 )
89 88 )
90 89 assert_error(id_, expected, given=response.body)
@@ -1,173 +1,172 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20 import mock
22 21 import pytest
23 22
24 23 from rhodecode.model.user import UserModel
25 24 from rhodecode.model.repo_group import RepoGroupModel
26 25 from rhodecode.api.tests.utils import (
27 26 build_data, api_call, assert_error, assert_ok, crash)
28 27
29 28
30 29 @pytest.mark.usefixtures("testuser_api", "app")
31 30 class TestGrantUserGroupPermissionFromRepoGroup(object):
32 31 @pytest.mark.parametrize("name, perm, apply_to_children", [
33 32 ('none', 'group.none', 'none'),
34 33 ('read', 'group.read', 'none'),
35 34 ('write', 'group.write', 'none'),
36 35 ('admin', 'group.admin', 'none'),
37 36
38 37 ('none', 'group.none', 'all'),
39 38 ('read', 'group.read', 'all'),
40 39 ('write', 'group.write', 'all'),
41 40 ('admin', 'group.admin', 'all'),
42 41
43 42 ('none', 'group.none', 'repos'),
44 43 ('read', 'group.read', 'repos'),
45 44 ('write', 'group.write', 'repos'),
46 45 ('admin', 'group.admin', 'repos'),
47 46
48 47 ('none', 'group.none', 'groups'),
49 48 ('read', 'group.read', 'groups'),
50 49 ('write', 'group.write', 'groups'),
51 50 ('admin', 'group.admin', 'groups'),
52 51 ])
53 52 def test_api_grant_user_group_permission_to_repo_group(
54 53 self, name, perm, apply_to_children, user_util):
55 54 user_group = user_util.create_user_group()
56 55 repo_group = user_util.create_repo_group()
57 56 user_util.create_repo(parent=repo_group)
58 57
59 58 id_, params = build_data(
60 59 self.apikey,
61 60 'grant_user_group_permission_to_repo_group',
62 61 repogroupid=repo_group.name,
63 62 usergroupid=user_group.users_group_name,
64 63 perm=perm,
65 64 apply_to_children=apply_to_children,)
66 65 response = api_call(self.app, params)
67 66
68 67 ret = {
69 68 'msg': (
70 69 'Granted perm: `%s` (recursive:%s) for user group: `%s`'
71 70 ' in repo group: `%s`' % (
72 71 perm, apply_to_children, user_group.users_group_name,
73 72 repo_group.name
74 73 )
75 74 ),
76 75 'success': True
77 76 }
78 77 expected = ret
79 78 try:
80 79 assert_ok(id_, expected, given=response.body)
81 80 finally:
82 81 RepoGroupModel().revoke_user_group_permission(
83 82 repo_group.group_id, user_group.users_group_id)
84 83
85 84 @pytest.mark.parametrize(
86 85 "name, perm, apply_to_children, grant_admin, access_ok", [
87 86 ('none_fails', 'group.none', 'none', False, False),
88 87 ('read_fails', 'group.read', 'none', False, False),
89 88 ('write_fails', 'group.write', 'none', False, False),
90 89 ('admin_fails', 'group.admin', 'none', False, False),
91 90
92 91 # with granted perms
93 92 ('none_ok', 'group.none', 'none', True, True),
94 93 ('read_ok', 'group.read', 'none', True, True),
95 94 ('write_ok', 'group.write', 'none', True, True),
96 95 ('admin_ok', 'group.admin', 'none', True, True),
97 96 ]
98 97 )
99 98 def test_api_grant_user_group_permission_to_repo_group_by_regular_user(
100 99 self, name, perm, apply_to_children, grant_admin, access_ok,
101 100 user_util):
102 101 user = UserModel().get_by_username(self.TEST_USER_LOGIN)
103 102 user_group = user_util.create_user_group()
104 103 repo_group = user_util.create_repo_group()
105 104 if grant_admin:
106 105 user_util.grant_user_permission_to_repo_group(
107 106 repo_group, user, 'group.admin')
108 107
109 108 id_, params = build_data(
110 109 self.apikey_regular,
111 110 'grant_user_group_permission_to_repo_group',
112 111 repogroupid=repo_group.name,
113 112 usergroupid=user_group.users_group_name,
114 113 perm=perm,
115 114 apply_to_children=apply_to_children,)
116 115 response = api_call(self.app, params)
117 116 if access_ok:
118 117 ret = {
119 118 'msg': (
120 119 'Granted perm: `%s` (recursive:%s) for user group: `%s`'
121 120 ' in repo group: `%s`' % (
122 121 perm, apply_to_children, user_group.users_group_name,
123 122 repo_group.name
124 123 )
125 124 ),
126 125 'success': True
127 126 }
128 127 expected = ret
129 128 try:
130 129 assert_ok(id_, expected, given=response.body)
131 130 finally:
132 131 RepoGroupModel().revoke_user_group_permission(
133 132 repo_group.group_id, user_group.users_group_id)
134 133 else:
135 134 expected = 'repository group `%s` does not exist' % (repo_group.name,)
136 135 assert_error(id_, expected, given=response.body)
137 136
138 137 def test_api_grant_user_group_permission_to_repo_group_wrong_permission(
139 138 self, user_util):
140 139 user_group = user_util.create_user_group()
141 140 repo_group = user_util.create_repo_group()
142 141 perm = 'haha.no.permission'
143 142 id_, params = build_data(
144 143 self.apikey,
145 144 'grant_user_group_permission_to_repo_group',
146 145 repogroupid=repo_group.name,
147 146 usergroupid=user_group.users_group_name,
148 147 perm=perm)
149 148 response = api_call(self.app, params)
150 149
151 150 expected = 'permission `%s` does not exist. Permission should start with prefix: `group.`' % (perm,)
152 151 assert_error(id_, expected, given=response.body)
153 152
154 153 @mock.patch.object(RepoGroupModel, 'grant_user_group_permission', crash)
155 154 def test_api_grant_user_group_permission_exception_when_adding_2(
156 155 self, user_util):
157 156 user_group = user_util.create_user_group()
158 157 repo_group = user_util.create_repo_group()
159 158 perm = 'group.read'
160 159 id_, params = build_data(
161 160 self.apikey,
162 161 'grant_user_group_permission_to_repo_group',
163 162 repogroupid=repo_group.name,
164 163 usergroupid=user_group.users_group_name,
165 164 perm=perm)
166 165 response = api_call(self.app, params)
167 166
168 167 expected = (
169 168 'failed to edit permission for user group: `%s`'
170 169 ' in repo group: `%s`' % (
171 170 user_group.users_group_name, repo_group.name)
172 171 )
173 172 assert_error(id_, expected, given=response.body)
@@ -1,97 +1,96 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20 import pytest
22 21
23 22 from rhodecode.model.user_group import UserGroupModel
24 23 from rhodecode.api.tests.utils import (
25 24 build_data, api_call, assert_ok, assert_error)
26 25
27 26
28 27 @pytest.mark.usefixtures("testuser_api", "app")
29 28 class TestGrantUserGroupPermissionFromUserGroup(object):
30 29 @pytest.mark.parametrize("name, perm", [
31 30 ('none', 'usergroup.none'),
32 31 ('read', 'usergroup.read'),
33 32 ('write', 'usergroup.write'),
34 33 ('admin', 'usergroup.admin'),
35 34
36 35 ('none', 'usergroup.none'),
37 36 ('read', 'usergroup.read'),
38 37 ('write', 'usergroup.write'),
39 38 ('admin', 'usergroup.admin'),
40 39
41 40 ('none', 'usergroup.none'),
42 41 ('read', 'usergroup.read'),
43 42 ('write', 'usergroup.write'),
44 43 ('admin', 'usergroup.admin'),
45 44
46 45 ('none', 'usergroup.none'),
47 46 ('read', 'usergroup.read'),
48 47 ('write', 'usergroup.write'),
49 48 ('admin', 'usergroup.admin'),
50 49 ])
51 50 def test_api_grant_user_group_permission_to_user_group(
52 51 self, name, perm, user_util):
53 52 group = user_util.create_user_group()
54 53 target_group = user_util.create_user_group()
55 54
56 55 id_, params = build_data(
57 56 self.apikey,
58 57 'grant_user_group_permission_to_user_group',
59 58 usergroupid=target_group.users_group_name,
60 59 sourceusergroupid=group.users_group_name,
61 60 perm=perm)
62 61 response = api_call(self.app, params)
63 62
64 63 expected = {
65 64 'msg': (
66 65 'Granted perm: `%s` for user group: `%s`'
67 66 ' in user group: `%s`' % (
68 67 perm, group.users_group_name,
69 68 target_group.users_group_name
70 69 )
71 70 ),
72 71 'success': True
73 72 }
74 73 try:
75 74 assert_ok(id_, expected, given=response.body)
76 75 finally:
77 76 UserGroupModel().revoke_user_group_permission(
78 77 target_group.users_group_id, group.users_group_id)
79 78
80 79 def test_api_grant_user_group_permission_to_user_group_same_failure(
81 80 self, user_util):
82 81 group = user_util.create_user_group()
83 82
84 83 id_, params = build_data(
85 84 self.apikey,
86 85 'grant_user_group_permission_to_user_group',
87 86 usergroupid=group.users_group_name,
88 87 sourceusergroupid=group.users_group_name,
89 88 perm='usergroup.none')
90 89 response = api_call(self.app, params)
91 90
92 91 expected = (
93 92 'failed to edit permission for user group: `%s`'
94 93 ' in user group: `%s`' % (
95 94 group.users_group_name, group.users_group_name)
96 95 )
97 96 assert_error(id_, expected, given=response.body)
@@ -1,87 +1,86 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20 import mock
22 21 import pytest
23 22
24 23 from rhodecode.model.repo import RepoModel
25 24 from rhodecode.api.tests.utils import (
26 25 build_data, api_call, assert_error, assert_ok, crash)
27 26
28 27
29 28 @pytest.mark.usefixtures("testuser_api", "app")
30 29 class TestGrantUserPermission(object):
31 30 @pytest.mark.parametrize("name, perm", [
32 31 ('none', 'repository.none'),
33 32 ('read', 'repository.read'),
34 33 ('write', 'repository.write'),
35 34 ('admin', 'repository.admin')
36 35 ])
37 36 def test_api_grant_user_permission(self, name, perm, backend, user_util):
38 37 user = user_util.create_user()
39 38 id_, params = build_data(
40 39 self.apikey,
41 40 'grant_user_permission',
42 41 repoid=backend.repo_name,
43 42 userid=user.username,
44 43 perm=perm)
45 44 response = api_call(self.app, params)
46 45
47 46 ret = {
48 47 'msg': 'Granted perm: `%s` for user: `%s` in repo: `%s`' % (
49 48 perm, user.username, backend.repo_name
50 49 ),
51 50 'success': True
52 51 }
53 52 expected = ret
54 53 assert_ok(id_, expected, given=response.body)
55 54
56 55 def test_api_grant_user_permission_wrong_permission(
57 56 self, backend, user_util):
58 57 user = user_util.create_user()
59 58 perm = 'haha.no.permission'
60 59 id_, params = build_data(
61 60 self.apikey,
62 61 'grant_user_permission',
63 62 repoid=backend.repo_name,
64 63 userid=user.username,
65 64 perm=perm)
66 65 response = api_call(self.app, params)
67 66
68 67 expected = 'permission `%s` does not exist.' % (perm,)
69 68 assert_error(id_, expected, given=response.body)
70 69
71 70 @mock.patch.object(RepoModel, 'grant_user_permission', crash)
72 71 def test_api_grant_user_permission_exception_when_adding(
73 72 self, backend, user_util):
74 73 user = user_util.create_user()
75 74 perm = 'repository.read'
76 75 id_, params = build_data(
77 76 self.apikey,
78 77 'grant_user_permission',
79 78 repoid=backend.repo_name,
80 79 userid=user.username,
81 80 perm=perm)
82 81 response = api_call(self.app, params)
83 82
84 83 expected = 'failed to edit permission for user: `%s` in repo: `%s`' % (
85 84 user.username, backend.repo_name
86 85 )
87 86 assert_error(id_, expected, given=response.body)
@@ -1,157 +1,156 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20 import mock
22 21 import pytest
23 22
24 23 from rhodecode.model.user import UserModel
25 24 from rhodecode.model.repo_group import RepoGroupModel
26 25 from rhodecode.api.tests.utils import (
27 26 build_data, api_call, assert_error, assert_ok, crash)
28 27
29 28
30 29 @pytest.mark.usefixtures("testuser_api", "app")
31 30 class TestGrantUserPermissionFromRepoGroup(object):
32 31 @pytest.mark.parametrize("name, perm, apply_to_children", [
33 32 ('none', 'group.none', 'none'),
34 33 ('read', 'group.read', 'none'),
35 34 ('write', 'group.write', 'none'),
36 35 ('admin', 'group.admin', 'none'),
37 36
38 37 ('none', 'group.none', 'all'),
39 38 ('read', 'group.read', 'all'),
40 39 ('write', 'group.write', 'all'),
41 40 ('admin', 'group.admin', 'all'),
42 41
43 42 ('none', 'group.none', 'repos'),
44 43 ('read', 'group.read', 'repos'),
45 44 ('write', 'group.write', 'repos'),
46 45 ('admin', 'group.admin', 'repos'),
47 46
48 47 ('none', 'group.none', 'groups'),
49 48 ('read', 'group.read', 'groups'),
50 49 ('write', 'group.write', 'groups'),
51 50 ('admin', 'group.admin', 'groups'),
52 51 ])
53 52 def test_api_grant_user_permission_to_repo_group(
54 53 self, name, perm, apply_to_children, user_util):
55 54 user = user_util.create_user()
56 55 repo_group = user_util.create_repo_group()
57 56 id_, params = build_data(
58 57 self.apikey, 'grant_user_permission_to_repo_group',
59 58 repogroupid=repo_group.name, userid=user.username,
60 59 perm=perm, apply_to_children=apply_to_children)
61 60 response = api_call(self.app, params)
62 61
63 62 ret = {
64 63 'msg': (
65 64 'Granted perm: `%s` (recursive:%s) for user: `%s`'
66 65 ' in repo group: `%s`' % (
67 66 perm, apply_to_children, user.username, repo_group.name
68 67 )
69 68 ),
70 69 'success': True
71 70 }
72 71 expected = ret
73 72 assert_ok(id_, expected, given=response.body)
74 73
75 74 @pytest.mark.parametrize(
76 75 "name, perm, apply_to_children, grant_admin, access_ok", [
77 76 ('none_fails', 'group.none', 'none', False, False),
78 77 ('read_fails', 'group.read', 'none', False, False),
79 78 ('write_fails', 'group.write', 'none', False, False),
80 79 ('admin_fails', 'group.admin', 'none', False, False),
81 80
82 81 # with granted perms
83 82 ('none_ok', 'group.none', 'none', True, True),
84 83 ('read_ok', 'group.read', 'none', True, True),
85 84 ('write_ok', 'group.write', 'none', True, True),
86 85 ('admin_ok', 'group.admin', 'none', True, True),
87 86 ]
88 87 )
89 88 def test_api_grant_user_permission_to_repo_group_by_regular_user(
90 89 self, name, perm, apply_to_children, grant_admin, access_ok,
91 90 user_util):
92 91 user = user_util.create_user()
93 92 repo_group = user_util.create_repo_group()
94 93
95 94 if grant_admin:
96 95 test_user = UserModel().get_by_username(self.TEST_USER_LOGIN)
97 96 user_util.grant_user_permission_to_repo_group(
98 97 repo_group, test_user, 'group.admin')
99 98
100 99 id_, params = build_data(
101 100 self.apikey_regular, 'grant_user_permission_to_repo_group',
102 101 repogroupid=repo_group.name, userid=user.username,
103 102 perm=perm, apply_to_children=apply_to_children)
104 103 response = api_call(self.app, params)
105 104 if access_ok:
106 105 ret = {
107 106 'msg': (
108 107 'Granted perm: `%s` (recursive:%s) for user: `%s`'
109 108 ' in repo group: `%s`' % (
110 109 perm, apply_to_children, user.username, repo_group.name
111 110 )
112 111 ),
113 112 'success': True
114 113 }
115 114 expected = ret
116 115 assert_ok(id_, expected, given=response.body)
117 116 else:
118 117 expected = 'repository group `%s` does not exist' % (
119 118 repo_group.name, )
120 119 assert_error(id_, expected, given=response.body)
121 120
122 121 def test_api_grant_user_permission_to_repo_group_wrong_permission(
123 122 self, user_util):
124 123 user = user_util.create_user()
125 124 repo_group = user_util.create_repo_group()
126 125 perm = 'haha.no.permission'
127 126 id_, params = build_data(
128 127 self.apikey,
129 128 'grant_user_permission_to_repo_group',
130 129 repogroupid=repo_group.name,
131 130 userid=user.username,
132 131 perm=perm)
133 132 response = api_call(self.app, params)
134 133
135 134 expected = 'permission `%s` does not exist. Permission should start with prefix: `group.`' % (perm,)
136 135 assert_error(id_, expected, given=response.body)
137 136
138 137 @mock.patch.object(RepoGroupModel, 'grant_user_permission', crash)
139 138 def test_api_grant_user_permission_to_repo_group_exception_when_adding(
140 139 self, user_util):
141 140 user = user_util.create_user()
142 141 repo_group = user_util.create_repo_group()
143 142 perm = 'group.read'
144 143 id_, params = build_data(
145 144 self.apikey,
146 145 'grant_user_permission_to_repo_group',
147 146 repogroupid=repo_group.name,
148 147 userid=user.username,
149 148 perm=perm)
150 149 response = api_call(self.app, params)
151 150
152 151 expected = (
153 152 'failed to edit permission for user: `%s` in repo group: `%s`' % (
154 153 user.username, repo_group.name
155 154 )
156 155 )
157 156 assert_error(id_, expected, given=response.body)
@@ -1,156 +1,155 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20 import mock
22 21 import pytest
23 22
24 23 from rhodecode.model.user import UserModel
25 24 from rhodecode.model.user_group import UserGroupModel
26 25 from rhodecode.api.tests.utils import (
27 26 build_data, api_call, assert_error, assert_ok, crash)
28 27
29 28
30 29 @pytest.mark.usefixtures("testuser_api", "app")
31 30 class TestGrantUserPermissionFromUserGroup(object):
32 31 @pytest.mark.parametrize("name, perm", [
33 32 ('none', 'usergroup.none'),
34 33 ('read', 'usergroup.read'),
35 34 ('write', 'usergroup.write'),
36 35 ('admin', 'usergroup.admin'),
37 36
38 37 ('none', 'usergroup.none'),
39 38 ('read', 'usergroup.read'),
40 39 ('write', 'usergroup.write'),
41 40 ('admin', 'usergroup.admin'),
42 41
43 42 ('none', 'usergroup.none'),
44 43 ('read', 'usergroup.read'),
45 44 ('write', 'usergroup.write'),
46 45 ('admin', 'usergroup.admin'),
47 46
48 47 ('none', 'usergroup.none'),
49 48 ('read', 'usergroup.read'),
50 49 ('write', 'usergroup.write'),
51 50 ('admin', 'usergroup.admin'),
52 51 ])
53 52 def test_api_grant_user_permission_to_user_group(
54 53 self, name, perm, user_util):
55 54 user = user_util.create_user()
56 55 group = user_util.create_user_group()
57 56 id_, params = build_data(
58 57 self.apikey,
59 58 'grant_user_permission_to_user_group',
60 59 usergroupid=group.users_group_name,
61 60 userid=user.username,
62 61 perm=perm)
63 62 response = api_call(self.app, params)
64 63
65 64 ret = {
66 65 'msg': 'Granted perm: `%s` for user: `%s` in user group: `%s`' % (
67 66 perm, user.username, group.users_group_name
68 67 ),
69 68 'success': True
70 69 }
71 70 expected = ret
72 71 assert_ok(id_, expected, given=response.body)
73 72
74 73 @pytest.mark.parametrize("name, perm, grant_admin, access_ok", [
75 74 ('none_fails', 'usergroup.none', False, False),
76 75 ('read_fails', 'usergroup.read', False, False),
77 76 ('write_fails', 'usergroup.write', False, False),
78 77 ('admin_fails', 'usergroup.admin', False, False),
79 78
80 79 # with granted perms
81 80 ('none_ok', 'usergroup.none', True, True),
82 81 ('read_ok', 'usergroup.read', True, True),
83 82 ('write_ok', 'usergroup.write', True, True),
84 83 ('admin_ok', 'usergroup.admin', True, True),
85 84 ])
86 85 def test_api_grant_user_permission_to_user_group_by_regular_user(
87 86 self, name, perm, grant_admin, access_ok, user_util):
88 87 api_user = UserModel().get_by_username(self.TEST_USER_LOGIN)
89 88 user = user_util.create_user()
90 89 group = user_util.create_user_group()
91 90 # grant the user ability to at least read the group
92 91 permission = 'usergroup.admin' if grant_admin else 'usergroup.read'
93 92 user_util.grant_user_permission_to_user_group(
94 93 group, api_user, permission)
95 94
96 95 id_, params = build_data(
97 96 self.apikey_regular,
98 97 'grant_user_permission_to_user_group',
99 98 usergroupid=group.users_group_name,
100 99 userid=user.username,
101 100 perm=perm)
102 101 response = api_call(self.app, params)
103 102
104 103 if access_ok:
105 104 ret = {
106 105 'msg': (
107 106 'Granted perm: `%s` for user: `%s` in user group: `%s`' % (
108 107 perm, user.username, group.users_group_name
109 108 )
110 109 ),
111 110 'success': True
112 111 }
113 112 expected = ret
114 113 assert_ok(id_, expected, given=response.body)
115 114 else:
116 115 expected = 'user group `%s` does not exist' % (
117 116 group.users_group_name)
118 117 assert_error(id_, expected, given=response.body)
119 118
120 119 def test_api_grant_user_permission_to_user_group_wrong_permission(
121 120 self, user_util):
122 121 user = user_util.create_user()
123 122 group = user_util.create_user_group()
124 123 perm = 'haha.no.permission'
125 124 id_, params = build_data(
126 125 self.apikey,
127 126 'grant_user_permission_to_user_group',
128 127 usergroupid=group.users_group_name,
129 128 userid=user.username,
130 129 perm=perm)
131 130 response = api_call(self.app, params)
132 131
133 132 expected = 'permission `%s` does not exist. Permission should start with prefix: `usergroup.`' % perm
134 133 assert_error(id_, expected, given=response.body)
135 134
136 135 def test_api_grant_user_permission_to_user_group_exception_when_adding(
137 136 self, user_util):
138 137 user = user_util.create_user()
139 138 group = user_util.create_user_group()
140 139
141 140 perm = 'usergroup.read'
142 141 id_, params = build_data(
143 142 self.apikey,
144 143 'grant_user_permission_to_user_group',
145 144 usergroupid=group.users_group_name,
146 145 userid=user.username,
147 146 perm=perm)
148 147 with mock.patch.object(UserGroupModel, 'grant_user_permission', crash):
149 148 response = api_call(self.app, params)
150 149
151 150 expected = (
152 151 'failed to edit permission for user: `%s` in user group: `%s`' % (
153 152 user.username, group.users_group_name
154 153 )
155 154 )
156 155 assert_error(id_, expected, given=response.body)
@@ -1,68 +1,67 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20 import mock
22 21 import pytest
23 22
24 23 from rhodecode.model.scm import ScmModel
25 24 from rhodecode.api.tests.utils import (
26 25 build_data, api_call, assert_ok, assert_error, crash)
27 26 from rhodecode.model.repo import RepoModel
28 27
29 28
30 29 @pytest.mark.usefixtures("testuser_api", "app")
31 30 class TestInvalidateCache(object):
32 31
33 32 def _set_cache(self, repo_name):
34 33 repo = RepoModel().get_by_repo_name(repo_name)
35 34 repo.scm_instance(cache=True)
36 35
37 36 def test_api_invalidate_cache(self, backend):
38 37 self._set_cache(backend.repo_name)
39 38
40 39 id_, params = build_data(
41 40 self.apikey, 'invalidate_cache', repoid=backend.repo_name)
42 41 response = api_call(self.app, params)
43 42
44 43 expected = {
45 44 'msg': "Cache for repository `%s` was invalidated" % (
46 45 backend.repo_name,),
47 46 'repository': backend.repo_name,
48 47 }
49 48 assert_ok(id_, expected, given=response.body)
50 49
51 50 @mock.patch.object(ScmModel, 'mark_for_invalidation', crash)
52 51 def test_api_invalidate_cache_error(self, backend):
53 52 id_, params = build_data(
54 53 self.apikey, 'invalidate_cache', repoid=backend.repo_name)
55 54 response = api_call(self.app, params)
56 55
57 56 expected = 'Error occurred during cache invalidation action'
58 57 assert_error(id_, expected, given=response.body)
59 58
60 59 def test_api_invalidate_cache_regular_user_no_permission(self, backend):
61 60 self._set_cache(backend.repo_name)
62 61
63 62 id_, params = build_data(
64 63 self.apikey_regular, 'invalidate_cache', repoid=backend.repo_name)
65 64 response = api_call(self.app, params)
66 65
67 66 expected = "repository `%s` does not exist" % (backend.repo_name,)
68 67 assert_error(id_, expected, given=response.body)
@@ -1,259 +1,258 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20 import pytest
22 21
23 22 from rhodecode.model.db import UserLog, PullRequest
24 23 from rhodecode.model.meta import Session
25 24 from rhodecode.tests import TEST_USER_ADMIN_LOGIN
26 25 from rhodecode.api.tests.utils import (
27 26 build_data, api_call, assert_error, assert_ok)
28 27
29 28
30 29 @pytest.mark.usefixtures("testuser_api", "app")
31 30 class TestMergePullRequest(object):
32 31
33 32 @pytest.mark.backends("git", "hg")
34 33 def test_api_merge_pull_request_merge_failed(self, pr_util, no_notifications):
35 34 pull_request = pr_util.create_pull_request(mergeable=True)
36 35 pull_request_id = pull_request.pull_request_id
37 36 pull_request_repo = pull_request.target_repo.repo_name
38 37
39 38 id_, params = build_data(
40 39 self.apikey, 'merge_pull_request',
41 40 repoid=pull_request_repo,
42 41 pullrequestid=pull_request_id)
43 42
44 43 response = api_call(self.app, params)
45 44
46 45 # The above api call detaches the pull request DB object from the
47 46 # session because of an unconditional transaction rollback in our
48 47 # middleware. Therefore we need to add it back here if we want to use it.
49 48 Session().add(pull_request)
50 49
51 50 expected = 'merge not possible for following reasons: ' \
52 51 'Pull request reviewer approval is pending.'
53 52 assert_error(id_, expected, given=response.body)
54 53
55 54 @pytest.mark.backends("git", "hg")
56 55 def test_api_merge_pull_request_merge_failed_disallowed_state(
57 56 self, pr_util, no_notifications):
58 57 pull_request = pr_util.create_pull_request(mergeable=True, approved=True)
59 58 pull_request_id = pull_request.pull_request_id
60 59 pull_request_repo = pull_request.target_repo.repo_name
61 60
62 61 pr = PullRequest.get(pull_request_id)
63 62 pr.pull_request_state = pull_request.STATE_UPDATING
64 63 Session().add(pr)
65 64 Session().commit()
66 65
67 66 id_, params = build_data(
68 67 self.apikey, 'merge_pull_request',
69 68 repoid=pull_request_repo,
70 69 pullrequestid=pull_request_id)
71 70
72 71 response = api_call(self.app, params)
73 72 expected = 'Operation forbidden because pull request is in state {}, '\
74 73 'only state {} is allowed.'.format(PullRequest.STATE_UPDATING,
75 74 PullRequest.STATE_CREATED)
76 75 assert_error(id_, expected, given=response.body)
77 76
78 77 @pytest.mark.backends("git", "hg")
79 78 def test_api_merge_pull_request(self, pr_util, no_notifications):
80 79 pull_request = pr_util.create_pull_request(mergeable=True, approved=True)
81 80 author = pull_request.user_id
82 81 repo = pull_request.target_repo.repo_id
83 82 pull_request_id = pull_request.pull_request_id
84 83 pull_request_repo = pull_request.target_repo.repo_name
85 84
86 85 id_, params = build_data(
87 86 self.apikey, 'comment_pull_request',
88 87 repoid=pull_request_repo,
89 88 pullrequestid=pull_request_id,
90 89 status='approved')
91 90
92 91 response = api_call(self.app, params)
93 92 expected = {
94 93 'comment_id': response.json.get('result', {}).get('comment_id'),
95 94 'pull_request_id': pull_request_id,
96 95 'status': {'given': 'approved', 'was_changed': True}
97 96 }
98 97 assert_ok(id_, expected, given=response.body)
99 98
100 99 id_, params = build_data(
101 100 self.apikey, 'merge_pull_request',
102 101 repoid=pull_request_repo,
103 102 pullrequestid=pull_request_id)
104 103
105 104 response = api_call(self.app, params)
106 105
107 106 pull_request = PullRequest.get(pull_request_id)
108 107
109 108 expected = {
110 109 'executed': True,
111 110 'failure_reason': 0,
112 111 'merge_status_message': 'This pull request can be automatically merged.',
113 112 'possible': True,
114 113 'merge_commit_id': pull_request.shadow_merge_ref.commit_id,
115 'merge_ref': pull_request.shadow_merge_ref._asdict()
114 'merge_ref': pull_request.shadow_merge_ref.asdict()
116 115 }
117 116
118 117 assert_ok(id_, expected, response.body)
119 118
120 119 journal = UserLog.query()\
121 120 .filter(UserLog.user_id == author)\
122 121 .filter(UserLog.repository_id == repo) \
123 122 .order_by(UserLog.user_log_id.asc()) \
124 123 .all()
125 124 assert journal[-2].action == 'repo.pull_request.merge'
126 125 assert journal[-1].action == 'repo.pull_request.close'
127 126
128 127 id_, params = build_data(
129 128 self.apikey, 'merge_pull_request',
130 129 repoid=pull_request_repo, pullrequestid=pull_request_id)
131 130 response = api_call(self.app, params)
132 131
133 132 expected = 'merge not possible for following reasons: This pull request is closed.'
134 133 assert_error(id_, expected, given=response.body)
135 134
136 135 @pytest.mark.backends("git", "hg")
137 136 def test_api_merge_pull_request_as_another_user_no_perms_to_merge(
138 137 self, pr_util, no_notifications, user_util):
139 138 merge_user = user_util.create_user()
140 139 merge_user_id = merge_user.user_id
141 140 merge_user_username = merge_user.username
142 141
143 142 pull_request = pr_util.create_pull_request(mergeable=True, approved=True)
144 143
145 144 pull_request_id = pull_request.pull_request_id
146 145 pull_request_repo = pull_request.target_repo.repo_name
147 146
148 147 id_, params = build_data(
149 148 self.apikey, 'comment_pull_request',
150 149 repoid=pull_request_repo,
151 150 pullrequestid=pull_request_id,
152 151 status='approved')
153 152
154 153 response = api_call(self.app, params)
155 154 expected = {
156 155 'comment_id': response.json.get('result', {}).get('comment_id'),
157 156 'pull_request_id': pull_request_id,
158 157 'status': {'given': 'approved', 'was_changed': True}
159 158 }
160 159 assert_ok(id_, expected, given=response.body)
161 160 id_, params = build_data(
162 161 self.apikey, 'merge_pull_request',
163 162 repoid=pull_request_repo,
164 163 pullrequestid=pull_request_id,
165 164 userid=merge_user_id
166 165 )
167 166
168 167 response = api_call(self.app, params)
169 168 expected = 'merge not possible for following reasons: User `{}` ' \
170 169 'not allowed to perform merge.'.format(merge_user_username)
171 170 assert_error(id_, expected, response.body)
172 171
173 172 @pytest.mark.backends("git", "hg")
174 173 def test_api_merge_pull_request_as_another_user(self, pr_util, no_notifications, user_util):
175 174 merge_user = user_util.create_user()
176 175 merge_user_id = merge_user.user_id
177 176 pull_request = pr_util.create_pull_request(mergeable=True, approved=True)
178 177 user_util.grant_user_permission_to_repo(
179 178 pull_request.target_repo, merge_user, 'repository.write')
180 179 author = pull_request.user_id
181 180 repo = pull_request.target_repo.repo_id
182 181 pull_request_id = pull_request.pull_request_id
183 182 pull_request_repo = pull_request.target_repo.repo_name
184 183
185 184 id_, params = build_data(
186 185 self.apikey, 'comment_pull_request',
187 186 repoid=pull_request_repo,
188 187 pullrequestid=pull_request_id,
189 188 status='approved')
190 189
191 190 response = api_call(self.app, params)
192 191 expected = {
193 192 'comment_id': response.json.get('result', {}).get('comment_id'),
194 193 'pull_request_id': pull_request_id,
195 194 'status': {'given': 'approved', 'was_changed': True}
196 195 }
197 196 assert_ok(id_, expected, given=response.body)
198 197
199 198 id_, params = build_data(
200 199 self.apikey, 'merge_pull_request',
201 200 repoid=pull_request_repo,
202 201 pullrequestid=pull_request_id,
203 202 userid=merge_user_id
204 203 )
205 204
206 205 response = api_call(self.app, params)
207 206
208 207 pull_request = PullRequest.get(pull_request_id)
209 208
210 209 expected = {
211 210 'executed': True,
212 211 'failure_reason': 0,
213 212 'merge_status_message': 'This pull request can be automatically merged.',
214 213 'possible': True,
215 214 'merge_commit_id': pull_request.shadow_merge_ref.commit_id,
216 'merge_ref': pull_request.shadow_merge_ref._asdict()
215 'merge_ref': pull_request.shadow_merge_ref.asdict()
217 216 }
218 217
219 218 assert_ok(id_, expected, response.body)
220 219
221 220 journal = UserLog.query() \
222 221 .filter(UserLog.user_id == merge_user_id) \
223 222 .filter(UserLog.repository_id == repo) \
224 223 .order_by(UserLog.user_log_id.asc()) \
225 224 .all()
226 225 assert journal[-2].action == 'repo.pull_request.merge'
227 226 assert journal[-1].action == 'repo.pull_request.close'
228 227
229 228 id_, params = build_data(
230 229 self.apikey, 'merge_pull_request',
231 230 repoid=pull_request_repo, pullrequestid=pull_request_id, userid=merge_user_id)
232 231 response = api_call(self.app, params)
233 232
234 233 expected = 'merge not possible for following reasons: This pull request is closed.'
235 234 assert_error(id_, expected, given=response.body)
236 235
237 236 @pytest.mark.backends("git", "hg")
238 237 def test_api_merge_pull_request_repo_error(self, pr_util):
239 238 pull_request = pr_util.create_pull_request()
240 239 id_, params = build_data(
241 240 self.apikey, 'merge_pull_request',
242 241 repoid=666, pullrequestid=pull_request.pull_request_id)
243 242 response = api_call(self.app, params)
244 243
245 244 expected = 'repository `666` does not exist'
246 245 assert_error(id_, expected, given=response.body)
247 246
248 247 @pytest.mark.backends("git", "hg")
249 248 def test_api_merge_pull_request_non_admin_with_userid_error(self, pr_util):
250 249 pull_request = pr_util.create_pull_request(mergeable=True)
251 250 id_, params = build_data(
252 251 self.apikey_regular, 'merge_pull_request',
253 252 repoid=pull_request.target_repo.repo_name,
254 253 pullrequestid=pull_request.pull_request_id,
255 254 userid=TEST_USER_ADMIN_LOGIN)
256 255 response = api_call(self.app, params)
257 256
258 257 expected = 'userid is not the same as your user'
259 258 assert_error(id_, expected, given=response.body)
@@ -1,55 +1,54 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20 import os
22 21 import mock
23 22 import pytest
24 23
25 24 from rhodecode.tests import TESTS_TMP_PATH
26 25 from rhodecode.api.tests.utils import (
27 26 build_data, api_call, assert_ok, assert_error)
28 27
29 28
30 29 @pytest.mark.usefixtures("testuser_api", "app")
31 30 class TestPull(object):
32 31
33 32 @pytest.mark.backends("git", "hg")
34 33 def test_api_pull(self, backend):
35 34 r = backend.create_repo()
36 35 repo_name = r.repo_name
37 36 clone_uri = os.path.join(TESTS_TMP_PATH, backend.repo_name)
38 37 r.clone_uri = clone_uri
39 38
40 39 id_, params = build_data(self.apikey, 'pull', repoid=repo_name,)
41 40 with mock.patch('rhodecode.model.scm.url_validator'):
42 41 response = api_call(self.app, params)
43 42 msg = 'Pulled from url `%s` on repo `%s`' % (
44 43 clone_uri, repo_name)
45 44 expected = {'msg': msg,
46 45 'repository': repo_name}
47 46 assert_ok(id_, expected, given=response.body)
48 47
49 48 def test_api_pull_error(self, backend):
50 49 id_, params = build_data(
51 50 self.apikey, 'pull', repoid=backend.repo_name)
52 51 response = api_call(self.app, params)
53 52
54 53 expected = 'Unable to pull changes from `None`'
55 54 assert_error(id_, expected, given=response.body)
@@ -1,66 +1,65 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20 import pytest
22 21
23 22 from rhodecode.model.db import Repository, RepositoryField
24 23 from rhodecode.api.tests.utils import build_data, api_call, assert_ok
25 24
26 25
27 26 @pytest.mark.usefixtures("testuser_api", "app")
28 27 class TestRemoveFieldFromRepo(object):
29 28 def test_api_remove_field_from_repo(self, backend):
30 29 repo = backend.create_repo()
31 30 repo_name = repo.repo_name
32 31
33 32 id_, params = build_data(
34 33 self.apikey, 'add_field_to_repo',
35 34 repoid=repo_name,
36 35 key='extra_field',
37 36 label='extra_field_label',
38 37 description='extra_field_desc')
39 38 response = api_call(self.app, params)
40 39 expected = {
41 40 'msg': 'Added new repository field `extra_field`',
42 41 'success': True,
43 42 }
44 43 assert_ok(id_, expected, given=response.body)
45 44
46 45 repo = Repository.get_by_repo_name(repo_name)
47 46 repo_field = RepositoryField.get_by_key_name('extra_field', repo)
48 47 _data = repo_field.get_dict()
49 48 assert _data['field_desc'] == 'extra_field_desc'
50 49 assert _data['field_key'] == 'extra_field'
51 50 assert _data['field_label'] == 'extra_field_label'
52 51
53 52 id_, params = build_data(
54 53 self.apikey, 'remove_field_from_repo',
55 54 repoid=repo_name,
56 55 key='extra_field')
57 56 response = api_call(self.app, params)
58 57 expected = {
59 58 'msg': 'Deleted repository field `extra_field`',
60 59 'success': True,
61 60 }
62 61 assert_ok(id_, expected, given=response.body)
63 62 repo = Repository.get_by_repo_name(repo_name)
64 63 repo_field = RepositoryField.get_by_key_name('extra_field', repo)
65 64
66 65 assert repo_field is None
@@ -1,58 +1,57 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20 import mock
22 21 import pytest
23 22
24 23 from rhodecode.model.user_group import UserGroupModel
25 24 from rhodecode.api.tests.utils import (
26 25 build_data, api_call, assert_error, assert_ok, crash)
27 26
28 27
29 28 @pytest.mark.usefixtures("testuser_api", "app")
30 29 class TestRemoveUserFromUserGroup(object):
31 30 def test_api_remove_user_from_user_group(self, user_util):
32 31 user, group = user_util.create_user_with_group()
33 32 user_name = user.username
34 33 group_name = group.users_group_name
35 34 id_, params = build_data(
36 35 self.apikey, 'remove_user_from_user_group',
37 36 usergroupid=group_name,
38 37 userid=user.username)
39 38 response = api_call(self.app, params)
40 39
41 40 expected = {
42 41 'msg': 'removed member `%s` from user group `%s`' % (
43 42 user_name, group_name
44 43 ),
45 44 'success': True}
46 45 assert_ok(id_, expected, given=response.body)
47 46
48 47 @mock.patch.object(UserGroupModel, 'remove_user_from_group', crash)
49 48 def test_api_remove_user_from_user_group_exception_occurred(
50 49 self, user_util):
51 50 user, group = user_util.create_user_with_group()
52 51 id_, params = build_data(
53 52 self.apikey, 'remove_user_from_user_group',
54 53 usergroupid=group.users_group_name, userid=user.username)
55 54 response = api_call(self.app, params)
56 55 expected = 'failed to remove member from user group `%s`' % (
57 56 group.users_group_name)
58 57 assert_error(id_, expected, given=response.body)
@@ -1,184 +1,183 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20
22 21 import mock
23 22 import pytest
24 23
25 24 from rhodecode.model.db import Repository
26 25 from rhodecode.model.user import UserModel
27 26 from rhodecode.lib.ext_json import json
28 27 from rhodecode.lib.utils2 import time_to_datetime
29 28 from rhodecode.api.tests.utils import (
30 29 build_data, api_call, assert_ok, assert_error, crash)
31 30 from rhodecode.tests import TEST_USER_ADMIN_LOGIN
32 31
33 32
34 33 @pytest.mark.usefixtures("testuser_api", "app")
35 34 class TestLock(object):
36 35 def test_api_lock_repo_lock_aquire(self, backend):
37 36 id_, params = build_data(
38 37 self.apikey, 'lock',
39 38 userid=TEST_USER_ADMIN_LOGIN,
40 39 repoid=backend.repo_name,
41 40 locked=True)
42 41 response = api_call(self.app, params)
43 42 expected = {
44 43 'repo': backend.repo_name, 'locked': True,
45 44 'locked_since': response.json['result']['locked_since'],
46 45 'locked_by': TEST_USER_ADMIN_LOGIN,
47 46 'lock_state_changed': True,
48 47 'lock_reason': Repository.LOCK_API,
49 48 'msg': ('User `%s` set lock state for repo `%s` to `%s`'
50 49 % (TEST_USER_ADMIN_LOGIN, backend.repo_name, True))
51 50 }
52 51 assert_ok(id_, expected, given=response.body)
53 52
54 53 def test_repo_lock_aquire_by_non_admin(self, backend):
55 54 repo = backend.create_repo(cur_user=self.TEST_USER_LOGIN)
56 55 repo_name = repo.repo_name
57 56 id_, params = build_data(
58 57 self.apikey_regular, 'lock',
59 58 repoid=repo_name,
60 59 locked=True)
61 60 response = api_call(self.app, params)
62 61 expected = {
63 62 'repo': repo_name,
64 63 'locked': True,
65 64 'locked_since': response.json['result']['locked_since'],
66 65 'locked_by': self.TEST_USER_LOGIN,
67 66 'lock_state_changed': True,
68 67 'lock_reason': Repository.LOCK_API,
69 68 'msg': ('User `%s` set lock state for repo `%s` to `%s`'
70 69 % (self.TEST_USER_LOGIN, repo_name, True))
71 70 }
72 71 assert_ok(id_, expected, given=response.body)
73 72
74 73 def test_api_lock_repo_lock_aquire_non_admin_with_userid(self, backend):
75 74 repo = backend.create_repo(cur_user=self.TEST_USER_LOGIN)
76 75 repo_name = repo.repo_name
77 76 id_, params = build_data(
78 77 self.apikey_regular, 'lock',
79 78 userid=TEST_USER_ADMIN_LOGIN,
80 79 repoid=repo_name,
81 80 locked=True)
82 81 response = api_call(self.app, params)
83 82 expected = 'userid is not the same as your user'
84 83 assert_error(id_, expected, given=response.body)
85 84
86 85 def test_api_lock_repo_lock_aquire_non_admin_not_his_repo(self, backend):
87 86 id_, params = build_data(
88 87 self.apikey_regular, 'lock',
89 88 repoid=backend.repo_name,
90 89 locked=True)
91 90 response = api_call(self.app, params)
92 91 expected = 'repository `%s` does not exist' % (backend.repo_name, )
93 92 assert_error(id_, expected, given=response.body)
94 93
95 94 def test_api_lock_repo_lock_release(self, backend):
96 95 id_, params = build_data(
97 96 self.apikey, 'lock',
98 97 userid=TEST_USER_ADMIN_LOGIN,
99 98 repoid=backend.repo_name,
100 99 locked=False)
101 100 response = api_call(self.app, params)
102 101 expected = {
103 102 'repo': backend.repo_name,
104 103 'locked': False,
105 104 'locked_since': None,
106 105 'locked_by': TEST_USER_ADMIN_LOGIN,
107 106 'lock_state_changed': True,
108 107 'lock_reason': Repository.LOCK_API,
109 108 'msg': ('User `%s` set lock state for repo `%s` to `%s`'
110 109 % (TEST_USER_ADMIN_LOGIN, backend.repo_name, False))
111 110 }
112 111 assert_ok(id_, expected, given=response.body)
113 112
114 113 def test_api_lock_repo_lock_aquire_optional_userid(self, backend):
115 114 id_, params = build_data(
116 115 self.apikey, 'lock',
117 116 repoid=backend.repo_name,
118 117 locked=True)
119 118 response = api_call(self.app, params)
120 119 time_ = response.json['result']['locked_since']
121 120 expected = {
122 121 'repo': backend.repo_name,
123 122 'locked': True,
124 123 'locked_since': time_,
125 124 'locked_by': TEST_USER_ADMIN_LOGIN,
126 125 'lock_state_changed': True,
127 126 'lock_reason': Repository.LOCK_API,
128 127 'msg': ('User `%s` set lock state for repo `%s` to `%s`'
129 128 % (TEST_USER_ADMIN_LOGIN, backend.repo_name, True))
130 129 }
131 130
132 131 assert_ok(id_, expected, given=response.body)
133 132
134 133 def test_api_lock_repo_lock_optional_locked(self, backend):
135 134 # TODO: Provide a fixture locked_repository or similar
136 135 repo = Repository.get_by_repo_name(backend.repo_name)
137 136 user = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN)
138 137 Repository.lock(repo, user.user_id, lock_reason=Repository.LOCK_API)
139 138
140 139 id_, params = build_data(self.apikey, 'lock', repoid=backend.repo_name)
141 140 response = api_call(self.app, params)
142 141 time_ = response.json['result']['locked_since']
143 142 expected = {
144 143 'repo': backend.repo_name,
145 144 'locked': True,
146 145 'locked_since': time_,
147 146 'locked_by': TEST_USER_ADMIN_LOGIN,
148 147 'lock_state_changed': False,
149 148 'lock_reason': Repository.LOCK_API,
150 149 'msg': ('Repo `%s` locked by `%s` on `%s`.'
151 150 % (backend.repo_name, TEST_USER_ADMIN_LOGIN,
152 151 json.dumps(time_to_datetime(time_))))
153 152 }
154 153 assert_ok(id_, expected, given=response.body)
155 154
156 155 def test_api_lock_repo_lock_optional_not_locked(self, backend):
157 156 repo = backend.create_repo(cur_user=self.TEST_USER_LOGIN)
158 157 repo_name = repo.repo_name
159 158 assert repo.locked == [None, None, None]
160 159 id_, params = build_data(self.apikey, 'lock', repoid=repo.repo_id)
161 160 response = api_call(self.app, params)
162 161 expected = {
163 162 'repo': repo_name,
164 163 'locked': False,
165 164 'locked_since': None,
166 165 'locked_by': None,
167 166 'lock_state_changed': False,
168 167 'lock_reason': None,
169 168 'msg': ('Repo `%s` not locked.' % (repo_name,))
170 169 }
171 170 assert_ok(id_, expected, given=response.body)
172 171
173 172 @mock.patch.object(Repository, 'lock', crash)
174 173 def test_api_lock_error(self, backend):
175 174 id_, params = build_data(
176 175 self.apikey, 'lock',
177 176 userid=TEST_USER_ADMIN_LOGIN,
178 177 repoid=backend.repo_name,
179 178 locked=True)
180 179 response = api_call(self.app, params)
181 180
182 181 expected = 'Error occurred locking repository `%s`' % (
183 182 backend.repo_name,)
184 183 assert_error(id_, expected, given=response.body)
@@ -1,44 +1,43 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20 import mock
22 21 import pytest
23 22
24 23 from rhodecode.model.scm import ScmModel
25 24 from rhodecode.api.tests.utils import (
26 25 build_data, api_call, assert_ok, assert_error, crash)
27 26
28 27
29 28 @pytest.mark.usefixtures("testuser_api", "app")
30 29 class TestRescanRepos(object):
31 30 def test_api_rescan_repos(self):
32 31 id_, params = build_data(self.apikey, 'rescan_repos')
33 32 response = api_call(self.app, params)
34 33
35 34 expected = {'added': [], 'removed': []}
36 35 assert_ok(id_, expected, given=response.body)
37 36
38 37 @mock.patch.object(ScmModel, 'repo_scan', crash)
39 38 def test_api_rescann_error(self):
40 39 id_, params = build_data(self.apikey, 'rescan_repos', )
41 40 response = api_call(self.app, params)
42 41
43 42 expected = 'Error occurred during rescan repositories action'
44 43 assert_error(id_, expected, given=response.body)
@@ -1,67 +1,66 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20 import mock
22 21 import pytest
23 22
24 23 from rhodecode.model.repo import RepoModel
25 24 from rhodecode.api.tests.utils import (
26 25 build_data, api_call, assert_error, assert_ok, crash)
27 26
28 27
29 28 @pytest.mark.usefixtures("testuser_api", "app")
30 29 class TestRevokeUserGroupPermission(object):
31 30 def test_api_revoke_user_group_permission(self, backend, user_util):
32 31 repo = backend.create_repo()
33 32 user_group = user_util.create_user_group()
34 33 user_util.grant_user_group_permission_to_repo(
35 34 repo, user_group, 'repository.read')
36 35 id_, params = build_data(
37 36 self.apikey,
38 37 'revoke_user_group_permission',
39 38 repoid=backend.repo_name,
40 39 usergroupid=user_group.users_group_name)
41 40 response = api_call(self.app, params)
42 41
43 42 expected = {
44 43 'msg': 'Revoked perm for user group: `%s` in repo: `%s`' % (
45 44 user_group.users_group_name, backend.repo_name
46 45 ),
47 46 'success': True
48 47 }
49 48 assert_ok(id_, expected, given=response.body)
50 49
51 50 @mock.patch.object(RepoModel, 'revoke_user_group_permission', crash)
52 51 def test_api_revoke_user_group_permission_exception_when_adding(
53 52 self, backend, user_util):
54 53 user_group = user_util.create_user_group()
55 54 id_, params = build_data(
56 55 self.apikey,
57 56 'revoke_user_group_permission',
58 57 repoid=backend.repo_name,
59 58 usergroupid=user_group.users_group_name)
60 59 response = api_call(self.app, params)
61 60
62 61 expected = (
63 62 'failed to edit permission for user group: `%s` in repo: `%s`' % (
64 63 user_group.users_group_name, backend.repo_name
65 64 )
66 65 )
67 66 assert_error(id_, expected, given=response.body)
@@ -1,129 +1,128 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20 import mock
22 21 import pytest
23 22
24 23 from rhodecode.model.repo_group import RepoGroupModel
25 24 from rhodecode.tests import TEST_USER_ADMIN_LOGIN
26 25 from rhodecode.api.tests.utils import (
27 26 build_data, api_call, assert_error, assert_ok, crash)
28 27
29 28
30 29 @pytest.mark.usefixtures("testuser_api", "app")
31 30 class TestRevokeUserGroupPermissionFromRepoGroup(object):
32 31 @pytest.mark.parametrize("name, apply_to_children", [
33 32 ('none', 'none'),
34 33 ('all', 'all'),
35 34 ('repos', 'repos'),
36 35 ('groups', 'groups'),
37 36 ])
38 37 def test_api_revoke_user_group_permission_from_repo_group(
39 38 self, name, apply_to_children, user_util):
40 39 user_group = user_util.create_user_group()
41 40 repo_group = user_util.create_repo_group()
42 41 user_util.grant_user_group_permission_to_repo_group(
43 42 repo_group, user_group, 'group.read')
44 43
45 44 id_, params = build_data(
46 45 self.apikey, 'revoke_user_group_permission_from_repo_group',
47 46 repogroupid=repo_group.name,
48 47 usergroupid=user_group.users_group_name,
49 48 apply_to_children=apply_to_children,)
50 49 response = api_call(self.app, params)
51 50
52 51 expected = {
53 52 'msg': (
54 53 'Revoked perm (recursive:%s) for user group: `%s`'
55 54 ' in repo group: `%s`' % (
56 55 apply_to_children, user_group.users_group_name,
57 56 repo_group.name
58 57 )
59 58 ),
60 59 'success': True
61 60 }
62 61 assert_ok(id_, expected, given=response.body)
63 62
64 63 @pytest.mark.parametrize(
65 64 "name, apply_to_children, grant_admin, access_ok", [
66 65 ('none', 'none', False, False),
67 66 ('all', 'all', False, False),
68 67 ('repos', 'repos', False, False),
69 68 ('groups', 'groups', False, False),
70 69
71 70 # after granting admin rights
72 71 ('none', 'none', False, False),
73 72 ('all', 'all', False, False),
74 73 ('repos', 'repos', False, False),
75 74 ('groups', 'groups', False, False),
76 75 ]
77 76 )
78 77 def test_api_revoke_user_group_permission_from_repo_group_by_regular_user(
79 78 self, name, apply_to_children, grant_admin, access_ok, user_util):
80 79 user_group = user_util.create_user_group()
81 80 repo_group = user_util.create_repo_group()
82 81 user_util.grant_user_group_permission_to_repo_group(
83 82 repo_group, user_group, 'group.read')
84 83
85 84 if grant_admin:
86 85 user_util.grant_user_permission_to_repo_group(
87 86 repo_group.name, self.TEST_USER_LOGIN, 'group.admin')
88 87
89 88 id_, params = build_data(
90 89 self.apikey_regular,
91 90 'revoke_user_group_permission_from_repo_group',
92 91 repogroupid=repo_group.name,
93 92 usergroupid=user_group.users_group_name,
94 93 apply_to_children=apply_to_children,)
95 94 response = api_call(self.app, params)
96 95 if access_ok:
97 96 expected = {
98 97 'msg': (
99 98 'Revoked perm (recursive:%s) for user group: `%s`'
100 99 ' in repo group: `%s`' % (
101 100 apply_to_children, TEST_USER_ADMIN_LOGIN,
102 101 repo_group.name
103 102 )
104 103 ),
105 104 'success': True
106 105 }
107 106 assert_ok(id_, expected, given=response.body)
108 107 else:
109 108 expected = 'repository group `%s` does not exist' % (
110 109 repo_group.name,)
111 110 assert_error(id_, expected, given=response.body)
112 111
113 112 @mock.patch.object(RepoGroupModel, 'revoke_user_group_permission', crash)
114 113 def test_api_revoke_user_group_permission_from_repo_group_exception_on_add(
115 114 self, user_util):
116 115 user_group = user_util.create_user_group()
117 116 repo_group = user_util.create_repo_group()
118 117 id_, params = build_data(
119 118 self.apikey, 'revoke_user_group_permission_from_repo_group',
120 119 repogroupid=repo_group.name,
121 120 usergroupid=user_group.users_group_name)
122 121 response = api_call(self.app, params)
123 122
124 123 expected = (
125 124 'failed to edit permission for user group: `%s`'
126 125 ' in repo group: `%s`' % (
127 126 user_group.users_group_name, repo_group.name)
128 127 )
129 128 assert_error(id_, expected, given=response.body)
@@ -1,58 +1,57 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20 import pytest
22 21
23 22 from rhodecode.model.user import UserModel
24 23 from rhodecode.api.tests.utils import build_data, api_call, assert_ok
25 24
26 25
27 26 @pytest.mark.usefixtures("testuser_api", "app")
28 27 class TestRevokeUserGroupPermissionFromUserGroup(object):
29 28 @pytest.mark.parametrize("name", [
30 29 ('none',),
31 30 ('all',),
32 31 ('repos',),
33 32 ('groups',),
34 33 ])
35 34 def test_api_revoke_user_group_permission_from_user_group(
36 35 self, name, user_util):
37 36 user = UserModel().get_by_username(self.TEST_USER_LOGIN)
38 37 group = user_util.create_user_group()
39 38 source_group = user_util.create_user_group()
40 39
41 40 user_util.grant_user_permission_to_user_group(
42 41 group, user, 'usergroup.read')
43 42 user_util.grant_user_group_permission_to_user_group(
44 43 source_group, group, 'usergroup.read')
45 44
46 45 id_, params = build_data(
47 46 self.apikey, 'revoke_user_group_permission_from_user_group',
48 47 usergroupid=group.users_group_name,
49 48 sourceusergroupid=source_group.users_group_name)
50 49 response = api_call(self.app, params)
51 50
52 51 expected = {
53 52 'msg': 'Revoked perm for user group: `%s` in user group: `%s`' % (
54 53 source_group.users_group_name, group.users_group_name
55 54 ),
56 55 'success': True
57 56 }
58 57 assert_ok(id_, expected, given=response.body)
@@ -1,66 +1,65 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20 import mock
22 21 import pytest
23 22
24 23 from rhodecode.model.repo import RepoModel
25 24 from rhodecode.api.tests.utils import (
26 25 build_data, api_call, assert_error, assert_ok, crash)
27 26
28 27
29 28 @pytest.mark.usefixtures("testuser_api", "app")
30 29 class TestRevokeUserPermission(object):
31 30 def test_api_revoke_user_permission(self, backend, user_util):
32 31 repo = backend.create_repo()
33 32 user = user_util.create_user()
34 33 user_util.grant_user_permission_to_repo(
35 34 repo, user, 'repository.read')
36 35
37 36 id_, params = build_data(
38 37 self.apikey,
39 38 'revoke_user_permission',
40 39 repoid=repo.repo_name,
41 40 userid=user.username)
42 41 response = api_call(self.app, params)
43 42
44 43 expected = {
45 44 'msg': 'Revoked perm for user: `%s` in repo: `%s`' % (
46 45 user.username, backend.repo_name
47 46 ),
48 47 'success': True
49 48 }
50 49 assert_ok(id_, expected, given=response.body)
51 50
52 51 @mock.patch.object(RepoModel, 'revoke_user_permission', crash)
53 52 def test_api_revoke_user_permission_exception_when_adding(
54 53 self, backend, user_util):
55 54 user = user_util.create_user()
56 55 id_, params = build_data(
57 56 self.apikey,
58 57 'revoke_user_permission',
59 58 repoid=backend.repo_name,
60 59 userid=user.username)
61 60 response = api_call(self.app, params)
62 61
63 62 expected = 'failed to edit permission for user: `%s` in repo: `%s`' % (
64 63 user.username, backend.repo_name
65 64 )
66 65 assert_error(id_, expected, given=response.body)
@@ -1,126 +1,125 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20 import mock
22 21 import pytest
23 22
24 23 from rhodecode.model.repo_group import RepoGroupModel
25 24 from rhodecode.api.tests.utils import (
26 25 build_data, api_call, assert_error, assert_ok, crash)
27 26
28 27
29 28 @pytest.mark.usefixtures("testuser_api", "app")
30 29 class TestRevokeUserPermissionFromRepoGroup(object):
31 30 @pytest.mark.parametrize("name, apply_to_children", [
32 31 ('none', 'none'),
33 32 ('all', 'all'),
34 33 ('repos', 'repos'),
35 34 ('groups', 'groups'),
36 35 ])
37 36 def test_api_revoke_user_permission_from_repo_group(
38 37 self, name, apply_to_children, user_util):
39 38 user = user_util.create_user()
40 39 repo_group = user_util.create_repo_group()
41 40 user_util.grant_user_permission_to_repo_group(
42 41 repo_group, user, 'group.read')
43 42
44 43 id_, params = build_data(
45 44 self.apikey,
46 45 'revoke_user_permission_from_repo_group',
47 46 repogroupid=repo_group.name,
48 47 userid=user.username,
49 48 apply_to_children=apply_to_children,)
50 49 response = api_call(self.app, params)
51 50
52 51 expected = {
53 52 'msg': (
54 53 'Revoked perm (recursive:%s) for user: `%s`'
55 54 ' in repo group: `%s`' % (
56 55 apply_to_children, user.username, repo_group.name
57 56 )
58 57 ),
59 58 'success': True
60 59 }
61 60 assert_ok(id_, expected, given=response.body)
62 61
63 62 @pytest.mark.parametrize(
64 63 "name, apply_to_children, grant_admin, access_ok", [
65 64 ('none', 'none', False, False),
66 65 ('all', 'all', False, False),
67 66 ('repos', 'repos', False, False),
68 67 ('groups', 'groups', False, False),
69 68
70 69 # after granting admin rights
71 70 ('none', 'none', False, False),
72 71 ('all', 'all', False, False),
73 72 ('repos', 'repos', False, False),
74 73 ('groups', 'groups', False, False),
75 74 ]
76 75 )
77 76 def test_api_revoke_user_permission_from_repo_group_by_regular_user(
78 77 self, name, apply_to_children, grant_admin, access_ok, user_util):
79 78 user = user_util.create_user()
80 79 repo_group = user_util.create_repo_group()
81 80 permission = 'group.admin' if grant_admin else 'group.read'
82 81 user_util.grant_user_permission_to_repo_group(
83 82 repo_group, user, permission)
84 83
85 84 id_, params = build_data(
86 85 self.apikey_regular,
87 86 'revoke_user_permission_from_repo_group',
88 87 repogroupid=repo_group.name,
89 88 userid=user.username,
90 89 apply_to_children=apply_to_children,)
91 90 response = api_call(self.app, params)
92 91 if access_ok:
93 92 expected = {
94 93 'msg': (
95 94 'Revoked perm (recursive:%s) for user: `%s`'
96 95 ' in repo group: `%s`' % (
97 96 apply_to_children, user.username, repo_group.name
98 97 )
99 98 ),
100 99 'success': True
101 100 }
102 101 assert_ok(id_, expected, given=response.body)
103 102 else:
104 103 expected = 'repository group `%s` does not exist' % (
105 104 repo_group.name)
106 105 assert_error(id_, expected, given=response.body)
107 106
108 107 @mock.patch.object(RepoGroupModel, 'revoke_user_permission', crash)
109 108 def test_api_revoke_user_permission_from_repo_group_exception_when_adding(
110 109 self, user_util):
111 110 user = user_util.create_user()
112 111 repo_group = user_util.create_repo_group()
113 112 id_, params = build_data(
114 113 self.apikey,
115 114 'revoke_user_permission_from_repo_group',
116 115 repogroupid=repo_group.name,
117 116 userid=user.username
118 117 )
119 118 response = api_call(self.app, params)
120 119
121 120 expected = (
122 121 'failed to edit permission for user: `%s` in repo group: `%s`' % (
123 122 user.username, repo_group.name
124 123 )
125 124 )
126 125 assert_error(id_, expected, given=response.body)
@@ -1,112 +1,111 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20 import mock
22 21 import pytest
23 22
24 23 from rhodecode.model.user_group import UserGroupModel
25 24 from rhodecode.api.tests.utils import (
26 25 build_data, api_call, assert_error, assert_ok, crash)
27 26
28 27
29 28 @pytest.mark.usefixtures("testuser_api", "app")
30 29 class TestRevokeUserPermissionFromUserGroup(object):
31 30 @pytest.mark.parametrize("name", [
32 31 ('none',),
33 32 ('all',),
34 33 ('repos',),
35 34 ('groups',),
36 35 ])
37 36 def test_api_revoke_user_permission_from_user_group(self, name, user_util):
38 37 user = user_util.create_user()
39 38 group = user_util.create_user_group()
40 39 user_util.grant_user_permission_to_user_group(
41 40 group, user, 'usergroup.admin')
42 41
43 42 id_, params = build_data(
44 43 self.apikey,
45 44 'revoke_user_permission_from_user_group',
46 45 usergroupid=group.users_group_name,
47 46 userid=user.username)
48 47 response = api_call(self.app, params)
49 48
50 49 expected = {
51 50 'msg': 'Revoked perm for user: `%s` in user group: `%s`' % (
52 51 user.username, group.users_group_name
53 52 ),
54 53 'success': True
55 54 }
56 55 assert_ok(id_, expected, given=response.body)
57 56
58 57 @pytest.mark.parametrize("name, grant_admin, access_ok", [
59 58 ('none', False, False),
60 59 ('all', False, False),
61 60 ('repos', False, False),
62 61 ('groups', False, False),
63 62
64 63 # after granting admin rights
65 64 ('none', False, False),
66 65 ('all', False, False),
67 66 ('repos', False, False),
68 67 ('groups', False, False),
69 68 ])
70 69 def test_api_revoke_user_permission_from_user_group_by_regular_user(
71 70 self, name, grant_admin, access_ok, user_util):
72 71 user = user_util.create_user()
73 72 group = user_util.create_user_group()
74 73 permission = 'usergroup.admin' if grant_admin else 'usergroup.read'
75 74 user_util.grant_user_permission_to_user_group(group, user, permission)
76 75
77 76 id_, params = build_data(
78 77 self.apikey_regular,
79 78 'revoke_user_permission_from_user_group',
80 79 usergroupid=group.users_group_name,
81 80 userid=user.username)
82 81 response = api_call(self.app, params)
83 82 if access_ok:
84 83 expected = {
85 84 'msg': 'Revoked perm for user: `%s` in user group: `%s`' % (
86 85 user.username, group.users_group_name
87 86 ),
88 87 'success': True
89 88 }
90 89 assert_ok(id_, expected, given=response.body)
91 90 else:
92 91 expected = 'user group `%s` does not exist' % (
93 92 group.users_group_name)
94 93 assert_error(id_, expected, given=response.body)
95 94
96 95 @mock.patch.object(UserGroupModel, 'revoke_user_permission', crash)
97 96 def test_api_revoke_user_permission_from_user_group_exception_when_adding(
98 97 self, user_util):
99 98 user = user_util.create_user()
100 99 group = user_util.create_user_group()
101 100 id_, params = build_data(
102 101 self.apikey,
103 102 'revoke_user_permission_from_user_group',
104 103 usergroupid=group.users_group_name,
105 104 userid=user.username)
106 105 response = api_call(self.app, params)
107 106
108 107 expected = (
109 108 'failed to edit permission for user: `%s` in user group: `%s`' % (
110 109 user.username, group.users_group_name)
111 110 )
112 111 assert_error(id_, expected, given=response.body)
@@ -1,59 +1,58 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20
22 21 import pytest
23 22
24 23 from rhodecode.api.tests.utils import build_data, api_call, assert_ok, assert_error
25 24
26 25
27 26 @pytest.mark.usefixtures("testuser_api", "app")
28 27 class TestStoreException(object):
29 28
30 29 def test_store_exception_invalid_json(self):
31 30 id_, params = build_data(self.apikey, 'store_exception',
32 31 exc_data_json='XXX,{')
33 32 response = api_call(self.app, params)
34 33
35 34 expected = 'Failed to parse JSON data from exc_data_json field. ' \
36 35 'Please make sure it contains a valid JSON.'
37 36 assert_error(id_, expected, given=response.body)
38 37
39 38 def test_store_exception_missing_json_params_json(self):
40 39 id_, params = build_data(self.apikey, 'store_exception',
41 40 exc_data_json='{"foo":"bar"}')
42 41 response = api_call(self.app, params)
43 42
44 43 expected = "Missing exc_traceback, or exc_type_name in " \
45 44 "exc_data_json field. Missing: 'exc_traceback'"
46 45 assert_error(id_, expected, given=response.body)
47 46
48 47 def test_store_exception(self):
49 48 id_, params = build_data(
50 49 self.apikey, 'store_exception',
51 50 exc_data_json='{"exc_traceback": "invalid", "exc_type_name":"ValueError"}')
52 51 response = api_call(self.app, params)
53 52 exc_id = response.json['result']['exc_id']
54 53
55 54 expected = {
56 55 'exc_id': exc_id,
57 56 'exc_url': 'http://example.com/_admin/settings/exceptions/{}'.format(exc_id)
58 57 }
59 58 assert_ok(id_, expected, given=response.body)
@@ -1,215 +1,214 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20 import pytest
22 21
23 22 from rhodecode.lib.vcs.nodes import FileNode
24 23 from rhodecode.model.db import User
25 24 from rhodecode.model.pull_request import PullRequestModel
26 25 from rhodecode.tests import TEST_USER_ADMIN_LOGIN
27 26 from rhodecode.api.tests.utils import (
28 27 build_data, api_call, assert_ok, assert_error)
29 28
30 29
31 30 @pytest.mark.usefixtures("testuser_api", "app")
32 31 class TestUpdatePullRequest(object):
33 32
34 33 @pytest.mark.backends("git", "hg")
35 34 def test_api_update_pull_request_title_or_description(
36 35 self, pr_util, no_notifications):
37 36 pull_request = pr_util.create_pull_request()
38 37
39 38 id_, params = build_data(
40 39 self.apikey, 'update_pull_request',
41 40 repoid=pull_request.target_repo.repo_name,
42 41 pullrequestid=pull_request.pull_request_id,
43 42 title='New TITLE OF A PR',
44 43 description='New DESC OF A PR',
45 44 )
46 45 response = api_call(self.app, params)
47 46
48 47 expected = {
49 48 "msg": "Updated pull request `{}`".format(
50 49 pull_request.pull_request_id),
51 50 "pull_request": response.json['result']['pull_request'],
52 51 "updated_commits": {"added": [], "common": [], "removed": []},
53 52 "updated_reviewers": {"added": [], "removed": []},
54 53 "updated_observers": {"added": [], "removed": []},
55 54 }
56 55
57 56 response_json = response.json['result']
58 57 assert response_json == expected
59 58 pr = response_json['pull_request']
60 59 assert pr['title'] == 'New TITLE OF A PR'
61 60 assert pr['description'] == 'New DESC OF A PR'
62 61
63 62 @pytest.mark.backends("git", "hg")
64 63 def test_api_try_update_closed_pull_request(
65 64 self, pr_util, no_notifications):
66 65 pull_request = pr_util.create_pull_request()
67 66 PullRequestModel().close_pull_request(
68 67 pull_request, TEST_USER_ADMIN_LOGIN)
69 68
70 69 id_, params = build_data(
71 70 self.apikey, 'update_pull_request',
72 71 repoid=pull_request.target_repo.repo_name,
73 72 pullrequestid=pull_request.pull_request_id)
74 73 response = api_call(self.app, params)
75 74
76 75 expected = 'pull request `{}` update failed, pull request ' \
77 76 'is closed'.format(pull_request.pull_request_id)
78 77
79 78 assert_error(id_, expected, response.body)
80 79
81 80 @pytest.mark.backends("git", "hg")
82 81 def test_api_update_update_commits(self, pr_util, no_notifications):
83 82 commits = [
84 83 {'message': 'a'},
85 {'message': 'b', 'added': [FileNode('file_b', 'test_content\n')]},
86 {'message': 'c', 'added': [FileNode('file_c', 'test_content\n')]},
84 {'message': 'b', 'added': [FileNode(b'file_b', b'test_content\n')]},
85 {'message': 'c', 'added': [FileNode(b'file_c', b'test_content\n')]},
87 86 ]
88 87 pull_request = pr_util.create_pull_request(
89 88 commits=commits, target_head='a', source_head='b', revisions=['b'])
90 89 pr_util.update_source_repository(head='c')
91 90 repo = pull_request.source_repo.scm_instance()
92 91 commits = [x for x in repo.get_commits()]
93 92
94 93 added_commit_id = commits[-1].raw_id # c commit
95 94 common_commit_id = commits[1].raw_id # b commit is common ancestor
96 95 total_commits = [added_commit_id, common_commit_id]
97 96
98 97 id_, params = build_data(
99 98 self.apikey, 'update_pull_request',
100 99 repoid=pull_request.target_repo.repo_name,
101 100 pullrequestid=pull_request.pull_request_id,
102 101 update_commits=True
103 102 )
104 103 response = api_call(self.app, params)
105 104
106 105 expected = {
107 106 "msg": "Updated pull request `{}`".format(
108 107 pull_request.pull_request_id),
109 108 "pull_request": response.json['result']['pull_request'],
110 109 "updated_commits": {"added": [added_commit_id],
111 110 "common": [common_commit_id],
112 111 "total": total_commits,
113 112 "removed": []},
114 113 "updated_reviewers": {"added": [], "removed": []},
115 114 "updated_observers": {"added": [], "removed": []},
116 115 }
117 116
118 117 assert_ok(id_, expected, response.body)
119 118
120 119 @pytest.mark.backends("git", "hg")
121 120 def test_api_update_change_reviewers(
122 121 self, user_util, pr_util, no_notifications):
123 122 a = user_util.create_user()
124 123 b = user_util.create_user()
125 124 c = user_util.create_user()
126 125 new_reviewers = [
127 126 {'username': b.username, 'reasons': ['updated via API'],
128 127 'mandatory':False},
129 128 {'username': c.username, 'reasons': ['updated via API'],
130 129 'mandatory':False},
131 130 ]
132 131
133 132 added = [b.username, c.username]
134 133 removed = [a.username]
135 134
136 135 pull_request = pr_util.create_pull_request(
137 136 reviewers=[(a.username, ['added via API'], False, 'reviewer', [])])
138 137
139 138 id_, params = build_data(
140 139 self.apikey, 'update_pull_request',
141 140 repoid=pull_request.target_repo.repo_name,
142 141 pullrequestid=pull_request.pull_request_id,
143 142 reviewers=new_reviewers)
144 143 response = api_call(self.app, params)
145 144 expected = {
146 145 "msg": "Updated pull request `{}`".format(
147 146 pull_request.pull_request_id),
148 147 "pull_request": response.json['result']['pull_request'],
149 148 "updated_commits": {"added": [], "common": [], "removed": []},
150 149 "updated_reviewers": {"added": added, "removed": removed},
151 150 "updated_observers": {"added": [], "removed": []},
152 151 }
153 152
154 153 assert_ok(id_, expected, response.body)
155 154
156 155 @pytest.mark.backends("git", "hg")
157 156 def test_api_update_bad_user_in_reviewers(self, pr_util):
158 157 pull_request = pr_util.create_pull_request()
159 158
160 159 id_, params = build_data(
161 160 self.apikey, 'update_pull_request',
162 161 repoid=pull_request.target_repo.repo_name,
163 162 pullrequestid=pull_request.pull_request_id,
164 163 reviewers=[{'username': 'bad_name'}])
165 164 response = api_call(self.app, params)
166 165
167 166 expected = 'user `bad_name` does not exist'
168 167
169 168 assert_error(id_, expected, response.body)
170 169
171 170 @pytest.mark.backends("git", "hg")
172 171 def test_api_update_repo_error(self, pr_util):
173 172 pull_request = pr_util.create_pull_request()
174 173 id_, params = build_data(
175 174 self.apikey, 'update_pull_request',
176 175 repoid='fake',
177 176 pullrequestid=pull_request.pull_request_id,
178 177 reviewers=[{'username': 'bad_name'}])
179 178 response = api_call(self.app, params)
180 179
181 180 expected = 'repository `fake` does not exist'
182 181
183 182 response_json = response.json['error']
184 183 assert response_json == expected
185 184
186 185 @pytest.mark.backends("git", "hg")
187 186 def test_api_update_pull_request_error(self, pr_util):
188 187 pull_request = pr_util.create_pull_request()
189 188
190 189 id_, params = build_data(
191 190 self.apikey, 'update_pull_request',
192 191 repoid=pull_request.target_repo.repo_name,
193 192 pullrequestid=999999,
194 193 reviewers=[{'username': 'bad_name'}])
195 194 response = api_call(self.app, params)
196 195
197 196 expected = 'pull request `999999` does not exist'
198 197 assert_error(id_, expected, response.body)
199 198
200 199 @pytest.mark.backends("git", "hg")
201 200 def test_api_update_pull_request_no_perms_to_update(
202 201 self, user_util, pr_util):
203 202 user = user_util.create_user()
204 203 pull_request = pr_util.create_pull_request()
205 204
206 205 id_, params = build_data(
207 206 user.api_key, 'update_pull_request',
208 207 repoid=pull_request.target_repo.repo_name,
209 208 pullrequestid=pull_request.pull_request_id,)
210 209 response = api_call(self.app, params)
211 210
212 211 expected = ('pull request `%s` update failed, '
213 212 'no permission to update.') % pull_request.pull_request_id
214 213
215 214 assert_error(id_, expected, response.body)
@@ -1,210 +1,209 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20 import mock
22 21 import pytest
23 22
24 23 from rhodecode.model.repo import RepoModel
25 24 from rhodecode.model.scm import ScmModel
26 25 from rhodecode.tests import TEST_USER_ADMIN_LOGIN, TEST_USER_REGULAR_LOGIN
27 26 from rhodecode.api.tests.utils import (
28 27 build_data, api_call, assert_error, assert_ok, crash, jsonify)
29 28 from rhodecode.tests.fixture import Fixture
30 29 from rhodecode.tests.fixture_mods.fixture_utils import plain_http_host_only_stub
31 30
32 31 fixture = Fixture()
33 32
34 33 UPDATE_REPO_NAME = 'api_update_me'
35 34
36 35
37 36 class SAME_AS_UPDATES(object):
38 37 """ Constant used for tests below """
39 38
40 39
41 40 @pytest.mark.usefixtures("testuser_api", "app")
42 41 class TestApiUpdateRepo(object):
43 42
44 43 @pytest.mark.parametrize("updates, expected", [
45 44 ({'owner': TEST_USER_REGULAR_LOGIN},
46 45 SAME_AS_UPDATES),
47 46
48 47 ({'description': 'new description'},
49 48 SAME_AS_UPDATES),
50 49
51 50 ({'clone_uri': 'http://foo.com/repo'},
52 51 SAME_AS_UPDATES),
53 52
54 53 ({'clone_uri': None},
55 54 {'clone_uri': ''}),
56 55
57 56 ({'clone_uri': ''},
58 57 {'clone_uri': ''}),
59 58
60 59 ({'clone_uri': 'http://example.com/repo_pull'},
61 60 {'clone_uri': 'http://example.com/repo_pull'}),
62 61
63 62 ({'push_uri': ''},
64 63 {'push_uri': ''}),
65 64
66 65 ({'push_uri': 'http://example.com/repo_push'},
67 66 {'push_uri': 'http://example.com/repo_push'}),
68 67
69 68 ({'landing_rev': None}, # auto-updated based on type of repo
70 69 {'landing_rev': [None, None]}),
71 70
72 71 ({'enable_statistics': True},
73 72 SAME_AS_UPDATES),
74 73
75 74 ({'enable_locking': True},
76 75 SAME_AS_UPDATES),
77 76
78 77 ({'enable_downloads': True},
79 78 SAME_AS_UPDATES),
80 79
81 80 ({'repo_name': 'new_repo_name'},
82 81 {
83 82 'repo_name': 'new_repo_name',
84 83 'url': 'http://{}/new_repo_name'.format(plain_http_host_only_stub())
85 84 }),
86 85
87 86 ({'repo_name': 'test_group_for_update/{}'.format(UPDATE_REPO_NAME),
88 87 '_group': 'test_group_for_update'},
89 88 {
90 89 'repo_name': 'test_group_for_update/{}'.format(UPDATE_REPO_NAME),
91 90 'url': 'http://{}/test_group_for_update/{}'.format(
92 91 plain_http_host_only_stub(), UPDATE_REPO_NAME)
93 92 }),
94 93 ])
95 94 def test_api_update_repo(self, updates, expected, backend):
96 95 repo_name = UPDATE_REPO_NAME
97 96 repo = fixture.create_repo(repo_name, repo_type=backend.alias)
98 97 if updates.get('_group'):
99 98 fixture.create_repo_group(updates['_group'])
100 99
101 100 if 'landing_rev' in updates:
102 101 default_landing_ref, _lbl = ScmModel.backend_landing_ref(backend.alias)
103 102 _type, _name = default_landing_ref.split(':')
104 103 updates['landing_rev'] = default_landing_ref
105 104 expected['landing_rev'] = [_type, _name]
106 105
107 106 expected_api_data = repo.get_api_data(include_secrets=True)
108 107 if expected is SAME_AS_UPDATES:
109 108 expected_api_data.update(updates)
110 109 else:
111 110 expected_api_data.update(expected)
112 111
113 112 id_, params = build_data(
114 113 self.apikey, 'update_repo', repoid=repo_name, **updates)
115 114
116 115 with mock.patch('rhodecode.model.validation_schema.validators.url_validator'):
117 116 response = api_call(self.app, params)
118 117
119 118 if updates.get('repo_name'):
120 119 repo_name = updates['repo_name']
121 120
122 121 try:
123 122 expected = {
124 123 'msg': 'updated repo ID:%s %s' % (repo.repo_id, repo_name),
125 124 'repository': jsonify(expected_api_data)
126 125 }
127 126 assert_ok(id_, expected, given=response.body)
128 127 finally:
129 128 fixture.destroy_repo(repo_name)
130 129 if updates.get('_group'):
131 130 fixture.destroy_repo_group(updates['_group'])
132 131
133 132 def test_api_update_repo_fork_of_field(self, backend):
134 133 master_repo = backend.create_repo()
135 134 repo = backend.create_repo()
136 135 updates = {
137 136 'fork_of': master_repo.repo_name,
138 137 'fork_of_id': master_repo.repo_id
139 138 }
140 139 expected_api_data = repo.get_api_data(include_secrets=True)
141 140 expected_api_data.update(updates)
142 141
143 142 id_, params = build_data(
144 143 self.apikey, 'update_repo', repoid=repo.repo_name, **updates)
145 144 response = api_call(self.app, params)
146 145 expected = {
147 146 'msg': 'updated repo ID:%s %s' % (repo.repo_id, repo.repo_name),
148 147 'repository': jsonify(expected_api_data)
149 148 }
150 149 assert_ok(id_, expected, given=response.body)
151 150 result = response.json['result']['repository']
152 151 assert result['fork_of'] == master_repo.repo_name
153 152 assert result['fork_of_id'] == master_repo.repo_id
154 153
155 154 def test_api_update_repo_fork_of_not_found(self, backend):
156 155 master_repo_name = 'fake-parent-repo'
157 156 repo = backend.create_repo()
158 157 updates = {
159 158 'fork_of': master_repo_name
160 159 }
161 160 id_, params = build_data(
162 161 self.apikey, 'update_repo', repoid=repo.repo_name, **updates)
163 162 response = api_call(self.app, params)
164 163 expected = {
165 164 'repo_fork_of': 'Fork with id `{}` does not exists'.format(
166 165 master_repo_name)}
167 166 assert_error(id_, expected, given=response.body)
168 167
169 168 def test_api_update_repo_with_repo_group_not_existing(self):
170 169 repo_name = 'admin_owned'
171 170 fake_repo_group = 'test_group_for_update'
172 171 fixture.create_repo(repo_name)
173 172 updates = {'repo_name': '{}/{}'.format(fake_repo_group, repo_name)}
174 173 id_, params = build_data(
175 174 self.apikey, 'update_repo', repoid=repo_name, **updates)
176 175 response = api_call(self.app, params)
177 176 try:
178 177 expected = {
179 178 'repo_group': 'Repository group `{}` does not exist'.format(fake_repo_group)
180 179 }
181 180 assert_error(id_, expected, given=response.body)
182 181 finally:
183 182 fixture.destroy_repo(repo_name)
184 183
185 184 def test_api_update_repo_regular_user_not_allowed(self):
186 185 repo_name = 'admin_owned'
187 186 fixture.create_repo(repo_name)
188 187 updates = {'active': False}
189 188 id_, params = build_data(
190 189 self.apikey_regular, 'update_repo', repoid=repo_name, **updates)
191 190 response = api_call(self.app, params)
192 191 try:
193 192 expected = 'repository `%s` does not exist' % (repo_name,)
194 193 assert_error(id_, expected, given=response.body)
195 194 finally:
196 195 fixture.destroy_repo(repo_name)
197 196
198 197 @mock.patch.object(RepoModel, 'update', crash)
199 198 def test_api_update_repo_exception_occurred(self, backend):
200 199 repo_name = UPDATE_REPO_NAME
201 200 fixture.create_repo(repo_name, repo_type=backend.alias)
202 201 id_, params = build_data(
203 202 self.apikey, 'update_repo', repoid=repo_name,
204 203 owner=TEST_USER_ADMIN_LOGIN,)
205 204 response = api_call(self.app, params)
206 205 try:
207 206 expected = 'failed to update repo `%s`' % (repo_name,)
208 207 assert_error(id_, expected, given=response.body)
209 208 finally:
210 209 fixture.destroy_repo(repo_name)
@@ -1,150 +1,149 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20 import os
22 21
23 22 import pytest
24 23
25 24 from rhodecode.model.repo_group import RepoGroupModel
26 25 from rhodecode.model.user import UserModel
27 26 from rhodecode.api.tests.utils import (
28 27 build_data, api_call, assert_error, assert_ok)
29 28
30 29
31 30 @pytest.mark.usefixtures("testuser_api", "app")
32 31 class TestApiUpdateRepoGroup(object):
33 32
34 33 def test_update_group_name(self, user_util):
35 34 new_group_name = 'new-group'
36 35 initial_name = self._update(user_util, group_name=new_group_name)
37 36 assert RepoGroupModel()._get_repo_group(initial_name) is None
38 37 new_group = RepoGroupModel()._get_repo_group(new_group_name)
39 38 assert new_group is not None
40 39 assert new_group.full_path == new_group_name
41 40
42 41 def test_update_group_name_change_parent(self, user_util):
43 42
44 43 parent_group = user_util.create_repo_group()
45 44 parent_group_name = parent_group.name
46 45
47 46 expected_group_name = '{}/{}'.format(parent_group_name, 'new-group')
48 47 initial_name = self._update(user_util, group_name=expected_group_name)
49 48
50 49 repo_group = RepoGroupModel()._get_repo_group(expected_group_name)
51 50
52 51 assert repo_group is not None
53 52 assert repo_group.group_name == expected_group_name
54 53 assert repo_group.full_path == expected_group_name
55 54 assert RepoGroupModel()._get_repo_group(initial_name) is None
56 55
57 56 new_path = os.path.join(
58 57 RepoGroupModel().repos_path, *repo_group.full_path_splitted)
59 58 assert os.path.exists(new_path)
60 59
61 60 def test_update_enable_locking(self, user_util):
62 61 initial_name = self._update(user_util, enable_locking=True)
63 62 repo_group = RepoGroupModel()._get_repo_group(initial_name)
64 63 assert repo_group.enable_locking is True
65 64
66 65 def test_update_description(self, user_util):
67 66 description = 'New description'
68 67 initial_name = self._update(user_util, description=description)
69 68 repo_group = RepoGroupModel()._get_repo_group(initial_name)
70 69 assert repo_group.group_description == description
71 70
72 71 def test_update_owner(self, user_util):
73 72 owner = self.TEST_USER_LOGIN
74 73 initial_name = self._update(user_util, owner=owner)
75 74 repo_group = RepoGroupModel()._get_repo_group(initial_name)
76 75 assert repo_group.user.username == owner
77 76
78 77 def test_update_group_name_conflict_with_existing(self, user_util):
79 78 group_1 = user_util.create_repo_group()
80 79 group_2 = user_util.create_repo_group()
81 80 repo_group_name_1 = group_1.group_name
82 81 repo_group_name_2 = group_2.group_name
83 82
84 83 id_, params = build_data(
85 84 self.apikey, 'update_repo_group', repogroupid=repo_group_name_1,
86 85 group_name=repo_group_name_2)
87 86 response = api_call(self.app, params)
88 87 expected = {
89 88 'unique_repo_group_name':
90 89 'Repository group with name `{}` already exists'.format(
91 90 repo_group_name_2)}
92 91 assert_error(id_, expected, given=response.body)
93 92
94 93 def test_api_update_repo_group_by_regular_user_no_permission(self, user_util):
95 94 temp_user = user_util.create_user()
96 95 temp_user_api_key = temp_user.api_key
97 96 parent_group = user_util.create_repo_group()
98 97 repo_group_name = parent_group.group_name
99 98 id_, params = build_data(
100 99 temp_user_api_key, 'update_repo_group', repogroupid=repo_group_name)
101 100 response = api_call(self.app, params)
102 101 expected = 'repository group `%s` does not exist' % (repo_group_name,)
103 102 assert_error(id_, expected, given=response.body)
104 103
105 104 def test_api_update_repo_group_regular_user_no_root_write_permissions(
106 105 self, user_util):
107 106 temp_user = user_util.create_user()
108 107 temp_user_api_key = temp_user.api_key
109 108 parent_group = user_util.create_repo_group(owner=temp_user.username)
110 109 repo_group_name = parent_group.group_name
111 110
112 111 id_, params = build_data(
113 112 temp_user_api_key, 'update_repo_group', repogroupid=repo_group_name,
114 113 group_name='at-root-level')
115 114 response = api_call(self.app, params)
116 115 expected = {
117 116 'repo_group': 'You do not have the permission to store '
118 117 'repository groups in the root location.'}
119 118 assert_error(id_, expected, given=response.body)
120 119
121 120 def _update(self, user_util, **kwargs):
122 121 repo_group = user_util.create_repo_group()
123 122 initial_name = repo_group.name
124 123 user = UserModel().get_by_username(self.TEST_USER_LOGIN)
125 124 user_util.grant_user_permission_to_repo_group(
126 125 repo_group, user, 'group.admin')
127 126
128 127 id_, params = build_data(
129 128 self.apikey, 'update_repo_group', repogroupid=initial_name,
130 129 **kwargs)
131 130 response = api_call(self.app, params)
132 131
133 132 repo_group = RepoGroupModel.cls.get(repo_group.group_id)
134 133
135 134 expected = {
136 135 'msg': 'updated repository group ID:{} {}'.format(
137 136 repo_group.group_id, repo_group.group_name),
138 137 'repo_group': {
139 138 'repositories': [],
140 139 'group_name': repo_group.group_name,
141 140 'group_description': repo_group.group_description,
142 141 'owner': repo_group.user.username,
143 142 'group_id': repo_group.group_id,
144 143 'parent_group': (
145 144 repo_group.parent_group.name
146 145 if repo_group.parent_group else None)
147 146 }
148 147 }
149 148 assert_ok(id_, expected, given=response.body)
150 149 return initial_name
@@ -1,121 +1,120 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20 import mock
22 21 import pytest
23 22
24 23 from rhodecode.model.db import User
25 24 from rhodecode.model.user import UserModel
26 25 from rhodecode.tests import TEST_USER_ADMIN_LOGIN
27 26 from rhodecode.api.tests.utils import (
28 27 build_data, api_call, assert_ok, assert_error, crash, jsonify)
29 28
30 29
31 30 @pytest.mark.usefixtures("testuser_api", "app")
32 31 class TestUpdateUser(object):
33 32 @pytest.mark.parametrize("name, expected", [
34 33 ('firstname', 'new_username'),
35 34 ('lastname', 'new_username'),
36 35 ('email', 'new_username'),
37 36 ('admin', True),
38 37 ('admin', False),
39 38 ('extern_type', 'ldap'),
40 39 ('extern_type', None),
41 40 ('extern_name', 'test'),
42 41 ('extern_name', None),
43 42 ('active', False),
44 43 ('active', True),
45 44 ('password', 'newpass'),
46 45 ('description', 'CTO 4 Life')
47 46 ])
48 47 def test_api_update_user(self, name, expected, user_util):
49 48 usr = user_util.create_user()
50 49
51 50 kw = {name: expected, 'userid': usr.user_id}
52 51 id_, params = build_data(self.apikey, 'update_user', **kw)
53 52 response = api_call(self.app, params)
54 53
55 54 ret = {
56 55 'msg': 'updated user ID:%s %s' % (usr.user_id, usr.username),
57 56 'user': jsonify(
58 57 UserModel()
59 58 .get_by_username(usr.username)
60 59 .get_api_data(include_secrets=True)
61 60 )
62 61 }
63 62
64 63 expected = ret
65 64 assert_ok(id_, expected, given=response.body)
66 65
67 66 def test_api_update_user_no_changed_params(self):
68 67 usr = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN)
69 68 ret = jsonify(usr.get_api_data(include_secrets=True))
70 69 id_, params = build_data(
71 70 self.apikey, 'update_user', userid=TEST_USER_ADMIN_LOGIN)
72 71
73 72 response = api_call(self.app, params)
74 73 ret = {
75 74 'msg': 'updated user ID:%s %s' % (
76 75 usr.user_id, TEST_USER_ADMIN_LOGIN),
77 76 'user': ret
78 77 }
79 78 expected = ret
80 79 expected['user']['last_activity'] = response.json['result']['user'][
81 80 'last_activity']
82 81 assert_ok(id_, expected, given=response.body)
83 82
84 83 def test_api_update_user_by_user_id(self):
85 84 usr = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN)
86 85 ret = jsonify(usr.get_api_data(include_secrets=True))
87 86 id_, params = build_data(
88 87 self.apikey, 'update_user', userid=usr.user_id)
89 88
90 89 response = api_call(self.app, params)
91 90 ret = {
92 91 'msg': 'updated user ID:%s %s' % (
93 92 usr.user_id, TEST_USER_ADMIN_LOGIN),
94 93 'user': ret
95 94 }
96 95 expected = ret
97 96 expected['user']['last_activity'] = response.json['result']['user'][
98 97 'last_activity']
99 98 assert_ok(id_, expected, given=response.body)
100 99
101 100 def test_api_update_user_default_user(self):
102 101 usr = User.get_default_user()
103 102 id_, params = build_data(
104 103 self.apikey, 'update_user', userid=usr.user_id)
105 104
106 105 response = api_call(self.app, params)
107 106 expected = 'editing default user is forbidden'
108 107 assert_error(id_, expected, given=response.body)
109 108
110 109 @mock.patch.object(UserModel, 'update_user', crash)
111 110 def test_api_update_user_when_exception_happens(self):
112 111 usr = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN)
113 112 ret = jsonify(usr.get_api_data(include_secrets=True))
114 113 id_, params = build_data(
115 114 self.apikey, 'update_user', userid=usr.user_id)
116 115
117 116 response = api_call(self.app, params)
118 117 ret = 'failed to update user `%s`' % (usr.user_id,)
119 118
120 119 expected = ret
121 120 assert_error(id_, expected, given=response.body)
@@ -1,125 +1,124 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20 import mock
22 21 import pytest
23 22
24 23 from rhodecode.model.user import UserModel
25 24 from rhodecode.model.user_group import UserGroupModel
26 25 from rhodecode.tests import TEST_USER_ADMIN_EMAIL
27 26 from rhodecode.api.tests.utils import (
28 27 build_data, api_call, assert_error, assert_ok, crash, jsonify)
29 28
30 29
31 30 @pytest.mark.usefixtures("testuser_api", "app")
32 31 class TestUpdateUserGroup(object):
33 32 @pytest.mark.parametrize("changing_attr, updates", [
34 33 ('group_name', {'group_name': 'new_group_name'}),
35 34 ('group_name', {'group_name': 'test_group_for_update'}),
36 35 # ('owner', {'owner': TEST_USER_REGULAR_LOGIN}),
37 36 ('owner_email', {'owner_email': TEST_USER_ADMIN_EMAIL}),
38 37 ('active', {'active': False}),
39 38 ('active', {'active': True}),
40 39 ('sync', {'sync': False}),
41 40 ('sync', {'sync': True})
42 41 ])
43 42 def test_api_update_user_group(self, changing_attr, updates, user_util):
44 43 user_group = user_util.create_user_group()
45 44 group_name = user_group.users_group_name
46 45 expected_api_data = user_group.get_api_data()
47 46 expected_api_data.update(updates)
48 47
49 48 id_, params = build_data(
50 49 self.apikey, 'update_user_group', usergroupid=group_name,
51 50 **updates)
52 51 response = api_call(self.app, params)
53 52
54 53 # special case for sync
55 54 if changing_attr == 'sync' and updates['sync'] is False:
56 55 expected_api_data['sync'] = None
57 56 elif changing_attr == 'sync' and updates['sync'] is True:
58 57 expected_api_data['sync'] = 'manual_api'
59 58
60 59 expected = {
61 60 'msg': 'updated user group ID:%s %s' % (
62 61 user_group.users_group_id, user_group.users_group_name),
63 62 'user_group': jsonify(expected_api_data)
64 63 }
65 64 assert_ok(id_, expected, given=response.body)
66 65
67 66 @pytest.mark.parametrize("changing_attr, updates", [
68 67 # TODO: mikhail: decide if we need to test against the commented params
69 68 # ('group_name', {'group_name': 'new_group_name'}),
70 69 # ('group_name', {'group_name': 'test_group_for_update'}),
71 70 # ('owner', {'owner': TEST_USER_REGULAR_LOGIN}),
72 71 ('owner_email', {'owner_email': TEST_USER_ADMIN_EMAIL}),
73 72 ('active', {'active': False}),
74 73 ('active', {'active': True}),
75 74 ('sync', {'sync': False}),
76 75 ('sync', {'sync': True})
77 76 ])
78 77 def test_api_update_user_group_regular_user(
79 78 self, changing_attr, updates, user_util):
80 79 user_group = user_util.create_user_group()
81 80 group_name = user_group.users_group_name
82 81 expected_api_data = user_group.get_api_data()
83 82 expected_api_data.update(updates)
84 83
85 84 # grant permission to this user
86 85 user = UserModel().get_by_username(self.TEST_USER_LOGIN)
87 86
88 87 user_util.grant_user_permission_to_user_group(
89 88 user_group, user, 'usergroup.admin')
90 89 id_, params = build_data(
91 90 self.apikey_regular, 'update_user_group',
92 91 usergroupid=group_name, **updates)
93 92 response = api_call(self.app, params)
94 93 # special case for sync
95 94 if changing_attr == 'sync' and updates['sync'] is False:
96 95 expected_api_data['sync'] = None
97 96 elif changing_attr == 'sync' and updates['sync'] is True:
98 97 expected_api_data['sync'] = 'manual_api'
99 98
100 99 expected = {
101 100 'msg': 'updated user group ID:%s %s' % (
102 101 user_group.users_group_id, user_group.users_group_name),
103 102 'user_group': jsonify(expected_api_data)
104 103 }
105 104 assert_ok(id_, expected, given=response.body)
106 105
107 106 def test_api_update_user_group_regular_user_no_permission(self, user_util):
108 107 user_group = user_util.create_user_group()
109 108 group_name = user_group.users_group_name
110 109 id_, params = build_data(
111 110 self.apikey_regular, 'update_user_group', usergroupid=group_name)
112 111 response = api_call(self.app, params)
113 112
114 113 expected = 'user group `%s` does not exist' % (group_name)
115 114 assert_error(id_, expected, given=response.body)
116 115
117 116 @mock.patch.object(UserGroupModel, 'update', crash)
118 117 def test_api_update_user_group_exception_occurred(self, user_util):
119 118 user_group = user_util.create_user_group()
120 119 group_name = user_group.users_group_name
121 120 id_, params = build_data(
122 121 self.apikey, 'update_user_group', usergroupid=group_name)
123 122 response = api_call(self.app, params)
124 123 expected = 'failed to update user group `%s`' % (group_name,)
125 124 assert_error(id_, expected, given=response.body)
@@ -1,295 +1,297 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20
22 21 import pytest
23 22 from mock import Mock, patch
24 23
25 24 from rhodecode.api import utils
26 25 from rhodecode.api import JSONRPCError
27 26 from rhodecode.lib.vcs.exceptions import RepositoryError
28 27
29 28
30 29 class TestGetCommitOrError(object):
31 def setup(self):
30
31 def setup_method(self):
32 32 self.commit_hash = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa10'
33 33
34 34 @pytest.mark.parametrize("ref", ['ref', '12345', 'a:b:c:d', 'branch:name'])
35 35 def test_ref_cannot_be_parsed(self, ref):
36 36 repo = Mock()
37 37 with pytest.raises(JSONRPCError) as excinfo:
38 38 utils.get_commit_or_error(ref, repo)
39 39 expected_message = (
40 40 'Ref `{ref}` given in a wrong format. Please check the API'
41 41 ' documentation for more details'.format(ref=ref)
42 42 )
43 43 assert excinfo.value.message == expected_message
44 44
45 45 def test_success_with_hash_specified(self):
46 46 repo = Mock()
47 47 ref_type = 'branch'
48 48 ref = '{}:master:{}'.format(ref_type, self.commit_hash)
49 49
50 50 with patch('rhodecode.api.utils.get_commit_from_ref_name') as get_commit:
51 51 result = utils.get_commit_or_error(ref, repo)
52 52 get_commit.assert_called_once_with(
53 53 repo, self.commit_hash)
54 54 assert result == get_commit()
55 55
56 56 def test_raises_an_error_when_commit_not_found(self):
57 57 repo = Mock()
58 58 ref = 'branch:master:{}'.format(self.commit_hash)
59 59
60 60 with patch('rhodecode.api.utils.get_commit_from_ref_name') as get_commit:
61 61 get_commit.side_effect = RepositoryError('Commit not found')
62 62 with pytest.raises(JSONRPCError) as excinfo:
63 63 utils.get_commit_or_error(ref, repo)
64 64 expected_message = 'Ref `{}` does not exist'.format(ref)
65 65 assert excinfo.value.message == expected_message
66 66
67 67
68 68 class TestResolveRefOrError(object):
69 def setup(self):
69
70 def setup_method(self):
70 71 self.commit_hash = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa10'
71 72
72 73 def test_success_with_no_hash_specified(self):
73 74 repo = Mock()
74 75 ref_type = 'branch'
75 76 ref_name = 'master'
76 77 ref = '{}:{}'.format(ref_type, ref_name)
77 78
78 79 with patch('rhodecode.api.utils._get_ref_hash') \
79 80 as _get_ref_hash:
80 81 _get_ref_hash.return_value = self.commit_hash
81 82 result = utils.resolve_ref_or_error(ref, repo)
82 83 _get_ref_hash.assert_called_once_with(repo, ref_type, ref_name)
83 84 assert result == '{}:{}'.format(ref, self.commit_hash)
84 85
85 86 def test_non_supported_refs(self):
86 87 repo = Mock()
87 88 ref = 'bookmark:ref'
88 89 with pytest.raises(JSONRPCError) as excinfo:
89 90 utils.resolve_ref_or_error(ref, repo)
90 91 expected_message = (
91 92 'The specified value:bookmark:`ref` does not exist, or is not allowed.')
92 93 assert excinfo.value.message == expected_message
93 94
94 95 def test_branch_is_not_found(self):
95 96 repo = Mock()
96 97 ref = 'branch:non-existing-one'
97 98 with patch('rhodecode.api.utils._get_ref_hash')\
98 99 as _get_ref_hash:
99 100 _get_ref_hash.side_effect = KeyError()
100 101 with pytest.raises(JSONRPCError) as excinfo:
101 102 utils.resolve_ref_or_error(ref, repo)
102 103 expected_message = (
103 104 'The specified value:branch:`non-existing-one` does not exist, or is not allowed.')
104 105 assert excinfo.value.message == expected_message
105 106
106 107 def test_bookmark_is_not_found(self):
107 108 repo = Mock()
108 109 ref = 'bookmark:non-existing-one'
109 110 with patch('rhodecode.api.utils._get_ref_hash')\
110 111 as _get_ref_hash:
111 112 _get_ref_hash.side_effect = KeyError()
112 113 with pytest.raises(JSONRPCError) as excinfo:
113 114 utils.resolve_ref_or_error(ref, repo)
114 115 expected_message = (
115 116 'The specified value:bookmark:`non-existing-one` does not exist, or is not allowed.')
116 117 assert excinfo.value.message == expected_message
117 118
118 119 @pytest.mark.parametrize("ref", ['ref', '12345', 'a:b:c:d'])
119 120 def test_ref_cannot_be_parsed(self, ref):
120 121 repo = Mock()
121 122 with pytest.raises(JSONRPCError) as excinfo:
122 123 utils.resolve_ref_or_error(ref, repo)
123 124 expected_message = (
124 125 'Ref `{ref}` given in a wrong format. Please check the API'
125 126 ' documentation for more details'.format(ref=ref)
126 127 )
127 128 assert excinfo.value.message == expected_message
128 129
129 130
130 131 class TestGetRefHash(object):
131 def setup(self):
132
133 def setup_method(self):
132 134 self.commit_hash = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa10'
133 135 self.bookmark_name = 'test-bookmark'
134 136
135 137 @pytest.mark.parametrize("alias, branch_name", [
136 138 ("git", "master"),
137 139 ("hg", "default")
138 140 ])
139 141 def test_returns_hash_by_branch_name(self, alias, branch_name):
140 142 with patch('rhodecode.model.db.Repository') as repo:
141 143 repo.scm_instance().alias = alias
142 144 repo.scm_instance().branches = {branch_name: self.commit_hash}
143 145 result_hash = utils._get_ref_hash(repo, 'branch', branch_name)
144 146 assert result_hash == self.commit_hash
145 147
146 148 @pytest.mark.parametrize("alias, branch_name", [
147 149 ("git", "master"),
148 150 ("hg", "default")
149 151 ])
150 152 def test_raises_error_when_branch_is_not_found(self, alias, branch_name):
151 153 with patch('rhodecode.model.db.Repository') as repo:
152 154 repo.scm_instance().alias = alias
153 155 repo.scm_instance().branches = {}
154 156 with pytest.raises(KeyError):
155 157 utils._get_ref_hash(repo, 'branch', branch_name)
156 158
157 159 def test_returns_hash_when_bookmark_is_specified_for_hg(self):
158 160 with patch('rhodecode.model.db.Repository') as repo:
159 161 repo.scm_instance().alias = 'hg'
160 162 repo.scm_instance().bookmarks = {
161 163 self.bookmark_name: self.commit_hash}
162 164 result_hash = utils._get_ref_hash(
163 165 repo, 'bookmark', self.bookmark_name)
164 166 assert result_hash == self.commit_hash
165 167
166 168 def test_raises_error_when_bookmark_is_not_found_in_hg_repo(self):
167 169 with patch('rhodecode.model.db.Repository') as repo:
168 170 repo.scm_instance().alias = 'hg'
169 171 repo.scm_instance().bookmarks = {}
170 172 with pytest.raises(KeyError):
171 173 utils._get_ref_hash(repo, 'bookmark', self.bookmark_name)
172 174
173 175 def test_raises_error_when_bookmark_is_specified_for_git(self):
174 176 with patch('rhodecode.model.db.Repository') as repo:
175 177 repo.scm_instance().alias = 'git'
176 178 repo.scm_instance().bookmarks = {
177 179 self.bookmark_name: self.commit_hash}
178 180 with pytest.raises(ValueError):
179 181 utils._get_ref_hash(repo, 'bookmark', self.bookmark_name)
180 182
181 183
182 184 class TestUserByNameOrError(object):
183 185 def test_user_found_by_id(self):
184 186 fake_user = Mock(id=123)
185 187
186 188 patcher = patch('rhodecode.model.user.UserModel.get_user')
187 189 with patcher as get_user:
188 190 get_user.return_value = fake_user
189 191
190 192 patcher = patch('rhodecode.model.user.UserModel.get_by_username')
191 193 with patcher as get_by_username:
192 194 result = utils.get_user_or_error(123)
193 195 assert result == fake_user
194 196
195 197 def test_user_not_found_by_id_as_str(self):
196 198 fake_user = Mock(id=123)
197 199
198 200 patcher = patch('rhodecode.model.user.UserModel.get_user')
199 201 with patcher as get_user:
200 202 get_user.return_value = fake_user
201 203 patcher = patch('rhodecode.model.user.UserModel.get_by_username')
202 204 with patcher as get_by_username:
203 205 get_by_username.return_value = None
204 206
205 207 with pytest.raises(JSONRPCError):
206 208 utils.get_user_or_error('123')
207 209
208 210 def test_user_found_by_name(self):
209 211 fake_user = Mock(id=123)
210 212
211 213 patcher = patch('rhodecode.model.user.UserModel.get_user')
212 214 with patcher as get_user:
213 215 get_user.return_value = None
214 216
215 217 patcher = patch('rhodecode.model.user.UserModel.get_by_username')
216 218 with patcher as get_by_username:
217 219 get_by_username.return_value = fake_user
218 220
219 221 result = utils.get_user_or_error('test')
220 222 assert result == fake_user
221 223
222 224 def test_user_not_found_by_id(self):
223 225 patcher = patch('rhodecode.model.user.UserModel.get_user')
224 226 with patcher as get_user:
225 227 get_user.return_value = None
226 228 patcher = patch('rhodecode.model.user.UserModel.get_by_username')
227 229 with patcher as get_by_username:
228 230 get_by_username.return_value = None
229 231
230 232 with pytest.raises(JSONRPCError) as excinfo:
231 233 utils.get_user_or_error(123)
232 234
233 235 expected_message = 'user `123` does not exist'
234 236 assert excinfo.value.message == expected_message
235 237
236 238 def test_user_not_found_by_name(self):
237 239 patcher = patch('rhodecode.model.user.UserModel.get_by_username')
238 240 with patcher as get_by_username:
239 241 get_by_username.return_value = None
240 242 with pytest.raises(JSONRPCError) as excinfo:
241 243 utils.get_user_or_error('test')
242 244
243 245 expected_message = 'user `test` does not exist'
244 246 assert excinfo.value.message == expected_message
245 247
246 248
247 249 class TestGetCommitDict(object):
248 250 @pytest.mark.parametrize('filename, expected', [
249 251 (b'sp\xc3\xa4cial', u'sp\xe4cial'),
250 252 (b'sp\xa4cial', u'sp\ufffdcial'),
251 253 ])
252 254 def test_decodes_filenames_to_unicode(self, filename, expected):
253 255 result = utils._get_commit_dict(filename=filename, op='A')
254 256 assert result['filename'] == expected
255 257
256 258
257 259 class TestRepoAccess(object):
258 260 def setup_method(self, method):
259 261
260 262 self.admin_perm_patch = patch(
261 263 'rhodecode.api.utils.HasPermissionAnyApi')
262 264 self.repo_perm_patch = patch(
263 265 'rhodecode.api.utils.HasRepoPermissionAnyApi')
264 266
265 267 def test_has_superadmin_permission_checks_for_admin(self):
266 268 admin_mock = Mock()
267 269 with self.admin_perm_patch as amock:
268 270 amock.return_value = admin_mock
269 271 assert utils.has_superadmin_permission('fake_user')
270 272 amock.assert_called_once_with('hg.admin')
271 273
272 274 admin_mock.assert_called_once_with(user='fake_user')
273 275
274 276 def test_has_repo_permissions_checks_for_repo_access(self):
275 277 repo_mock = Mock()
276 278 fake_repo = Mock()
277 279 with self.repo_perm_patch as rmock:
278 280 rmock.return_value = repo_mock
279 281 assert utils.validate_repo_permissions(
280 282 'fake_user', 'fake_repo_id', fake_repo,
281 283 ['perm1', 'perm2'])
282 284 rmock.assert_called_once_with(*['perm1', 'perm2'])
283 285
284 286 repo_mock.assert_called_once_with(
285 287 user='fake_user', repo_name=fake_repo.repo_name)
286 288
287 289 def test_has_repo_permissions_raises_not_found(self):
288 290 repo_mock = Mock(return_value=False)
289 291 fake_repo = Mock()
290 292 with self.repo_perm_patch as rmock:
291 293 rmock.return_value = repo_mock
292 294 with pytest.raises(JSONRPCError) as excinfo:
293 295 utils.validate_repo_permissions(
294 296 'fake_user', 'fake_repo_id', fake_repo, 'perms')
295 297 assert 'fake_repo_id' in excinfo
@@ -1,124 +1,123 b''
1 # -*- coding: utf-8 -*-
2 1
3 2 # Copyright (C) 2010-2020 RhodeCode GmbH
4 3 #
5 4 # This program is free software: you can redistribute it and/or modify
6 5 # it under the terms of the GNU Affero General Public License, version 3
7 6 # (only), as published by the Free Software Foundation.
8 7 #
9 8 # This program is distributed in the hope that it will be useful,
10 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 11 # GNU General Public License for more details.
13 12 #
14 13 # You should have received a copy of the GNU Affero General Public License
15 14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 15 #
17 16 # This program is dual-licensed. If you wish to learn more about the
18 17 # RhodeCode Enterprise Edition, including its added features, Support services,
19 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 19
21 20
22 21 import random
23 22 import pytest
24 23
25 24 from rhodecode.api.utils import get_origin
26 25 from rhodecode.lib.ext_json import json
27 26
28 27
29 28 def jsonify(obj):
30 29 return json.loads(json.dumps(obj))
31 30
32 31
33 32 API_URL = '/_admin/api'
34 33
35 34
36 35 def assert_call_ok(id_, given):
37 36 expected = jsonify({
38 37 'id': id_,
39 38 'error': None,
40 39 'result': None
41 40 })
42 41 given = json.loads(given)
43 42
44 43 assert expected['id'] == given['id']
45 44 assert expected['error'] == given['error']
46 45 return given['result']
47 46
48 47
49 48 def assert_ok(id_, expected, given):
50 49 given = json.loads(given)
51 50 if given.get('error'):
52 51 err = given['error']
53 pytest.fail(u"Unexpected ERROR in success response: {}".format(err))
52 pytest.fail(f"Unexpected ERROR in expected success response: `{err}`")
54 53
55 54 expected = jsonify({
56 55 'id': id_,
57 56 'error': None,
58 57 'result': expected
59 58 })
60 59
61 60 assert expected == given
62 61
63 62
64 63 def assert_error(id_, expected, given):
65 64 expected = jsonify({
66 65 'id': id_,
67 66 'error': expected,
68 67 'result': None
69 68 })
70 69 given = json.loads(given)
71 70 assert expected == given
72 71
73 72
74 73 def build_data(apikey, method, **kw):
75 74 """
76 75 Builds API data with given random ID
77 76 """
78 77 random_id = random.randrange(1, 9999)
79 78 return random_id, json.dumps({
80 79 "id": random_id,
81 80 "api_key": apikey,
82 81 "method": method,
83 82 "args": kw
84 83 })
85 84
86 85
87 86 def api_call(app, params, status=None):
88 87 response = app.post(
89 88 API_URL, content_type='application/json', params=params, status=status,
90 89 headers=[('Content-Type', 'application/json')])
91 90 return response
92 91
93 92
94 93 def crash(*args, **kwargs):
95 94 raise Exception('Total Crash !')
96 95
97 96
98 97 def expected_permissions(object_with_permissions):
99 98 """
100 99 Returns the expected permissions structure for the given object.
101 100
102 101 The object is expected to be a `Repository`, `RepositoryGroup`,
103 102 or `UserGroup`. They all implement the same permission handling
104 103 API.
105 104 """
106 105 permissions = []
107 106 for _user in object_with_permissions.permissions():
108 107 user_data = {
109 108 'name': _user.username,
110 109 'permission': _user.permission,
111 110 'origin': get_origin(_user),
112 111 'type': "user",
113 112 }
114 113 permissions.append(user_data)
115 114
116 115 for _user_group in object_with_permissions.permission_user_groups():
117 116 user_group_data = {
118 117 'name': _user_group.users_group_name,
119 118 'permission': _user_group.permission,
120 119 'origin': get_origin(_user_group),
121 120 'type': "user_group",
122 121 }
123 122 permissions.append(user_group_data)
124 123 return permissions
@@ -1,152 +1,152 b''
1 # -*- coding: utf-8 -*-
1
2 2
3 3 # Copyright (C) 2011-2020 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21
22 22 import logging
23 23
24 24 from rhodecode.api import jsonrpc_method
25 25 from rhodecode.api.exc import JSONRPCValidationError, JSONRPCForbidden
26 26 from rhodecode.api.utils import Optional, has_superadmin_permission
27 27 from rhodecode.lib.index import searcher_from_config
28 28 from rhodecode.lib.user_log_filter import user_log_filter
29 29 from rhodecode.model import validation_schema
30 30 from rhodecode.model.db import joinedload, UserLog
31 31 from rhodecode.model.validation_schema.schemas import search_schema
32 32
33 33 log = logging.getLogger(__name__)
34 34
35 35
36 36 @jsonrpc_method()
37 37 def search(request, apiuser, search_query, search_type, page_limit=Optional(10),
38 38 page=Optional(1), search_sort=Optional('desc:date'),
39 39 repo_name=Optional(None), repo_group_name=Optional(None)):
40 40 """
41 41 Fetch Full Text Search results using API.
42 42
43 43 :param apiuser: This is filled automatically from the |authtoken|.
44 44 :type apiuser: AuthUser
45 45 :param search_query: Search query.
46 46 :type search_query: str
47 47 :param search_type: Search type. The following are valid options:
48 48 * commit
49 49 * content
50 50 * path
51 51 :type search_type: str
52 52 :param page_limit: Page item limit, from 1 to 500. Default 10 items.
53 53 :type page_limit: Optional(int)
54 54 :param page: Page number. Default first page.
55 55 :type page: Optional(int)
56 56 :param search_sort: Search sort order.Must start with asc: or desc: Default desc:date.
57 57 The following are valid options:
58 58 * asc|desc:message.raw
59 59 * asc|desc:date
60 60 * asc|desc:author.email.raw
61 61 * asc|desc:message.raw
62 62 * newfirst (old legacy equal to desc:date)
63 63 * oldfirst (old legacy equal to asc:date)
64 64
65 65 :type search_sort: Optional(str)
66 66 :param repo_name: Filter by one repo. Default is all.
67 67 :type repo_name: Optional(str)
68 68 :param repo_group_name: Filter by one repo group. Default is all.
69 69 :type repo_group_name: Optional(str)
70 70 """
71 71
72 72 data = {'execution_time': ''}
73 73 repo_name = Optional.extract(repo_name)
74 74 repo_group_name = Optional.extract(repo_group_name)
75 75
76 76 schema = search_schema.SearchParamsSchema()
77 77
78 78 try:
79 79 search_params = schema.deserialize(
80 80 dict(search_query=search_query,
81 81 search_type=search_type,
82 82 search_sort=Optional.extract(search_sort),
83 83 page_limit=Optional.extract(page_limit),
84 84 requested_page=Optional.extract(page))
85 85 )
86 86 except validation_schema.Invalid as err:
87 87 raise JSONRPCValidationError(colander_exc=err)
88 88
89 89 search_query = search_params.get('search_query')
90 90 search_type = search_params.get('search_type')
91 91 search_sort = search_params.get('search_sort')
92 92
93 93 if search_params.get('search_query'):
94 94 page_limit = search_params['page_limit']
95 95 requested_page = search_params['requested_page']
96 96
97 97 searcher = searcher_from_config(request.registry.settings)
98 98
99 99 try:
100 100 search_result = searcher.search(
101 101 search_query, search_type, apiuser, repo_name, repo_group_name,
102 102 requested_page=requested_page, page_limit=page_limit, sort=search_sort)
103 103
104 104 data.update(dict(
105 105 results=list(search_result['results']), page=requested_page,
106 106 item_count=search_result['count'],
107 107 items_per_page=page_limit))
108 108 finally:
109 109 searcher.cleanup()
110 110
111 111 if not search_result['error']:
112 112 data['execution_time'] = '%s results (%.4f seconds)' % (
113 113 search_result['count'],
114 114 search_result['runtime'])
115 115 else:
116 116 node = schema['search_query']
117 117 raise JSONRPCValidationError(
118 118 colander_exc=validation_schema.Invalid(node, search_result['error']))
119 119
120 120 return data
121 121
122 122
123 123 @jsonrpc_method()
124 124 def get_audit_logs(request, apiuser, query):
125 125 """
126 126 return full audit logs based on the query.
127 127
128 128 Please see `example query in admin > settings > audit logs` for examples
129 129
130 130 :param apiuser: This is filled automatically from the |authtoken|.
131 131 :type apiuser: AuthUser
132 132 :param query: filter query, example: action:repo.artifact.add date:[20200401 TO 20200601]"
133 133 :type query: str
134 134 """
135 135
136 136 if not has_superadmin_permission(apiuser):
137 137 raise JSONRPCForbidden()
138 138
139 139 filter_term = query
140 140 ret = []
141 141
142 142 # show all user actions
143 143 user_log = UserLog.query() \
144 144 .options(joinedload(UserLog.user)) \
145 145 .options(joinedload(UserLog.repository)) \
146 146 .order_by(UserLog.action_date.desc())
147 147
148 148 audit_log = user_log_filter(user_log, filter_term)
149 149
150 150 for entry in audit_log:
151 151 ret.append(entry)
152 152 return ret
General Comments 0
You need to be logged in to leave comments. Login now