Show More
@@ -687,6 +687,8 b' class PullrequestsController(BaseRepoCon' | |||
|
687 | 687 | c.pull_request, c.rhodecode_user) and not c.pull_request.is_closed() |
|
688 | 688 | c.shadow_clone_url = PullRequestModel().get_shadow_clone_url( |
|
689 | 689 | c.pull_request) |
|
690 | c.allowed_to_delete = PullRequestModel().check_user_delete( | |
|
691 | c.pull_request, c.rhodecode_user) and not c.pull_request.is_closed() | |
|
690 | 692 | |
|
691 | 693 | cc_model = ChangesetCommentsModel() |
|
692 | 694 |
@@ -149,6 +149,11 b' class PullRequestModel(BaseModel):' | |||
|
149 | 149 | owner = user.user_id == pull_request.user_id |
|
150 | 150 | return self.check_user_merge(pull_request, user, api) or owner |
|
151 | 151 | |
|
152 | def check_user_delete(self, pull_request, user): | |
|
153 | owner = user.user_id == pull_request.user_id | |
|
154 | _perms = ('repository.admin') | |
|
155 | return self._check_perms(_perms, pull_request, user) or owner | |
|
156 | ||
|
152 | 157 | def check_user_change_status(self, pull_request, user, api=False): |
|
153 | 158 | reviewer = user.user_id in [x.user_id for x in |
|
154 | 159 | pull_request.reviewers] |
@@ -1343,6 +1343,11 b' table.integrations {' | |||
|
1343 | 1343 | .pr-details-title { |
|
1344 | 1344 | padding-bottom: 8px; |
|
1345 | 1345 | border-bottom: @border-thickness solid @grey5; |
|
1346 | ||
|
1347 | .action_button.disabled { | |
|
1348 | color: @grey4; | |
|
1349 | cursor: inherit; | |
|
1350 | } | |
|
1346 | 1351 | .action_button { |
|
1347 | 1352 | color: @rcblue; |
|
1348 | 1353 | } |
@@ -47,8 +47,18 b'' | |||
|
47 | 47 | <div class="pr-details-title"> |
|
48 | 48 | ${_('Pull request #%s') % c.pull_request.pull_request_id} ${_('From')} ${h.format_date(c.pull_request.created_on)} |
|
49 | 49 | %if c.allowed_to_update: |
|
50 | <span id="open_edit_pullrequest" class="block-right action_button">${_('Edit')}</span> | |
|
51 | <span id="close_edit_pullrequest" class="block-right action_button" style="display: none;">${_('Close')}</span> | |
|
50 | <div id="delete_pullrequest" class="pull-right action_button ${'' if c.allowed_to_delete else 'disabled' }" style="clear:inherit;padding: 0"> | |
|
51 | % if c.allowed_to_delete: | |
|
52 | ${h.secure_form(url('pullrequest_delete', repo_name=c.pull_request.target_repo.repo_name, pull_request_id=c.pull_request.pull_request_id),method='delete')} | |
|
53 | ${h.submit('remove_%s' % c.pull_request.pull_request_id, _('Delete'), | |
|
54 | class_="btn btn-link btn-danger",onclick="return confirm('"+_('Confirm to delete this pull request')+"');")} | |
|
55 | ${h.end_form()} | |
|
56 | % else: | |
|
57 | ${_('Delete')} | |
|
58 | % endif | |
|
59 | </div> | |
|
60 | <div id="open_edit_pullrequest" class="pull-right action_button">${_('Edit')}</div> | |
|
61 | <div id="close_edit_pullrequest" class="pull-right action_button" style="display: none;padding: 0">${_('Cancel edit')}</div> | |
|
52 | 62 | %endif |
|
53 | 63 | </div> |
|
54 | 64 | |
@@ -457,6 +467,7 b'' | |||
|
457 | 467 | var PRDetails = { |
|
458 | 468 | editButton: $('#open_edit_pullrequest'), |
|
459 | 469 | closeButton: $('#close_edit_pullrequest'), |
|
470 | deleteButton: $('#delete_pullrequest'), | |
|
460 | 471 | viewFields: $('#pr-desc, #pr-title'), |
|
461 | 472 | editFields: $('#pr-desc-edit, #pr-title-edit, #pr-save'), |
|
462 | 473 | |
@@ -469,11 +480,15 b'' | |||
|
469 | 480 | edit: function(event) { |
|
470 | 481 | this.viewFields.hide(); |
|
471 | 482 | this.editButton.hide(); |
|
483 | this.deleteButton.hide(); | |
|
484 | this.closeButton.show(); | |
|
472 | 485 | this.editFields.show(); |
|
473 | 486 | codeMirrorInstance.refresh(); |
|
474 | 487 | }, |
|
475 | 488 | |
|
476 | 489 | view: function(event) { |
|
490 | this.editButton.show(); | |
|
491 | this.deleteButton.show(); | |
|
477 | 492 | this.editFields.hide(); |
|
478 | 493 | this.closeButton.hide(); |
|
479 | 494 | this.viewFields.show(); |
@@ -504,7 +519,7 b'' | |||
|
504 | 519 | this.closeButton.hide(); |
|
505 | 520 | this.addButton.hide(); |
|
506 | 521 | this.removeButtons.css('visibility', 'hidden'); |
|
507 | } | |
|
522 | }, | |
|
508 | 523 | }; |
|
509 | 524 | |
|
510 | 525 | PRDetails.init(); |
@@ -603,12 +618,12 b'' | |||
|
603 | 618 | if(button.hasClass("comments-visible")) { |
|
604 | 619 | $('#{0} .inline-comments'.format(boxid)).each(function(index){ |
|
605 | 620 | $(this).hide(); |
|
606 | }) | |
|
621 | }); | |
|
607 | 622 | button.removeClass("comments-visible"); |
|
608 | 623 | } else { |
|
609 | 624 | $('#{0} .inline-comments'.format(boxid)).each(function(index){ |
|
610 | 625 | $(this).show(); |
|
611 | }) | |
|
626 | }); | |
|
612 | 627 | button.addClass("comments-visible"); |
|
613 | 628 | } |
|
614 | 629 | }); |
@@ -27,7 +27,7 b' from rhodecode.model.pull_request import' | |||
|
27 | 27 | from rhodecode.tests import assert_session_flash |
|
28 | 28 | |
|
29 | 29 | |
|
30 | def test_merge_pull_request_renders_failure_reason(user_regular): | |
|
30 | def test_merge_pull_request_renders_failure_reason(app, user_regular): | |
|
31 | 31 | pull_request = mock.Mock() |
|
32 | 32 | controller = pullrequests.PullrequestsController() |
|
33 | 33 | model_patcher = mock.patch.multiple( |
@@ -30,6 +30,7 b' from rhodecode.model.db import (' | |||
|
30 | 30 | from rhodecode.model.meta import Session |
|
31 | 31 | from rhodecode.model.pull_request import PullRequestModel |
|
32 | 32 | from rhodecode.model.user import UserModel |
|
33 | from rhodecode.model.repo import RepoModel | |
|
33 | 34 | from rhodecode.tests import assert_session_flash, url, TEST_USER_ADMIN_LOGIN |
|
34 | 35 | from rhodecode.tests.utils import AssertResponse |
|
35 | 36 | |
@@ -966,6 +967,68 b' class TestPullrequestsController:' | |||
|
966 | 967 | assertr.no_element_exists('div.pr-mergeinfo') |
|
967 | 968 | |
|
968 | 969 | |
|
970 | @pytest.mark.usefixtures('app') | |
|
971 | @pytest.mark.backends("git", "hg") | |
|
972 | class TestPullrequestsControllerDelete(object): | |
|
973 | def test_pull_request_delete_button_permissions_admin( | |
|
974 | self, autologin_user, user_admin, pr_util): | |
|
975 | pull_request = pr_util.create_pull_request( | |
|
976 | author=user_admin.username, enable_notifications=False) | |
|
977 | ||
|
978 | response = self.app.get(url( | |
|
979 | controller='pullrequests', action='show', | |
|
980 | repo_name=pull_request.target_repo.scm_instance().name, | |
|
981 | pull_request_id=str(pull_request.pull_request_id))) | |
|
982 | ||
|
983 | response.mustcontain('id="delete_pullrequest"') | |
|
984 | response.mustcontain('Confirm to delete this pull request') | |
|
985 | ||
|
986 | def test_pull_request_delete_button_permissions_owner( | |
|
987 | self, autologin_regular_user, user_regular, pr_util): | |
|
988 | pull_request = pr_util.create_pull_request( | |
|
989 | author=user_regular.username, enable_notifications=False) | |
|
990 | ||
|
991 | response = self.app.get(url( | |
|
992 | controller='pullrequests', action='show', | |
|
993 | repo_name=pull_request.target_repo.scm_instance().name, | |
|
994 | pull_request_id=str(pull_request.pull_request_id))) | |
|
995 | ||
|
996 | response.mustcontain('id="delete_pullrequest"') | |
|
997 | response.mustcontain('Confirm to delete this pull request') | |
|
998 | ||
|
999 | def test_pull_request_delete_button_permissions_forbidden( | |
|
1000 | self, autologin_regular_user, user_regular, user_admin, pr_util): | |
|
1001 | pull_request = pr_util.create_pull_request( | |
|
1002 | author=user_admin.username, enable_notifications=False) | |
|
1003 | ||
|
1004 | response = self.app.get(url( | |
|
1005 | controller='pullrequests', action='show', | |
|
1006 | repo_name=pull_request.target_repo.scm_instance().name, | |
|
1007 | pull_request_id=str(pull_request.pull_request_id))) | |
|
1008 | response.mustcontain(no=['id="delete_pullrequest"']) | |
|
1009 | response.mustcontain(no=['Confirm to delete this pull request']) | |
|
1010 | ||
|
1011 | def test_pull_request_delete_button_permissions_can_update_cannot_delete( | |
|
1012 | self, autologin_regular_user, user_regular, user_admin, pr_util, | |
|
1013 | user_util): | |
|
1014 | ||
|
1015 | pull_request = pr_util.create_pull_request( | |
|
1016 | author=user_admin.username, enable_notifications=False) | |
|
1017 | ||
|
1018 | user_util.grant_user_permission_to_repo( | |
|
1019 | pull_request.target_repo, user_regular, | |
|
1020 | 'repository.write') | |
|
1021 | ||
|
1022 | response = self.app.get(url( | |
|
1023 | controller='pullrequests', action='show', | |
|
1024 | repo_name=pull_request.target_repo.scm_instance().name, | |
|
1025 | pull_request_id=str(pull_request.pull_request_id))) | |
|
1026 | ||
|
1027 | response.mustcontain('id="open_edit_pullrequest"') | |
|
1028 | response.mustcontain('id="delete_pullrequest"') | |
|
1029 | response.mustcontain(no=['Confirm to delete this pull request']) | |
|
1030 | ||
|
1031 | ||
|
969 | 1032 | def assert_pull_request_status(pull_request, expected_status): |
|
970 | 1033 | status = ChangesetStatusModel().calculated_review_status( |
|
971 | 1034 | pull_request=pull_request) |
General Comments 0
You need to be logged in to leave comments.
Login now