Handle GitHub comment reviews carefully

A comment review should not mask a previously provided approval or
changes_requested review from a given user. The GitHub UX follows the
same logic. If an approval or a changes_requested review was already
provided from a user, that user can issue future comment reviews and it
will not change their vote. Our algorithm needed to be updated to handle
this scenario, and a test case was added to validate it.

Change-Id: Iac10544a1f24362c27220a44edbdb988b7caa989
diff --git a/tests/unit/test_github_requirements.py b/tests/unit/test_github_requirements.py
index 135f7ab..34da88f 100644
--- a/tests/unit/test_github_requirements.py
+++ b/tests/unit/test_github_requirements.py
@@ -256,6 +256,37 @@
         self.assertEqual(self.history[0].name, 'project5-reviewuserstate')
 
     @simple_layout('layouts/requirements-github.yaml', driver='github')
+    def test_pipeline_require_review_comment_masked(self):
+        "Test pipeline requirement: review comments on top of votes"
+
+        A = self.fake_github.openFakePullRequest('org/project5', 'master', 'A')
+        # Add derp to writers
+        A.writers.append('derp')
+        # A comment event that we will keep submitting to trigger
+        comment = A.getCommentAddedEvent('test me')
+        self.fake_github.emitEvent(comment)
+        self.waitUntilSettled()
+        # No positive review from derp so should not be enqueued
+        self.assertEqual(len(self.history), 0)
+
+        # The first negative review from derp should not cause it to be
+        # enqueued
+        A.addReview('derp', 'CHANGES_REQUESTED')
+        self.fake_github.emitEvent(comment)
+        self.waitUntilSettled()
+        self.assertEqual(len(self.history), 0)
+
+        # A positive review is required, so provide it
+        A.addReview('derp', 'APPROVED')
+
+        # Add a comment review on top to make sure we can still enqueue
+        A.addReview('derp', 'COMMENTED')
+        self.fake_github.emitEvent(comment)
+        self.waitUntilSettled()
+        self.assertEqual(len(self.history), 1)
+        self.assertEqual(self.history[0].name, 'project5-reviewuserstate')
+
+    @simple_layout('layouts/requirements-github.yaml', driver='github')
     def test_require_review_newer_than(self):
 
         A = self.fake_github.openFakePullRequest('org/project6', 'master', 'A')