Only show help for creating changes to new users

The conditions for displaying expanded in-product help for creating a
change are now:

  * user is signed in
  * user is viewing own dashboard
  * user owns zero changes

The zero changes owned condition is determined by adding an additional
query to the set sent to the changes endpoint.

Bug: Issue 9728
Change-Id: I165a3e5e126185b0965d87649d612064eb498e76
diff --git a/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.html b/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.html
index 84ada58..a61d00d 100644
--- a/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.html
+++ b/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.html
@@ -126,23 +126,25 @@
           on-toggle-star="_handleToggleStar"
           on-toggle-reviewed="_handleToggleReviewed">
         <div id="emptyOutgoing" slot="empty-outgoing">
-          <div id="graphic">
-            <svg width="150" height="100">
-              <circle cx="50" cy="50" r="50"></circle>
-            </svg>
-            <p>
-              No outgoing changes yet
-            </p>
-          </div>
-          <div id="help">
-            <h1>Push your first changes for code review</h1>
-            <p>
-              Pushing a change for review is easy, but a little different from
-              other git code review tools. Click on the `Create Change' button
-              and follow the step by step instructions.
-            </p>
-            <gr-button on-tap="_createChangeTap">Create Change</gr-button>
-          </div>
+          <template is="dom-if" if="_showNewUserHelp">
+            <div id="graphic">
+              <svg width="150" height="100">
+                <circle cx="50" cy="50" r="50"></circle>
+              </svg>
+              <p>
+                No outgoing changes yet
+              </p>
+            </div>
+            <div id="help">
+              <h1>Push your first changes for code review</h1>
+              <p>
+                Pushing a change for review is easy, but a little different from
+                other git code review tools. Click on the `Create Change' button
+                and follow the step by step instructions.
+              </p>
+              <gr-button on-tap="_createChangeTap">Create Change</gr-button>
+            </div>
+          </template>
         </div>
       </gr-change-list>
     </div>
diff --git a/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.js b/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.js
index 54fd8b3..99cb1e9 100644
--- a/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.js
+++ b/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.js
@@ -56,6 +56,11 @@
         type: Boolean,
         value: false,
       },
+
+      _showNewUserHelp: {
+        type: Boolean,
+        value: false,
+      },
     },
 
     observers: [
@@ -156,7 +161,9 @@
               sections,
               title || this._computeTitle(user)));
 
-      return dashboardPromise.then(this._fetchDashboardChanges.bind(this))
+      const checkForNewUser = !project && user === 'self';
+      return dashboardPromise
+          .then(res => this._fetchDashboardChanges(res, checkForNewUser))
           .then(() => {
             this._maybeShowDraftsBanner();
             this.$.reporting.dashboardDisplayed();
@@ -170,26 +177,36 @@
      * with the response.
      *
      * @param {!Object} res
+     * @param {boolean} checkForNewUser
      * @return {Promise}
      */
-    _fetchDashboardChanges(res) {
+    _fetchDashboardChanges(res, checkForNewUser) {
       if (!res) { return Promise.resolve(); }
-      const queries = res.sections.map(section => {
-        if (section.suffixForDashboard) {
-          return section.query + ' ' + section.suffixForDashboard;
-        }
-        return section.query;
-      });
+
+      const queries = res.sections
+          .map(section => section.suffixForDashboard ?
+              section.query + ' ' + section.suffixForDashboard :
+              section.query);
+
+      if (checkForNewUser) {
+        queries.push('owner:self');
+      }
 
       return this.$.restAPI.getChanges(null, queries, null, this.options)
           .then(changes => {
+            if (checkForNewUser) {
+              // Last set of results is not meant for dashboard display.
+              const lastResultSet = changes.pop();
+              this._showNewUserHelp = lastResultSet.length == 0;
+            }
             this._results = changes.map((results, i) => ({
               sectionName: res.sections[i].name,
               query: res.sections[i].query,
               results,
               isOutgoing: res.sections[i].isOutgoing,
-            })).filter((section, i) => !res.sections[i].hideIfEmpty ||
-                section.results.length);
+            })).filter((section, i) => i < res.sections.length && (
+                !res.sections[i].hideIfEmpty ||
+                section.results.length));
           });
     },
 
diff --git a/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view_test.html b/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view_test.html
index 83ba096..17484b0 100644
--- a/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view_test.html
+++ b/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view_test.html
@@ -47,7 +47,7 @@
       element = fixture('basic');
       sandbox = sinon.sandbox.create();
       getChangesStub = sandbox.stub(element.$.restAPI, 'getChanges',
-          () => Promise.resolve([]));
+          (_, qs) => Promise.resolve(qs.map(() => [])));
 
       let resolver;
       paramsChangedPromise = new Promise(resolve => {
@@ -177,12 +177,12 @@
             {query: '1'},
             {query: '2', selfOnly: true},
           ],
-          user: 'user',
+          user: 'self',
         };
         return paramsChangedPromise.then(() => {
           assert.isTrue(
               getChangesStub.calledWith(
-                  null, ['1'], null, element.options));
+                  null, ['1', '2', 'owner:self'], null, element.options));
         });
       });
 
@@ -193,12 +193,12 @@
             {query: '1'},
             {query: '2', selfOnly: true},
           ],
-          user: 'self',
+          user: 'user',
         };
         return paramsChangedPromise.then(() => {
           assert.isTrue(
               getChangesStub.calledWith(
-                  null, ['1', '2'], null, element.options));
+                  null, ['1'], null, element.options));
         });
       });
     });
@@ -277,7 +277,7 @@
       sandbox.stub(element.$.restAPI, 'getChanges')
           .returns(Promise.resolve([[], ['nonempty']]));
 
-      return element._fetchDashboardChanges({sections}).then(() => {
+      return element._fetchDashboardChanges({sections}, false).then(() => {
         assert.equal(element._results.length, 1);
         assert.equal(element._results[0].sectionName, 'test2');
       });
@@ -292,7 +292,7 @@
       sandbox.stub(element.$.restAPI, 'getChanges')
           .returns(Promise.resolve([[], []]));
 
-      return element._fetchDashboardChanges({sections}).then(() => {
+      return element._fetchDashboardChanges({sections}, false).then(() => {
         assert.equal(element._results.length, 2);
         assert.isTrue(element._results[0].isOutgoing);
         assert.isNotOk(element._results[1].isOutgoing);
@@ -308,8 +308,8 @@
 
     test('404 page', done => {
       const response = {status: 404};
-      sandbox.stub(
-          element.$.restAPI, 'getDashboard', (project, dashboard, errFn) => {
+      sandbox.stub(element.$.restAPI, 'getDashboard',
+          async (project, dashboard, errFn) => {
             errFn(response);
           });
       element.addEventListener('page-error', e => {