Enable arrow-body-style with as-needed
				
					
				
			requireReturnForObjectLiteral for readability Change-Id: I433937b44757939a31ca92512f0aaf0884f86d27
This commit is contained in:
		@@ -23,6 +23,7 @@
 | 
			
		||||
  "rules": {
 | 
			
		||||
    "no-confusing-arrow": "error",
 | 
			
		||||
    "newline-per-chained-call": ["error", { "ignoreChainWithDepth": 2 }],
 | 
			
		||||
    "arrow-body-style": ["error", "as-needed", { "requireReturnForObjectLiteral": true }],
 | 
			
		||||
    "arrow-parens": ["error", "as-needed"],
 | 
			
		||||
    "block-spacing": ["error", "always"],
 | 
			
		||||
    "brace-style": ["error", "1tbs", { "allowSingleLine": true }],
 | 
			
		||||
 
 | 
			
		||||
@@ -146,10 +146,10 @@ limitations under the License.
 | 
			
		||||
              value: obj[key],
 | 
			
		||||
            };
 | 
			
		||||
          })
 | 
			
		||||
          .sort((a, b) => {
 | 
			
		||||
          .sort((a, b) =>
 | 
			
		||||
            // Since IDs are strings, use localeCompare.
 | 
			
		||||
            return a.id.localeCompare(b.id);
 | 
			
		||||
          });
 | 
			
		||||
            a.id.localeCompare(b.id)
 | 
			
		||||
          );
 | 
			
		||||
    },
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -64,12 +64,11 @@ limitations under the License.
 | 
			
		||||
            getAdminMenuLinks, opt_options));
 | 
			
		||||
      }
 | 
			
		||||
      return getAccountCapabilities()
 | 
			
		||||
          .then(capabilities => {
 | 
			
		||||
            return this._filterLinks(link => {
 | 
			
		||||
              return !link.capability ||
 | 
			
		||||
                  capabilities.hasOwnProperty(link.capability);
 | 
			
		||||
            }, getAdminMenuLinks, opt_options);
 | 
			
		||||
          });
 | 
			
		||||
          .then(capabilities => this._filterLinks(
 | 
			
		||||
              link => !link.capability
 | 
			
		||||
              || capabilities.hasOwnProperty(link.capability),
 | 
			
		||||
              getAdminMenuLinks,
 | 
			
		||||
              opt_options));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -92,15 +91,17 @@ limitations under the License.
 | 
			
		||||
      const isExernalLink = link => link.url[0] !== '/';
 | 
			
		||||
 | 
			
		||||
      // Append top-level links that are defined by plugins.
 | 
			
		||||
      links.push(...getAdminMenuLinks().map(link => ({
 | 
			
		||||
        url: link.url,
 | 
			
		||||
        name: link.text,
 | 
			
		||||
        capability: link.capability || null,
 | 
			
		||||
        noBaseUrl: !isExernalLink(link),
 | 
			
		||||
        view: null,
 | 
			
		||||
        viewableToAll: !link.capability,
 | 
			
		||||
        target: isExernalLink(link) ? '_blank' : null,
 | 
			
		||||
      })));
 | 
			
		||||
      links.push(...getAdminMenuLinks().map(link => {
 | 
			
		||||
        return {
 | 
			
		||||
          url: link.url,
 | 
			
		||||
          name: link.text,
 | 
			
		||||
          capability: link.capability || null,
 | 
			
		||||
          noBaseUrl: !isExernalLink(link),
 | 
			
		||||
          view: null,
 | 
			
		||||
          viewableToAll: !link.capability,
 | 
			
		||||
          target: isExernalLink(link) ? '_blank' : null,
 | 
			
		||||
        };
 | 
			
		||||
      }));
 | 
			
		||||
 | 
			
		||||
      links = links.filter(filterFn);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -95,9 +95,8 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
            if (expected.pluginGeneratedLinks) {
 | 
			
		||||
              for (const link of expected.pluginGeneratedLinks) {
 | 
			
		||||
                const linkMatch = res.links.find(l => {
 | 
			
		||||
                  return (l.url === link.url && l.name === link.text);
 | 
			
		||||
                });
 | 
			
		||||
                const linkMatch = res.links
 | 
			
		||||
                    .find(l => (l.url === link.url && l.name === link.text));
 | 
			
		||||
                assert.isTrue(!!linkMatch);
 | 
			
		||||
 | 
			
		||||
                // External links should open in new tab.
 | 
			
		||||
@@ -325,7 +324,9 @@ limitations under the License.
 | 
			
		||||
        let options;
 | 
			
		||||
        const generatedLinks = [
 | 
			
		||||
          {text: 'without capability', url: '/without'},
 | 
			
		||||
          {text: 'with capability', url: '/with', capability: 'pluginCapability'},
 | 
			
		||||
          {text: 'with capability',
 | 
			
		||||
            url: '/with',
 | 
			
		||||
            capability: 'pluginCapability'},
 | 
			
		||||
        ];
 | 
			
		||||
        menuLinkStub.returns(generatedLinks);
 | 
			
		||||
        expected = Object.assign(expected, {
 | 
			
		||||
 
 | 
			
		||||
@@ -46,9 +46,7 @@ limitations under the License.
 | 
			
		||||
     * @return {!Array}
 | 
			
		||||
     */
 | 
			
		||||
    getComplementColumns(columns) {
 | 
			
		||||
      return this.columnNames.filter(column => {
 | 
			
		||||
        return !columns.includes(column);
 | 
			
		||||
      });
 | 
			
		||||
      return this.columnNames.filter(column => !columns.includes(column));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -150,9 +150,8 @@ limitations under the License.
 | 
			
		||||
      if (!change) { return []; }
 | 
			
		||||
      let patchNums = [];
 | 
			
		||||
      if (change.revisions && Object.keys(change.revisions).length) {
 | 
			
		||||
        const revisions = Object.keys(change.revisions).map(sha => {
 | 
			
		||||
          return Object.assign({sha}, change.revisions[sha]);
 | 
			
		||||
        });
 | 
			
		||||
        const revisions = Object.keys(change.revisions)
 | 
			
		||||
            .map(sha => Object.assign({sha}, change.revisions[sha]));
 | 
			
		||||
        patchNums =
 | 
			
		||||
          Gerrit.PatchSetBehavior.sortRevisions(revisions)
 | 
			
		||||
              .map(e => {
 | 
			
		||||
 
 | 
			
		||||
@@ -170,9 +170,7 @@ limitations under the License.
 | 
			
		||||
          messages: [],
 | 
			
		||||
          work_in_progress: initialWip,
 | 
			
		||||
        };
 | 
			
		||||
        const revs = Object.keys(tagsByRevision).sort((a, b) => {
 | 
			
		||||
          return a - b;
 | 
			
		||||
        });
 | 
			
		||||
        const revs = Object.keys(tagsByRevision).sort((a, b) => a - b);
 | 
			
		||||
        for (const rev of revs) {
 | 
			
		||||
          for (const tag of tagsByRevision[rev]) {
 | 
			
		||||
            change.messages.push({
 | 
			
		||||
@@ -190,9 +188,7 @@ limitations under the License.
 | 
			
		||||
        }
 | 
			
		||||
        const verifier = {
 | 
			
		||||
          assertWip(revision, expectedWip) {
 | 
			
		||||
            const patchNum = patchNums.find(patchNum => {
 | 
			
		||||
              return patchNum.num == revision;
 | 
			
		||||
            });
 | 
			
		||||
            const patchNum = patchNums.find(patchNum => patchNum.num == revision);
 | 
			
		||||
            if (!patchNum) {
 | 
			
		||||
              assert.fail('revision ' + revision + ' not found');
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -146,9 +146,8 @@
 | 
			
		||||
        allPermissions = labelOptions.concat(
 | 
			
		||||
            this.toSortedArray(this.permissionValues));
 | 
			
		||||
      }
 | 
			
		||||
      return allPermissions.filter(permission => {
 | 
			
		||||
        return !this.section.value.permissions[permission.id];
 | 
			
		||||
      });
 | 
			
		||||
      return allPermissions
 | 
			
		||||
          .filter(permission => !this.section.value.permissions[permission.id]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _computeHideEditClass(section) {
 | 
			
		||||
@@ -248,7 +247,8 @@
 | 
			
		||||
 | 
			
		||||
    _computeSectionClass(editing, canUpload, ownerOf, editingRef, deleted) {
 | 
			
		||||
      const classList = [];
 | 
			
		||||
      if (editing && this._isEditEnabled(canUpload, ownerOf, this.section.id)) {
 | 
			
		||||
      if (editing
 | 
			
		||||
         && this._isEditEnabled(canUpload, ownerOf, this.section.id)) {
 | 
			
		||||
        classList.push('editing');
 | 
			
		||||
      }
 | 
			
		||||
      if (editingRef) {
 | 
			
		||||
 
 | 
			
		||||
@@ -127,9 +127,10 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
    suite('filter', () => {
 | 
			
		||||
      test('_paramsChanged', done => {
 | 
			
		||||
        sandbox.stub(element.$.restAPI, 'getGroups', () => {
 | 
			
		||||
          return Promise.resolve(groups);
 | 
			
		||||
        });
 | 
			
		||||
        sandbox.stub(
 | 
			
		||||
            element.$.restAPI,
 | 
			
		||||
            'getGroups',
 | 
			
		||||
            () => Promise.resolve(groups));
 | 
			
		||||
        const value = {
 | 
			
		||||
          filter: 'test',
 | 
			
		||||
          offset: 25,
 | 
			
		||||
 
 | 
			
		||||
@@ -101,13 +101,15 @@ limitations under the License.
 | 
			
		||||
      sandbox.stub(element.$.restAPI, 'getAccount').returns(Promise.resolve({
 | 
			
		||||
        name: 'test-user',
 | 
			
		||||
      }));
 | 
			
		||||
      sandbox.stub(element.$.restAPI, 'getAccountCapabilities', () => {
 | 
			
		||||
        return Promise.resolve({
 | 
			
		||||
          createGroup: true,
 | 
			
		||||
          createProject: true,
 | 
			
		||||
          viewPlugins: true,
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
      sandbox.stub(
 | 
			
		||||
          element.$.restAPI,
 | 
			
		||||
          'getAccountCapabilities',
 | 
			
		||||
          () => Promise.resolve({
 | 
			
		||||
            createGroup: true,
 | 
			
		||||
            createProject: true,
 | 
			
		||||
            viewPlugins: true,
 | 
			
		||||
          })
 | 
			
		||||
      );
 | 
			
		||||
      element.reload().then(() => {
 | 
			
		||||
        assert.equal(element._filteredLinks.length, 3);
 | 
			
		||||
 | 
			
		||||
@@ -127,9 +129,11 @@ limitations under the License.
 | 
			
		||||
      sandbox.stub(element.$.restAPI, 'getAccount').returns(Promise.resolve({
 | 
			
		||||
        name: 'test-user',
 | 
			
		||||
      }));
 | 
			
		||||
      sandbox.stub(element.$.restAPI, 'getAccountCapabilities', () => {
 | 
			
		||||
        return Promise.resolve({});
 | 
			
		||||
      });
 | 
			
		||||
      sandbox.stub(
 | 
			
		||||
          element.$.restAPI,
 | 
			
		||||
          'getAccountCapabilities',
 | 
			
		||||
          () => Promise.resolve({})
 | 
			
		||||
      );
 | 
			
		||||
      element.reload().then(() => {
 | 
			
		||||
        assert.equal(element._filteredLinks.length, 2);
 | 
			
		||||
 | 
			
		||||
@@ -185,13 +189,14 @@ limitations under the License.
 | 
			
		||||
      sandbox.stub(element.$.restAPI, 'getAccount').returns(Promise.resolve({
 | 
			
		||||
        name: 'test-user',
 | 
			
		||||
      }));
 | 
			
		||||
      sandbox.stub(element.$.restAPI, 'getAccountCapabilities', () => {
 | 
			
		||||
        return Promise.resolve({
 | 
			
		||||
          createGroup: true,
 | 
			
		||||
          createProject: true,
 | 
			
		||||
          viewPlugins: true,
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
      sandbox.stub(
 | 
			
		||||
          element.$.restAPI,
 | 
			
		||||
          'getAccountCapabilities',
 | 
			
		||||
          () => Promise.resolve({
 | 
			
		||||
            createGroup: true,
 | 
			
		||||
            createProject: true,
 | 
			
		||||
            viewPlugins: true,
 | 
			
		||||
          }));
 | 
			
		||||
      element.reload().then(() => {
 | 
			
		||||
        flushAsynchronousOperations();
 | 
			
		||||
        assert.equal(Polymer.dom(element.root)
 | 
			
		||||
@@ -214,13 +219,14 @@ limitations under the License.
 | 
			
		||||
      sandbox.stub(element.$.restAPI, 'getAccount').returns(Promise.resolve({
 | 
			
		||||
        name: 'test-user',
 | 
			
		||||
      }));
 | 
			
		||||
      sandbox.stub(element.$.restAPI, 'getAccountCapabilities', () => {
 | 
			
		||||
        return Promise.resolve({
 | 
			
		||||
          createGroup: true,
 | 
			
		||||
          createProject: true,
 | 
			
		||||
          viewPlugins: true,
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
      sandbox.stub(
 | 
			
		||||
          element.$.restAPI,
 | 
			
		||||
          'getAccountCapabilities',
 | 
			
		||||
          () => Promise.resolve({
 | 
			
		||||
            createGroup: true,
 | 
			
		||||
            createProject: true,
 | 
			
		||||
            viewPlugins: true,
 | 
			
		||||
          }));
 | 
			
		||||
      element.reload().then(() => {
 | 
			
		||||
        flushAsynchronousOperations();
 | 
			
		||||
        assert.equal(element._filteredLinks.length, 3);
 | 
			
		||||
@@ -239,16 +245,18 @@ limitations under the License.
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('Nav is reloaded when repo changes', () => {
 | 
			
		||||
      sandbox.stub(element.$.restAPI, 'getAccountCapabilities', () => {
 | 
			
		||||
        return Promise.resolve({
 | 
			
		||||
          createGroup: true,
 | 
			
		||||
          createProject: true,
 | 
			
		||||
          viewPlugins: true,
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
      sandbox.stub(element.$.restAPI, 'getAccount', () => {
 | 
			
		||||
        return Promise.resolve({_id: 1});
 | 
			
		||||
      });
 | 
			
		||||
      sandbox.stub(
 | 
			
		||||
          element.$.restAPI,
 | 
			
		||||
          'getAccountCapabilities',
 | 
			
		||||
          () => Promise.resolve({
 | 
			
		||||
            createGroup: true,
 | 
			
		||||
            createProject: true,
 | 
			
		||||
            viewPlugins: true,
 | 
			
		||||
          }));
 | 
			
		||||
      sandbox.stub(
 | 
			
		||||
          element.$.restAPI,
 | 
			
		||||
          'getAccount',
 | 
			
		||||
          () => Promise.resolve({_id: 1}));
 | 
			
		||||
      sandbox.stub(element, 'reload');
 | 
			
		||||
      element.params = {repo: 'Test Repo', adminView: 'gr-repo'};
 | 
			
		||||
      assert.equal(element.reload.callCount, 1);
 | 
			
		||||
@@ -259,16 +267,18 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
    test('Nav is reloaded when group changes', () => {
 | 
			
		||||
      sandbox.stub(element, '_computeGroupName');
 | 
			
		||||
      sandbox.stub(element.$.restAPI, 'getAccountCapabilities', () => {
 | 
			
		||||
        return Promise.resolve({
 | 
			
		||||
          createGroup: true,
 | 
			
		||||
          createProject: true,
 | 
			
		||||
          viewPlugins: true,
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
      sandbox.stub(element.$.restAPI, 'getAccount', () => {
 | 
			
		||||
        return Promise.resolve({_id: 1});
 | 
			
		||||
      });
 | 
			
		||||
      sandbox.stub(
 | 
			
		||||
          element.$.restAPI,
 | 
			
		||||
          'getAccountCapabilities',
 | 
			
		||||
          () => Promise.resolve({
 | 
			
		||||
            createGroup: true,
 | 
			
		||||
            createProject: true,
 | 
			
		||||
            viewPlugins: true,
 | 
			
		||||
          }));
 | 
			
		||||
      sandbox.stub(
 | 
			
		||||
          element.$.restAPI,
 | 
			
		||||
          'getAccount',
 | 
			
		||||
          () => Promise.resolve({_id: 1}));
 | 
			
		||||
      sandbox.stub(element, 'reload');
 | 
			
		||||
      element.params = {groupId: '1', adminView: 'gr-group'};
 | 
			
		||||
      assert.equal(element.reload.callCount, 1);
 | 
			
		||||
@@ -304,7 +314,9 @@ limitations under the License.
 | 
			
		||||
      assert.isOk(element.$$('.mainHeader'));
 | 
			
		||||
      element._subsectionLinks = undefined;
 | 
			
		||||
      flushAsynchronousOperations();
 | 
			
		||||
      assert.equal(getComputedStyle(element.$$('.mainHeader')).display, 'none');
 | 
			
		||||
      assert.equal(
 | 
			
		||||
          getComputedStyle(element.$$('.mainHeader')).display,
 | 
			
		||||
          'none');
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('Dropdown only triggers navigation on explicit select', done => {
 | 
			
		||||
@@ -314,16 +326,18 @@ limitations under the License.
 | 
			
		||||
        view: Gerrit.Nav.View.REPO,
 | 
			
		||||
        detail: Gerrit.Nav.RepoDetailView.ACCESS,
 | 
			
		||||
      };
 | 
			
		||||
      sandbox.stub(element.$.restAPI, 'getAccountCapabilities', () => {
 | 
			
		||||
        return Promise.resolve({
 | 
			
		||||
          createGroup: true,
 | 
			
		||||
          createProject: true,
 | 
			
		||||
          viewPlugins: true,
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
      sandbox.stub(element.$.restAPI, 'getAccount', () => {
 | 
			
		||||
        return Promise.resolve({_id: 1});
 | 
			
		||||
      });
 | 
			
		||||
      sandbox.stub(
 | 
			
		||||
          element.$.restAPI,
 | 
			
		||||
          'getAccountCapabilities',
 | 
			
		||||
          () => Promise.resolve({
 | 
			
		||||
            createGroup: true,
 | 
			
		||||
            createProject: true,
 | 
			
		||||
            viewPlugins: true,
 | 
			
		||||
          }));
 | 
			
		||||
      sandbox.stub(
 | 
			
		||||
          element.$.restAPI,
 | 
			
		||||
          'getAccount',
 | 
			
		||||
          () => Promise.resolve({_id: 1}));
 | 
			
		||||
      flushAsynchronousOperations();
 | 
			
		||||
      const expectedFilteredLinks = [
 | 
			
		||||
        {
 | 
			
		||||
@@ -475,16 +489,18 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
    suite('_computeSelectedClass', () => {
 | 
			
		||||
      setup(() => {
 | 
			
		||||
        sandbox.stub(element.$.restAPI, 'getAccountCapabilities', () => {
 | 
			
		||||
          return Promise.resolve({
 | 
			
		||||
            createGroup: true,
 | 
			
		||||
            createProject: true,
 | 
			
		||||
            viewPlugins: true,
 | 
			
		||||
          });
 | 
			
		||||
        });
 | 
			
		||||
        sandbox.stub(element.$.restAPI, 'getAccount', () => {
 | 
			
		||||
          return Promise.resolve({_id: 1});
 | 
			
		||||
        });
 | 
			
		||||
        sandbox.stub(
 | 
			
		||||
            element.$.restAPI,
 | 
			
		||||
            'getAccountCapabilities',
 | 
			
		||||
            () => Promise.resolve({
 | 
			
		||||
              createGroup: true,
 | 
			
		||||
              createProject: true,
 | 
			
		||||
              viewPlugins: true,
 | 
			
		||||
            }));
 | 
			
		||||
        sandbox.stub(
 | 
			
		||||
            element.$.restAPI,
 | 
			
		||||
            'getAccount',
 | 
			
		||||
            () => Promise.resolve({_id: 1}));
 | 
			
		||||
 | 
			
		||||
        return element.reload();
 | 
			
		||||
      });
 | 
			
		||||
 
 | 
			
		||||
@@ -81,9 +81,7 @@ limitations under the License.
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      const saveStub = sandbox.stub(element.$.restAPI,
 | 
			
		||||
          'createChange', () => {
 | 
			
		||||
            return Promise.resolve({});
 | 
			
		||||
          });
 | 
			
		||||
          'createChange', () => Promise.resolve({}));
 | 
			
		||||
 | 
			
		||||
      element.branch = 'test-branch';
 | 
			
		||||
      element.topic = 'test-topic';
 | 
			
		||||
@@ -109,9 +107,7 @@ limitations under the License.
 | 
			
		||||
        configured_value: 'TRUE',
 | 
			
		||||
        inherited_value: false,
 | 
			
		||||
      };
 | 
			
		||||
      sandbox.stub(element, '_formatBooleanString', () => {
 | 
			
		||||
        return Promise.resolve(true);
 | 
			
		||||
      });
 | 
			
		||||
      sandbox.stub(element, '_formatBooleanString', () => Promise.resolve(true));
 | 
			
		||||
      flushAsynchronousOperations();
 | 
			
		||||
 | 
			
		||||
      const configInputObj = {
 | 
			
		||||
@@ -123,9 +119,7 @@ limitations under the License.
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      const saveStub = sandbox.stub(element.$.restAPI,
 | 
			
		||||
          'createChange', () => {
 | 
			
		||||
            return Promise.resolve({});
 | 
			
		||||
          });
 | 
			
		||||
          'createChange', () => Promise.resolve({}));
 | 
			
		||||
 | 
			
		||||
      element.branch = 'test-branch';
 | 
			
		||||
      element.topic = 'test-topic';
 | 
			
		||||
 
 | 
			
		||||
@@ -56,9 +56,10 @@ limitations under the License.
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('branch created', done => {
 | 
			
		||||
      sandbox.stub(element.$.restAPI, 'createRepoBranch', () => {
 | 
			
		||||
        return Promise.resolve({});
 | 
			
		||||
      });
 | 
			
		||||
      sandbox.stub(
 | 
			
		||||
          element.$.restAPI,
 | 
			
		||||
          'createRepoBranch',
 | 
			
		||||
          () => Promise.resolve({}));
 | 
			
		||||
 | 
			
		||||
      assert.isFalse(element.hasNewItemName);
 | 
			
		||||
 | 
			
		||||
@@ -77,9 +78,10 @@ limitations under the License.
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('tag created', done => {
 | 
			
		||||
      sandbox.stub(element.$.restAPI, 'createRepoTag', () => {
 | 
			
		||||
        return Promise.resolve({});
 | 
			
		||||
      });
 | 
			
		||||
      sandbox.stub(
 | 
			
		||||
          element.$.restAPI,
 | 
			
		||||
          'createRepoTag',
 | 
			
		||||
          () => Promise.resolve({}));
 | 
			
		||||
 | 
			
		||||
      assert.isFalse(element.hasNewItemName);
 | 
			
		||||
 | 
			
		||||
@@ -98,9 +100,10 @@ limitations under the License.
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('tag created with annotations', done => {
 | 
			
		||||
      sandbox.stub(element.$.restAPI, 'createRepoTag', () => {
 | 
			
		||||
        return Promise.resolve({});
 | 
			
		||||
      });
 | 
			
		||||
      sandbox.stub(
 | 
			
		||||
          element.$.restAPI,
 | 
			
		||||
          'createRepoTag',
 | 
			
		||||
          () => Promise.resolve({}));
 | 
			
		||||
 | 
			
		||||
      assert.isFalse(element.hasNewItemName);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -66,9 +66,7 @@ limitations under the License.
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      const saveStub = sandbox.stub(element.$.restAPI,
 | 
			
		||||
          'createRepo', () => {
 | 
			
		||||
            return Promise.resolve({});
 | 
			
		||||
          });
 | 
			
		||||
          'createRepo', () => Promise.resolve({}));
 | 
			
		||||
 | 
			
		||||
      assert.isFalse(element.hasNewRepoName);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -153,9 +153,10 @@ limitations under the License.
 | 
			
		||||
      element = fixture('basic');
 | 
			
		||||
      sandbox.stub(element, 'getBaseUrl').returns('https://test/site');
 | 
			
		||||
      element.groupId = 1;
 | 
			
		||||
      groupStub = sandbox.stub(element.$.restAPI, 'getGroupConfig', () => {
 | 
			
		||||
        return Promise.resolve(groups);
 | 
			
		||||
      });
 | 
			
		||||
      groupStub = sandbox.stub(
 | 
			
		||||
          element.$.restAPI,
 | 
			
		||||
          'getGroupConfig',
 | 
			
		||||
          () => Promise.resolve(groups));
 | 
			
		||||
      return element._loadGroupDetails();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
@@ -181,9 +182,7 @@ limitations under the License.
 | 
			
		||||
      const memberName = 'test-admin';
 | 
			
		||||
 | 
			
		||||
      const saveStub = sandbox.stub(element.$.restAPI, 'saveGroupMembers',
 | 
			
		||||
          () => {
 | 
			
		||||
            return Promise.resolve({});
 | 
			
		||||
          });
 | 
			
		||||
          () => Promise.resolve({}));
 | 
			
		||||
 | 
			
		||||
      const button = element.$.saveGroupMember;
 | 
			
		||||
 | 
			
		||||
@@ -208,9 +207,7 @@ limitations under the License.
 | 
			
		||||
      const includedGroupName = 'testName';
 | 
			
		||||
 | 
			
		||||
      const saveIncludedGroupStub = sandbox.stub(
 | 
			
		||||
          element.$.restAPI, 'saveIncludedGroup', () => {
 | 
			
		||||
            return Promise.resolve({});
 | 
			
		||||
          });
 | 
			
		||||
          element.$.restAPI, 'saveIncludedGroup', () => Promise.resolve({}));
 | 
			
		||||
 | 
			
		||||
      const button = element.$.saveIncludedGroups;
 | 
			
		||||
 | 
			
		||||
@@ -248,35 +245,31 @@ limitations under the License.
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('_getAccountSuggestions empty', () => {
 | 
			
		||||
      return element._getAccountSuggestions('nonexistent').then(accounts => {
 | 
			
		||||
        assert.equal(accounts.length, 0);
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
    test('_getAccountSuggestions empty', () => element
 | 
			
		||||
        ._getAccountSuggestions('nonexistent').then(accounts => {
 | 
			
		||||
          assert.equal(accounts.length, 0);
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
    test('_getAccountSuggestions non-empty', () => {
 | 
			
		||||
      return element._getAccountSuggestions('test-').then(accounts => {
 | 
			
		||||
        assert.equal(accounts.length, 3);
 | 
			
		||||
        assert.equal(accounts[0].name,
 | 
			
		||||
            'test-account <test.account@example.com>');
 | 
			
		||||
        assert.equal(accounts[1].name, 'test-admin <test.admin@example.com>');
 | 
			
		||||
        assert.equal(accounts[2].name, 'test-git');
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
    test('_getAccountSuggestions non-empty', () => element
 | 
			
		||||
        ._getAccountSuggestions('test-').then(accounts => {
 | 
			
		||||
          assert.equal(accounts.length, 3);
 | 
			
		||||
          assert.equal(accounts[0].name,
 | 
			
		||||
              'test-account <test.account@example.com>');
 | 
			
		||||
          assert.equal(accounts[1].name, 'test-admin <test.admin@example.com>');
 | 
			
		||||
          assert.equal(accounts[2].name, 'test-git');
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
    test('_getGroupSuggestions empty', () => {
 | 
			
		||||
      return element._getGroupSuggestions('nonexistent').then(groups => {
 | 
			
		||||
        assert.equal(groups.length, 0);
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
    test('_getGroupSuggestions empty', () => element
 | 
			
		||||
        ._getGroupSuggestions('nonexistent').then(groups => {
 | 
			
		||||
          assert.equal(groups.length, 0);
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
    test('_getGroupSuggestions non-empty', () => {
 | 
			
		||||
      return element._getGroupSuggestions('test').then(groups => {
 | 
			
		||||
        assert.equal(groups.length, 2);
 | 
			
		||||
        assert.equal(groups[0].name, 'test-admin');
 | 
			
		||||
        assert.equal(groups[1].name, 'test/Administrator (admin)');
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
    test('_getGroupSuggestions non-empty', () => element
 | 
			
		||||
        ._getGroupSuggestions('test').then(groups => {
 | 
			
		||||
          assert.equal(groups.length, 2);
 | 
			
		||||
          assert.equal(groups[0].name, 'test-admin');
 | 
			
		||||
          assert.equal(groups[1].name, 'test/Administrator (admin)');
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
    test('_computeHideItemClass returns string for admin', () => {
 | 
			
		||||
      const admin = true;
 | 
			
		||||
 
 | 
			
		||||
@@ -56,9 +56,11 @@ limitations under the License.
 | 
			
		||||
        getLoggedIn() { return Promise.resolve(true); },
 | 
			
		||||
      });
 | 
			
		||||
      element = fixture('basic');
 | 
			
		||||
      groupStub = sandbox.stub(element.$.restAPI, 'getGroupConfig', () => {
 | 
			
		||||
        return Promise.resolve(group);
 | 
			
		||||
      });
 | 
			
		||||
      groupStub = sandbox.stub(
 | 
			
		||||
          element.$.restAPI,
 | 
			
		||||
          'getGroupConfig',
 | 
			
		||||
          () => Promise.resolve(group)
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    teardown(() => {
 | 
			
		||||
@@ -74,9 +76,10 @@ limitations under the License.
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('default values are populated with internal group', done => {
 | 
			
		||||
      sandbox.stub(element.$.restAPI, 'getIsGroupOwner', () => {
 | 
			
		||||
        return Promise.resolve(true);
 | 
			
		||||
      });
 | 
			
		||||
      sandbox.stub(
 | 
			
		||||
          element.$.restAPI,
 | 
			
		||||
          'getIsGroupOwner',
 | 
			
		||||
          () => Promise.resolve(true));
 | 
			
		||||
      element.groupId = 1;
 | 
			
		||||
      element._loadGroup().then(() => {
 | 
			
		||||
        assert.isTrue(element._groupIsInternal);
 | 
			
		||||
@@ -89,12 +92,14 @@ limitations under the License.
 | 
			
		||||
      const groupExternal = Object.assign({}, group);
 | 
			
		||||
      groupExternal.id = 'external-group-id';
 | 
			
		||||
      groupStub.restore();
 | 
			
		||||
      groupStub = sandbox.stub(element.$.restAPI, 'getGroupConfig', () => {
 | 
			
		||||
        return Promise.resolve(groupExternal);
 | 
			
		||||
      });
 | 
			
		||||
      sandbox.stub(element.$.restAPI, 'getIsGroupOwner', () => {
 | 
			
		||||
        return Promise.resolve(true);
 | 
			
		||||
      });
 | 
			
		||||
      groupStub = sandbox.stub(
 | 
			
		||||
          element.$.restAPI,
 | 
			
		||||
          'getGroupConfig',
 | 
			
		||||
          () => Promise.resolve(groupExternal));
 | 
			
		||||
      sandbox.stub(
 | 
			
		||||
          element.$.restAPI,
 | 
			
		||||
          'getIsGroupOwner',
 | 
			
		||||
          () => Promise.resolve(true));
 | 
			
		||||
      element.groupId = 1;
 | 
			
		||||
      element._loadGroup().then(() => {
 | 
			
		||||
        assert.isFalse(element._groupIsInternal);
 | 
			
		||||
@@ -114,13 +119,15 @@ limitations under the License.
 | 
			
		||||
      element._groupName = groupName;
 | 
			
		||||
      element._groupOwner = true;
 | 
			
		||||
 | 
			
		||||
      sandbox.stub(element.$.restAPI, 'getIsGroupOwner', () => {
 | 
			
		||||
        return Promise.resolve(true);
 | 
			
		||||
      });
 | 
			
		||||
      sandbox.stub(
 | 
			
		||||
          element.$.restAPI,
 | 
			
		||||
          'getIsGroupOwner',
 | 
			
		||||
          () => Promise.resolve(true));
 | 
			
		||||
 | 
			
		||||
      sandbox.stub(element.$.restAPI, 'saveGroupName', () => {
 | 
			
		||||
        return Promise.resolve({status: 200});
 | 
			
		||||
      });
 | 
			
		||||
      sandbox.stub(
 | 
			
		||||
          element.$.restAPI,
 | 
			
		||||
          'saveGroupName',
 | 
			
		||||
          () => Promise.resolve({status: 200}));
 | 
			
		||||
 | 
			
		||||
      const button = element.$.inputUpdateNameBtn;
 | 
			
		||||
 | 
			
		||||
@@ -154,9 +161,10 @@ limitations under the License.
 | 
			
		||||
    test('test for undefined group name', done => {
 | 
			
		||||
      groupStub.restore();
 | 
			
		||||
 | 
			
		||||
      sandbox.stub(element.$.restAPI, 'getGroupConfig', () => {
 | 
			
		||||
        return Promise.resolve({});
 | 
			
		||||
      });
 | 
			
		||||
      sandbox.stub(
 | 
			
		||||
          element.$.restAPI,
 | 
			
		||||
          'getGroupConfig',
 | 
			
		||||
          () => Promise.resolve({}));
 | 
			
		||||
 | 
			
		||||
      assert.isUndefined(element.groupId);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -209,9 +209,8 @@
 | 
			
		||||
 | 
			
		||||
    _computeLabelValues(values) {
 | 
			
		||||
      const valuesArr = [];
 | 
			
		||||
      const keys = Object.keys(values).sort((a, b) => {
 | 
			
		||||
        return parseInt(a, 10) - parseInt(b, 10);
 | 
			
		||||
      });
 | 
			
		||||
      const keys = Object.keys(values)
 | 
			
		||||
          .sort((a, b) => parseInt(a, 10) - parseInt(b, 10));
 | 
			
		||||
 | 
			
		||||
      for (const key of keys) {
 | 
			
		||||
        let text = values[key];
 | 
			
		||||
@@ -255,9 +254,8 @@
 | 
			
		||||
              });
 | 
			
		||||
            }
 | 
			
		||||
            // Does not return groups in which we already have rules for.
 | 
			
		||||
            return groups.filter(group => {
 | 
			
		||||
              return !this._groupsWithRules[group.value.id];
 | 
			
		||||
            });
 | 
			
		||||
            return groups
 | 
			
		||||
                .filter(group => !this._groupsWithRules[group.value.id]);
 | 
			
		||||
          });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -268,7 +266,8 @@
 | 
			
		||||
    _handleAddRuleItem(e) {
 | 
			
		||||
      // The group id is encoded, but have to decode in order for the access
 | 
			
		||||
      // API to work as expected.
 | 
			
		||||
      const groupId = decodeURIComponent(e.detail.value.id).replace(/\+/g, ' ');
 | 
			
		||||
      const groupId = decodeURIComponent(e.detail.value.id)
 | 
			
		||||
          .replace(/\+/g, ' ');
 | 
			
		||||
      this.set(['permission', 'value', 'rules', groupId], {});
 | 
			
		||||
 | 
			
		||||
      // Purposely don't recompute sorted array so that the newly added rule
 | 
			
		||||
 
 | 
			
		||||
@@ -125,9 +125,10 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
    suite('filter', () => {
 | 
			
		||||
      test('_paramsChanged', done => {
 | 
			
		||||
        sandbox.stub(element.$.restAPI, 'getPlugins', () => {
 | 
			
		||||
          return Promise.resolve(plugins);
 | 
			
		||||
        });
 | 
			
		||||
        sandbox.stub(
 | 
			
		||||
            element.$.restAPI,
 | 
			
		||||
            'getPlugins',
 | 
			
		||||
            () => Promise.resolve(plugins));
 | 
			
		||||
        const value = {
 | 
			
		||||
          filter: 'test',
 | 
			
		||||
          offset: 25,
 | 
			
		||||
 
 | 
			
		||||
@@ -44,9 +44,10 @@ limitations under the License.
 | 
			
		||||
    setup(() => {
 | 
			
		||||
      sandbox = sinon.sandbox.create();
 | 
			
		||||
      element = fixture('basic');
 | 
			
		||||
      repoStub = sandbox.stub(element.$.restAPI, 'getProjectConfig', () => {
 | 
			
		||||
        return Promise.resolve({});
 | 
			
		||||
      });
 | 
			
		||||
      repoStub = sandbox.stub(
 | 
			
		||||
          element.$.restAPI,
 | 
			
		||||
          'getProjectConfig',
 | 
			
		||||
          () => Promise.resolve({}));
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    teardown(() => {
 | 
			
		||||
 
 | 
			
		||||
@@ -297,9 +297,10 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
    suite('filter', () => {
 | 
			
		||||
      test('_paramsChanged', done => {
 | 
			
		||||
        sandbox.stub(element.$.restAPI, 'getRepoBranches', () => {
 | 
			
		||||
          return Promise.resolve(branches);
 | 
			
		||||
        });
 | 
			
		||||
        sandbox.stub(
 | 
			
		||||
            element.$.restAPI,
 | 
			
		||||
            'getRepoBranches',
 | 
			
		||||
            () => Promise.resolve(branches));
 | 
			
		||||
        const params = {
 | 
			
		||||
          detail: 'branches',
 | 
			
		||||
          repo: 'test',
 | 
			
		||||
@@ -480,9 +481,10 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
    suite('filter', () => {
 | 
			
		||||
      test('_paramsChanged', done => {
 | 
			
		||||
        sandbox.stub(element.$.restAPI, 'getRepoTags', () => {
 | 
			
		||||
          return Promise.resolve(tags);
 | 
			
		||||
        });
 | 
			
		||||
        sandbox.stub(
 | 
			
		||||
            element.$.restAPI,
 | 
			
		||||
            'getRepoTags',
 | 
			
		||||
            () => Promise.resolve(tags));
 | 
			
		||||
        const params = {
 | 
			
		||||
          repo: 'test',
 | 
			
		||||
          detail: 'tags',
 | 
			
		||||
 
 | 
			
		||||
@@ -127,9 +127,7 @@ limitations under the License.
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      test('_paramsChanged', done => {
 | 
			
		||||
        sandbox.stub(element.$.restAPI, 'getRepos', () => {
 | 
			
		||||
          return Promise.resolve(repos);
 | 
			
		||||
        });
 | 
			
		||||
        sandbox.stub(element.$.restAPI, 'getRepos', () => Promise.resolve(repos));
 | 
			
		||||
        const value = {
 | 
			
		||||
          filter: 'test',
 | 
			
		||||
          offset: 25,
 | 
			
		||||
 
 | 
			
		||||
@@ -49,7 +49,8 @@
 | 
			
		||||
        return [];
 | 
			
		||||
      }
 | 
			
		||||
      const {config} = dataRecord.base;
 | 
			
		||||
      return Object.keys(config).map(_key => ({_key, info: config[_key]}));
 | 
			
		||||
      return Object.keys(config)
 | 
			
		||||
          .map(_key => { return {_key, info: config[_key]}; });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _isArray(type) {
 | 
			
		||||
 
 | 
			
		||||
@@ -136,7 +136,7 @@
 | 
			
		||||
 | 
			
		||||
      const pluginConfig = configRecord.base;
 | 
			
		||||
      return Object.keys(pluginConfig)
 | 
			
		||||
          .map(name => ({name, config: pluginConfig[name]}));
 | 
			
		||||
          .map(name => { return {name, config: pluginConfig[name]}; });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _loadRepo() {
 | 
			
		||||
 
 | 
			
		||||
@@ -120,9 +120,10 @@ limitations under the License.
 | 
			
		||||
        },
 | 
			
		||||
      });
 | 
			
		||||
      element = fixture('basic');
 | 
			
		||||
      repoStub = sandbox.stub(element.$.restAPI, 'getProjectConfig', () => {
 | 
			
		||||
        return Promise.resolve(repoConf);
 | 
			
		||||
      });
 | 
			
		||||
      repoStub = sandbox.stub(
 | 
			
		||||
          element.$.restAPI,
 | 
			
		||||
          'getProjectConfig',
 | 
			
		||||
          () => Promise.resolve(repoConf));
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    teardown(() => {
 | 
			
		||||
@@ -187,12 +188,11 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
    test('form defaults to read only when logged in and not admin', done => {
 | 
			
		||||
      element.repo = REPO;
 | 
			
		||||
      sandbox.stub(element, '_getLoggedIn', () => {
 | 
			
		||||
        return Promise.resolve(true);
 | 
			
		||||
      });
 | 
			
		||||
      sandbox.stub(element.$.restAPI, 'getRepoAccess', () => {
 | 
			
		||||
        return Promise.resolve({'test-repo': {}});
 | 
			
		||||
      });
 | 
			
		||||
      sandbox.stub(element, '_getLoggedIn', () => Promise.resolve(true));
 | 
			
		||||
      sandbox.stub(
 | 
			
		||||
          element.$.restAPI,
 | 
			
		||||
          'getRepoAccess',
 | 
			
		||||
          () => Promise.resolve({'test-repo': {}}));
 | 
			
		||||
      element._loadRepo().then(() => {
 | 
			
		||||
        assert.isTrue(element._readOnly);
 | 
			
		||||
        done();
 | 
			
		||||
@@ -280,12 +280,11 @@ limitations under the License.
 | 
			
		||||
    suite('admin', () => {
 | 
			
		||||
      setup(() => {
 | 
			
		||||
        element.repo = REPO;
 | 
			
		||||
        sandbox.stub(element, '_getLoggedIn', () => {
 | 
			
		||||
          return Promise.resolve(true);
 | 
			
		||||
        });
 | 
			
		||||
        sandbox.stub(element.$.restAPI, 'getRepoAccess', () => {
 | 
			
		||||
          return Promise.resolve({'test-repo': {is_owner: true}});
 | 
			
		||||
        });
 | 
			
		||||
        sandbox.stub(element, '_getLoggedIn', () => Promise.resolve(true));
 | 
			
		||||
        sandbox.stub(
 | 
			
		||||
            element.$.restAPI,
 | 
			
		||||
            'getRepoAccess',
 | 
			
		||||
            () => Promise.resolve({'test-repo': {is_owner: true}}));
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      test('all form elements are enabled', done => {
 | 
			
		||||
@@ -308,14 +307,13 @@ limitations under the License.
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      test('inherited submit type value is calculated correctly', () => {
 | 
			
		||||
        return element._loadRepo().then(() => {
 | 
			
		||||
          const sel = element.$.submitTypeSelect;
 | 
			
		||||
          assert.equal(sel.bindValue, 'INHERIT');
 | 
			
		||||
          assert.equal(
 | 
			
		||||
              sel.nativeSelect.options[0].text, 'Inherit (Merge if necessary)');
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
      test('inherited submit type value is calculated correctly', () => element
 | 
			
		||||
          ._loadRepo().then(() => {
 | 
			
		||||
            const sel = element.$.submitTypeSelect;
 | 
			
		||||
            assert.equal(sel.bindValue, 'INHERIT');
 | 
			
		||||
            assert.equal(
 | 
			
		||||
                sel.nativeSelect.options[0].text, 'Inherit (Merge if necessary)');
 | 
			
		||||
          }));
 | 
			
		||||
 | 
			
		||||
      test('fields update and save correctly', () => {
 | 
			
		||||
        const configInputObj = {
 | 
			
		||||
@@ -338,9 +336,7 @@ limitations under the License.
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        const saveStub = sandbox.stub(element.$.restAPI, 'saveRepoConfig'
 | 
			
		||||
            , () => {
 | 
			
		||||
              return Promise.resolve({});
 | 
			
		||||
            });
 | 
			
		||||
            , () => Promise.resolve({}));
 | 
			
		||||
 | 
			
		||||
        const button = Polymer.dom(element.root).querySelector('gr-button');
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -234,11 +234,8 @@
 | 
			
		||||
    _processQuery(query) {
 | 
			
		||||
      let tokens = query.split(' ');
 | 
			
		||||
      const invalidTokens = ['limit:', 'age:', '-age:'];
 | 
			
		||||
      tokens = tokens.filter(token => {
 | 
			
		||||
        return !invalidTokens.some(invalidToken => {
 | 
			
		||||
          return token.startsWith(invalidToken);
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
      tokens = tokens.filter(token => !invalidTokens
 | 
			
		||||
          .some(invalidToken => token.startsWith(invalidToken)));
 | 
			
		||||
      return tokens.join(' ');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -218,13 +218,15 @@
 | 
			
		||||
              const lastResultSet = changes.pop();
 | 
			
		||||
              this._showNewUserHelp = lastResultSet.length == 0;
 | 
			
		||||
            }
 | 
			
		||||
            this._results = changes.map((results, i) => ({
 | 
			
		||||
              name: res.sections[i].name,
 | 
			
		||||
              countLabel: this._computeSectionCountLabel(results),
 | 
			
		||||
              query: res.sections[i].query,
 | 
			
		||||
              results,
 | 
			
		||||
              isOutgoing: res.sections[i].isOutgoing,
 | 
			
		||||
            })).filter((section, i) => i < res.sections.length && (
 | 
			
		||||
            this._results = changes.map((results, i) => {
 | 
			
		||||
              return {
 | 
			
		||||
                name: res.sections[i].name,
 | 
			
		||||
                countLabel: this._computeSectionCountLabel(results),
 | 
			
		||||
                query: res.sections[i].query,
 | 
			
		||||
                results,
 | 
			
		||||
                isOutgoing: res.sections[i].isOutgoing,
 | 
			
		||||
              };
 | 
			
		||||
            }).filter((section, i) => i < res.sections.length && (
 | 
			
		||||
              !res.sections[i].hideIfEmpty ||
 | 
			
		||||
                section.results.length));
 | 
			
		||||
          });
 | 
			
		||||
 
 | 
			
		||||
@@ -561,9 +561,8 @@
 | 
			
		||||
      if (type !== ActionType.CHANGE && type !== ActionType.REVISION) {
 | 
			
		||||
        throw Error(`Invalid action type given: ${type}`);
 | 
			
		||||
      }
 | 
			
		||||
      const index = this._actionPriorityOverrides.findIndex(action => {
 | 
			
		||||
        return action.type === type && action.key === key;
 | 
			
		||||
      });
 | 
			
		||||
      const index = this._actionPriorityOverrides
 | 
			
		||||
          .findIndex(action => action.type === type && action.key === key);
 | 
			
		||||
      const action = {
 | 
			
		||||
        type,
 | 
			
		||||
        key,
 | 
			
		||||
@@ -726,9 +725,7 @@
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _getValuesFor(obj) {
 | 
			
		||||
      return Object.keys(obj).map(key => {
 | 
			
		||||
        return obj[key];
 | 
			
		||||
      });
 | 
			
		||||
      return Object.keys(obj).map(key => obj[key]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _getLabelStatus(label) {
 | 
			
		||||
@@ -793,9 +790,8 @@
 | 
			
		||||
 | 
			
		||||
    hideQuickApproveAction() {
 | 
			
		||||
      this._topLevelSecondaryActions =
 | 
			
		||||
        this._topLevelSecondaryActions.filter(sa => {
 | 
			
		||||
          return sa.key !== QUICK_APPROVE_ACTION.key;
 | 
			
		||||
        });
 | 
			
		||||
        this._topLevelSecondaryActions
 | 
			
		||||
            .filter(sa => sa.key !== QUICK_APPROVE_ACTION.key);
 | 
			
		||||
      this._hideQuickApproveAction = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -853,13 +849,13 @@
 | 
			
		||||
 | 
			
		||||
      let additionalActions = (additionalActionsChangeRecord &&
 | 
			
		||||
      additionalActionsChangeRecord.base) || [];
 | 
			
		||||
      additionalActions = additionalActions.filter(a => {
 | 
			
		||||
        return a.__type === type;
 | 
			
		||||
      }).map(a => {
 | 
			
		||||
        a.__primary = primaryActionKeys.includes(a.__key);
 | 
			
		||||
        // Triggers a re-render by ensuring object inequality.
 | 
			
		||||
        return Object.assign({}, a);
 | 
			
		||||
      });
 | 
			
		||||
      additionalActions = additionalActions
 | 
			
		||||
          .filter(a => a.__type === type)
 | 
			
		||||
          .map(a => {
 | 
			
		||||
            a.__primary = primaryActionKeys.includes(a.__key);
 | 
			
		||||
            // Triggers a re-render by ensuring object inequality.
 | 
			
		||||
            return Object.assign({}, a);
 | 
			
		||||
          });
 | 
			
		||||
      return result.concat(additionalActions).concat(pluginActions);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -996,9 +992,7 @@
 | 
			
		||||
          this._showActionDialog(this.$.confirmAbandonDialog);
 | 
			
		||||
          break;
 | 
			
		||||
        case QUICK_APPROVE_ACTION.key:
 | 
			
		||||
          action = this._allActionValues.find(o => {
 | 
			
		||||
            return o.key === key;
 | 
			
		||||
          });
 | 
			
		||||
          action = this._allActionValues.find(o => o.key === key);
 | 
			
		||||
          this._fireAction(
 | 
			
		||||
              this._prependSlash(key), action, true, action.payload);
 | 
			
		||||
          break;
 | 
			
		||||
@@ -1196,9 +1190,8 @@
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _getActionOverflowIndex(type, key) {
 | 
			
		||||
      return this._overflowActions.findIndex(action => {
 | 
			
		||||
        return action.type === type && action.key === key;
 | 
			
		||||
      });
 | 
			
		||||
      return this._overflowActions
 | 
			
		||||
          .findIndex(action => action.type === type && action.key === key);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _setLoadingOnButtonWithKey(type, key) {
 | 
			
		||||
@@ -1460,9 +1453,8 @@
 | 
			
		||||
 | 
			
		||||
    _getActionPriority(action) {
 | 
			
		||||
      if (action.__type && action.__key) {
 | 
			
		||||
        const overrideAction = this._actionPriorityOverrides.find(i => {
 | 
			
		||||
          return i.type === action.__type && i.key === action.__key;
 | 
			
		||||
        });
 | 
			
		||||
        const overrideAction = this._actionPriorityOverrides
 | 
			
		||||
            .find(i => i.type === action.__type && i.key === action.__key);
 | 
			
		||||
 | 
			
		||||
        if (overrideAction !== undefined) {
 | 
			
		||||
          return overrideAction.priority;
 | 
			
		||||
 
 | 
			
		||||
@@ -220,9 +220,8 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
    test('delete buttons have explicit labels', done => {
 | 
			
		||||
      flush(() => {
 | 
			
		||||
        const deleteItems = element.$.moreActions.items.filter(item => {
 | 
			
		||||
          return item.id.startsWith('delete');
 | 
			
		||||
        });
 | 
			
		||||
        const deleteItems = element.$.moreActions.items
 | 
			
		||||
            .filter(item => item.id.startsWith('delete'));
 | 
			
		||||
        assert.equal(deleteItems.length, 1);
 | 
			
		||||
        assert.notEqual(deleteItems[0].name);
 | 
			
		||||
        assert.equal(deleteItems[0].name, 'Delete change');
 | 
			
		||||
@@ -261,7 +260,7 @@ limitations under the License.
 | 
			
		||||
      sandbox.stub(element.$.restAPI, 'getFromProjectLookup')
 | 
			
		||||
          .returns(Promise.resolve('test'));
 | 
			
		||||
      sandbox.stub(element, 'fetchChangeUpdates',
 | 
			
		||||
          () => { return Promise.resolve({isLatest: true}); });
 | 
			
		||||
          () => Promise.resolve({isLatest: true}));
 | 
			
		||||
      sandbox.stub(element.$.overlay, 'open').returns(Promise.resolve());
 | 
			
		||||
      element.change = {
 | 
			
		||||
        revisions: {
 | 
			
		||||
@@ -284,7 +283,7 @@ limitations under the License.
 | 
			
		||||
      sandbox.stub(element.$.restAPI, 'getFromProjectLookup')
 | 
			
		||||
          .returns(Promise.resolve('test'));
 | 
			
		||||
      sandbox.stub(element, 'fetchChangeUpdates',
 | 
			
		||||
          () => { return Promise.resolve({isLatest: true}); });
 | 
			
		||||
          () => Promise.resolve({isLatest: true}));
 | 
			
		||||
      sandbox.stub(element.$.overlay, 'open').returns(Promise.resolve());
 | 
			
		||||
      element.change = {
 | 
			
		||||
        revisions: {
 | 
			
		||||
@@ -318,7 +317,7 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
    test('submit change with plugin hook', done => {
 | 
			
		||||
      sandbox.stub(element, '_canSubmitChange',
 | 
			
		||||
          () => { return false; });
 | 
			
		||||
          () => false);
 | 
			
		||||
      const fireActionStub = sandbox.stub(element, '_fireAction');
 | 
			
		||||
      flush(() => {
 | 
			
		||||
        const submitButton = element.$$('gr-button[data-action-key="submit"]');
 | 
			
		||||
@@ -819,9 +818,9 @@ limitations under the License.
 | 
			
		||||
        };
 | 
			
		||||
        const newRevertMsg = 'Modified revert msg';
 | 
			
		||||
        sandbox.stub(element, '_modifyRevertMsg',
 | 
			
		||||
            () => { return newRevertMsg; });
 | 
			
		||||
            () => newRevertMsg);
 | 
			
		||||
        sandbox.stub(element.$.confirmRevertDialog, 'populateRevertMessage',
 | 
			
		||||
            () => { return 'original msg'; });
 | 
			
		||||
            () => 'original msg');
 | 
			
		||||
        flush(() => {
 | 
			
		||||
          const revertButton =
 | 
			
		||||
              element.$$('gr-button[data-action-key="revert"]');
 | 
			
		||||
@@ -837,7 +836,7 @@ limitations under the License.
 | 
			
		||||
          current_revision: 'abc1234',
 | 
			
		||||
        };
 | 
			
		||||
        sandbox.stub(element.$.confirmRevertDialog, 'populateRevertMessage',
 | 
			
		||||
            () => { return 'original msg'; });
 | 
			
		||||
            () => 'original msg');
 | 
			
		||||
        const revertButton = element.$$('gr-button[data-action-key="revert"]');
 | 
			
		||||
        MockInteractions.tap(revertButton);
 | 
			
		||||
 | 
			
		||||
@@ -1398,15 +1397,13 @@ limitations under the License.
 | 
			
		||||
          sandbox.stub(element, 'async', fn => fn());
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        const makeGetChange = numTries => {
 | 
			
		||||
          return () => {
 | 
			
		||||
            if (numTries === 1) {
 | 
			
		||||
              return Promise.resolve({_number: 123});
 | 
			
		||||
            } else {
 | 
			
		||||
              numTries--;
 | 
			
		||||
              return Promise.resolve(undefined);
 | 
			
		||||
            }
 | 
			
		||||
          };
 | 
			
		||||
        const makeGetChange = numTries => () => {
 | 
			
		||||
          if (numTries === 1) {
 | 
			
		||||
            return Promise.resolve({_number: 123});
 | 
			
		||||
          } else {
 | 
			
		||||
            numTries--;
 | 
			
		||||
            return Promise.resolve(undefined);
 | 
			
		||||
          }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        test('succeed', () => {
 | 
			
		||||
@@ -1457,15 +1454,14 @@ limitations under the License.
 | 
			
		||||
              'navigateToChange').returns(Promise.resolve(true));
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        test('change action', () => {
 | 
			
		||||
          return element._send('DELETE', payload, '/endpoint', false, cleanup)
 | 
			
		||||
              .then(() => {
 | 
			
		||||
                assert.isFalse(onShowError.called);
 | 
			
		||||
                assert.isTrue(cleanup.calledOnce);
 | 
			
		||||
                assert.isTrue(sendStub.calledWith(42, 'DELETE', '/endpoint',
 | 
			
		||||
                    null, payload));
 | 
			
		||||
              });
 | 
			
		||||
        });
 | 
			
		||||
        test('change action', () => element
 | 
			
		||||
            ._send('DELETE', payload, '/endpoint', false, cleanup)
 | 
			
		||||
            .then(() => {
 | 
			
		||||
              assert.isFalse(onShowError.called);
 | 
			
		||||
              assert.isTrue(cleanup.calledOnce);
 | 
			
		||||
              assert.isTrue(sendStub.calledWith(42, 'DELETE', '/endpoint',
 | 
			
		||||
                  null, payload));
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
        suite('show revert submission dialog', () => {
 | 
			
		||||
          setup(() => {
 | 
			
		||||
@@ -1549,15 +1545,14 @@ limitations under the License.
 | 
			
		||||
          });
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        test('revision action', () => {
 | 
			
		||||
          return element._send('DELETE', payload, '/endpoint', true, cleanup)
 | 
			
		||||
              .then(() => {
 | 
			
		||||
                assert.isFalse(onShowError.called);
 | 
			
		||||
                assert.isTrue(cleanup.calledOnce);
 | 
			
		||||
                assert.isTrue(sendStub.calledWith(42, 'DELETE', '/endpoint',
 | 
			
		||||
                    12, payload));
 | 
			
		||||
              });
 | 
			
		||||
        });
 | 
			
		||||
        test('revision action', () => element
 | 
			
		||||
            ._send('DELETE', payload, '/endpoint', true, cleanup)
 | 
			
		||||
            .then(() => {
 | 
			
		||||
              assert.isFalse(onShowError.called);
 | 
			
		||||
              assert.isTrue(cleanup.calledOnce);
 | 
			
		||||
              assert.isTrue(sendStub.calledWith(42, 'DELETE', '/endpoint',
 | 
			
		||||
                  12, payload));
 | 
			
		||||
            }));
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      suite('failure modes', () => {
 | 
			
		||||
 
 | 
			
		||||
@@ -608,11 +608,11 @@
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      diffDrafts[draft.path].push(draft);
 | 
			
		||||
      diffDrafts[draft.path].sort((c1, c2) => {
 | 
			
		||||
      diffDrafts[draft.path].sort((c1, c2) =>
 | 
			
		||||
        // No line number means that it’s a file comment. Sort it above the
 | 
			
		||||
        // others.
 | 
			
		||||
        return (c1.line || -1) - (c2.line || -1);
 | 
			
		||||
      });
 | 
			
		||||
        (c1.line || -1) - (c2.line || -1)
 | 
			
		||||
      );
 | 
			
		||||
      this._diffDrafts = diffDrafts;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -694,7 +694,7 @@
 | 
			
		||||
    _handleMessageReply(e) {
 | 
			
		||||
      const msg = e.detail.message.message;
 | 
			
		||||
      const quoteStr = msg.split('\n').map(
 | 
			
		||||
          line => { return '> ' + line; })
 | 
			
		||||
          line => '> ' + line)
 | 
			
		||||
          .join('\n') + '\n\n';
 | 
			
		||||
      this.$.replyDialog.quote = quoteStr;
 | 
			
		||||
      this._openReplyDialog(this.$.replyDialog.FocusTarget.BODY);
 | 
			
		||||
@@ -1093,9 +1093,8 @@
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const drafts = (changeRecord && changeRecord.base) || {};
 | 
			
		||||
      const draftCount = Object.keys(drafts).reduce((count, file) => {
 | 
			
		||||
        return count + drafts[file].length;
 | 
			
		||||
      }, 0);
 | 
			
		||||
      const draftCount = Object.keys(drafts)
 | 
			
		||||
          .reduce((count, file) => count + drafts[file].length, 0);
 | 
			
		||||
 | 
			
		||||
      let label = 'Reply';
 | 
			
		||||
      if (draftCount > 0) {
 | 
			
		||||
@@ -1401,9 +1400,7 @@
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _reloadDraftsWithCallback(e) {
 | 
			
		||||
      return this._reloadDrafts().then(() => {
 | 
			
		||||
        return e.detail.resolve();
 | 
			
		||||
      });
 | 
			
		||||
      return this._reloadDrafts().then(() => e.detail.resolve());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -91,9 +91,7 @@ limitations under the License.
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    getCustomCssValue = cssParam => {
 | 
			
		||||
      return util.getComputedStyleValue(cssParam, element);
 | 
			
		||||
    };
 | 
			
		||||
    getCustomCssValue = cssParam => util.getComputedStyleValue(cssParam, element);
 | 
			
		||||
 | 
			
		||||
    test('_handleMessageAnchorTap', () => {
 | 
			
		||||
      element._changeNum = '1';
 | 
			
		||||
@@ -725,10 +723,10 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
    test('don’t reload entire page when patchRange changes', () => {
 | 
			
		||||
      const reloadStub = sandbox.stub(element, '_reload',
 | 
			
		||||
          () => { return Promise.resolve(); });
 | 
			
		||||
          () => Promise.resolve());
 | 
			
		||||
      const reloadPatchDependentStub = sandbox.stub(element,
 | 
			
		||||
          '_reloadPatchNumDependentResources',
 | 
			
		||||
          () => { return Promise.resolve(); });
 | 
			
		||||
          () => Promise.resolve());
 | 
			
		||||
      const relatedClearSpy = sandbox.spy(element.$.relatedChanges, 'clear');
 | 
			
		||||
      const collapseStub = sandbox.stub(element.$.fileList, 'collapseAllDiffs');
 | 
			
		||||
 | 
			
		||||
@@ -753,7 +751,7 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
    test('reload entire page when patchRange doesnt change', () => {
 | 
			
		||||
      const reloadStub = sandbox.stub(element, '_reload',
 | 
			
		||||
          () => { return Promise.resolve(); });
 | 
			
		||||
          () => Promise.resolve());
 | 
			
		||||
      const collapseStub = sandbox.stub(element.$.fileList, 'collapseAllDiffs');
 | 
			
		||||
      const value = {
 | 
			
		||||
        view: Gerrit.Nav.View.CHANGE,
 | 
			
		||||
@@ -769,11 +767,9 @@ limitations under the License.
 | 
			
		||||
    test('related changes are updated and new patch selected after rebase',
 | 
			
		||||
        done => {
 | 
			
		||||
          element._changeNum = '42';
 | 
			
		||||
          sandbox.stub(element, 'computeLatestPatchNum', () => {
 | 
			
		||||
            return 1;
 | 
			
		||||
          });
 | 
			
		||||
          sandbox.stub(element, 'computeLatestPatchNum', () => 1);
 | 
			
		||||
          sandbox.stub(element, '_reload',
 | 
			
		||||
              () => { return Promise.resolve(); });
 | 
			
		||||
              () => Promise.resolve());
 | 
			
		||||
          const e = {detail: {action: 'rebase'}};
 | 
			
		||||
          element._handleReloadChange(e).then(() => {
 | 
			
		||||
            assert.isTrue(navigateToChangeStub.lastCall.calledWithExactly(
 | 
			
		||||
@@ -783,7 +779,7 @@ limitations under the License.
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    test('related changes are not updated after other action', done => {
 | 
			
		||||
      sandbox.stub(element, '_reload', () => { return Promise.resolve(); });
 | 
			
		||||
      sandbox.stub(element, '_reload', () => Promise.resolve());
 | 
			
		||||
      sandbox.stub(element.$.relatedChanges, 'reload');
 | 
			
		||||
      const e = {detail: {action: 'abandon'}};
 | 
			
		||||
      element._handleReloadChange(e).then(() => {
 | 
			
		||||
@@ -929,14 +925,12 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
    test('topic is coalesced to null', done => {
 | 
			
		||||
      sandbox.stub(element, '_changeChanged');
 | 
			
		||||
      sandbox.stub(element.$.restAPI, 'getChangeDetail', () => {
 | 
			
		||||
        return Promise.resolve({
 | 
			
		||||
          id: '123456789',
 | 
			
		||||
          labels: {},
 | 
			
		||||
          current_revision: 'foo',
 | 
			
		||||
          revisions: {foo: {commit: {}}},
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
      sandbox.stub(element.$.restAPI, 'getChangeDetail', () => Promise.resolve({
 | 
			
		||||
        id: '123456789',
 | 
			
		||||
        labels: {},
 | 
			
		||||
        current_revision: 'foo',
 | 
			
		||||
        revisions: {foo: {commit: {}}},
 | 
			
		||||
      }));
 | 
			
		||||
 | 
			
		||||
      element._getChangeDetail().then(() => {
 | 
			
		||||
        assert.isNull(element._change.topic);
 | 
			
		||||
@@ -946,14 +940,12 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
    test('commit sha is populated from getChangeDetail', done => {
 | 
			
		||||
      sandbox.stub(element, '_changeChanged');
 | 
			
		||||
      sandbox.stub(element.$.restAPI, 'getChangeDetail', () => {
 | 
			
		||||
        return Promise.resolve({
 | 
			
		||||
          id: '123456789',
 | 
			
		||||
          labels: {},
 | 
			
		||||
          current_revision: 'foo',
 | 
			
		||||
          revisions: {foo: {commit: {}}},
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
      sandbox.stub(element.$.restAPI, 'getChangeDetail', () => Promise.resolve({
 | 
			
		||||
        id: '123456789',
 | 
			
		||||
        labels: {},
 | 
			
		||||
        current_revision: 'foo',
 | 
			
		||||
        revisions: {foo: {commit: {}}},
 | 
			
		||||
      }));
 | 
			
		||||
 | 
			
		||||
      element._getChangeDetail().then(() => {
 | 
			
		||||
        assert.equal('foo', element._commitInfo.commit);
 | 
			
		||||
@@ -963,20 +955,16 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
    test('edit is added to change', () => {
 | 
			
		||||
      sandbox.stub(element, '_changeChanged');
 | 
			
		||||
      sandbox.stub(element.$.restAPI, 'getChangeDetail', () => {
 | 
			
		||||
        return Promise.resolve({
 | 
			
		||||
          id: '123456789',
 | 
			
		||||
          labels: {},
 | 
			
		||||
          current_revision: 'foo',
 | 
			
		||||
          revisions: {foo: {commit: {}}},
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
      sandbox.stub(element, '_getEdit', () => {
 | 
			
		||||
        return Promise.resolve({
 | 
			
		||||
          base_patch_set_number: 1,
 | 
			
		||||
          commit: {commit: 'bar'},
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
      sandbox.stub(element.$.restAPI, 'getChangeDetail', () => Promise.resolve({
 | 
			
		||||
        id: '123456789',
 | 
			
		||||
        labels: {},
 | 
			
		||||
        current_revision: 'foo',
 | 
			
		||||
        revisions: {foo: {commit: {}}},
 | 
			
		||||
      }));
 | 
			
		||||
      sandbox.stub(element, '_getEdit', () => Promise.resolve({
 | 
			
		||||
        base_patch_set_number: 1,
 | 
			
		||||
        commit: {commit: 'bar'},
 | 
			
		||||
      }));
 | 
			
		||||
      element._patchRange = {};
 | 
			
		||||
 | 
			
		||||
      return element._getChangeDetail().then(() => {
 | 
			
		||||
@@ -1097,12 +1085,8 @@ limitations under the License.
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('revert dialog opened with revert param', done => {
 | 
			
		||||
      sandbox.stub(element.$.restAPI, 'getLoggedIn', () => {
 | 
			
		||||
        return Promise.resolve(true);
 | 
			
		||||
      });
 | 
			
		||||
      sandbox.stub(Gerrit, 'awaitPluginsLoaded', () => {
 | 
			
		||||
        return Promise.resolve();
 | 
			
		||||
      });
 | 
			
		||||
      sandbox.stub(element.$.restAPI, 'getLoggedIn', () => Promise.resolve(true));
 | 
			
		||||
      sandbox.stub(Gerrit, 'awaitPluginsLoaded', () => Promise.resolve());
 | 
			
		||||
 | 
			
		||||
      element._patchRange = {
 | 
			
		||||
        basePatchNum: 'PARENT',
 | 
			
		||||
@@ -1173,7 +1157,7 @@ limitations under the License.
 | 
			
		||||
      setup(() => {
 | 
			
		||||
        sandbox.stub(element.$.replyDialog, '_draftChanged');
 | 
			
		||||
        sandbox.stub(element.$.replyDialog, 'fetchChangeUpdates',
 | 
			
		||||
            () => { return Promise.resolve({isLatest: true}); });
 | 
			
		||||
            () => Promise.resolve({isLatest: true}));
 | 
			
		||||
        element._change = {labels: {}};
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
@@ -1222,7 +1206,7 @@ limitations under the License.
 | 
			
		||||
    suite('commit message expand/collapse', () => {
 | 
			
		||||
      setup(() => {
 | 
			
		||||
        sandbox.stub(element, 'fetchChangeUpdates',
 | 
			
		||||
            () => { return Promise.resolve({isLatest: false}); });
 | 
			
		||||
            () => Promise.resolve({isLatest: false}));
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      test('commitCollapseToggle hidden for short commit message', () => {
 | 
			
		||||
@@ -1260,7 +1244,7 @@ limitations under the License.
 | 
			
		||||
            sandbox.stub(element, '_getOffsetHeight', () => 50);
 | 
			
		||||
            sandbox.stub(element, '_getScrollHeight', () => 60);
 | 
			
		||||
            sandbox.stub(element, '_getLineHeight', () => 5);
 | 
			
		||||
            sandbox.stub(window, 'matchMedia', () => ({matches: true}));
 | 
			
		||||
            sandbox.stub(window, 'matchMedia', () => { return {matches: true}; });
 | 
			
		||||
            element.$.relatedChanges.dispatchEvent(
 | 
			
		||||
                new CustomEvent('new-section-loaded'));
 | 
			
		||||
            assert.isTrue(element.$.relatedChangesToggle.classList
 | 
			
		||||
@@ -1275,7 +1259,7 @@ limitations under the License.
 | 
			
		||||
            sandbox.stub(element, '_getOffsetHeight', () => 50);
 | 
			
		||||
            sandbox.stub(element, '_getScrollHeight', () => 40);
 | 
			
		||||
            sandbox.stub(element, '_getLineHeight', () => 5);
 | 
			
		||||
            sandbox.stub(window, 'matchMedia', () => ({matches: true}));
 | 
			
		||||
            sandbox.stub(window, 'matchMedia', () => { return {matches: true}; });
 | 
			
		||||
            element.$.relatedChanges.dispatchEvent(
 | 
			
		||||
                new CustomEvent('new-section-loaded'));
 | 
			
		||||
            assert.isFalse(element.$.relatedChangesToggle.classList
 | 
			
		||||
@@ -1285,7 +1269,7 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
      test('relatedChangesToggle functions', () => {
 | 
			
		||||
        sandbox.stub(element, '_getOffsetHeight', () => 50);
 | 
			
		||||
        sandbox.stub(window, 'matchMedia', () => ({matches: false}));
 | 
			
		||||
        sandbox.stub(window, 'matchMedia', () => { return {matches: false}; });
 | 
			
		||||
        element._relatedChangesLoading = false;
 | 
			
		||||
        assert.isTrue(element._relatedChangesCollapsed);
 | 
			
		||||
        assert.isTrue(
 | 
			
		||||
@@ -1299,7 +1283,7 @@ limitations under the License.
 | 
			
		||||
      test('_updateRelatedChangeMaxHeight without commit toggle', () => {
 | 
			
		||||
        sandbox.stub(element, '_getOffsetHeight', () => 50);
 | 
			
		||||
        sandbox.stub(element, '_getLineHeight', () => 12);
 | 
			
		||||
        sandbox.stub(window, 'matchMedia', () => ({matches: false}));
 | 
			
		||||
        sandbox.stub(window, 'matchMedia', () => { return {matches: false}; });
 | 
			
		||||
 | 
			
		||||
        // 50 (existing height) - 30 (extra height) = 20 (adjusted height).
 | 
			
		||||
        // 20 (max existing height)  % 12 (line height) = 6 (remainder).
 | 
			
		||||
@@ -1316,7 +1300,7 @@ limitations under the License.
 | 
			
		||||
        element._latestCommitMessage = _.times(31, String).join('\n');
 | 
			
		||||
        sandbox.stub(element, '_getOffsetHeight', () => 50);
 | 
			
		||||
        sandbox.stub(element, '_getLineHeight', () => 12);
 | 
			
		||||
        sandbox.stub(window, 'matchMedia', () => ({matches: false}));
 | 
			
		||||
        sandbox.stub(window, 'matchMedia', () => { return {matches: false}; });
 | 
			
		||||
 | 
			
		||||
        // 50 (existing height) % 12 (line height) = 2 (remainder).
 | 
			
		||||
        // 50 (existing height)  - 2 (remainder) = 48 (max height to set).
 | 
			
		||||
@@ -1332,7 +1316,7 @@ limitations under the License.
 | 
			
		||||
        element._latestCommitMessage = _.times(31, String).join('\n');
 | 
			
		||||
        sandbox.stub(element, '_getOffsetHeight', () => 50);
 | 
			
		||||
        sandbox.stub(element, '_getLineHeight', () => 12);
 | 
			
		||||
        sandbox.stub(window, 'matchMedia', () => ({matches: true}));
 | 
			
		||||
        sandbox.stub(window, 'matchMedia', () => { return {matches: true}; });
 | 
			
		||||
 | 
			
		||||
        element._updateRelatedChangeMaxHeight();
 | 
			
		||||
 | 
			
		||||
@@ -1383,7 +1367,7 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
        test('_startUpdateCheckTimer up-to-date', () => {
 | 
			
		||||
          sandbox.stub(element, 'fetchChangeUpdates',
 | 
			
		||||
              () => { return Promise.resolve({isLatest: true}); });
 | 
			
		||||
              () => Promise.resolve({isLatest: true}));
 | 
			
		||||
 | 
			
		||||
          element._serverConfig = {change: {update_delay: 12345}};
 | 
			
		||||
 | 
			
		||||
@@ -1394,7 +1378,7 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
        test('_startUpdateCheckTimer out-of-date shows an alert', done => {
 | 
			
		||||
          sandbox.stub(element, 'fetchChangeUpdates',
 | 
			
		||||
              () => { return Promise.resolve({isLatest: false}); });
 | 
			
		||||
              () => Promise.resolve({isLatest: false}));
 | 
			
		||||
          element.addEventListener('show-alert', e => {
 | 
			
		||||
            assert.equal(e.detail.message,
 | 
			
		||||
                'A newer patch set has been uploaded');
 | 
			
		||||
 
 | 
			
		||||
@@ -298,9 +298,7 @@
 | 
			
		||||
        this._filesByPath = filesByPath;
 | 
			
		||||
      }));
 | 
			
		||||
      promises.push(this._getLoggedIn()
 | 
			
		||||
          .then(loggedIn => {
 | 
			
		||||
            return this._loggedIn = loggedIn;
 | 
			
		||||
          })
 | 
			
		||||
          .then(loggedIn => this._loggedIn = loggedIn)
 | 
			
		||||
          .then(loggedIn => {
 | 
			
		||||
            if (!loggedIn) { return; }
 | 
			
		||||
 | 
			
		||||
@@ -1065,30 +1063,28 @@
 | 
			
		||||
 | 
			
		||||
      return (new Promise(resolve => {
 | 
			
		||||
        this.fire('reload-drafts', {resolve});
 | 
			
		||||
      })).then(() => {
 | 
			
		||||
        return this.asyncForeach(paths, (path, cancel) => {
 | 
			
		||||
          this._cancelForEachDiff = cancel;
 | 
			
		||||
      })).then(() => this.asyncForeach(paths, (path, cancel) => {
 | 
			
		||||
        this._cancelForEachDiff = cancel;
 | 
			
		||||
 | 
			
		||||
          iter++;
 | 
			
		||||
          console.log('Expanding diff', iter, 'of', initialCount, ':',
 | 
			
		||||
              path);
 | 
			
		||||
          const diffElem = this._findDiffByPath(path, diffElements);
 | 
			
		||||
          diffElem.comments = this.changeComments.getCommentsBySideForPath(
 | 
			
		||||
              path, this.patchRange, this.projectConfig);
 | 
			
		||||
          const promises = [diffElem.reload()];
 | 
			
		||||
          if (this._loggedIn && !this.diffPrefs.manual_review) {
 | 
			
		||||
            promises.push(this._reviewFile(path, true));
 | 
			
		||||
          }
 | 
			
		||||
          return Promise.all(promises);
 | 
			
		||||
        }).then(() => {
 | 
			
		||||
          this._cancelForEachDiff = null;
 | 
			
		||||
          this._nextRenderParams = null;
 | 
			
		||||
          console.log('Finished expanding', initialCount, 'diff(s)');
 | 
			
		||||
          this.$.reporting.timeEndWithAverage(EXPAND_ALL_TIMING_LABEL,
 | 
			
		||||
              EXPAND_ALL_AVG_TIMING_LABEL, initialCount);
 | 
			
		||||
          this.$.diffCursor.handleDiffUpdate();
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
        iter++;
 | 
			
		||||
        console.log('Expanding diff', iter, 'of', initialCount, ':',
 | 
			
		||||
            path);
 | 
			
		||||
        const diffElem = this._findDiffByPath(path, diffElements);
 | 
			
		||||
        diffElem.comments = this.changeComments.getCommentsBySideForPath(
 | 
			
		||||
            path, this.patchRange, this.projectConfig);
 | 
			
		||||
        const promises = [diffElem.reload()];
 | 
			
		||||
        if (this._loggedIn && !this.diffPrefs.manual_review) {
 | 
			
		||||
          promises.push(this._reviewFile(path, true));
 | 
			
		||||
        }
 | 
			
		||||
        return Promise.all(promises);
 | 
			
		||||
      }).then(() => {
 | 
			
		||||
        this._cancelForEachDiff = null;
 | 
			
		||||
        this._nextRenderParams = null;
 | 
			
		||||
        console.log('Finished expanding', initialCount, 'diff(s)');
 | 
			
		||||
        this.$.reporting.timeEndWithAverage(EXPAND_ALL_TIMING_LABEL,
 | 
			
		||||
            EXPAND_ALL_AVG_TIMING_LABEL, initialCount);
 | 
			
		||||
        this.$.diffCursor.handleDiffUpdate();
 | 
			
		||||
      }));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** Cancel the rendering work of every diff in the list */
 | 
			
		||||
@@ -1143,9 +1139,9 @@
 | 
			
		||||
      // comments due to use in the _handleCommentUpdate function.
 | 
			
		||||
      // The comment thread already has a side associated with it, so
 | 
			
		||||
      // set the comment's side to match.
 | 
			
		||||
      threadEl.comments = newComments.map(c => {
 | 
			
		||||
        return Object.assign(c, {__commentSide: threadEl.commentSide});
 | 
			
		||||
      });
 | 
			
		||||
      threadEl.comments = newComments.map(c => Object.assign(
 | 
			
		||||
          c, {__commentSide: threadEl.commentSide}
 | 
			
		||||
      ));
 | 
			
		||||
      Polymer.dom.flush();
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -115,7 +115,7 @@ limitations under the License.
 | 
			
		||||
        patchNum: '2',
 | 
			
		||||
      };
 | 
			
		||||
      saveStub = sandbox.stub(element, '_saveReviewedState',
 | 
			
		||||
          () => { return Promise.resolve(); });
 | 
			
		||||
          () => Promise.resolve());
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    teardown(() => {
 | 
			
		||||
@@ -1477,9 +1477,7 @@ limitations under the License.
 | 
			
		||||
        basePatchNum: 'PARENT',
 | 
			
		||||
        patchNum: '2',
 | 
			
		||||
      };
 | 
			
		||||
      sandbox.stub(window, 'fetch', () => {
 | 
			
		||||
        return Promise.resolve();
 | 
			
		||||
      });
 | 
			
		||||
      sandbox.stub(window, 'fetch', () => Promise.resolve());
 | 
			
		||||
      flushAsynchronousOperations();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -115,9 +115,7 @@
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const orderedValues = Object.keys(values).sort((a, b) => {
 | 
			
		||||
        return a - b;
 | 
			
		||||
      });
 | 
			
		||||
      const orderedValues = Object.keys(values).sort((a, b) => a - b);
 | 
			
		||||
 | 
			
		||||
      for (let i = 0; i < orderedValues.length; i++) {
 | 
			
		||||
        values[orderedValues[i]] = i;
 | 
			
		||||
 
 | 
			
		||||
@@ -207,7 +207,7 @@
 | 
			
		||||
      return scoresRaw.split(' ')
 | 
			
		||||
          .map(s => s.match(LABEL_TITLE_SCORE_PATTERN))
 | 
			
		||||
          .filter(ms => ms && ms.length === 3)
 | 
			
		||||
          .map(ms => ({label: ms[1], value: ms[2]}));
 | 
			
		||||
          .map(ms => { return {label: ms[1], value: ms[2]}; });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _computeScoreClass(score, labelExtremes) {
 | 
			
		||||
 
 | 
			
		||||
@@ -324,9 +324,7 @@
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _getHumanMessages(messages) {
 | 
			
		||||
      return messages.filter(msg => {
 | 
			
		||||
        return !this._isAutomated(msg);
 | 
			
		||||
      });
 | 
			
		||||
      return messages.filter(msg => !this._isAutomated(msg));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _computeShowHideTextHidden(visibleMessages, messages,
 | 
			
		||||
 
 | 
			
		||||
@@ -354,7 +354,7 @@
 | 
			
		||||
          changeRevision = rev;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      const commits = relatedChanges.map(c => { return c.commit; });
 | 
			
		||||
      const commits = relatedChanges.map(c => c.commit);
 | 
			
		||||
      let pos = commits.length - 1;
 | 
			
		||||
 | 
			
		||||
      while (pos >= 0) {
 | 
			
		||||
 
 | 
			
		||||
@@ -136,23 +136,24 @@ limitations under the License.
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    function stubSaveReview(jsonResponseProducer) {
 | 
			
		||||
      return sandbox.stub(element, '_saveReview', review => {
 | 
			
		||||
        return new Promise((resolve, reject) => {
 | 
			
		||||
          try {
 | 
			
		||||
            const result = jsonResponseProducer(review) || {};
 | 
			
		||||
            const resultStr =
 | 
			
		||||
                element.$.restAPI.JSON_PREFIX + JSON.stringify(result);
 | 
			
		||||
            resolve({
 | 
			
		||||
              ok: true,
 | 
			
		||||
              text() {
 | 
			
		||||
                return Promise.resolve(resultStr);
 | 
			
		||||
              },
 | 
			
		||||
            });
 | 
			
		||||
          } catch (err) {
 | 
			
		||||
            reject(err);
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
      return sandbox.stub(
 | 
			
		||||
          element,
 | 
			
		||||
          '_saveReview',
 | 
			
		||||
          review => new Promise((resolve, reject) => {
 | 
			
		||||
            try {
 | 
			
		||||
              const result = jsonResponseProducer(review) || {};
 | 
			
		||||
              const resultStr =
 | 
			
		||||
              element.$.restAPI.JSON_PREFIX + JSON.stringify(result);
 | 
			
		||||
              resolve({
 | 
			
		||||
                ok: true,
 | 
			
		||||
                text() {
 | 
			
		||||
                  return Promise.resolve(resultStr);
 | 
			
		||||
                },
 | 
			
		||||
              });
 | 
			
		||||
            } catch (err) {
 | 
			
		||||
              reject(err);
 | 
			
		||||
            }
 | 
			
		||||
          }));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    test('default to publishing drafts with reply', done => {
 | 
			
		||||
@@ -379,7 +380,8 @@ limitations under the License.
 | 
			
		||||
            observer = overlayObserver('closed');
 | 
			
		||||
            const expected = 'Group name has 10 members';
 | 
			
		||||
            assert.notEqual(
 | 
			
		||||
                element.$.reviewerConfirmationOverlay.innerText.indexOf(expected),
 | 
			
		||||
                element.$.reviewerConfirmationOverlay.innerText
 | 
			
		||||
                    .indexOf(expected),
 | 
			
		||||
                -1);
 | 
			
		||||
            MockInteractions.tap(noButton); // close the overlay
 | 
			
		||||
            return observer;
 | 
			
		||||
@@ -982,9 +984,10 @@ limitations under the License.
 | 
			
		||||
      let startReviewStub;
 | 
			
		||||
 | 
			
		||||
      setup(() => {
 | 
			
		||||
        startReviewStub = sandbox.stub(element.$.restAPI, 'startReview', () => {
 | 
			
		||||
          return Promise.resolve();
 | 
			
		||||
        });
 | 
			
		||||
        startReviewStub = sandbox.stub(
 | 
			
		||||
            element.$.restAPI,
 | 
			
		||||
            'startReview',
 | 
			
		||||
            () => Promise.resolve());
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      test('ready property in review input on start review', () => {
 | 
			
		||||
 
 | 
			
		||||
@@ -102,10 +102,12 @@
 | 
			
		||||
     */
 | 
			
		||||
    _permittedLabelsToNumericScores(labels) {
 | 
			
		||||
      if (!labels) return [];
 | 
			
		||||
      return Object.keys(labels).map(label => ({
 | 
			
		||||
        label,
 | 
			
		||||
        scores: labels[label].map(v => parseInt(v, 10)),
 | 
			
		||||
      }));
 | 
			
		||||
      return Object.keys(labels).map(label => {
 | 
			
		||||
        return {
 | 
			
		||||
          label,
 | 
			
		||||
          scores: labels[label].map(v => parseInt(v, 10)),
 | 
			
		||||
        };
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -116,10 +118,12 @@
 | 
			
		||||
     */
 | 
			
		||||
    _getMaxPermittedScores(change) {
 | 
			
		||||
      return this._permittedLabelsToNumericScores(change.permitted_labels)
 | 
			
		||||
          .map(({label, scores}) => ({
 | 
			
		||||
            [label]: scores
 | 
			
		||||
                .map(v => parseInt(v, 10))
 | 
			
		||||
                .reduce((a, b) => Math.max(a, b))}))
 | 
			
		||||
          .map(({label, scores}) => {
 | 
			
		||||
            return {
 | 
			
		||||
              [label]: scores
 | 
			
		||||
                  .map(v => parseInt(v, 10))
 | 
			
		||||
                  .reduce((a, b) => Math.max(a, b))};
 | 
			
		||||
          })
 | 
			
		||||
          .reduce((acc, i) => Object.assign(acc, i), {});
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -189,9 +193,8 @@
 | 
			
		||||
          result = result.concat(reviewers[key]);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      this._reviewers = result.filter(reviewer => {
 | 
			
		||||
        return reviewer._account_id != owner._account_id;
 | 
			
		||||
      });
 | 
			
		||||
      this._reviewers = result
 | 
			
		||||
          .filter(reviewer => reviewer._account_id != owner._account_id);
 | 
			
		||||
 | 
			
		||||
      // If there is one or two more than the max reviewers, don't show the
 | 
			
		||||
      // 'show more' button, because it takes up just as much space.
 | 
			
		||||
 
 | 
			
		||||
@@ -102,9 +102,9 @@
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _interpolateUrl(url, replacements) {
 | 
			
		||||
      return url.replace(INTERPOLATE_URL_PATTERN, (match, p1) => {
 | 
			
		||||
        return replacements[p1] || '';
 | 
			
		||||
      });
 | 
			
		||||
      return url.replace(
 | 
			
		||||
          INTERPOLATE_URL_PATTERN,
 | 
			
		||||
          (match, p1) => replacements[p1] || '');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _accountName(account) {
 | 
			
		||||
 
 | 
			
		||||
@@ -107,7 +107,7 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
      test('show normal Error', done => {
 | 
			
		||||
        const showErrorStub = sandbox.stub(element, '_showErrorDialog');
 | 
			
		||||
        const textSpy = sandbox.spy(() => { return Promise.resolve('ZOMG'); });
 | 
			
		||||
        const textSpy = sandbox.spy(() => Promise.resolve('ZOMG'));
 | 
			
		||||
        element.fire('server-error', {response: {status: 500, text: textSpy}});
 | 
			
		||||
 | 
			
		||||
        assert.isTrue(textSpy.called);
 | 
			
		||||
@@ -129,8 +129,9 @@ limitations under the License.
 | 
			
		||||
            'Error 409');
 | 
			
		||||
        assert.equal(element._constructServerErrorMsg({status, url}),
 | 
			
		||||
            'Error 409: \nEndpoint: /my/test/url');
 | 
			
		||||
        assert.equal(element._constructServerErrorMsg({status, statusText, url}),
 | 
			
		||||
            'Error 409 (Conflict): \nEndpoint: /my/test/url');
 | 
			
		||||
        assert.equal(element.
 | 
			
		||||
            _constructServerErrorMsg({status, statusText, url}),
 | 
			
		||||
        'Error 409 (Conflict): \nEndpoint: /my/test/url');
 | 
			
		||||
        assert.equal(element._constructServerErrorMsg({
 | 
			
		||||
          status,
 | 
			
		||||
          statusText,
 | 
			
		||||
@@ -142,9 +143,9 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
      test('suppress TOO_MANY_FILES error', done => {
 | 
			
		||||
        const showAlertStub = sandbox.stub(element, '_showAlert');
 | 
			
		||||
        const textSpy = sandbox.spy(() => {
 | 
			
		||||
          return Promise.resolve('too many files to find conflicts');
 | 
			
		||||
        });
 | 
			
		||||
        const textSpy = sandbox.spy(
 | 
			
		||||
            () => Promise.resolve('too many files to find conflicts')
 | 
			
		||||
        );
 | 
			
		||||
        element.fire('server-error', {response: {status: 500, text: textSpy}});
 | 
			
		||||
 | 
			
		||||
        assert.isTrue(textSpy.called);
 | 
			
		||||
@@ -172,7 +173,7 @@ limitations under the License.
 | 
			
		||||
        // starts with authed state
 | 
			
		||||
        element.$.restAPI.getLoggedIn();
 | 
			
		||||
        const refreshStub = sandbox.stub(element.$.restAPI, 'getAccount',
 | 
			
		||||
            () => { return Promise.resolve({}); });
 | 
			
		||||
            () => Promise.resolve({}));
 | 
			
		||||
        const toastSpy = sandbox.spy(element, '_createToastAlert');
 | 
			
		||||
        const windowOpen = sandbox.stub(window, 'open');
 | 
			
		||||
        const responseText = Promise.resolve('Authentication required\n');
 | 
			
		||||
@@ -297,7 +298,10 @@ limitations under the License.
 | 
			
		||||
      test('show-error', () => {
 | 
			
		||||
        const openStub = sandbox.stub(element.$.errorOverlay, 'open');
 | 
			
		||||
        const closeStub = sandbox.stub(element.$.errorOverlay, 'close');
 | 
			
		||||
        const reportStub = sandbox.stub(element.$.reporting, 'reportErrorDialog');
 | 
			
		||||
        const reportStub = sandbox.stub(
 | 
			
		||||
            element.$.reporting,
 | 
			
		||||
            'reportErrorDialog'
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        const message = 'test message';
 | 
			
		||||
        element.fire('show-error', {message});
 | 
			
		||||
@@ -317,7 +321,9 @@ limitations under the License.
 | 
			
		||||
        const accountPromise = Promise.resolve({_account_id: 1234});
 | 
			
		||||
        sandbox.stub(element.$.restAPI, 'getAccount')
 | 
			
		||||
            .returns(accountPromise);
 | 
			
		||||
        const requestCheckStub = sandbox.stub(element, '_requestCheckLoggedIn');
 | 
			
		||||
        const requestCheckStub = sandbox.stub(
 | 
			
		||||
            element,
 | 
			
		||||
            '_requestCheckLoggedIn');
 | 
			
		||||
        const handleRefreshStub = sandbox.stub(element,
 | 
			
		||||
            '_handleCredentialRefreshed');
 | 
			
		||||
        const reloadStub = sandbox.stub(element, '_reloadPage');
 | 
			
		||||
@@ -344,7 +350,9 @@ limitations under the License.
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      test('refresh loop continues on credential fail', done => {
 | 
			
		||||
        const requestCheckStub = sandbox.stub(element, '_requestCheckLoggedIn');
 | 
			
		||||
        const requestCheckStub = sandbox.stub(
 | 
			
		||||
            element,
 | 
			
		||||
            '_requestCheckLoggedIn');
 | 
			
		||||
        const handleRefreshStub = sandbox.stub(element,
 | 
			
		||||
            '_handleCredentialRefreshed');
 | 
			
		||||
        const reloadStub = sandbox.stub(element, '_reloadPage');
 | 
			
		||||
 
 | 
			
		||||
@@ -231,10 +231,10 @@
 | 
			
		||||
      const topMenuLinks = [];
 | 
			
		||||
      links.forEach(link => { topMenuLinks[link.title] = link.links; });
 | 
			
		||||
      for (const m of topMenus) {
 | 
			
		||||
        const items = m.items.map(this._fixCustomMenuItem).filter(link => {
 | 
			
		||||
        const items = m.items.map(this._fixCustomMenuItem).filter(link =>
 | 
			
		||||
          // Ignore GWT project links
 | 
			
		||||
          return !link.url.includes('${projectName}');
 | 
			
		||||
        });
 | 
			
		||||
          !link.url.includes('${projectName}')
 | 
			
		||||
        );
 | 
			
		||||
        if (m.name in topMenuLinks) {
 | 
			
		||||
          items.forEach(link => { topMenuLinks[m.name].push(link); });
 | 
			
		||||
        } else {
 | 
			
		||||
 
 | 
			
		||||
@@ -74,7 +74,7 @@ limitations under the License.
 | 
			
		||||
    test('_getChangeWeblinks', () => {
 | 
			
		||||
      const link = {name: 'test', url: 'test/url'};
 | 
			
		||||
      const browserLink = {name: 'browser', url: 'browser/url'};
 | 
			
		||||
      const mapLinksToConfig = weblinks => ({options: {weblinks}});
 | 
			
		||||
      const mapLinksToConfig = weblinks => { return {options: {weblinks}}; };
 | 
			
		||||
      sandbox.stub(element, '_getBrowseCommitWeblink').returns(browserLink);
 | 
			
		||||
 | 
			
		||||
      assert.deepEqual(
 | 
			
		||||
 
 | 
			
		||||
@@ -200,9 +200,7 @@
 | 
			
		||||
      const trimmedInput = this._inputVal && this._inputVal.trim();
 | 
			
		||||
      if (trimmedInput) {
 | 
			
		||||
        const predefinedOpOnlyQuery = SEARCH_OPERATORS_WITH_NEGATIONS.some(
 | 
			
		||||
            op => {
 | 
			
		||||
              return op.endsWith(':') && op === trimmedInput;
 | 
			
		||||
            }
 | 
			
		||||
            op => op.endsWith(':') && op === trimmedInput
 | 
			
		||||
        );
 | 
			
		||||
        if (predefinedOpOnlyQuery) {
 | 
			
		||||
          return;
 | 
			
		||||
@@ -252,7 +250,7 @@
 | 
			
		||||
        default:
 | 
			
		||||
          return Promise.resolve(SEARCH_OPERATORS_WITH_NEGATIONS
 | 
			
		||||
              .filter(operator => operator.includes(input))
 | 
			
		||||
              .map(operator => ({text: operator})));
 | 
			
		||||
              .map(operator => { return {text: operator}; }));
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -59,11 +59,9 @@ limitations under the License.
 | 
			
		||||
      assert.equal(element._inputVal, 'foo');
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    getActiveElement = () => {
 | 
			
		||||
      return document.activeElement.shadowRoot ?
 | 
			
		||||
        document.activeElement.shadowRoot.activeElement :
 | 
			
		||||
        document.activeElement;
 | 
			
		||||
    };
 | 
			
		||||
    getActiveElement = () => (document.activeElement.shadowRoot ?
 | 
			
		||||
      document.activeElement.shadowRoot.activeElement :
 | 
			
		||||
      document.activeElement);
 | 
			
		||||
 | 
			
		||||
    test('enter in search input fires event', done => {
 | 
			
		||||
      element.addEventListener('handle-search', () => {
 | 
			
		||||
 
 | 
			
		||||
@@ -91,7 +91,7 @@
 | 
			
		||||
          .then(projects => {
 | 
			
		||||
            if (!projects) { return []; }
 | 
			
		||||
            const keys = Object.keys(projects);
 | 
			
		||||
            return keys.map(key => ({text: predicate + ':' + key}));
 | 
			
		||||
            return keys.map(key => { return {text: predicate + ':' + key}; });
 | 
			
		||||
          });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -113,7 +113,7 @@
 | 
			
		||||
          .then(groups => {
 | 
			
		||||
            if (!groups) { return []; }
 | 
			
		||||
            const keys = Object.keys(groups);
 | 
			
		||||
            return keys.map(key => ({text: predicate + ':' + key}));
 | 
			
		||||
            return keys.map(key => { return {text: predicate + ':' + key}; });
 | 
			
		||||
          });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -151,12 +151,14 @@
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _mapAccountsHelper(accounts, predicate) {
 | 
			
		||||
      return accounts.map(account => ({
 | 
			
		||||
        label: account.name || '',
 | 
			
		||||
        text: account.email ?
 | 
			
		||||
          `${predicate}:${account.email}` :
 | 
			
		||||
          `${predicate}:"${this._accountOrAnon(account)}"`,
 | 
			
		||||
      }));
 | 
			
		||||
      return accounts.map(account => {
 | 
			
		||||
        return {
 | 
			
		||||
          label: account.name || '',
 | 
			
		||||
          text: account.email ?
 | 
			
		||||
            `${predicate}:${account.email}` :
 | 
			
		||||
            `${predicate}:"${this._accountOrAnon(account)}"`,
 | 
			
		||||
        };
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -85,8 +85,9 @@
 | 
			
		||||
          .getRobotCommentFixPreview(this.changeNum, this._patchNum, fixId)
 | 
			
		||||
          .then(res => {
 | 
			
		||||
            if (res != null) {
 | 
			
		||||
              const previews = Object.keys(res).map(key =>
 | 
			
		||||
                ({filepath: key, preview: res[key]}));
 | 
			
		||||
              const previews = Object.keys(res).map(key => {
 | 
			
		||||
                return {filepath: key, preview: res[key]};
 | 
			
		||||
              });
 | 
			
		||||
              this._currentPreviews = previews;
 | 
			
		||||
            }
 | 
			
		||||
          })
 | 
			
		||||
 
 | 
			
		||||
@@ -39,9 +39,7 @@
 | 
			
		||||
     * file simpler by just using _reloadComments here instead.
 | 
			
		||||
     */
 | 
			
		||||
    _reloadDraftsWithCallback(e) {
 | 
			
		||||
      return this._reloadComments().then(() => {
 | 
			
		||||
        return e.detail.resolve();
 | 
			
		||||
      });
 | 
			
		||||
      return this._reloadComments().then(() => e.detail.resolve());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _reloadComments() {
 | 
			
		||||
 
 | 
			
		||||
@@ -362,9 +362,10 @@
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  ChangeComments.prototype._sortComments = function(comments) {
 | 
			
		||||
    return comments.slice(0).sort((c1, c2) => {
 | 
			
		||||
      return util.parseDate(c1.updated) - util.parseDate(c2.updated);
 | 
			
		||||
    });
 | 
			
		||||
    return comments.slice(0)
 | 
			
		||||
        .sort(
 | 
			
		||||
            (c1, c2) => util.parseDate(c1.updated) - util.parseDate(c2.updated)
 | 
			
		||||
        );
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
 
 | 
			
		||||
@@ -230,7 +230,7 @@
 | 
			
		||||
  GrDiffBuilder.prototype.getSectionsByLineRange = function(
 | 
			
		||||
      startLine, endLine, opt_side) {
 | 
			
		||||
    return this.getGroupsByLineRange(startLine, endLine, opt_side).map(
 | 
			
		||||
        group => { return group.element; });
 | 
			
		||||
        group => group.element);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  GrDiffBuilder.prototype._createContextControl = function(section, line) {
 | 
			
		||||
 
 | 
			
		||||
@@ -812,9 +812,8 @@ limitations under the License.
 | 
			
		||||
          sandbox.stub(builder, 'addColumns');
 | 
			
		||||
          builder.buildSectionElement = function(group) {
 | 
			
		||||
            const section = document.createElement('stub');
 | 
			
		||||
            section.textContent = group.lines.reduce((acc, line) => {
 | 
			
		||||
              return acc + line.text;
 | 
			
		||||
            }, '');
 | 
			
		||||
            section.textContent = group.lines
 | 
			
		||||
                .reduce((acc, line) => acc + line.text, '');
 | 
			
		||||
            return section;
 | 
			
		||||
          };
 | 
			
		||||
          return builder;
 | 
			
		||||
@@ -859,7 +858,7 @@ limitations under the License.
 | 
			
		||||
        const dispatchEventStub = sandbox.stub(element, 'dispatchEvent');
 | 
			
		||||
        element.render(keyLocations, {}).then(() => {
 | 
			
		||||
          const firedEventTypes = dispatchEventStub.getCalls()
 | 
			
		||||
              .map(c => { return c.args[0].type; });
 | 
			
		||||
              .map(c => c.args[0].type);
 | 
			
		||||
          assert.include(firedEventTypes, 'render-start');
 | 
			
		||||
          assert.include(firedEventTypes, 'render-content');
 | 
			
		||||
          done();
 | 
			
		||||
 
 | 
			
		||||
@@ -165,9 +165,7 @@
 | 
			
		||||
 | 
			
		||||
    moveToNextChunk(opt_clipToTop) {
 | 
			
		||||
      this.$.cursorManager.next(this._isFirstRowOfChunk.bind(this),
 | 
			
		||||
          target => {
 | 
			
		||||
            return target.parentNode.scrollHeight;
 | 
			
		||||
          }, opt_clipToTop);
 | 
			
		||||
          target => target.parentNode.scrollHeight, opt_clipToTop);
 | 
			
		||||
      this._fixSide();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -273,9 +271,8 @@
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    createCommentInPlace() {
 | 
			
		||||
      const diffWithRangeSelected = this.diffs.find(diff => {
 | 
			
		||||
        return diff.isRangeSelected();
 | 
			
		||||
      });
 | 
			
		||||
      const diffWithRangeSelected = this.diffs
 | 
			
		||||
          .find(diff => diff.isRangeSelected());
 | 
			
		||||
      if (diffWithRangeSelected) {
 | 
			
		||||
        diffWithRangeSelected.createRangeComment();
 | 
			
		||||
      } else {
 | 
			
		||||
@@ -404,9 +401,7 @@
 | 
			
		||||
 | 
			
		||||
    _getStops() {
 | 
			
		||||
      return this.diffs.reduce(
 | 
			
		||||
          (stops, diff) => {
 | 
			
		||||
            return stops.concat(diff.getCursorStops());
 | 
			
		||||
          }, []);
 | 
			
		||||
          (stops, diff) => stops.concat(diff.getCursorStops()), []);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _updateStops() {
 | 
			
		||||
 
 | 
			
		||||
@@ -123,9 +123,8 @@ limitations under the License.
 | 
			
		||||
        element.comments.left.push(comment);
 | 
			
		||||
        comment.id = id;
 | 
			
		||||
        element.fire('comment-discard', {comment});
 | 
			
		||||
        const drafts = element.comments.left.filter(item => {
 | 
			
		||||
          return item.__draftID === draftID;
 | 
			
		||||
        });
 | 
			
		||||
        const drafts = element.comments.left
 | 
			
		||||
            .filter(item => item.__draftID === draftID);
 | 
			
		||||
        assert.equal(drafts.length, 0);
 | 
			
		||||
        assert.isTrue(diffCommentsModifiedStub.called);
 | 
			
		||||
      });
 | 
			
		||||
@@ -145,9 +144,8 @@ limitations under the License.
 | 
			
		||||
        element.comments.left.push(comment);
 | 
			
		||||
        comment.id = id;
 | 
			
		||||
        element.fire('comment-save', {comment});
 | 
			
		||||
        const drafts = element.comments.left.filter(item => {
 | 
			
		||||
          return item.__draftID === draftID;
 | 
			
		||||
        });
 | 
			
		||||
        const drafts = element.comments.left
 | 
			
		||||
            .filter(item => item.__draftID === draftID);
 | 
			
		||||
        assert.equal(drafts.length, 1);
 | 
			
		||||
        assert.equal(drafts[0].id, id);
 | 
			
		||||
        assert.isTrue(diffCommentsModifiedStub.called);
 | 
			
		||||
@@ -508,10 +506,10 @@ limitations under the License.
 | 
			
		||||
          };
 | 
			
		||||
          sandbox.stub(element.$.restAPI,
 | 
			
		||||
              'getB64FileContents',
 | 
			
		||||
              (changeId, patchNum, path, opt_parentIndex) => {
 | 
			
		||||
                return Promise.resolve(opt_parentIndex === 1 ? mockFile1 :
 | 
			
		||||
                  mockFile2);
 | 
			
		||||
              });
 | 
			
		||||
              (changeId, patchNum, path, opt_parentIndex) => Promise.resolve(
 | 
			
		||||
                  opt_parentIndex === 1 ? mockFile1 :
 | 
			
		||||
                    mockFile2)
 | 
			
		||||
          );
 | 
			
		||||
 | 
			
		||||
          element.patchRange = {basePatchNum: 'PARENT', patchNum: 1};
 | 
			
		||||
          element.comments = {
 | 
			
		||||
@@ -1382,7 +1380,8 @@ limitations under the License.
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      test('starts syntax layer processing on render event', done => {
 | 
			
		||||
        sandbox.stub(element.$.syntaxLayer, 'process').returns(Promise.resolve());
 | 
			
		||||
        sandbox.stub(element.$.syntaxLayer, 'process')
 | 
			
		||||
            .returns(Promise.resolve());
 | 
			
		||||
        sandbox.stub(element.$.restAPI, 'getDiff').returns(
 | 
			
		||||
            Promise.resolve({content: []}));
 | 
			
		||||
        element.reload();
 | 
			
		||||
 
 | 
			
		||||
@@ -500,7 +500,7 @@ limitations under the License.
 | 
			
		||||
      test('breaks down shared chunks w/ whole-file', () => {
 | 
			
		||||
        const size = 120 * 2 + 5;
 | 
			
		||||
        const content = [{
 | 
			
		||||
          ab: _.times(size, () => { return `${Math.random()}`; }),
 | 
			
		||||
          ab: _.times(size, () => `${Math.random()}`),
 | 
			
		||||
        }];
 | 
			
		||||
        element.context = -1;
 | 
			
		||||
        const result = element._splitLargeChunks(content);
 | 
			
		||||
@@ -511,7 +511,7 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
      test('does not break-down common chunks w/ context', () => {
 | 
			
		||||
        const content = [{
 | 
			
		||||
          ab: _.times(75, () => { return `${Math.random()}`; }),
 | 
			
		||||
          ab: _.times(75, () => `${Math.random()}`),
 | 
			
		||||
        }];
 | 
			
		||||
        element.context = 4;
 | 
			
		||||
        const result =
 | 
			
		||||
@@ -897,7 +897,7 @@ limitations under the License.
 | 
			
		||||
            assert.isAtMost(subResult.length, size);
 | 
			
		||||
          }
 | 
			
		||||
          const flattened = result
 | 
			
		||||
              .reduce((a, b) => { return a.concat(b); }, []);
 | 
			
		||||
              .reduce((a, b) => a.concat(b), []);
 | 
			
		||||
          assert.deepEqual(flattened, array);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -169,7 +169,7 @@
 | 
			
		||||
        },
 | 
			
		||||
        _panelFloatingDisabled: {
 | 
			
		||||
          type: Boolean,
 | 
			
		||||
          value: () => { return window.PANEL_FLOATING_DISABLED; },
 | 
			
		||||
          value: () => window.PANEL_FLOATING_DISABLED,
 | 
			
		||||
        },
 | 
			
		||||
        _editMode: {
 | 
			
		||||
          type: Boolean,
 | 
			
		||||
 
 | 
			
		||||
@@ -281,8 +281,11 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
      MockInteractions.pressAndReleaseKeyOn(element, 219, null, '[');
 | 
			
		||||
      assert.isTrue(element._loading);
 | 
			
		||||
      assert(diffNavStub.lastCall.calledWithExactly(element._change, 'chell.go',
 | 
			
		||||
          '10', '5'),
 | 
			
		||||
      assert(diffNavStub.lastCall.calledWithExactly(
 | 
			
		||||
          element._change,
 | 
			
		||||
          'chell.go',
 | 
			
		||||
          '10',
 | 
			
		||||
          '5'),
 | 
			
		||||
      'Should navigate to /c/42/5..10/chell.go');
 | 
			
		||||
      element._path = 'chell.go';
 | 
			
		||||
 | 
			
		||||
@@ -342,8 +345,11 @@ limitations under the License.
 | 
			
		||||
      element._path = 'glados.txt';
 | 
			
		||||
 | 
			
		||||
      MockInteractions.pressAndReleaseKeyOn(element, 219, null, '[');
 | 
			
		||||
      assert(diffNavStub.lastCall.calledWithExactly(element._change, 'chell.go',
 | 
			
		||||
          '1', PARENT), 'Should navigate to /c/42/1/chell.go');
 | 
			
		||||
      assert(diffNavStub.lastCall.calledWithExactly(
 | 
			
		||||
          element._change,
 | 
			
		||||
          'chell.go',
 | 
			
		||||
          '1',
 | 
			
		||||
          PARENT), 'Should navigate to /c/42/1/chell.go');
 | 
			
		||||
      element._path = 'chell.go';
 | 
			
		||||
 | 
			
		||||
      MockInteractions.pressAndReleaseKeyOn(element, 219, null, '[');
 | 
			
		||||
@@ -429,12 +435,14 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
    suite('url params', () => {
 | 
			
		||||
      setup(() => {
 | 
			
		||||
        sandbox.stub(Gerrit.Nav, 'getUrlForDiff', (c, p, pn, bpn) => {
 | 
			
		||||
          return `${c._number}-${p}-${pn}-${bpn}`;
 | 
			
		||||
        });
 | 
			
		||||
        sandbox.stub(Gerrit.Nav, 'getUrlForChange', (c, pn, bpn) => {
 | 
			
		||||
          return `${c._number}-${pn}-${bpn}`;
 | 
			
		||||
        });
 | 
			
		||||
        sandbox.stub(
 | 
			
		||||
            Gerrit.Nav,
 | 
			
		||||
            'getUrlForDiff',
 | 
			
		||||
            (c, p, pn, bpn) => `${c._number}-${p}-${pn}-${bpn}`);
 | 
			
		||||
        sandbox.stub(
 | 
			
		||||
            Gerrit.Nav
 | 
			
		||||
            , 'getUrlForChange',
 | 
			
		||||
            (c, pn, bpn) => `${c._number}-${pn}-${bpn}`);
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      test('_formattedFiles', () => {
 | 
			
		||||
 
 | 
			
		||||
@@ -374,10 +374,11 @@
 | 
			
		||||
          .map(commentRangeFromThreadEl)
 | 
			
		||||
          .filter(({range}) => range);
 | 
			
		||||
      for (const removedCommentRange of removedCommentRanges) {
 | 
			
		||||
        const i = this._commentRanges.findIndex(commentRange => {
 | 
			
		||||
          return commentRange.side === removedCommentRange.side &&
 | 
			
		||||
              Gerrit.rangesEqual(commentRange.range, removedCommentRange.range);
 | 
			
		||||
        });
 | 
			
		||||
        const i = this._commentRanges
 | 
			
		||||
            .findIndex(
 | 
			
		||||
                cr => cr.side === removedCommentRange.side &&
 | 
			
		||||
              Gerrit.rangesEqual(cr.range, removedCommentRange.range)
 | 
			
		||||
            );
 | 
			
		||||
        this.splice('_commentRanges', i, 1);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@@ -584,7 +585,7 @@
 | 
			
		||||
     * @param {string=} side
 | 
			
		||||
     * @param {!Object=} range
 | 
			
		||||
     */
 | 
			
		||||
    _createComment(lineEl, lineNum=undefined, side=undefined, range=undefined) {
 | 
			
		||||
    _createComment(lineEl, lineNum, side, range) {
 | 
			
		||||
      const contentText = this.$.diffBuilder.getContentByLineEl(lineEl);
 | 
			
		||||
      const contentEl = contentText.parentElement;
 | 
			
		||||
      side = side ||
 | 
			
		||||
@@ -870,13 +871,12 @@
 | 
			
		||||
    _computeDiffHeaderItems(diffInfoRecord) {
 | 
			
		||||
      const diffInfo = diffInfoRecord.base;
 | 
			
		||||
      if (!diffInfo || !diffInfo.diff_header) { return []; }
 | 
			
		||||
      return diffInfo.diff_header.filter(item => {
 | 
			
		||||
        return !(item.startsWith('diff --git ') ||
 | 
			
		||||
      return diffInfo.diff_header
 | 
			
		||||
          .filter(item => !(item.startsWith('diff --git ') ||
 | 
			
		||||
            item.startsWith('index ') ||
 | 
			
		||||
            item.startsWith('+++ ') ||
 | 
			
		||||
            item.startsWith('--- ') ||
 | 
			
		||||
            item === 'Binary files differ');
 | 
			
		||||
      });
 | 
			
		||||
            item === 'Binary files differ'));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** @return {boolean} */
 | 
			
		||||
 
 | 
			
		||||
@@ -271,39 +271,37 @@
 | 
			
		||||
      const rangesCache = new Map();
 | 
			
		||||
 | 
			
		||||
      this._processPromise = util.makeCancelable(this._loadHLJS()
 | 
			
		||||
          .then(() => {
 | 
			
		||||
            return new Promise(resolve => {
 | 
			
		||||
              const nextStep = () => {
 | 
			
		||||
                this._processHandle = null;
 | 
			
		||||
                this._processNextLine(state, rangesCache);
 | 
			
		||||
          .then(() => new Promise(resolve => {
 | 
			
		||||
            const nextStep = () => {
 | 
			
		||||
              this._processHandle = null;
 | 
			
		||||
              this._processNextLine(state, rangesCache);
 | 
			
		||||
 | 
			
		||||
                // Move to the next line in the section.
 | 
			
		||||
                state.lineIndex++;
 | 
			
		||||
              // Move to the next line in the section.
 | 
			
		||||
              state.lineIndex++;
 | 
			
		||||
 | 
			
		||||
                // If the section has been exhausted, move to the next one.
 | 
			
		||||
                if (this._isSectionDone(state)) {
 | 
			
		||||
                  state.lineIndex = 0;
 | 
			
		||||
                  state.sectionIndex++;
 | 
			
		||||
                }
 | 
			
		||||
              // If the section has been exhausted, move to the next one.
 | 
			
		||||
              if (this._isSectionDone(state)) {
 | 
			
		||||
                state.lineIndex = 0;
 | 
			
		||||
                state.sectionIndex++;
 | 
			
		||||
              }
 | 
			
		||||
 | 
			
		||||
                // If all sections have been exhausted, finish.
 | 
			
		||||
                if (state.sectionIndex >= this.diff.content.length) {
 | 
			
		||||
                  resolve();
 | 
			
		||||
                  this._notify(state);
 | 
			
		||||
                  return;
 | 
			
		||||
                }
 | 
			
		||||
              // If all sections have been exhausted, finish.
 | 
			
		||||
              if (state.sectionIndex >= this.diff.content.length) {
 | 
			
		||||
                resolve();
 | 
			
		||||
                this._notify(state);
 | 
			
		||||
                return;
 | 
			
		||||
              }
 | 
			
		||||
 | 
			
		||||
                if (state.lineIndex % 100 === 0) {
 | 
			
		||||
                  this._notify(state);
 | 
			
		||||
                  this._processHandle = this.async(nextStep, ASYNC_DELAY);
 | 
			
		||||
                } else {
 | 
			
		||||
                  nextStep.call(this);
 | 
			
		||||
                }
 | 
			
		||||
              };
 | 
			
		||||
              if (state.lineIndex % 100 === 0) {
 | 
			
		||||
                this._notify(state);
 | 
			
		||||
                this._processHandle = this.async(nextStep, ASYNC_DELAY);
 | 
			
		||||
              } else {
 | 
			
		||||
                nextStep.call(this);
 | 
			
		||||
              }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
              this._processHandle = this.async(nextStep, 1);
 | 
			
		||||
            });
 | 
			
		||||
          }));
 | 
			
		||||
            this._processHandle = this.async(nextStep, 1);
 | 
			
		||||
          })));
 | 
			
		||||
      return this._processPromise
 | 
			
		||||
          .finally(() => { this._processPromise = null; });
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -194,7 +194,7 @@ limitations under the License.
 | 
			
		||||
      const mockHLJS = getMockHLJS();
 | 
			
		||||
      const highlightSpy = sinon.spy(mockHLJS, 'highlight');
 | 
			
		||||
      sandbox.stub(element.$.libLoader, 'getHLJS',
 | 
			
		||||
          () => { return Promise.resolve(mockHLJS); });
 | 
			
		||||
          () => Promise.resolve(mockHLJS));
 | 
			
		||||
      const processNextSpy = sandbox.spy(element, '_processNextLine');
 | 
			
		||||
      const processPromise = element.process();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -90,9 +90,10 @@ limitations under the License.
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      test('_paramsChanged', done => {
 | 
			
		||||
        sandbox.stub(element.$.restAPI, 'getDocumentationSearches', () => {
 | 
			
		||||
          return Promise.resolve(documentationSearches);
 | 
			
		||||
        });
 | 
			
		||||
        sandbox.stub(
 | 
			
		||||
            element.$.restAPI,
 | 
			
		||||
            'getDocumentationSearches',
 | 
			
		||||
            () => Promise.resolve(documentationSearches));
 | 
			
		||||
        const value = {
 | 
			
		||||
          filter: 'test',
 | 
			
		||||
        };
 | 
			
		||||
 
 | 
			
		||||
@@ -336,13 +336,12 @@ suite('gr-edit-controls tests', () => {
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  test('openOpenDialog', () => {
 | 
			
		||||
    return element.openOpenDialog('test/path.cpp').then(() => {
 | 
			
		||||
      assert.isFalse(element.$.openDialog.hasAttribute('hidden'));
 | 
			
		||||
      assert.equal(element.$.openDialog.querySelector('gr-autocomplete').text,
 | 
			
		||||
          'test/path.cpp');
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
  test('openOpenDialog', () => element.openOpenDialog('test/path.cpp')
 | 
			
		||||
      .then(() => {
 | 
			
		||||
        assert.isFalse(element.$.openDialog.hasAttribute('hidden'));
 | 
			
		||||
        assert.equal(element.$.openDialog.querySelector('gr-autocomplete').text,
 | 
			
		||||
            'test/path.cpp');
 | 
			
		||||
      }));
 | 
			
		||||
 | 
			
		||||
  test('_getDialogFromEvent', () => {
 | 
			
		||||
    const spy = sandbox.spy(element, '_getDialogFromEvent');
 | 
			
		||||
 
 | 
			
		||||
@@ -82,9 +82,7 @@ limitations under the License.
 | 
			
		||||
      sandbox.restore();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    appElement = () => {
 | 
			
		||||
      return element.$['app-element'];
 | 
			
		||||
    };
 | 
			
		||||
    appElement = () => element.$['app-element'];
 | 
			
		||||
 | 
			
		||||
    test('reporting', () => {
 | 
			
		||||
      assert.isTrue(appElement().$.reporting.appStarted.calledOnce);
 | 
			
		||||
 
 | 
			
		||||
@@ -56,11 +56,9 @@ limitations under the License.
 | 
			
		||||
      assert.isOk(element);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('open uses open() from gr-overlay', () => {
 | 
			
		||||
      return element.open().then(() => {
 | 
			
		||||
        assert.isTrue(element.$.overlay.open.called);
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
    test('open uses open() from gr-overlay', () => element.open().then(() => {
 | 
			
		||||
      assert.isTrue(element.$.overlay.open.called);
 | 
			
		||||
    }));
 | 
			
		||||
 | 
			
		||||
    test('close uses close() from gr-overlay', () => {
 | 
			
		||||
      element.close();
 | 
			
		||||
 
 | 
			
		||||
@@ -69,26 +69,22 @@ limitations under the License.
 | 
			
		||||
        instance = new GrPopupInterface(plugin);
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      test('open', () => {
 | 
			
		||||
        return instance.open().then(api => {
 | 
			
		||||
          assert.strictEqual(api, instance);
 | 
			
		||||
          const manual = document.createElement('div');
 | 
			
		||||
          manual.id = 'foobar';
 | 
			
		||||
          manual.innerHTML = 'manual content';
 | 
			
		||||
          api._getElement().appendChild(manual);
 | 
			
		||||
          flushAsynchronousOperations();
 | 
			
		||||
          assert.equal(
 | 
			
		||||
              container.querySelector('#foobar').textContent, 'manual content');
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
      test('open', () => instance.open().then(api => {
 | 
			
		||||
        assert.strictEqual(api, instance);
 | 
			
		||||
        const manual = document.createElement('div');
 | 
			
		||||
        manual.id = 'foobar';
 | 
			
		||||
        manual.innerHTML = 'manual content';
 | 
			
		||||
        api._getElement().appendChild(manual);
 | 
			
		||||
        flushAsynchronousOperations();
 | 
			
		||||
        assert.equal(
 | 
			
		||||
            container.querySelector('#foobar').textContent, 'manual content');
 | 
			
		||||
      }));
 | 
			
		||||
 | 
			
		||||
      test('close', () => {
 | 
			
		||||
        return instance.open().then(api => {
 | 
			
		||||
          assert.isTrue(api._getElement().node.opened);
 | 
			
		||||
          api.close();
 | 
			
		||||
          assert.isFalse(api._getElement().node.opened);
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
      test('close', () => instance.open().then(api => {
 | 
			
		||||
        assert.isTrue(api._getElement().node.opened);
 | 
			
		||||
        api.close();
 | 
			
		||||
        assert.isFalse(api._getElement().node.opened);
 | 
			
		||||
      }));
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    suite('components', () => {
 | 
			
		||||
@@ -96,20 +92,16 @@ limitations under the License.
 | 
			
		||||
        instance = new GrPopupInterface(plugin, 'gr-user-test-popup');
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      test('open', () => {
 | 
			
		||||
        return instance.open().then(api => {
 | 
			
		||||
          assert.isNotNull(
 | 
			
		||||
              Polymer.dom(container).querySelector('gr-user-test-popup'));
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
      test('open', () => instance.open().then(api => {
 | 
			
		||||
        assert.isNotNull(
 | 
			
		||||
            Polymer.dom(container).querySelector('gr-user-test-popup'));
 | 
			
		||||
      }));
 | 
			
		||||
 | 
			
		||||
      test('close', () => {
 | 
			
		||||
        return instance.open().then(api => {
 | 
			
		||||
          assert.isTrue(api._getElement().node.opened);
 | 
			
		||||
          api.close();
 | 
			
		||||
          assert.isFalse(api._getElement().node.opened);
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
      test('close', () => instance.open().then(api => {
 | 
			
		||||
        assert.isTrue(api._getElement().node.opened);
 | 
			
		||||
        api.close();
 | 
			
		||||
        assert.isFalse(api._getElement().node.opened);
 | 
			
		||||
      }));
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
</script>
 | 
			
		||||
 
 | 
			
		||||
@@ -59,9 +59,7 @@
 | 
			
		||||
      }));
 | 
			
		||||
 | 
			
		||||
      promises.push(this.$.restAPI.getAccountGroups().then(groups => {
 | 
			
		||||
        this._groups = groups.sort((a, b) => {
 | 
			
		||||
          return a.name.localeCompare(b.name);
 | 
			
		||||
        });
 | 
			
		||||
        this._groups = groups.sort((a, b) => a.name.localeCompare(b.name));
 | 
			
		||||
      }));
 | 
			
		||||
 | 
			
		||||
      promises.push(this.$.restAPI.getAccountAgreements().then(agreements => {
 | 
			
		||||
 
 | 
			
		||||
@@ -90,7 +90,7 @@ limitations under the License.
 | 
			
		||||
      const lastKey = keys[Object.keys(keys)[1]];
 | 
			
		||||
 | 
			
		||||
      const saveStub = sinon.stub(element.$.restAPI, 'deleteAccountGPGKey',
 | 
			
		||||
          () => { return Promise.resolve(); });
 | 
			
		||||
          () => Promise.resolve());
 | 
			
		||||
 | 
			
		||||
      assert.equal(element._keysToRemove.length, 0);
 | 
			
		||||
      assert.isFalse(element.hasUnsavedChanges);
 | 
			
		||||
@@ -146,7 +146,7 @@ limitations under the License.
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      const addStub = sinon.stub(element.$.restAPI, 'addAccountGPGKey',
 | 
			
		||||
          () => { return Promise.resolve(newKeyObject); });
 | 
			
		||||
          () => Promise.resolve(newKeyObject));
 | 
			
		||||
 | 
			
		||||
      element._newKey = newKeyString;
 | 
			
		||||
 | 
			
		||||
@@ -171,7 +171,7 @@ limitations under the License.
 | 
			
		||||
      const newKeyString = 'not even close to valid';
 | 
			
		||||
 | 
			
		||||
      const addStub = sinon.stub(element.$.restAPI, 'addAccountGPGKey',
 | 
			
		||||
          () => { return Promise.reject(new Error('error')); });
 | 
			
		||||
          () => Promise.reject(new Error('error')));
 | 
			
		||||
 | 
			
		||||
      element._newKey = newKeyString;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -30,9 +30,7 @@
 | 
			
		||||
 | 
			
		||||
    loadData() {
 | 
			
		||||
      return this.$.restAPI.getAccountGroups().then(groups => {
 | 
			
		||||
        this._groups = groups.sort((a, b) => {
 | 
			
		||||
          return a.name.localeCompare(b.name);
 | 
			
		||||
        });
 | 
			
		||||
        this._groups = groups.sort((a, b) => a.name.localeCompare(b.name));
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -58,11 +58,9 @@ limitations under the License.
 | 
			
		||||
      const nextPassword = 'the new password';
 | 
			
		||||
      let generateResolve;
 | 
			
		||||
      const generateStub = sinon.stub(element.$.restAPI,
 | 
			
		||||
          'generateAccountHttpPassword', () => {
 | 
			
		||||
            return new Promise(resolve => {
 | 
			
		||||
              generateResolve = resolve;
 | 
			
		||||
            });
 | 
			
		||||
          });
 | 
			
		||||
          'generateAccountHttpPassword', () => new Promise(resolve => {
 | 
			
		||||
            generateResolve = resolve;
 | 
			
		||||
          }));
 | 
			
		||||
 | 
			
		||||
      assert.isNotOk(element._generatedPassword);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -40,7 +40,7 @@ limitations under the License.
 | 
			
		||||
    let menu;
 | 
			
		||||
 | 
			
		||||
    function assertMenuNamesEqual(element, expected) {
 | 
			
		||||
      const names = element.menuItems.map(i => { return i.name; });
 | 
			
		||||
      const names = element.menuItems.map(i => i.name);
 | 
			
		||||
      assert.equal(names.length, expected.length);
 | 
			
		||||
      for (let i = 0; i < names.length; i++) {
 | 
			
		||||
        assert.equal(names[i], expected[i]);
 | 
			
		||||
 
 | 
			
		||||
@@ -70,7 +70,7 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
    function stubAddAccountEmail(statusCode) {
 | 
			
		||||
      return sandbox.stub(element.$.restAPI, 'addAccountEmail',
 | 
			
		||||
          () => { return Promise.resolve({status: statusCode}); });
 | 
			
		||||
          () => Promise.resolve({status: statusCode}));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setup(done => {
 | 
			
		||||
@@ -487,9 +487,10 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
      setup(() => {
 | 
			
		||||
        sandbox.stub(element.$.emailEditor, 'loadData');
 | 
			
		||||
        sandbox.stub(element.$.restAPI, 'confirmEmail', () => {
 | 
			
		||||
          return new Promise(resolve => { resolveConfirm = resolve; });
 | 
			
		||||
        });
 | 
			
		||||
        sandbox.stub(
 | 
			
		||||
            element.$.restAPI,
 | 
			
		||||
            'confirmEmail',
 | 
			
		||||
            () => new Promise(resolve => { resolveConfirm = resolve; }));
 | 
			
		||||
        element.params = {emailToken: 'foo'};
 | 
			
		||||
        element.attached();
 | 
			
		||||
      });
 | 
			
		||||
 
 | 
			
		||||
@@ -81,7 +81,7 @@ limitations under the License.
 | 
			
		||||
      const lastKey = keys[1];
 | 
			
		||||
 | 
			
		||||
      const saveStub = sinon.stub(element.$.restAPI, 'deleteAccountSSHKey',
 | 
			
		||||
          () => { return Promise.resolve(); });
 | 
			
		||||
          () => Promise.resolve());
 | 
			
		||||
 | 
			
		||||
      assert.equal(element._keysToRemove.length, 0);
 | 
			
		||||
      assert.isFalse(element.hasUnsavedChanges);
 | 
			
		||||
@@ -132,7 +132,7 @@ limitations under the License.
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      const addStub = sinon.stub(element.$.restAPI, 'addAccountSSHKey',
 | 
			
		||||
          () => { return Promise.resolve(newKeyObject); });
 | 
			
		||||
          () => Promise.resolve(newKeyObject));
 | 
			
		||||
 | 
			
		||||
      element._newKey = newKeyString;
 | 
			
		||||
 | 
			
		||||
@@ -157,7 +157,7 @@ limitations under the License.
 | 
			
		||||
      const newKeyString = 'not even close to valid';
 | 
			
		||||
 | 
			
		||||
      const addStub = sinon.stub(element.$.restAPI, 'addAccountSSHKey',
 | 
			
		||||
          () => { return Promise.reject(new Error('error')); });
 | 
			
		||||
          () => Promise.reject(new Error('error')));
 | 
			
		||||
 | 
			
		||||
      element._newKey = newKeyString;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -68,9 +68,7 @@
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return deletePromise
 | 
			
		||||
          .then(() => {
 | 
			
		||||
            return this.$.restAPI.saveWatchedProjects(this._projects);
 | 
			
		||||
          })
 | 
			
		||||
          .then(() => this.$.restAPI.saveWatchedProjects(this._projects))
 | 
			
		||||
          .then(projects => {
 | 
			
		||||
            this._projects = projects;
 | 
			
		||||
            this._projectsToRemove = [];
 | 
			
		||||
 
 | 
			
		||||
@@ -88,7 +88,7 @@ limitations under the License.
 | 
			
		||||
      function getKeysOfRow(row) {
 | 
			
		||||
        const boxes = rows[row].querySelectorAll('input[checked]');
 | 
			
		||||
        return Array.prototype.map.call(boxes,
 | 
			
		||||
            e => { return e.getAttribute('data-key'); });
 | 
			
		||||
            e => e.getAttribute('data-key'));
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      let checkedKeys = getKeysOfRow(0);
 | 
			
		||||
 
 | 
			
		||||
@@ -80,9 +80,10 @@
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _getHasAvatars() {
 | 
			
		||||
      return this.$.restAPI.getConfig().then(cfg => {
 | 
			
		||||
        return Promise.resolve(!!(cfg && cfg.plugin && cfg.plugin.has_avatars));
 | 
			
		||||
      });
 | 
			
		||||
      return this.$.restAPI.getConfig()
 | 
			
		||||
          .then(cfg => Promise.resolve(!!(
 | 
			
		||||
            cfg && cfg.plugin && cfg.plugin.has_avatars
 | 
			
		||||
          )));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -67,13 +67,11 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
    suite('stubbed values for querySuggestions', () => {
 | 
			
		||||
      setup(() => {
 | 
			
		||||
        element.querySuggestions = input => {
 | 
			
		||||
          return Promise.resolve([
 | 
			
		||||
            suggestion1,
 | 
			
		||||
            suggestion2,
 | 
			
		||||
            suggestion3,
 | 
			
		||||
          ]);
 | 
			
		||||
        };
 | 
			
		||||
        element.querySuggestions = input => Promise.resolve([
 | 
			
		||||
          suggestion1,
 | 
			
		||||
          suggestion2,
 | 
			
		||||
          suggestion3,
 | 
			
		||||
        ]);
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -333,15 +333,15 @@
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    additions() {
 | 
			
		||||
      return this.accounts.filter(account => {
 | 
			
		||||
        return account._pendingAdd;
 | 
			
		||||
      }).map(account => {
 | 
			
		||||
        if (account._group) {
 | 
			
		||||
          return {group: account};
 | 
			
		||||
        } else {
 | 
			
		||||
          return {account};
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
      return this.accounts
 | 
			
		||||
          .filter(account => account._pendingAdd)
 | 
			
		||||
          .map(account => {
 | 
			
		||||
            if (account._group) {
 | 
			
		||||
              return {group: account};
 | 
			
		||||
            } else {
 | 
			
		||||
              return {account};
 | 
			
		||||
            }
 | 
			
		||||
          });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _computeEntryHidden(maxCount, accountsRecord, readonly) {
 | 
			
		||||
 
 | 
			
		||||
@@ -54,15 +54,13 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
    test('renders', () => {
 | 
			
		||||
      let promise;
 | 
			
		||||
      const queryStub = sandbox.spy(input => {
 | 
			
		||||
        return promise = Promise.resolve([
 | 
			
		||||
          {name: input + ' 0', value: 0},
 | 
			
		||||
          {name: input + ' 1', value: 1},
 | 
			
		||||
          {name: input + ' 2', value: 2},
 | 
			
		||||
          {name: input + ' 3', value: 3},
 | 
			
		||||
          {name: input + ' 4', value: 4},
 | 
			
		||||
        ]);
 | 
			
		||||
      });
 | 
			
		||||
      const queryStub = sandbox.spy(input => promise = Promise.resolve([
 | 
			
		||||
        {name: input + ' 0', value: 0},
 | 
			
		||||
        {name: input + ' 1', value: 1},
 | 
			
		||||
        {name: input + ' 2', value: 2},
 | 
			
		||||
        {name: input + ' 3', value: 3},
 | 
			
		||||
        {name: input + ' 4', value: 4},
 | 
			
		||||
      ]));
 | 
			
		||||
      element.query = queryStub;
 | 
			
		||||
      assert.isTrue(element.$.suggestions.isHidden);
 | 
			
		||||
      assert.equal(element.$.suggestions.$.cursor.index, -1);
 | 
			
		||||
@@ -104,11 +102,9 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
    test('esc key behavior', done => {
 | 
			
		||||
      let promise;
 | 
			
		||||
      const queryStub = sandbox.spy(() => {
 | 
			
		||||
        return promise = Promise.resolve([
 | 
			
		||||
          {name: 'blah', value: 123},
 | 
			
		||||
        ]);
 | 
			
		||||
      });
 | 
			
		||||
      const queryStub = sandbox.spy(() => promise = Promise.resolve([
 | 
			
		||||
        {name: 'blah', value: 123},
 | 
			
		||||
      ]));
 | 
			
		||||
      element.query = queryStub;
 | 
			
		||||
 | 
			
		||||
      assert.isTrue(element.$.suggestions.isHidden);
 | 
			
		||||
@@ -135,15 +131,13 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
    test('emits commit and handles cursor movement', done => {
 | 
			
		||||
      let promise;
 | 
			
		||||
      const queryStub = sandbox.spy(input => {
 | 
			
		||||
        return promise = Promise.resolve([
 | 
			
		||||
          {name: input + ' 0', value: 0},
 | 
			
		||||
          {name: input + ' 1', value: 1},
 | 
			
		||||
          {name: input + ' 2', value: 2},
 | 
			
		||||
          {name: input + ' 3', value: 3},
 | 
			
		||||
          {name: input + ' 4', value: 4},
 | 
			
		||||
        ]);
 | 
			
		||||
      });
 | 
			
		||||
      const queryStub = sandbox.spy(input => promise = Promise.resolve([
 | 
			
		||||
        {name: input + ' 0', value: 0},
 | 
			
		||||
        {name: input + ' 1', value: 1},
 | 
			
		||||
        {name: input + ' 2', value: 2},
 | 
			
		||||
        {name: input + ' 3', value: 3},
 | 
			
		||||
        {name: input + ' 4', value: 4},
 | 
			
		||||
      ]));
 | 
			
		||||
      element.query = queryStub;
 | 
			
		||||
 | 
			
		||||
      assert.isTrue(element.$.suggestions.isHidden);
 | 
			
		||||
@@ -188,7 +182,8 @@ limitations under the License.
 | 
			
		||||
    test('clear-on-commit behavior (off)', done => {
 | 
			
		||||
      let promise;
 | 
			
		||||
      const queryStub = sandbox.spy(() => {
 | 
			
		||||
        return promise = Promise.resolve([{name: 'suggestion', value: 0}]);
 | 
			
		||||
        promise = Promise.resolve([{name: 'suggestion', value: 0}]);
 | 
			
		||||
        return promise;
 | 
			
		||||
      });
 | 
			
		||||
      element.query = queryStub;
 | 
			
		||||
      focusOnInput(element);
 | 
			
		||||
@@ -210,7 +205,8 @@ limitations under the License.
 | 
			
		||||
    test('clear-on-commit behavior (on)', done => {
 | 
			
		||||
      let promise;
 | 
			
		||||
      const queryStub = sandbox.spy(() => {
 | 
			
		||||
        return promise = Promise.resolve([{name: 'suggestion', value: 0}]);
 | 
			
		||||
        promise = Promise.resolve([{name: 'suggestion', value: 0}]);
 | 
			
		||||
        return promise;
 | 
			
		||||
      });
 | 
			
		||||
      element.query = queryStub;
 | 
			
		||||
      focusOnInput(element);
 | 
			
		||||
@@ -231,9 +227,7 @@ limitations under the License.
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('threshold guards the query', () => {
 | 
			
		||||
      const queryStub = sandbox.spy(() => {
 | 
			
		||||
        return Promise.resolve([]);
 | 
			
		||||
      });
 | 
			
		||||
      const queryStub = sandbox.spy(() => Promise.resolve([]));
 | 
			
		||||
      element.query = queryStub;
 | 
			
		||||
      element.threshold = 2;
 | 
			
		||||
      focusOnInput(element);
 | 
			
		||||
@@ -244,9 +238,7 @@ limitations under the License.
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('noDebounce=false debounces the query', () => {
 | 
			
		||||
      const queryStub = sandbox.spy(() => {
 | 
			
		||||
        return Promise.resolve([]);
 | 
			
		||||
      });
 | 
			
		||||
      const queryStub = sandbox.spy(() => Promise.resolve([]));
 | 
			
		||||
      let callback;
 | 
			
		||||
      const debounceStub = sandbox.stub(element, 'debounce',
 | 
			
		||||
          (name, cb) => { callback = cb; });
 | 
			
		||||
@@ -276,7 +268,9 @@ limitations under the License.
 | 
			
		||||
    test('when focused', done => {
 | 
			
		||||
      let promise;
 | 
			
		||||
      const queryStub = sandbox.stub()
 | 
			
		||||
          .returns(promise = Promise.resolve([{name: 'suggestion', value: 0}]));
 | 
			
		||||
          .returns(promise = Promise.resolve([
 | 
			
		||||
            {name: 'suggestion', value: 0},
 | 
			
		||||
          ]));
 | 
			
		||||
      element.query = queryStub;
 | 
			
		||||
      element.suggestOnlyWhenFocus = true;
 | 
			
		||||
      focusOnInput(element);
 | 
			
		||||
@@ -293,7 +287,9 @@ limitations under the License.
 | 
			
		||||
    test('when not focused', done => {
 | 
			
		||||
      let promise;
 | 
			
		||||
      const queryStub = sandbox.stub()
 | 
			
		||||
          .returns(promise = Promise.resolve([{name: 'suggestion', value: 0}]));
 | 
			
		||||
          .returns(promise = Promise.resolve([
 | 
			
		||||
            {name: 'suggestion', value: 0},
 | 
			
		||||
          ]));
 | 
			
		||||
      element.query = queryStub;
 | 
			
		||||
      element.suggestOnlyWhenFocus = true;
 | 
			
		||||
      element.text = 'bla';
 | 
			
		||||
@@ -308,7 +304,9 @@ limitations under the License.
 | 
			
		||||
    test('suggestions should not carry over', done => {
 | 
			
		||||
      let promise;
 | 
			
		||||
      const queryStub = sandbox.stub()
 | 
			
		||||
          .returns(promise = Promise.resolve([{name: 'suggestion', value: 0}]));
 | 
			
		||||
          .returns(promise = Promise.resolve([
 | 
			
		||||
            {name: 'suggestion', value: 0},
 | 
			
		||||
          ]));
 | 
			
		||||
      element.query = queryStub;
 | 
			
		||||
      focusOnInput(element);
 | 
			
		||||
      element.text = 'bla';
 | 
			
		||||
@@ -324,7 +322,9 @@ limitations under the License.
 | 
			
		||||
    test('multi completes only the last part of the query', done => {
 | 
			
		||||
      let promise;
 | 
			
		||||
      const queryStub = sandbox.stub()
 | 
			
		||||
          .returns(promise = Promise.resolve([{name: 'suggestion', value: 0}]));
 | 
			
		||||
          .returns(promise = Promise.resolve([
 | 
			
		||||
            {name: 'suggestion', value: 0},
 | 
			
		||||
          ]));
 | 
			
		||||
      element.query = queryStub;
 | 
			
		||||
      focusOnInput(element);
 | 
			
		||||
      element.text = 'blah blah';
 | 
			
		||||
@@ -449,7 +449,12 @@ limitations under the License.
 | 
			
		||||
      // Must set the value, because the MockInteraction does not.
 | 
			
		||||
      element.$.input.value = 'file:x';
 | 
			
		||||
      assert.isTrue(keydownSpy.calledOnce);
 | 
			
		||||
      MockInteractions.pressAndReleaseKeyOn(element.$.input, 13, null, 'enter');
 | 
			
		||||
      MockInteractions.pressAndReleaseKeyOn(
 | 
			
		||||
          element.$.input,
 | 
			
		||||
          13,
 | 
			
		||||
          null,
 | 
			
		||||
          'enter'
 | 
			
		||||
      );
 | 
			
		||||
      assert.isTrue(keydownSpy.calledTwice);
 | 
			
		||||
      assert.equal(element.text, 'file:x');
 | 
			
		||||
    });
 | 
			
		||||
 
 | 
			
		||||
@@ -105,9 +105,10 @@ limitations under the License.
 | 
			
		||||
    test('dom for existing account', () => {
 | 
			
		||||
      assert.isFalse(element.hasAttribute('hidden'));
 | 
			
		||||
 | 
			
		||||
      sandbox.stub(element, '_getConfig', () => {
 | 
			
		||||
        return Promise.resolve({plugin: {has_avatars: true}});
 | 
			
		||||
      });
 | 
			
		||||
      sandbox.stub(
 | 
			
		||||
          element,
 | 
			
		||||
          '_getConfig',
 | 
			
		||||
          () => Promise.resolve({plugin: {has_avatars: true}}));
 | 
			
		||||
 | 
			
		||||
      element.imageSize = 64;
 | 
			
		||||
      element.account = {
 | 
			
		||||
@@ -139,9 +140,7 @@ limitations under the License.
 | 
			
		||||
      sandbox = sinon.sandbox.create();
 | 
			
		||||
 | 
			
		||||
      stub('gr-avatar', {
 | 
			
		||||
        _getConfig: () => {
 | 
			
		||||
          return Promise.resolve({plugin: {has_avatars: true}});
 | 
			
		||||
        },
 | 
			
		||||
        _getConfig: () => Promise.resolve({plugin: {has_avatars: true}}),
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      element = fixture('basic');
 | 
			
		||||
@@ -176,9 +175,7 @@ limitations under the License.
 | 
			
		||||
      sandbox = sinon.sandbox.create();
 | 
			
		||||
 | 
			
		||||
      stub('gr-avatar', {
 | 
			
		||||
        _getConfig: () => {
 | 
			
		||||
          return Promise.resolve({});
 | 
			
		||||
        },
 | 
			
		||||
        _getConfig: () => Promise.resolve({}),
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      element = fixture('basic');
 | 
			
		||||
 
 | 
			
		||||
@@ -280,9 +280,7 @@ limitations under the License.
 | 
			
		||||
      MockInteractions.tap(replyBtn);
 | 
			
		||||
      flushAsynchronousOperations();
 | 
			
		||||
 | 
			
		||||
      const drafts = element._orderedComments.filter(c => {
 | 
			
		||||
        return c.__draft == true;
 | 
			
		||||
      });
 | 
			
		||||
      const drafts = element._orderedComments.filter(c => c.__draft == true);
 | 
			
		||||
      assert.equal(drafts.length, 1);
 | 
			
		||||
      assert.notOk(drafts[0].message, 'message should be empty');
 | 
			
		||||
      assert.equal(drafts[0].in_reply_to, 'baf0414d_60047215');
 | 
			
		||||
@@ -299,9 +297,7 @@ limitations under the License.
 | 
			
		||||
      MockInteractions.tap(quoteBtn);
 | 
			
		||||
      flushAsynchronousOperations();
 | 
			
		||||
 | 
			
		||||
      const drafts = element._orderedComments.filter(c => {
 | 
			
		||||
        return c.__draft == true;
 | 
			
		||||
      });
 | 
			
		||||
      const drafts = element._orderedComments.filter(c => c.__draft == true);
 | 
			
		||||
      assert.equal(drafts.length, 1);
 | 
			
		||||
      assert.equal(drafts[0].message, '> is this a crossover episode!?\n\n');
 | 
			
		||||
      assert.equal(drafts[0].in_reply_to, 'baf0414d_60047215');
 | 
			
		||||
@@ -330,9 +326,7 @@ limitations under the License.
 | 
			
		||||
      MockInteractions.tap(quoteBtn);
 | 
			
		||||
      flushAsynchronousOperations();
 | 
			
		||||
 | 
			
		||||
      const drafts = element._orderedComments.filter(c => {
 | 
			
		||||
        return c.__draft == true;
 | 
			
		||||
      });
 | 
			
		||||
      const drafts = element._orderedComments.filter(c => c.__draft == true);
 | 
			
		||||
      assert.equal(drafts.length, 1);
 | 
			
		||||
      assert.equal(drafts[0].message,
 | 
			
		||||
          '> is this a crossover episode!?\n> It might be!\n\n');
 | 
			
		||||
@@ -352,9 +346,7 @@ limitations under the License.
 | 
			
		||||
      const ackBtn = element.$.ackBtn;
 | 
			
		||||
      MockInteractions.tap(ackBtn);
 | 
			
		||||
      flush(() => {
 | 
			
		||||
        const drafts = element.comments.filter(c => {
 | 
			
		||||
          return c.__draft == true;
 | 
			
		||||
        });
 | 
			
		||||
        const drafts = element.comments.filter(c => c.__draft == true);
 | 
			
		||||
        assert.equal(drafts.length, 1);
 | 
			
		||||
        assert.equal(drafts[0].message, 'Ack');
 | 
			
		||||
        assert.equal(drafts[0].in_reply_to, 'baf0414d_60047215');
 | 
			
		||||
@@ -375,9 +367,7 @@ limitations under the License.
 | 
			
		||||
      const doneBtn = element.$.doneBtn;
 | 
			
		||||
      MockInteractions.tap(doneBtn);
 | 
			
		||||
      flush(() => {
 | 
			
		||||
        const drafts = element.comments.filter(c => {
 | 
			
		||||
          return c.__draft == true;
 | 
			
		||||
        });
 | 
			
		||||
        const drafts = element.comments.filter(c => c.__draft == true);
 | 
			
		||||
        assert.equal(drafts.length, 1);
 | 
			
		||||
        assert.equal(drafts[0].message, 'Done');
 | 
			
		||||
        assert.equal(drafts[0].in_reply_to, 'baf0414d_60047215');
 | 
			
		||||
@@ -415,9 +405,7 @@ limitations under the License.
 | 
			
		||||
      const commentEl = element.$$('gr-comment');
 | 
			
		||||
      assert.ok(commentEl);
 | 
			
		||||
      commentEl.addEventListener('create-fix-comment', () => {
 | 
			
		||||
        const drafts = element._orderedComments.filter(c => {
 | 
			
		||||
          return c.__draft == true;
 | 
			
		||||
        });
 | 
			
		||||
        const drafts = element._orderedComments.filter(c => c.__draft == true);
 | 
			
		||||
        assert.equal(drafts.length, 1);
 | 
			
		||||
        assert.equal(
 | 
			
		||||
            drafts[0].message, '> is this a crossover episode!?\n\nPlease fix.');
 | 
			
		||||
@@ -446,9 +434,7 @@ limitations under the License.
 | 
			
		||||
          Polymer.dom(element.root).querySelectorAll('gr-comment')[1];
 | 
			
		||||
      assert.ok(draftEl);
 | 
			
		||||
      draftEl.addEventListener('comment-discard', () => {
 | 
			
		||||
        const drafts = element.comments.filter(c => {
 | 
			
		||||
          return c.__draft == true;
 | 
			
		||||
        });
 | 
			
		||||
        const drafts = element.comments.filter(c => c.__draft == true);
 | 
			
		||||
        assert.equal(drafts.length, 0);
 | 
			
		||||
        assert.isTrue(saveOrDiscardStub.called);
 | 
			
		||||
        assert.equal(saveOrDiscardStub.lastCall.args[0].detail.rootId,
 | 
			
		||||
@@ -507,9 +493,7 @@ limitations under the License.
 | 
			
		||||
      MockInteractions.tap(replyBtn);
 | 
			
		||||
      flushAsynchronousOperations();
 | 
			
		||||
 | 
			
		||||
      const editing = element._orderedComments.filter(c => {
 | 
			
		||||
        return c.__editing == true;
 | 
			
		||||
      });
 | 
			
		||||
      const editing = element._orderedComments.filter(c => c.__editing == true);
 | 
			
		||||
      assert.equal(editing.length, 1);
 | 
			
		||||
      assert.equal(!!editing[0].__otherEditing, false);
 | 
			
		||||
    });
 | 
			
		||||
 
 | 
			
		||||
@@ -164,7 +164,7 @@
 | 
			
		||||
         */
 | 
			
		||||
        _overlays: {
 | 
			
		||||
          type: Object,
 | 
			
		||||
          value: () => ({}),
 | 
			
		||||
          value: () => { return {}; },
 | 
			
		||||
        },
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
@@ -325,10 +325,9 @@
 | 
			
		||||
    _computeHasHumanReply() {
 | 
			
		||||
      if (!this.comment || !this.comments) return;
 | 
			
		||||
      // hide please fix button for robot comment that has human reply
 | 
			
		||||
      this._hasHumanReply = this.comments.some(c => {
 | 
			
		||||
        return c.in_reply_to && c.in_reply_to === this.comment.id &&
 | 
			
		||||
            !c.robot_id;
 | 
			
		||||
      });
 | 
			
		||||
      this._hasHumanReply = this.comments
 | 
			
		||||
          .some(c => c.in_reply_to && c.in_reply_to === this.comment.id &&
 | 
			
		||||
            !c.robot_id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -89,15 +89,13 @@ limitations under the License.
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suite('24 hours time format preference', () => {
 | 
			
		||||
      setup(() => {
 | 
			
		||||
        return stubRestAPI(
 | 
			
		||||
            {time_format: 'HHMM_24', relative_date_in_change_table: false}
 | 
			
		||||
        ).then(() => {
 | 
			
		||||
          element = fixture('basic');
 | 
			
		||||
          sandbox.stub(element, '_getUtcOffsetString').returns('');
 | 
			
		||||
          return element._loadPreferences();
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
      setup(() => stubRestAPI(
 | 
			
		||||
          {time_format: 'HHMM_24', relative_date_in_change_table: false}
 | 
			
		||||
      ).then(() => {
 | 
			
		||||
        element = fixture('basic');
 | 
			
		||||
        sandbox.stub(element, '_getUtcOffsetString').returns('');
 | 
			
		||||
        return element._loadPreferences();
 | 
			
		||||
      }));
 | 
			
		||||
 | 
			
		||||
      test('invalid dates are quietly rejected', () => {
 | 
			
		||||
        assert.notOk((new Date('foo')).valueOf());
 | 
			
		||||
@@ -138,16 +136,16 @@ limitations under the License.
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    suite('12 hours time format preference', () => {
 | 
			
		||||
      setup(() => {
 | 
			
		||||
        // relative_date_in_change_table is not set when false.
 | 
			
		||||
        return stubRestAPI(
 | 
			
		||||
      setup(() =>
 | 
			
		||||
      // relative_date_in_change_table is not set when false.
 | 
			
		||||
        stubRestAPI(
 | 
			
		||||
            {time_format: 'HHMM_12'}
 | 
			
		||||
        ).then(() => {
 | 
			
		||||
          element = fixture('basic');
 | 
			
		||||
          sandbox.stub(element, '_getUtcOffsetString').returns('');
 | 
			
		||||
          return element._loadPreferences();
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
        })
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
      test('Within 24 hours on same day', done => {
 | 
			
		||||
        testDates('2015-07-29 20:34:14.985000000',
 | 
			
		||||
@@ -159,15 +157,13 @@ limitations under the License.
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    suite('relative date preference', () => {
 | 
			
		||||
      setup(() => {
 | 
			
		||||
        return stubRestAPI(
 | 
			
		||||
            {time_format: 'HHMM_12', relative_date_in_change_table: true}
 | 
			
		||||
        ).then(() => {
 | 
			
		||||
          element = fixture('basic');
 | 
			
		||||
          sandbox.stub(element, '_getUtcOffsetString').returns('');
 | 
			
		||||
          return element._loadPreferences();
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
      setup(() => stubRestAPI(
 | 
			
		||||
          {time_format: 'HHMM_12', relative_date_in_change_table: true}
 | 
			
		||||
      ).then(() => {
 | 
			
		||||
        element = fixture('basic');
 | 
			
		||||
        sandbox.stub(element, '_getUtcOffsetString').returns('');
 | 
			
		||||
        return element._loadPreferences();
 | 
			
		||||
      }));
 | 
			
		||||
 | 
			
		||||
      test('Within 24 hours on same day', done => {
 | 
			
		||||
        testDates('2015-07-29 20:34:14.985000000',
 | 
			
		||||
@@ -187,14 +183,12 @@ limitations under the License.
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    suite('logged in', () => {
 | 
			
		||||
      setup(() => {
 | 
			
		||||
        return stubRestAPI(
 | 
			
		||||
            {time_format: 'HHMM_12', relative_date_in_change_table: true}
 | 
			
		||||
        ).then(() => {
 | 
			
		||||
          element = fixture('basic');
 | 
			
		||||
          return element._loadPreferences();
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
      setup(() => stubRestAPI(
 | 
			
		||||
          {time_format: 'HHMM_12', relative_date_in_change_table: true}
 | 
			
		||||
      ).then(() => {
 | 
			
		||||
        element = fixture('basic');
 | 
			
		||||
        return element._loadPreferences();
 | 
			
		||||
      }));
 | 
			
		||||
 | 
			
		||||
      test('Preferences are respected', () => {
 | 
			
		||||
        assert.equal(element._timeFormat, 'h:mm A');
 | 
			
		||||
@@ -203,12 +197,10 @@ limitations under the License.
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    suite('logged out', () => {
 | 
			
		||||
      setup(() => {
 | 
			
		||||
        return stubRestAPI(null).then(() => {
 | 
			
		||||
          element = fixture('basic');
 | 
			
		||||
          return element._loadPreferences();
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
      setup(() => stubRestAPI(null).then(() => {
 | 
			
		||||
        element = fixture('basic');
 | 
			
		||||
        return element._loadPreferences();
 | 
			
		||||
      }));
 | 
			
		||||
 | 
			
		||||
      test('Default preferences are respected', () => {
 | 
			
		||||
        assert.equal(element._timeFormat, 'HH:mm');
 | 
			
		||||
 
 | 
			
		||||
@@ -131,7 +131,7 @@ limitations under the License.
 | 
			
		||||
      test('saves scheme to preferences', () => {
 | 
			
		||||
        element._loggedIn = true;
 | 
			
		||||
        const savePrefsStub = sandbox.stub(element.$.restAPI, 'savePreferences',
 | 
			
		||||
            () => { return Promise.resolve(); });
 | 
			
		||||
            () => Promise.resolve());
 | 
			
		||||
 | 
			
		||||
        flushAsynchronousOperations();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -120,9 +120,7 @@
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (!value) { return; }
 | 
			
		||||
      const selectedObj = items.find(item => {
 | 
			
		||||
        return item.value + '' === value + '';
 | 
			
		||||
      });
 | 
			
		||||
      const selectedObj = items.find(item => item.value + '' === value + '');
 | 
			
		||||
      if (!selectedObj) { return; }
 | 
			
		||||
      this.text = selectedObj.triggerText? selectedObj.triggerText :
 | 
			
		||||
        selectedObj.text;
 | 
			
		||||
 
 | 
			
		||||
@@ -62,9 +62,8 @@
 | 
			
		||||
 | 
			
		||||
  GrChangeActionsInterface.prototype.removePrimaryActionKey = function(key) {
 | 
			
		||||
    ensureEl(this);
 | 
			
		||||
    this._el.primaryActionKeys = this._el.primaryActionKeys.filter(k => {
 | 
			
		||||
      return k !== key;
 | 
			
		||||
    });
 | 
			
		||||
    this._el.primaryActionKeys = this._el.primaryActionKeys
 | 
			
		||||
        .filter(k => k !== key);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  GrChangeActionsInterface.prototype.hideQuickApproveAction = function() {
 | 
			
		||||
 
 | 
			
		||||
@@ -304,11 +304,11 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
    test('submitchange', () => {
 | 
			
		||||
      plugin.on(element.EventType.SUBMIT_CHANGE, throwErrFn);
 | 
			
		||||
      plugin.on(element.EventType.SUBMIT_CHANGE, () => { return true; });
 | 
			
		||||
      plugin.on(element.EventType.SUBMIT_CHANGE, () => true);
 | 
			
		||||
      assert.isTrue(element.canSubmitChange());
 | 
			
		||||
      assert.isTrue(errorStub.calledOnce);
 | 
			
		||||
      plugin.on(element.EventType.SUBMIT_CHANGE, () => { return false; });
 | 
			
		||||
      plugin.on(element.EventType.SUBMIT_CHANGE, () => { return true; });
 | 
			
		||||
      plugin.on(element.EventType.SUBMIT_CHANGE, () => false);
 | 
			
		||||
      plugin.on(element.EventType.SUBMIT_CHANGE, () => true);
 | 
			
		||||
      assert.isFalse(element.canSubmitChange());
 | 
			
		||||
      assert.isTrue(errorStub.calledTwice);
 | 
			
		||||
    });
 | 
			
		||||
@@ -326,9 +326,7 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
    test('getLoggedIn', done => {
 | 
			
		||||
      // fake fetch for authCheck
 | 
			
		||||
      sandbox.stub(window, 'fetch', () => {
 | 
			
		||||
        return Promise.resolve({status: 204});
 | 
			
		||||
      });
 | 
			
		||||
      sandbox.stub(window, 'fetch', () => Promise.resolve({status: 204}));
 | 
			
		||||
      plugin.restApi().getLoggedIn()
 | 
			
		||||
          .then(loggedIn => {
 | 
			
		||||
            assert.isTrue(loggedIn);
 | 
			
		||||
 
 | 
			
		||||
@@ -369,9 +369,7 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
      test('relative path should honor getBaseUrl', () => {
 | 
			
		||||
        const testUrl = '/test';
 | 
			
		||||
        sandbox.stub(Gerrit.BaseUrlBehavior, 'getBaseUrl', () => {
 | 
			
		||||
          return testUrl;
 | 
			
		||||
        });
 | 
			
		||||
        sandbox.stub(Gerrit.BaseUrlBehavior, 'getBaseUrl', () => testUrl);
 | 
			
		||||
 | 
			
		||||
        Gerrit._loadPlugins([
 | 
			
		||||
          'foo/bar.js',
 | 
			
		||||
 
 | 
			
		||||
@@ -84,10 +84,12 @@
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _repoResponseToSuggestions(res) {
 | 
			
		||||
      return res.map(repo => ({
 | 
			
		||||
        name: repo.name,
 | 
			
		||||
        value: this.singleDecodeURL(repo.id),
 | 
			
		||||
      }));
 | 
			
		||||
      return res.map(repo => {
 | 
			
		||||
        return {
 | 
			
		||||
          name: repo.name,
 | 
			
		||||
          value: this.singleDecodeURL(repo.id),
 | 
			
		||||
        };
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _branchResponseToSuggestions(res) {
 | 
			
		||||
 
 | 
			
		||||
@@ -126,17 +126,16 @@ limitations under the License.
 | 
			
		||||
            });
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      test('does not query when repo is unset', () => {
 | 
			
		||||
        return element._getRepoBranchesSuggestions('')
 | 
			
		||||
            .then(() => {
 | 
			
		||||
              assert.isFalse(element.$.restAPI.getRepoBranches.called);
 | 
			
		||||
              element.repo = 'gerrit';
 | 
			
		||||
              return element._getRepoBranchesSuggestions('');
 | 
			
		||||
            })
 | 
			
		||||
            .then(() => {
 | 
			
		||||
              assert.isTrue(element.$.restAPI.getRepoBranches.called);
 | 
			
		||||
            });
 | 
			
		||||
      });
 | 
			
		||||
      test('does not query when repo is unset', () => element
 | 
			
		||||
          ._getRepoBranchesSuggestions('')
 | 
			
		||||
          .then(() => {
 | 
			
		||||
            assert.isFalse(element.$.restAPI.getRepoBranches.called);
 | 
			
		||||
            element.repo = 'gerrit';
 | 
			
		||||
            return element._getRepoBranchesSuggestions('');
 | 
			
		||||
          })
 | 
			
		||||
          .then(() => {
 | 
			
		||||
            assert.isTrue(element.$.restAPI.getRepoBranches.called);
 | 
			
		||||
          }));
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
</script>
 | 
			
		||||
 
 | 
			
		||||
@@ -801,7 +801,7 @@
 | 
			
		||||
      let queryString = '';
 | 
			
		||||
      if (opt_params) {
 | 
			
		||||
        queryString = '?q=' + opt_params
 | 
			
		||||
            .map(param => { return encodeURIComponent(param); })
 | 
			
		||||
            .map(param => encodeURIComponent(param))
 | 
			
		||||
            .join('&q=');
 | 
			
		||||
      }
 | 
			
		||||
      return this._fetchSharedCacheURL({
 | 
			
		||||
@@ -823,9 +823,9 @@
 | 
			
		||||
              return Promise.resolve();
 | 
			
		||||
            }
 | 
			
		||||
          })
 | 
			
		||||
          .then(capabilities => {
 | 
			
		||||
            return capabilities && capabilities.administrateServer;
 | 
			
		||||
          });
 | 
			
		||||
          .then(
 | 
			
		||||
              capabilities => capabilities && capabilities.administrateServer
 | 
			
		||||
          );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getDefaultPreferences() {
 | 
			
		||||
@@ -1644,14 +1644,12 @@
 | 
			
		||||
        this.awaitPendingDiffDrafts(),
 | 
			
		||||
        this.getChangeActionURL(changeNum, patchNum, '/review'),
 | 
			
		||||
      ];
 | 
			
		||||
      return Promise.all(promises).then(([, url]) => {
 | 
			
		||||
        return this._restApiHelper.send({
 | 
			
		||||
          method: 'POST',
 | 
			
		||||
          url,
 | 
			
		||||
          body: review,
 | 
			
		||||
          errFn: opt_errFn,
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
      return Promise.all(promises).then(([, url]) => this._restApiHelper.send({
 | 
			
		||||
        method: 'POST',
 | 
			
		||||
        url,
 | 
			
		||||
        body: review,
 | 
			
		||||
        errFn: opt_errFn,
 | 
			
		||||
      }));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getChangeEdit(changeNum, opt_download_commands) {
 | 
			
		||||
@@ -2015,9 +2013,9 @@
 | 
			
		||||
 | 
			
		||||
    _setRanges(comments) {
 | 
			
		||||
      comments = comments || [];
 | 
			
		||||
      comments.sort((a, b) => {
 | 
			
		||||
        return util.parseDate(a.updated) - util.parseDate(b.updated);
 | 
			
		||||
      });
 | 
			
		||||
      comments.sort(
 | 
			
		||||
          (a, b) => util.parseDate(a.updated) - util.parseDate(b.updated)
 | 
			
		||||
      );
 | 
			
		||||
      for (const comment of comments) {
 | 
			
		||||
        this._setRange(comments, comment);
 | 
			
		||||
      }
 | 
			
		||||
@@ -2041,14 +2039,12 @@
 | 
			
		||||
       * @param {string|number=} opt_patchNum
 | 
			
		||||
       * @return {!Promise<!Object>} Diff comments response.
 | 
			
		||||
       */
 | 
			
		||||
      const fetchComments = opt_patchNum => {
 | 
			
		||||
        return this._getChangeURLAndFetch({
 | 
			
		||||
          changeNum,
 | 
			
		||||
          endpoint,
 | 
			
		||||
          patchNum: opt_patchNum,
 | 
			
		||||
          reportEndpointAsIs: true,
 | 
			
		||||
        });
 | 
			
		||||
      };
 | 
			
		||||
      const fetchComments = opt_patchNum => this._getChangeURLAndFetch({
 | 
			
		||||
        changeNum,
 | 
			
		||||
        endpoint,
 | 
			
		||||
        patchNum: opt_patchNum,
 | 
			
		||||
        reportEndpointAsIs: true,
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      if (!opt_basePatchNum && !opt_patchNum && !opt_path) {
 | 
			
		||||
        return fetchComments();
 | 
			
		||||
@@ -2089,12 +2085,10 @@
 | 
			
		||||
        promises.push(fetchPromise);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return Promise.all(promises).then(() => {
 | 
			
		||||
        return Promise.resolve({
 | 
			
		||||
          baseComments,
 | 
			
		||||
          comments,
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
      return Promise.all(promises).then(() => Promise.resolve({
 | 
			
		||||
        baseComments,
 | 
			
		||||
        comments,
 | 
			
		||||
      }));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -2467,9 +2461,7 @@
 | 
			
		||||
 | 
			
		||||
    probePath(path) {
 | 
			
		||||
      return fetch(new Request(path, {method: 'HEAD'}))
 | 
			
		||||
          .then(response => {
 | 
			
		||||
            return response.ok;
 | 
			
		||||
          });
 | 
			
		||||
          .then(response => response.ok);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -2597,19 +2589,18 @@
 | 
			
		||||
      const anonymizedEndpoint = req.reportEndpointAsIs ?
 | 
			
		||||
        req.endpoint : req.anonymizedEndpoint;
 | 
			
		||||
 | 
			
		||||
      return this._changeBaseURL(req.changeNum, req.patchNum).then(url => {
 | 
			
		||||
        return this._restApiHelper.send({
 | 
			
		||||
          method: req.method,
 | 
			
		||||
          url: url + req.endpoint,
 | 
			
		||||
          body: req.body,
 | 
			
		||||
          errFn: req.errFn,
 | 
			
		||||
          contentType: req.contentType,
 | 
			
		||||
          headers: req.headers,
 | 
			
		||||
          parseResponse: req.parseResponse,
 | 
			
		||||
          anonymizedUrl: anonymizedEndpoint ?
 | 
			
		||||
            (anonymizedBaseUrl + anonymizedEndpoint) : undefined,
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
      return this._changeBaseURL(req.changeNum, req.patchNum)
 | 
			
		||||
          .then(url => this._restApiHelper.send({
 | 
			
		||||
            method: req.method,
 | 
			
		||||
            url: url + req.endpoint,
 | 
			
		||||
            body: req.body,
 | 
			
		||||
            errFn: req.errFn,
 | 
			
		||||
            contentType: req.contentType,
 | 
			
		||||
            headers: req.headers,
 | 
			
		||||
            parseResponse: req.parseResponse,
 | 
			
		||||
            anonymizedUrl: anonymizedEndpoint ?
 | 
			
		||||
              (anonymizedBaseUrl + anonymizedEndpoint) : undefined,
 | 
			
		||||
          }));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -2623,16 +2614,15 @@
 | 
			
		||||
        req.endpoint : req.anonymizedEndpoint;
 | 
			
		||||
      const anonymizedBaseUrl = req.patchNum ?
 | 
			
		||||
        ANONYMIZED_REVISION_BASE_URL : ANONYMIZED_CHANGE_BASE_URL;
 | 
			
		||||
      return this._changeBaseURL(req.changeNum, req.patchNum).then(url => {
 | 
			
		||||
        return this._restApiHelper.fetchJSON({
 | 
			
		||||
          url: url + req.endpoint,
 | 
			
		||||
          errFn: req.errFn,
 | 
			
		||||
          params: req.params,
 | 
			
		||||
          fetchOptions: req.fetchOptions,
 | 
			
		||||
          anonymizedUrl: anonymizedEndpoint ?
 | 
			
		||||
            (anonymizedBaseUrl + anonymizedEndpoint) : undefined,
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
      return this._changeBaseURL(req.changeNum, req.patchNum)
 | 
			
		||||
          .then(url => this._restApiHelper.fetchJSON({
 | 
			
		||||
            url: url + req.endpoint,
 | 
			
		||||
            errFn: req.errFn,
 | 
			
		||||
            params: req.params,
 | 
			
		||||
            fetchOptions: req.fetchOptions,
 | 
			
		||||
            anonymizedUrl: anonymizedEndpoint ?
 | 
			
		||||
              (anonymizedBaseUrl + anonymizedEndpoint) : undefined,
 | 
			
		||||
          }));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -66,22 +66,20 @@ limitations under the License.
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('parent diff comments are properly grouped', done => {
 | 
			
		||||
      sandbox.stub(element._restApiHelper, 'fetchJSON', () => {
 | 
			
		||||
        return Promise.resolve({
 | 
			
		||||
          '/COMMIT_MSG': [],
 | 
			
		||||
          'sieve.go': [
 | 
			
		||||
            {
 | 
			
		||||
              updated: '2017-02-03 22:32:28.000000000',
 | 
			
		||||
              message: 'this isn’t quite right',
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              side: 'PARENT',
 | 
			
		||||
              message: 'how did this work in the first place?',
 | 
			
		||||
              updated: '2017-02-03 22:33:28.000000000',
 | 
			
		||||
            },
 | 
			
		||||
          ],
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
      sandbox.stub(element._restApiHelper, 'fetchJSON', () => Promise.resolve({
 | 
			
		||||
        '/COMMIT_MSG': [],
 | 
			
		||||
        'sieve.go': [
 | 
			
		||||
          {
 | 
			
		||||
            updated: '2017-02-03 22:32:28.000000000',
 | 
			
		||||
            message: 'this isn’t quite right',
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            side: 'PARENT',
 | 
			
		||||
            message: 'how did this work in the first place?',
 | 
			
		||||
            updated: '2017-02-03 22:33:28.000000000',
 | 
			
		||||
          },
 | 
			
		||||
        ],
 | 
			
		||||
      }));
 | 
			
		||||
      element._getDiffComments('42', '', 'PARENT', 1, 'sieve.go').then(
 | 
			
		||||
          obj => {
 | 
			
		||||
            assert.equal(obj.baseComments.length, 1);
 | 
			
		||||
@@ -430,15 +428,12 @@ limitations under the License.
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    const preferenceSetup = function(testJSON, loggedIn, smallScreen) {
 | 
			
		||||
      sandbox.stub(element, 'getLoggedIn', () => {
 | 
			
		||||
        return Promise.resolve(loggedIn);
 | 
			
		||||
      });
 | 
			
		||||
      sandbox.stub(element, '_isNarrowScreen', () => {
 | 
			
		||||
        return smallScreen;
 | 
			
		||||
      });
 | 
			
		||||
      sandbox.stub(element._restApiHelper, 'fetchCacheURL', () => {
 | 
			
		||||
        return Promise.resolve(testJSON);
 | 
			
		||||
      });
 | 
			
		||||
      sandbox.stub(element, 'getLoggedIn', () => Promise.resolve(loggedIn));
 | 
			
		||||
      sandbox.stub(element, '_isNarrowScreen', () => smallScreen);
 | 
			
		||||
      sandbox.stub(
 | 
			
		||||
          element._restApiHelper,
 | 
			
		||||
          'fetchCacheURL',
 | 
			
		||||
          () => Promise.resolve(testJSON));
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    test('getPreferences returns correctly on small screens logged in',
 | 
			
		||||
@@ -537,9 +532,7 @@ limitations under the License.
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('getEditPreferences returns correct defaults', done => {
 | 
			
		||||
      sandbox.stub(element, 'getLoggedIn', () => {
 | 
			
		||||
        return Promise.resolve(false);
 | 
			
		||||
      });
 | 
			
		||||
      sandbox.stub(element, 'getLoggedIn', () => Promise.resolve(false));
 | 
			
		||||
 | 
			
		||||
      element.getEditPreferences().then(obj => {
 | 
			
		||||
        assert.equal(obj.auto_close_brackets, false);
 | 
			
		||||
@@ -982,12 +975,12 @@ limitations under the License.
 | 
			
		||||
          toHexStub = sandbox.stub(element, 'listChangesOptionsToHex',
 | 
			
		||||
              options => 'deadbeef');
 | 
			
		||||
          sandbox.stub(element, '_getChangeDetail',
 | 
			
		||||
              async (changeNum, options) => ({changeNum, options}));
 | 
			
		||||
              async (changeNum, options) => { return {changeNum, options}; });
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        test('signed pushes disabled', async () => {
 | 
			
		||||
          const {PUSH_CERTIFICATES} = element.ListChangesOption;
 | 
			
		||||
          sandbox.stub(element, 'getConfig', async () => ({}));
 | 
			
		||||
          sandbox.stub(element, 'getConfig', async () => { return {}; });
 | 
			
		||||
          const {changeNum, options} = await element.getChangeDetail(123);
 | 
			
		||||
          assert.strictEqual(123, changeNum);
 | 
			
		||||
          assert.strictEqual('deadbeef', options);
 | 
			
		||||
 
 | 
			
		||||
@@ -97,9 +97,7 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
    test('cached results', done => {
 | 
			
		||||
      let n = 0;
 | 
			
		||||
      sandbox.stub(helper, 'fetchJSON', () => {
 | 
			
		||||
        return Promise.resolve(++n);
 | 
			
		||||
      });
 | 
			
		||||
      sandbox.stub(helper, 'fetchJSON', () => Promise.resolve(++n));
 | 
			
		||||
      const promises = [];
 | 
			
		||||
      promises.push(helper.fetchCacheURL('/foo'));
 | 
			
		||||
      promises.push(helper.fetchCacheURL('/foo'));
 | 
			
		||||
@@ -164,7 +162,7 @@ limitations under the License.
 | 
			
		||||
          cancel() { cancelCalled = true; },
 | 
			
		||||
        },
 | 
			
		||||
      }));
 | 
			
		||||
      const cancelCondition = () => { return true; };
 | 
			
		||||
      const cancelCondition = () => true;
 | 
			
		||||
      helper.fetchJSON({url: '/dummy/url', cancelCondition}).then(
 | 
			
		||||
          obj => {
 | 
			
		||||
            assert.isUndefined(obj);
 | 
			
		||||
 
 | 
			
		||||
@@ -54,9 +54,10 @@
 | 
			
		||||
   * are used.
 | 
			
		||||
   */
 | 
			
		||||
  GrReviewerUpdatesParser.prototype._filterRemovedMessages = function() {
 | 
			
		||||
    this.result.messages = this.result.messages.filter(message => {
 | 
			
		||||
      return message.tag !== 'autogenerated:gerrit:deleteReviewer';
 | 
			
		||||
    });
 | 
			
		||||
    this.result.messages = this.result.messages
 | 
			
		||||
        .filter(
 | 
			
		||||
            message => message.tag !== 'autogenerated:gerrit:deleteReviewer'
 | 
			
		||||
        );
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
 
 | 
			
		||||
@@ -253,12 +253,10 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
    test('_advanceUpdates', () => {
 | 
			
		||||
      const T0 = util.parseDate('2017-02-17 19:04:18.000000000').getTime();
 | 
			
		||||
      const tplus = delta => {
 | 
			
		||||
        return new Date(T0 + delta)
 | 
			
		||||
            .toISOString()
 | 
			
		||||
            .replace('T', ' ')
 | 
			
		||||
            .replace('Z', '000000');
 | 
			
		||||
      };
 | 
			
		||||
      const tplus = delta => new Date(T0 + delta)
 | 
			
		||||
          .toISOString()
 | 
			
		||||
          .replace('T', ' ')
 | 
			
		||||
          .replace('Z', '000000');
 | 
			
		||||
      const change = {
 | 
			
		||||
        reviewer_updates: [{
 | 
			
		||||
          date: tplus(0),
 | 
			
		||||
 
 | 
			
		||||
@@ -302,9 +302,9 @@
 | 
			
		||||
        this._formatSuggestions(ALL_SUGGESTIONS);
 | 
			
		||||
        this.disableEnterKeyForSelectingEmoji = true;
 | 
			
		||||
      } else {
 | 
			
		||||
        const matches = ALL_SUGGESTIONS.filter(suggestion => {
 | 
			
		||||
          return suggestion.match.includes(emojiText);
 | 
			
		||||
        }).slice(0, MAX_ITEMS_DROPDOWN);
 | 
			
		||||
        const matches = ALL_SUGGESTIONS
 | 
			
		||||
            .filter(suggestion => suggestion.match.includes(emojiText))
 | 
			
		||||
            .slice(0, MAX_ITEMS_DROPDOWN);
 | 
			
		||||
        this._formatSuggestions(matches);
 | 
			
		||||
        this.disableEnterKeyForSelectingEmoji = false;
 | 
			
		||||
      }
 | 
			
		||||
 
 | 
			
		||||
@@ -31,9 +31,7 @@
 | 
			
		||||
          .then(groups => {
 | 
			
		||||
            if (!groups) { return []; }
 | 
			
		||||
            const keys = Object.keys(groups);
 | 
			
		||||
            return keys.map(key => {
 | 
			
		||||
              return Object.assign({}, groups[key], {name: key});
 | 
			
		||||
            });
 | 
			
		||||
            return keys.map(key => Object.assign({}, groups[key], {name: key}));
 | 
			
		||||
          });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -181,9 +181,7 @@ limitations under the License.
 | 
			
		||||
          });
 | 
			
		||||
 | 
			
		||||
          sandbox.stub(GrDisplayNameUtils, '_accountEmail',
 | 
			
		||||
              () => {
 | 
			
		||||
                return '';
 | 
			
		||||
              });
 | 
			
		||||
              () => '');
 | 
			
		||||
 | 
			
		||||
          suggestion = provider.makeSuggestionItem(account3);
 | 
			
		||||
          assert.deepEqual(suggestion, {
 | 
			
		||||
 
 | 
			
		||||
@@ -11,15 +11,11 @@ jasmine.DEFAULT_TIMEOUT_INTERVAL = 20000;
 | 
			
		||||
describe('example ', () => {
 | 
			
		||||
  let driver;
 | 
			
		||||
 | 
			
		||||
  beforeAll(() => {
 | 
			
		||||
    return setup().then(d => driver = d);
 | 
			
		||||
  });
 | 
			
		||||
  beforeAll(() => setup().then(d => driver = d));
 | 
			
		||||
 | 
			
		||||
  afterAll(() => {
 | 
			
		||||
    return cleanup();
 | 
			
		||||
  });
 | 
			
		||||
  afterAll(() => cleanup());
 | 
			
		||||
 | 
			
		||||
  it('should update title', () => {
 | 
			
		||||
    return driver.wait(until.titleIs('status:open · Gerrit Code Review'), 5000);
 | 
			
		||||
  });
 | 
			
		||||
  it('should update title', () => driver.wait(
 | 
			
		||||
      until.titleIs('status:open · Gerrit Code Review'), 5000
 | 
			
		||||
  ));
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user