Merge "Set version to 3.3.5" into stable-3.3
diff --git a/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header.ts b/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header.ts
index b86dd90..f4aa768 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header.ts
+++ b/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header.ts
@@ -43,6 +43,8 @@
 import {
   AccountInfo,
   ChangeInfo,
+  EditPatchSetNum,
+  ParentPatchSetNum,
   PatchSetNum,
   CommitInfo,
   ServerInfo,
@@ -336,6 +338,10 @@
     ) {
       return;
     }
+    if (patchNum === EditPatchSetNum && basePatchNum === ParentPatchSetNum) {
+      GerritNav.navigateToChange(this.change, undefined, undefined, true);
+      return;
+    }
     GerritNav.navigateToChange(this.change, patchNum, basePatchNum);
   }
 
diff --git a/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header_test.js b/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header_test.js
index 3469b3a..c053d1f 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header_test.js
+++ b/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header_test.js
@@ -21,6 +21,7 @@
 import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
 import 'lodash/lodash.js';
 import {createRevisions} from '../../../test/test-data-generators.js';
+import {EditPatchSetNum, ParentPatchSetNum} from '../../../types/common.js';
 
 const basicFixture = fixtureFromElement('gr-file-list-header');
 
@@ -247,6 +248,34 @@
         .calledWithExactly(element.change, 3, 1));
   });
 
+  test('navigateToChange called when range select changes with edit', () => {
+    const navigateToChangeStub = sinon.stub(GerritNav, 'navigateToChange');
+    element.change = {
+      change_id: 'Iad9dc96274af6946f3632be53b106ef80f7ba6ca',
+      revisions: {
+        rev2: {_number: 2},
+        rev1: {_number: 1},
+        rev13: {_number: 13},
+        rev3: {_number: 3},
+      },
+      status: 'NEW',
+      labels: {},
+    };
+    element.basePatchNum = 1;
+    element.patchNum = EditPatchSetNum;
+
+    const detail = {
+      detail: {
+        basePatchNum: ParentPatchSetNum,
+        patchNum: EditPatchSetNum,
+      },
+    };
+    element._handlePatchChange(detail);
+    assert.equal(navigateToChangeStub.callCount, 1);
+    assert.isTrue(navigateToChangeStub.lastCall
+        .calledWithExactly(element.change, undefined, undefined, true));
+  });
+
   test('class is applied to file list on old patch set', () => {
     const allPatchSets = [{num: 4}, {num: 2}, {num: 1}];
     assert.equal(element._computePatchInfoClass('1', allPatchSets),
diff --git a/polygerrit-ui/app/elements/core/gr-router/gr-router.ts b/polygerrit-ui/app/elements/core/gr-router/gr-router.ts
index 21bf900..eb7f41e 100644
--- a/polygerrit-ui/app/elements/core/gr-router/gr-router.ts
+++ b/polygerrit-ui/app/elements/core/gr-router/gr-router.ts
@@ -56,6 +56,7 @@
 import {assertNever} from '../../../utils/common-util';
 import {
   DashboardId,
+  EditPatchSetNum,
   GroupId,
   NumericChangeId,
   PatchSetNum,
@@ -1548,6 +1549,15 @@
       queryMap: ctx.queryMap,
     };
 
+    // We do not want to allow "edit" to be used as a
+    // patch number. Instead redirect to ,edit.
+    if (ctx.params[4] === EditPatchSetNum && !ctx.params[6]) {
+      params.basePatchNum = undefined;
+      params.edit = true;
+      this._redirect(this._generateUrl(params));
+      return;
+    }
+
     this.reporting.setRepoName(params.project);
     this._redirectOrNavigate(params);
   }
diff --git a/polygerrit-ui/app/elements/core/gr-router/gr-router_test.js b/polygerrit-ui/app/elements/core/gr-router/gr-router_test.js
index 927434b..bb6d729 100644
--- a/polygerrit-ui/app/elements/core/gr-router/gr-router_test.js
+++ b/polygerrit-ui/app/elements/core/gr-router/gr-router_test.js
@@ -21,6 +21,7 @@
 import {GerritNav} from '../gr-navigation/gr-navigation.js';
 import {stubBaseUrl} from '../../../test/test-utils.js';
 import {_testOnly_RoutePattern} from './gr-router.js';
+import {EditPatchSetNum} from '../../../types/common.js';
 
 const basicFixture = fixtureFromElement('gr-router');
 
@@ -1426,16 +1427,16 @@
       suite('_handleChangeRoute', () => {
         let normalizeRangeStub;
 
-        function makeParams(path, hash) {
+        function makeParams(path, hash, baseNum, patchNum) {
           return {
             params: [
               'foo/bar', // 0 Project
               1234, // 1 Change number
               null, // 2 Unused
               null, // 3 Unused
-              4, // 4 Base patch number
+              baseNum ? baseNum : 4, // 4 Base patch number
               null, // 5 Unused
-              7, // 6 Patch number
+              patchNum ? patchNum : 7, // 6 Patch number
             ],
             queryMap: new Map(),
           };
@@ -1473,6 +1474,23 @@
           assert.isFalse(redirectStub.called);
           assert.isTrue(normalizeRangeStub.called);
         });
+
+        test('redirect due to patchNum being an edit', () => {
+          normalizeRangeStub.returns(true);
+          const ctx = makeParams(null, '');
+          element._handleChangeRoute(ctx, undefined, EditPatchSetNum, false);
+          assert.isTrue(normalizeRangeStub.called);
+          assert.isFalse(setParamsStub.called);
+          assert.isTrue(redirectStub.calledOnce);
+
+          const params = {
+            view: GerritNav.View.CHANGE,
+            changeNum: '1234',
+            project: 'test',
+            edit: true,
+          };
+          assert.equal(element._generateUrl(params), '/c/test/+/1234,edit');
+        });
       });
 
       suite('_handleDiffRoute', () => {