Add handling for Commit message and Rebase change messages

When commit message is updated, or the change is rebased the change
log generates a message with 'newPatchSet' tag.
If the change message has the 'newPatchSet' tag but does not match
the pattern of "Uploaded Patchset X", we assume it's refering to the
latest patchset and the View Diff button resolves to latest vs
latest - 1.

Change-Id: I261d8e4d8df31f7624923e430a69488c2c2b52f5
diff --git a/polygerrit-ui/app/elements/change/gr-message/gr-message.ts b/polygerrit-ui/app/elements/change/gr-message/gr-message.ts
index fb20f0c..bc61dad 100644
--- a/polygerrit-ui/app/elements/change/gr-message/gr-message.ts
+++ b/polygerrit-ui/app/elements/change/gr-message/gr-message.ts
@@ -46,6 +46,11 @@
 import {appContext} from '../../../services/app-context';
 import {pluralize} from '../../../utils/string-util';
 import {GerritNav} from '../../core/gr-navigation/gr-navigation';
+import {
+  computeAllPatchSets,
+  computeLatestPatchNum,
+  computePredecessor,
+} from '../../../utils/patch-set-util';
 
 const PATCH_SET_PREFIX_PATTERN = /^(?:Uploaded\s*)?(?:P|p)atch (?:S|s)et \d+:\s*(.*)/;
 const LABEL_TITLE_SCORE_PATTERN = /^(-?)([A-Za-z0-9-]+?)([+-]\d+)?[.]?$/;
@@ -270,13 +275,20 @@
   _handleViewPatchsetDiff(e: Event) {
     if (!this.message || !this.change) return;
     const match = this.message.message.match(/Uploaded patch set (\d+)./);
-    if (!match || match.length < 1) return;
-    const patchNum = Number(match[1]);
-    if (isNaN(patchNum)) throw new Error('invalid patchnum in message');
+    let patchNum: PatchSetNum;
+    // Message is of the form "Commit Message was updated" or "Patchset X
+    // was rebased"
+    if (!match || match.length < 1) {
+      patchNum = computeLatestPatchNum(computeAllPatchSets(this.change))!;
+    } else {
+      if (isNaN(Number(match[1])))
+        throw new Error('invalid patchnum in message');
+      patchNum = Number(match[1]) as PatchSetNum;
+    }
     GerritNav.navigateToChange(
       this.change,
-      patchNum as PatchSetNum,
-      (patchNum === 1 ? 'PARENT' : patchNum - 1) as PatchSetNum
+      patchNum,
+      computePredecessor(patchNum)
     );
     // stop propagation to stop message expansion
     e.stopPropagation();
diff --git a/polygerrit-ui/app/elements/change/gr-message/gr-message_test.js b/polygerrit-ui/app/elements/change/gr-message/gr-message_test.js
index 94507e6..facde01 100644
--- a/polygerrit-ui/app/elements/change/gr-message/gr-message_test.js
+++ b/polygerrit-ui/app/elements/change/gr-message/gr-message_test.js
@@ -18,6 +18,7 @@
 import '../../../test/common-test-setup-karma.js';
 import './gr-message.js';
 import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
+import {createChange, createRevisions} from '../../../test/test-data-generators.js';
 
 const basicFixture = fixtureFromElement('gr-message');
 
@@ -232,7 +233,7 @@
     suite('uploaded patchset X message navigates to X - 1 vs  X', () => {
       let navStub;
       setup(() => {
-        element.change = {changeNum: 12345};
+        element.change = {...createChange(), revisions: createRevisions(4)};
         navStub = sinon.stub(GerritNav, 'navigateToChange');
       });
 
@@ -241,7 +242,7 @@
           message: 'Uploaded patch set 1.',
         };
         element._handleViewPatchsetDiff(new MouseEvent('click'));
-        assert.isTrue(navStub.calledWithExactly({changeNum: 12345}, 1,
+        assert.isTrue(navStub.calledWithExactly(element.change, 1,
             'PARENT'));
       });
 
@@ -250,21 +251,21 @@
           message: 'Uploaded patch set 2.',
         };
         element._handleViewPatchsetDiff(new MouseEvent('click'));
-        assert.isTrue(navStub.calledWithExactly({changeNum: 12345}, 2, 1));
+        assert.isTrue(navStub.calledWithExactly(element.change, 2, 1));
 
         element.message = {
           message: 'Uploaded patch set 200.',
         };
         element._handleViewPatchsetDiff(new MouseEvent('click'));
-        assert.isTrue(navStub.calledWithExactly({changeNum: 12345}, 200, 199));
+        assert.isTrue(navStub.calledWithExactly(element.change, 200, 199));
       });
 
-      test('invalid patchset does not cause navigation', () => {
+      test('Commit message updated', () => {
         element.message = {
-          message: 'Uploaded patch set XYZ.',
+          message: 'Commit message updated.',
         };
         element._handleViewPatchsetDiff(new MouseEvent('click'));
-        assert.isFalse(navStub.called);
+        assert.isTrue(navStub.calledWithExactly(element.change, 4, 3));
       });
     });
 
diff --git a/polygerrit-ui/app/utils/patch-set-util.ts b/polygerrit-ui/app/utils/patch-set-util.ts
index bda4658..cb0bdec 100644
--- a/polygerrit-ui/app/utils/patch-set-util.ts
+++ b/polygerrit-ui/app/utils/patch-set-util.ts
@@ -262,6 +262,20 @@
   return allPatchSets[0].num;
 }
 
+export function computePredecessor(
+  patchset?: PatchSetNum
+): PatchSetNum | undefined {
+  if (
+    !patchset ||
+    patchset === ParentPatchSetNum ||
+    patchset === EditPatchSetNum
+  ) {
+    return undefined;
+  }
+  if (patchset === 1) return ParentPatchSetNum;
+  return (Number(patchset) - 1) as PatchSetNum;
+}
+
 export function hasEditBasedOnCurrentPatchSet(allPatchSets: PatchSet[]) {
   if (!allPatchSets || allPatchSets.length < 2) {
     return false;