##// END OF EJS Templates
observers: code cleanups and fixed tests.
marcink -
r4519:ea50ffa9 stable
parent child
Show More
@@ -320,7 +320,7 class TestCreatePullRequestApi(object):
320 320 id_, params = build_data(
321 321 self.apikey_regular, 'create_pull_request', **data)
322 322 response = api_call(self.app, params)
323 expected_message = 'no commits found'
323 expected_message = 'no commits found for merge between specified references'
324 324 assert_error(id_, expected_message, given=response.body)
325 325
326 326 @pytest.mark.backends("git", "hg")
@@ -29,6 +29,7 from rhodecode.api.tests.utils import (
29 29
30 30 @pytest.mark.usefixtures("testuser_api", "app")
31 31 class TestGetPullRequest(object):
32
32 33 @pytest.mark.backends("git", "hg")
33 34 def test_api_get_pull_requests(self, pr_util):
34 35 pull_request = pr_util.create_pull_request()
@@ -40,6 +41,7 class TestGetPullRequest(object):
40 41 target_ref=pull_request.target_ref,
41 42 revisions=pull_request.revisions,
42 43 reviewers=(),
44 observers=(),
43 45 title=pull_request.title,
44 46 description=pull_request.description,
45 47 )
@@ -51,6 +51,7 class TestUpdatePullRequest(object):
51 51 "pull_request": response.json['result']['pull_request'],
52 52 "updated_commits": {"added": [], "common": [], "removed": []},
53 53 "updated_reviewers": {"added": [], "removed": []},
54 "updated_observers": {"added": [], "removed": []},
54 55 }
55 56
56 57 response_json = response.json['result']
@@ -111,6 +112,7 class TestUpdatePullRequest(object):
111 112 "total": total_commits,
112 113 "removed": []},
113 114 "updated_reviewers": {"added": [], "removed": []},
115 "updated_observers": {"added": [], "removed": []},
114 116 }
115 117
116 118 assert_ok(id_, expected, response.body)
@@ -122,7 +124,7 class TestUpdatePullRequest(object):
122 124 b = user_util.create_user()
123 125 c = user_util.create_user()
124 126 new_reviewers = [
125 {'username': b.username,'reasons': ['updated via API'],
127 {'username': b.username, 'reasons': ['updated via API'],
126 128 'mandatory':False},
127 129 {'username': c.username, 'reasons': ['updated via API'],
128 130 'mandatory':False},
@@ -132,7 +134,7 class TestUpdatePullRequest(object):
132 134 removed = [a.username]
133 135
134 136 pull_request = pr_util.create_pull_request(
135 reviewers=[(a.username, ['added via API'], False, [])])
137 reviewers=[(a.username, ['added via API'], False, 'reviewer', [])])
136 138
137 139 id_, params = build_data(
138 140 self.apikey, 'update_pull_request',
@@ -146,6 +148,7 class TestUpdatePullRequest(object):
146 148 "pull_request": response.json['result']['pull_request'],
147 149 "updated_commits": {"added": [], "common": [], "removed": []},
148 150 "updated_reviewers": {"added": added, "removed": removed},
151 "updated_observers": {"added": [], "removed": []},
149 152 }
150 153
151 154 assert_ok(id_, expected, response.body)
@@ -30,9 +30,11 from rhodecode.lib import channelstream
30 30 from rhodecode.lib.auth import (HasRepoPermissionAnyApi)
31 31 from rhodecode.lib.base import vcs_operation_context
32 32 from rhodecode.lib.utils2 import str2bool
33 from rhodecode.lib.vcs.backends.base import unicode_to_reference
33 34 from rhodecode.model.changeset_status import ChangesetStatusModel
34 35 from rhodecode.model.comment import CommentsModel
35 from rhodecode.model.db import Session, ChangesetStatus, ChangesetComment, PullRequest
36 from rhodecode.model.db import (
37 Session, ChangesetStatus, ChangesetComment, PullRequest, PullRequestReviewers)
36 38 from rhodecode.model.pull_request import PullRequestModel, MergeCheck
37 39 from rhodecode.model.settings import SettingsModel
38 40 from rhodecode.model.validation_schema import Invalid
@@ -600,7 +602,7 def comment_pull_request(
600 602 extra_recipients=extra_recipients,
601 603 send_email=send_email
602 604 )
603 is_inline = bool(comment.f_path and comment.line_no)
605 is_inline = comment.is_inline
604 606
605 607 if allowed_to_change_status and status:
606 608 old_calculated_status = pull_request.calculated_review_status()
@@ -646,12 +648,26 def comment_pull_request(
646 648
647 649 return data
648 650
651 def _reviewers_validation(obj_list):
652 schema = ReviewerListSchema()
653 try:
654 reviewer_objects = schema.deserialize(obj_list)
655 except Invalid as err:
656 raise JSONRPCValidationError(colander_exc=err)
657
658 # validate users
659 for reviewer_object in reviewer_objects:
660 user = get_user_or_error(reviewer_object['username'])
661 reviewer_object['user_id'] = user.user_id
662 return reviewer_objects
663
649 664
650 665 @jsonrpc_method()
651 666 def create_pull_request(
652 667 request, apiuser, source_repo, target_repo, source_ref, target_ref,
653 668 owner=Optional(OAttr('apiuser')), title=Optional(''), description=Optional(''),
654 description_renderer=Optional(''), reviewers=Optional(None)):
669 description_renderer=Optional(''),
670 reviewers=Optional(None), observers=Optional(None)):
655 671 """
656 672 Creates a new pull request.
657 673
@@ -689,6 +705,13 def create_pull_request(
689 705 Accepts username strings or objects of the format:
690 706
691 707 [{'username': 'nick', 'reasons': ['original author'], 'mandatory': <bool>}]
708 :param observers: Set the new pull request observers list.
709 Reviewer defined by review rules will be added automatically to the
710 defined list. This feature is only available in RhodeCode EE
711 :type observers: Optional(list)
712 Accepts username strings or objects of the format:
713
714 [{'username': 'nick', 'reasons': ['original author']}]
692 715 """
693 716
694 717 source_db_repo = get_repo_or_error(source_repo)
@@ -702,38 +725,39 def create_pull_request(
702 725 full_source_ref = resolve_ref_or_error(source_ref, source_db_repo)
703 726 full_target_ref = resolve_ref_or_error(target_ref, target_db_repo)
704 727
705 source_commit = get_commit_or_error(full_source_ref, source_db_repo)
706 target_commit = get_commit_or_error(full_target_ref, target_db_repo)
728 get_commit_or_error(full_source_ref, source_db_repo)
729 get_commit_or_error(full_target_ref, target_db_repo)
707 730
708 731 reviewer_objects = Optional.extract(reviewers) or []
732 observer_objects = Optional.extract(observers) or []
709 733
710 734 # serialize and validate passed in given reviewers
711 735 if reviewer_objects:
712 schema = ReviewerListSchema()
713 try:
714 reviewer_objects = schema.deserialize(reviewer_objects)
715 except Invalid as err:
716 raise JSONRPCValidationError(colander_exc=err)
736 reviewer_objects = _reviewers_validation(reviewer_objects)
717 737
718 # validate users
719 for reviewer_object in reviewer_objects:
720 user = get_user_or_error(reviewer_object['username'])
721 reviewer_object['user_id'] = user.user_id
738 if observer_objects:
739 observer_objects = _reviewers_validation(reviewer_objects)
722 740
723 741 get_default_reviewers_data, validate_default_reviewers, validate_observers = \
724 742 PullRequestModel().get_reviewer_functions()
725 743
744 source_ref_obj = unicode_to_reference(full_source_ref)
745 target_ref_obj = unicode_to_reference(full_target_ref)
746
726 747 # recalculate reviewers logic, to make sure we can validate this
727 748 default_reviewers_data = get_default_reviewers_data(
728 749 owner,
729 source_repo,
730 Reference(source_type, source_name, source_commit_id),
731 target_repo,
732 Reference(target_type, target_name, target_commit_id)
750 source_db_repo,
751 source_ref_obj,
752 target_db_repo,
753 target_ref_obj,
733 754 )
734 755
735 # now MERGE our given with the calculated
736 reviewer_objects = default_reviewers_data['reviewers'] + reviewer_objects
756 # now MERGE our given with the calculated from the default rules
757 just_reviewers = [
758 x for x in default_reviewers_data['reviewers']
759 if x['role'] == PullRequestReviewers.ROLE_REVIEWER]
760 reviewer_objects = just_reviewers + reviewer_objects
737 761
738 762 try:
739 763 reviewers = validate_default_reviewers(
@@ -741,9 +765,21 def create_pull_request(
741 765 except ValueError as e:
742 766 raise JSONRPCError('Reviewers Validation: {}'.format(e))
743 767
768 # now MERGE our given with the calculated from the default rules
769 just_observers = [
770 x for x in default_reviewers_data['reviewers']
771 if x['role'] == PullRequestReviewers.ROLE_OBSERVER]
772 observer_objects = just_observers + observer_objects
773
774 try:
775 observers = validate_observers(
776 observer_objects, default_reviewers_data)
777 except ValueError as e:
778 raise JSONRPCError('Observer Validation: {}'.format(e))
779
744 780 title = Optional.extract(title)
745 781 if not title:
746 title_source_ref = source_ref.split(':', 2)[1]
782 title_source_ref = source_ref_obj.name
747 783 title = PullRequestModel().generate_pullrequest_title(
748 784 source=source_repo,
749 785 source_ref=title_source_ref,
@@ -752,20 +788,17 def create_pull_request(
752 788
753 789 diff_info = default_reviewers_data['diff_info']
754 790 common_ancestor_id = diff_info['ancestor']
755 commits = diff_info['commits']
791 # NOTE(marcink): reversed is consistent with how we open it in the WEB interface
792 commits = [commit['commit_id'] for commit in reversed(diff_info['commits'])]
756 793
757 794 if not common_ancestor_id:
758 raise JSONRPCError('no common ancestor found')
795 raise JSONRPCError('no common ancestor found between specified references')
759 796
760 797 if not commits:
761 raise JSONRPCError('no commits found')
762
763 # NOTE(marcink): reversed is consistent with how we open it in the WEB interface
764 revisions = [commit.raw_id for commit in reversed(commits)]
798 raise JSONRPCError('no commits found for merge between specified references')
765 799
766 800 # recalculate target ref based on ancestor
767 target_ref_type, target_ref_name, __ = full_target_ref.split(':')
768 full_target_ref = ':'.join((target_ref_type, target_ref_name, common_ancestor_id))
801 full_target_ref = ':'.join((target_ref_obj.type, target_ref_obj.name, common_ancestor_id))
769 802
770 803 # fetch renderer, if set fallback to plain in case of PR
771 804 rc_config = SettingsModel().get_all_settings()
@@ -780,8 +813,9 def create_pull_request(
780 813 target_repo=target_repo,
781 814 target_ref=full_target_ref,
782 815 common_ancestor_id=common_ancestor_id,
783 revisions=revisions,
816 revisions=commits,
784 817 reviewers=reviewers,
818 observers=observers,
785 819 title=title,
786 820 description=description,
787 821 description_renderer=description_renderer,
@@ -801,7 +835,7 def create_pull_request(
801 835 def update_pull_request(
802 836 request, apiuser, pullrequestid, repoid=Optional(None),
803 837 title=Optional(''), description=Optional(''), description_renderer=Optional(''),
804 reviewers=Optional(None), update_commits=Optional(None)):
838 reviewers=Optional(None), observers=Optional(None), update_commits=Optional(None)):
805 839 """
806 840 Updates a pull request.
807 841
@@ -823,7 +857,11 def update_pull_request(
823 857 Accepts username strings or objects of the format:
824 858
825 859 [{'username': 'nick', 'reasons': ['original author'], 'mandatory': <bool>}]
860 :param observers: Update pull request observers list with new value.
861 :type observers: Optional(list)
862 Accepts username strings or objects of the format:
826 863
864 [{'username': 'nick', 'reasons': ['should be aware about this PR']}]
827 865 :param update_commits: Trigger update of commits for this pull request
828 866 :type: update_commits: Optional(bool)
829 867
@@ -841,6 +879,12 def update_pull_request(
841 879 ],
842 880 "removed": []
843 881 },
882 "updated_observers": {
883 "added": [
884 "username"
885 ],
886 "removed": []
887 },
844 888 "updated_commits": {
845 889 "added": [
846 890 "<sha1_hash>"
@@ -872,30 +916,7 def update_pull_request(
872 916 pullrequestid,))
873 917
874 918 reviewer_objects = Optional.extract(reviewers) or []
875
876 if reviewer_objects:
877 schema = ReviewerListSchema()
878 try:
879 reviewer_objects = schema.deserialize(reviewer_objects)
880 except Invalid as err:
881 raise JSONRPCValidationError(colander_exc=err)
882
883 # validate users
884 for reviewer_object in reviewer_objects:
885 user = get_user_or_error(reviewer_object['username'])
886 reviewer_object['user_id'] = user.user_id
887
888 get_default_reviewers_data, get_validated_reviewers, validate_observers = \
889 PullRequestModel().get_reviewer_functions()
890
891 # re-use stored rules
892 reviewer_rules = pull_request.reviewer_data
893 try:
894 reviewers = get_validated_reviewers(reviewer_objects, reviewer_rules)
895 except ValueError as e:
896 raise JSONRPCError('Reviewers Validation: {}'.format(e))
897 else:
898 reviewers = []
919 observer_objects = Optional.extract(observers) or []
899 920
900 921 title = Optional.extract(title)
901 922 description = Optional.extract(description)
@@ -935,12 +956,41 def update_pull_request(
935 956 commits_changed = True
936 957
937 958 # Update reviewers
959 # serialize and validate passed in given reviewers
960 if reviewer_objects:
961 reviewer_objects = _reviewers_validation(reviewer_objects)
962
963 if observer_objects:
964 observer_objects = _reviewers_validation(reviewer_objects)
965
966 # re-use stored rules
967 default_reviewers_data = pull_request.reviewer_data
968
969 __, validate_default_reviewers, validate_observers = \
970 PullRequestModel().get_reviewer_functions()
971
972 if reviewer_objects:
973 try:
974 reviewers = validate_default_reviewers(reviewer_objects, default_reviewers_data)
975 except ValueError as e:
976 raise JSONRPCError('Reviewers Validation: {}'.format(e))
977 else:
978 reviewers = []
979
980 if observer_objects:
981 try:
982 observers = validate_default_reviewers(reviewer_objects, default_reviewers_data)
983 except ValueError as e:
984 raise JSONRPCError('Observer Validation: {}'.format(e))
985 else:
986 observers = []
987
938 988 reviewers_changed = False
939 989 reviewers_changes = {"added": [], "removed": []}
940 990 if reviewers:
941 991 old_calculated_status = pull_request.calculated_review_status()
942 992 added_reviewers, removed_reviewers = \
943 PullRequestModel().update_reviewers(pull_request, reviewers, apiuser)
993 PullRequestModel().update_reviewers(pull_request, reviewers, apiuser.get_instance())
944 994
945 995 reviewers_changes['added'] = sorted(
946 996 [get_user_or_error(n).username for n in added_reviewers])
@@ -957,6 +1007,18 def update_pull_request(
957 1007 reviewers_changed = True
958 1008
959 1009 observers_changed = False
1010 observers_changes = {"added": [], "removed": []}
1011 if observers:
1012 added_observers, removed_observers = \
1013 PullRequestModel().update_observers(pull_request, observers, apiuser.get_instance())
1014
1015 observers_changes['added'] = sorted(
1016 [get_user_or_error(n).username for n in added_observers])
1017 observers_changes['removed'] = sorted(
1018 [get_user_or_error(n).username for n in removed_observers])
1019 Session().commit()
1020
1021 reviewers_changed = True
960 1022
961 1023 # push changed to channelstream
962 1024 if commits_changed or reviewers_changed or observers_changed:
@@ -966,11 +1028,11 def update_pull_request(
966 1028 request, pr_broadcast_channel, apiuser, msg)
967 1029
968 1030 data = {
969 'msg': 'Updated pull request `{}`'.format(
970 pull_request.pull_request_id),
1031 'msg': 'Updated pull request `{}`'.format(pull_request.pull_request_id),
971 1032 'pull_request': pull_request.get_api_data(),
972 1033 'updated_commits': commit_changes,
973 'updated_reviewers': reviewers_changes
1034 'updated_reviewers': reviewers_changes,
1035 'updated_observers': observers_changes,
974 1036 }
975 1037
976 1038 return data
@@ -1653,7 +1653,7 def comment_commit(
1653 1653 extra_recipients=extra_recipients,
1654 1654 send_email=send_email
1655 1655 )
1656 is_inline = bool(comment.f_path and comment.line_no)
1656 is_inline = comment.is_inline
1657 1657
1658 1658 if status:
1659 1659 # also do a status change
@@ -523,7 +523,9 class TestPullrequestsView(object):
523 523 pull_request = pr_util.create_pull_request()
524 524 pull_request_id = pull_request.pull_request_id
525 525 PullRequestModel().update_reviewers(
526 pull_request_id, [(1, ['reason'], False, []), (2, ['reason2'], False, [])],
526 pull_request_id, [
527 (1, ['reason'], False, 'reviewer', []),
528 (2, ['reason2'], False, 'reviewer', [])],
527 529 pull_request.author)
528 530 author = pull_request.user_id
529 531 repo = pull_request.target_repo.repo_id
@@ -906,12 +908,13 class TestPullrequestsView(object):
906 908
907 909 # Change reviewers and check that a notification was made
908 910 PullRequestModel().update_reviewers(
909 pull_request.pull_request_id, [(1, [], False, [])],
911 pull_request.pull_request_id, [
912 (1, [], False, 'reviewer', [])
913 ],
910 914 pull_request.author)
911 915 assert len(notifications.all()) == 2
912 916
913 def test_create_pull_request_stores_ancestor_commit_id(self, backend,
914 csrf_token):
917 def test_create_pull_request_stores_ancestor_commit_id(self, backend, csrf_token):
915 918 commits = [
916 919 {'message': 'ancestor',
917 920 'added': [FileNode('file_A', content='content_of_ancestor')]},
@@ -413,7 +413,7 class RepoCommitsView(RepoAppView):
413 413 resolves_comment_id=resolves_comment_id,
414 414 auth_user=self._rhodecode_user
415 415 )
416 is_inline = bool(comment.f_path and comment.line_no)
416 is_inline = comment.is_inline
417 417
418 418 # get status if set !
419 419 if status:
@@ -40,7 +40,8 from rhodecode.lib.auth import (
40 40 LoginRequired, HasRepoPermissionAny, HasRepoPermissionAnyDecorator,
41 41 NotAnonymous, CSRFRequired)
42 42 from rhodecode.lib.utils2 import str2bool, safe_str, safe_unicode, safe_int, aslist
43 from rhodecode.lib.vcs.backends.base import EmptyCommit, UpdateFailureReason, Reference
43 from rhodecode.lib.vcs.backends.base import (
44 EmptyCommit, UpdateFailureReason, unicode_to_reference)
44 45 from rhodecode.lib.vcs.exceptions import (
45 46 CommitDoesNotExistError, RepositoryRequirementError, EmptyRepositoryError)
46 47 from rhodecode.model.changeset_status import ChangesetStatusModel
@@ -1146,16 +1147,17 class RepoPullRequestsView(RepoAppView,
1146 1147 source_scm = source_db_repo.scm_instance()
1147 1148 target_scm = target_db_repo.scm_instance()
1148 1149
1149 source_commit = source_scm.get_commit(source_ref.split(':')[-1])
1150 target_commit = target_scm.get_commit(target_ref.split(':')[-1])
1150 source_ref_obj = unicode_to_reference(source_ref)
1151 target_ref_obj = unicode_to_reference(target_ref)
1152
1153 source_commit = source_scm.get_commit(source_ref_obj.commit_id)
1154 target_commit = target_scm.get_commit(target_ref_obj.commit_id)
1151 1155
1152 1156 ancestor = source_scm.get_common_ancestor(
1153 1157 source_commit.raw_id, target_commit.raw_id, target_scm)
1154 1158
1155 source_ref_type, source_ref_name, source_commit_id = _form['target_ref'].split(':')
1156 target_ref_type, target_ref_name, target_commit_id = _form['source_ref'].split(':')
1157 1159 # recalculate target ref based on ancestor
1158 target_ref = ':'.join((target_ref_type, target_ref_name, ancestor))
1160 target_ref = ':'.join((target_ref_obj.type, target_ref_obj.name, ancestor))
1159 1161
1160 1162 get_default_reviewers_data, validate_default_reviewers, validate_observers = \
1161 1163 PullRequestModel().get_reviewer_functions()
@@ -1164,16 +1166,16 class RepoPullRequestsView(RepoAppView,
1164 1166 reviewer_rules = get_default_reviewers_data(
1165 1167 self._rhodecode_db_user,
1166 1168 source_db_repo,
1167 Reference(source_ref_type, source_ref_name, source_commit_id),
1169 source_ref_obj,
1168 1170 target_db_repo,
1169 Reference(target_ref_type, target_ref_name, target_commit_id),
1171 target_ref_obj,
1170 1172 include_diff_info=False)
1171 1173
1172 1174 reviewers = validate_default_reviewers(_form['review_members'], reviewer_rules)
1173 1175 observers = validate_observers(_form['observer_members'], reviewer_rules)
1174 1176
1175 1177 pullrequest_title = _form['pullrequest_title']
1176 title_source_ref = source_ref.split(':', 2)[1]
1178 title_source_ref = source_ref_obj.name
1177 1179 if not pullrequest_title:
1178 1180 pullrequest_title = PullRequestModel().generate_pullrequest_title(
1179 1181 source=source_repo,
@@ -1371,7 +1373,7 class RepoPullRequestsView(RepoAppView,
1371 1373
1372 1374 old_calculated_status = pull_request.calculated_review_status()
1373 1375 PullRequestModel().update_reviewers(
1374 pull_request, reviewers, self._rhodecode_user)
1376 pull_request, reviewers, self._rhodecode_db_user)
1375 1377
1376 1378 Session().commit()
1377 1379
@@ -1396,7 +1398,7 class RepoPullRequestsView(RepoAppView,
1396 1398 return
1397 1399
1398 1400 PullRequestModel().update_observers(
1399 pull_request, observers, self._rhodecode_user)
1401 pull_request, observers, self._rhodecode_db_user)
1400 1402
1401 1403 Session().commit()
1402 1404 msg = _('Pull request observers updated.')
@@ -1563,6 +1565,7 class RepoPullRequestsView(RepoAppView,
1563 1565 pull_request, self._rhodecode_user, self.db_repo, message=text,
1564 1566 auth_user=self._rhodecode_user)
1565 1567 Session().flush()
1568 is_inline = comment.is_inline
1566 1569
1567 1570 PullRequestModel().trigger_pull_request_hook(
1568 1571 pull_request, self._rhodecode_user, 'comment',
@@ -1596,7 +1599,7 class RepoPullRequestsView(RepoAppView,
1596 1599 resolves_comment_id=resolves_comment_id,
1597 1600 auth_user=self._rhodecode_user
1598 1601 )
1599 is_inline = bool(comment.f_path and comment.line_no)
1602 is_inline = comment.is_inline
1600 1603
1601 1604 if allowed_to_change_status:
1602 1605 # calculate old status before we change it
@@ -73,6 +73,29 class Reference(_Reference):
73 73 return self.name
74 74
75 75
76 def unicode_to_reference(raw):
77 """
78 Convert a unicode (or string) to a reference object.
79 If unicode evaluates to False it returns None.
80 """
81 if raw:
82 refs = raw.split(':')
83 return Reference(*refs)
84 else:
85 return None
86
87
88 def reference_to_unicode(ref):
89 """
90 Convert a reference object to unicode.
91 If reference is None it returns None.
92 """
93 if ref:
94 return u':'.join(ref)
95 else:
96 return None
97
98
76 99 class MergeFailureReason(object):
77 100 """
78 101 Enumeration with all the reasons why the server side merge could fail.
@@ -56,7 +56,8 from webhelpers2.text import remove_form
56 56
57 57 from rhodecode.translation import _
58 58 from rhodecode.lib.vcs import get_vcs_instance, VCSError
59 from rhodecode.lib.vcs.backends.base import EmptyCommit, Reference
59 from rhodecode.lib.vcs.backends.base import (
60 EmptyCommit, Reference, unicode_to_reference, reference_to_unicode)
60 61 from rhodecode.lib.utils2 import (
61 62 str2bool, safe_str, get_commit_safe, safe_unicode, sha1_safe,
62 63 time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict,
@@ -4248,26 +4249,11 class _PullRequestBase(BaseModel):
4248 4249
4249 4250 @staticmethod
4250 4251 def unicode_to_reference(raw):
4251 """
4252 Convert a unicode (or string) to a reference object.
4253 If unicode evaluates to False it returns None.
4254 """
4255 if raw:
4256 refs = raw.split(':')
4257 return Reference(*refs)
4258 else:
4259 return None
4252 return unicode_to_reference(raw)
4260 4253
4261 4254 @staticmethod
4262 4255 def reference_to_unicode(ref):
4263 """
4264 Convert a reference object to unicode.
4265 If reference is None it returns None.
4266 """
4267 if ref:
4268 return u':'.join(ref)
4269 else:
4270 return None
4256 return reference_to_unicode(ref)
4271 4257
4272 4258 def get_api_data(self, with_merge_state=True):
4273 4259 from rhodecode.model.pull_request import PullRequestModel
@@ -4543,6 +4529,9 class PullRequestVersion(Base, _PullRequ
4543 4529 @property
4544 4530 def reviewers(self):
4545 4531 return self.pull_request.reviewers
4532 @property
4533 def reviewers(self):
4534 return self.pull_request.reviewers
4546 4535
4547 4536 @property
4548 4537 def versions(self):
@@ -4561,7 +4550,7 class PullRequestVersion(Base, _PullRequ
4561 4550 def reviewers_statuses(self):
4562 4551 return self.pull_request.reviewers_statuses()
4563 4552
4564 def observer(self):
4553 def observers(self):
4565 4554 return self.pull_request.observers()
4566 4555
4567 4556
@@ -1342,7 +1342,7 class PullRequestModel(BaseModel):
1342 1342 'repo.pull_request.reviewer.delete', {'old_data': user_data},
1343 1343 user, pull_request)
1344 1344
1345 self.notify_reviewers(pull_request, ids_to_add, user.get_instance())
1345 self.notify_reviewers(pull_request, ids_to_add, user)
1346 1346 return ids_to_add, ids_to_remove
1347 1347
1348 1348 def update_observers(self, pull_request, observer_data, user):
@@ -1425,7 +1425,7 class PullRequestModel(BaseModel):
1425 1425 'repo.pull_request.observer.delete', {'old_data': user_data},
1426 1426 user, pull_request)
1427 1427
1428 self.notify_observers(pull_request, ids_to_add, user.get_instance())
1428 self.notify_observers(pull_request, ids_to_add, user)
1429 1429 return ids_to_add, ids_to_remove
1430 1430
1431 1431 def get_url(self, pull_request, request=None, permalink=False):
@@ -21,12 +21,17
21 21 import colander
22 22 from rhodecode.model.validation_schema import validators, preparers, types
23 23
24 DEFAULT_ROLE = 'reviewer'
25 VALID_ROLES = ['reviewer', 'observer']
26
24 27
25 28 class ReviewerSchema(colander.MappingSchema):
26 29 username = colander.SchemaNode(types.StrOrIntType())
27 30 reasons = colander.SchemaNode(colander.List(), missing=['no reason specified'])
28 31 mandatory = colander.SchemaNode(colander.Boolean(), missing=False)
29 32 rules = colander.SchemaNode(colander.List(), missing=[])
33 role = colander.SchemaNode(colander.String(), missing=DEFAULT_ROLE,
34 validator=colander.OneOf(VALID_ROLES))
30 35
31 36
32 37 class ReviewerListSchema(colander.SequenceSchema):
@@ -97,6 +97,7
97 97 <li>The server is being restarted.</li>
98 98 <li>The server is overloaded.</li>
99 99 <li>The link may be incorrect.</li>
100 <li><a onclick="window.location.reload()">Reload page</a></li>
100 101 </ul>
101 102 </div>
102 103 <div class="inner-column">
@@ -122,7 +122,7 class TestPullRequestModel(object):
122 122
123 123 def test_get_awaiting_my_review(self, pull_request):
124 124 PullRequestModel().update_reviewers(
125 pull_request, [(pull_request.author, ['author'], False, [])],
125 pull_request, [(pull_request.author, ['author'], False, 'reviewer', [])],
126 126 pull_request.author)
127 127 Session().commit()
128 128
@@ -133,7 +133,7 class TestPullRequestModel(object):
133 133
134 134 def test_count_awaiting_my_review(self, pull_request):
135 135 PullRequestModel().update_reviewers(
136 pull_request, [(pull_request.author, ['author'], False, [])],
136 pull_request, [(pull_request.author, ['author'], False, 'reviewer', [])],
137 137 pull_request.author)
138 138 Session().commit()
139 139
@@ -43,8 +43,8 from rhodecode.lib.utils2 import Attribu
43 43 from rhodecode.model.changeset_status import ChangesetStatusModel
44 44 from rhodecode.model.comment import CommentsModel
45 45 from rhodecode.model.db import (
46 PullRequest, Repository, RhodeCodeSetting, ChangesetStatus, RepoGroup,
47 UserGroup, RepoRhodeCodeUi, RepoRhodeCodeSetting, RhodeCodeUi)
46 PullRequest, PullRequestReviewers, Repository, RhodeCodeSetting, ChangesetStatus,
47 RepoGroup, UserGroup, RepoRhodeCodeUi, RepoRhodeCodeSetting, RhodeCodeUi)
48 48 from rhodecode.model.meta import Session
49 49 from rhodecode.model.pull_request import PullRequestModel
50 50 from rhodecode.model.repo import RepoModel
@@ -968,7 +968,7 class PRTestUtility(object):
968 968 def create_pull_request(
969 969 self, commits=None, target_head=None, source_head=None,
970 970 revisions=None, approved=False, author=None, mergeable=False,
971 enable_notifications=True, name_suffix=u'', reviewers=None,
971 enable_notifications=True, name_suffix=u'', reviewers=None, observers=None,
972 972 title=u"Test", description=u"Description"):
973 973 self.set_mergeable(mergeable)
974 974 if not enable_notifications:
@@ -1005,6 +1005,7 class PRTestUtility(object):
1005 1005 'target_ref': self._default_branch_reference(target_head),
1006 1006 'revisions': [self.commit_ids[r] for r in revisions],
1007 1007 'reviewers': reviewers or self._get_reviewers(),
1008 'observers': observers or self._get_observers(),
1008 1009 'title': title,
1009 1010 'description': description,
1010 1011 }
@@ -1037,9 +1038,15 class PRTestUtility(object):
1037 1038 return reference
1038 1039
1039 1040 def _get_reviewers(self):
1041 role = PullRequestReviewers.ROLE_REVIEWER
1040 1042 return [
1041 (TEST_USER_REGULAR_LOGIN, ['default1'], False, []),
1042 (TEST_USER_REGULAR2_LOGIN, ['default2'], False, []),
1043 (TEST_USER_REGULAR_LOGIN, ['default1'], False, role, []),
1044 (TEST_USER_REGULAR2_LOGIN, ['default2'], False, role, []),
1045 ]
1046
1047 def _get_observers(self):
1048 return [
1049
1043 1050 ]
1044 1051
1045 1052 def update_source_repository(self, head=None):
General Comments 0
You need to be logged in to leave comments. Login now