Changeset - 99f090563f5f
[Not reviewed]
default
0 2 0
Thomas De Schampheleire - 11 years ago 2015-04-20 17:02:42
thomas.de.schampheleire@gmail.com
changeset status: fix common case where a reviewer did not yet review anything

When a reviewer did not yet make any review, its status for the changeset is
None, causing the code to crash. The unit tests also did not cover this case.
2 files changed with 12 insertions and 2 deletions:
0 comments (0 inline, 0 general)
kallithea/model/changeset_status.py
Show inline comments
 
@@ -54,52 +54,52 @@ class ChangesetStatusModel(BaseModel):
 
        q = ChangesetStatus.query()\
 
            .filter(ChangesetStatus.repo == repo)
 
        if not with_revisions:
 
            q = q.filter(ChangesetStatus.version == 0)
 

	
 
        if revision:
 
            q = q.filter(ChangesetStatus.revision == revision)
 
        elif pull_request:
 
            pull_request = self.__get_pull_request(pull_request)
 
            q = q.filter(ChangesetStatus.pull_request == pull_request)
 
        else:
 
            raise Exception('Please specify revision or pull_request')
 
        q = q.order_by(ChangesetStatus.version.asc())
 
        return q
 

	
 
    def _calculate_status(self, statuses):
 
        """
 
        Given a list of statuses, calculate the resulting status, according to
 
        the policy: approve if consensus, reject when at least one reject.
 
        """
 

	
 
        if not statuses:
 
            return ChangesetStatus.STATUS_UNDER_REVIEW
 

	
 
        if all(st.status == ChangesetStatus.STATUS_APPROVED for st in statuses):
 
        if all(st and st.status == ChangesetStatus.STATUS_APPROVED for st in statuses):
 
            return ChangesetStatus.STATUS_APPROVED
 

	
 
        if any(st.status == ChangesetStatus.STATUS_REJECTED for st in statuses):
 
        if any(st and st.status == ChangesetStatus.STATUS_REJECTED for st in statuses):
 
            return ChangesetStatus.STATUS_REJECTED
 

	
 
        return ChangesetStatus.STATUS_UNDER_REVIEW
 

	
 
    def calculate_pull_request_result(self, pull_request):
 
        """
 
        Return a tuple (reviewers, pending reviewers, pull request status)
 
        Only approve and reject counts as valid votes.
 
        """
 

	
 
        # collect latest votes from all voters
 
        cs_statuses = dict()
 
        for st in reversed(self.get_statuses(pull_request.org_repo,
 
                                             pull_request=pull_request,
 
                                             with_revisions=True)):
 
            cs_statuses[st.author.username] = st
 

	
 
        # collect votes from official reviewers
 
        pull_request_reviewers = []
 
        pull_request_pending_reviewers = []
 
        relevant_statuses = []
 
        for r in pull_request.reviewers:
 
            st = cs_statuses.get(r.user.username)
 
            relevant_statuses.append(st)
kallithea/tests/models/test_changeset_status.py
Show inline comments
 
@@ -11,28 +11,38 @@ STATUS_UNDER_REVIEW = ChangesetStatus.ST
 
class ChangesetStatusMock(object):
 

	
 
    def __init__(self, status):
 
        self.status = status
 

	
 
S = ChangesetStatusMock
 

	
 
class TestChangesetStatusCalculation(BaseTestCase):
 

	
 
    def setUp(self):
 
        self.m = ChangesetStatusModel()
 

	
 
    @parameterized.expand([
 
        ('empty list', STATUS_UNDER_REVIEW, []),
 
        ('approve', STATUS_APPROVED, [S(STATUS_APPROVED)]),
 
        ('approve2', STATUS_APPROVED, [S(STATUS_APPROVED), S(STATUS_APPROVED)]),
 
        ('approve_reject', STATUS_REJECTED, [S(STATUS_APPROVED), S(STATUS_REJECTED)]),
 
        ('approve_underreview', STATUS_UNDER_REVIEW, [S(STATUS_APPROVED), S(STATUS_UNDER_REVIEW)]),
 
        ('approve_notreviewed', STATUS_UNDER_REVIEW, [S(STATUS_APPROVED), S(STATUS_NOT_REVIEWED)]),
 
        ('underreview', STATUS_UNDER_REVIEW, [S(STATUS_UNDER_REVIEW), S(STATUS_UNDER_REVIEW)]),
 
        ('reject', STATUS_REJECTED, [S(STATUS_REJECTED)]),
 
        ('reject_underreview', STATUS_REJECTED, [S(STATUS_REJECTED), S(STATUS_UNDER_REVIEW)]),
 
        ('reject_notreviewed', STATUS_REJECTED, [S(STATUS_REJECTED), S(STATUS_NOT_REVIEWED)]),
 
        ('notreviewed', STATUS_UNDER_REVIEW, [S(STATUS_NOT_REVIEWED)]),
 
        ('approve_none', STATUS_UNDER_REVIEW, [S(STATUS_APPROVED), None]),
 
        ('approve2_none', STATUS_UNDER_REVIEW, [S(STATUS_APPROVED), S(STATUS_APPROVED), None]),
 
        ('approve_reject_none', STATUS_REJECTED, [S(STATUS_APPROVED), S(STATUS_REJECTED), None]),
 
        ('approve_underreview_none', STATUS_UNDER_REVIEW, [S(STATUS_APPROVED), S(STATUS_UNDER_REVIEW), None]),
 
        ('approve_notreviewed_none', STATUS_UNDER_REVIEW, [S(STATUS_APPROVED), S(STATUS_NOT_REVIEWED), None]),
 
        ('underreview_none', STATUS_UNDER_REVIEW, [S(STATUS_UNDER_REVIEW), S(STATUS_UNDER_REVIEW), None]),
 
        ('reject_none', STATUS_REJECTED, [S(STATUS_REJECTED), None]),
 
        ('reject_underreview_none', STATUS_REJECTED, [S(STATUS_REJECTED), S(STATUS_UNDER_REVIEW), None]),
 
        ('reject_notreviewed_none', STATUS_REJECTED, [S(STATUS_REJECTED), S(STATUS_NOT_REVIEWED), None]),
 
        ('notreviewed_none', STATUS_UNDER_REVIEW, [S(STATUS_NOT_REVIEWED), None]),
 
    ])
 
    def test_result(self, name, expected_result, statuses):
 
        result = self.m._calculate_status(statuses)
 
        self.assertEqual(result, expected_result)
0 comments (0 inline, 0 general)