Refactor gr-download-commands to use preferences state

Change-Id: Ic658d2e7d9286803519508a3b1b9f7f57989086b
diff --git a/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands.ts b/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands.ts
index e93013e..191cadf 100644
--- a/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands.ts
+++ b/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands.ts
@@ -19,11 +19,14 @@
 import '../../../styles/shared-styles';
 import {PolymerElement} from '@polymer/polymer/polymer-element';
 import {htmlTemplate} from './gr-download-commands_html';
-import {customElement, property, observe} from '@polymer/decorators';
+import {customElement, property} from '@polymer/decorators';
 import {PaperTabsElement} from '@polymer/paper-tabs/paper-tabs';
 import {appContext} from '../../../services/app-context';
 import {queryAndAssert} from '../../../utils/common-util';
 import {GrShellCommand} from '../gr-shell-command/gr-shell-command';
+import {preferences$} from '../../../services/user/user-model';
+import {takeUntil} from 'rxjs/operators';
+import {Subject} from 'rxjs';
 
 declare global {
   interface HTMLElementTagNameMap {
@@ -66,12 +69,26 @@
 
   private readonly restApiService = appContext.restApiService;
 
+  disconnected$ = new Subject();
+
   /** @override */
   connectedCallback() {
     super.connectedCallback();
     this._getLoggedIn().then(loggedIn => {
       this._loggedIn = loggedIn;
     });
+    preferences$.pipe(takeUntil(this.disconnected$)).subscribe(prefs => {
+      if (prefs?.download_scheme) {
+        // Note (issue 5180): normalize the download scheme with lower-case.
+        this.selectedScheme = prefs.download_scheme.toLowerCase();
+      }
+    });
+  }
+
+  /** @override */
+  disconnectedCallback() {
+    this.disconnected$.next();
+    super.disconnectedCallback();
   }
 
   focusOnCopy() {
@@ -82,19 +99,6 @@
     return this.restApiService.getLoggedIn();
   }
 
-  @observe('_loggedIn')
-  _loggedInChanged(loggedIn: boolean) {
-    if (!loggedIn) {
-      return;
-    }
-    return this.restApiService.getPreferences().then(prefs => {
-      if (prefs?.download_scheme) {
-        // Note (issue 5180): normalize the download scheme with lower-case.
-        this.selectedScheme = prefs.download_scheme.toLowerCase();
-      }
-    });
-  }
-
   _handleTabChange(e: CustomEvent<{value: number}>) {
     const scheme = this.schemes[e.detail.value];
     if (scheme && scheme !== this.selectedScheme) {
diff --git a/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands_test.js b/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands_test.js
index 6427c6b..694cfca 100644
--- a/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands_test.js
@@ -18,6 +18,8 @@
 import '../../../test/common-test-setup-karma.js';
 import './gr-download-commands.js';
 import {isHidden, stubRestApi} from '../../../test/test-utils.js';
+import {updatePreferences} from '../../../services/user/user-model.js';
+import {createPreferences} from '../../../test/test-data-generators.js';
 
 const basicFixture = fixtureFromElement('gr-download-commands');
 
@@ -84,26 +86,6 @@
       assert.equal(element.$.downloadTabs.selected, '2');
     });
 
-    test('loads scheme from preferences', async () => {
-      const stub = stubRestApi('getPreferences').returns(
-          Promise.resolve({download_scheme: 'repo'}));
-      element._loggedIn = true;
-      await flush();
-      assert.isTrue(stub.called);
-      await stub.lastCall.returnValue;
-      assert.equal(element.selectedScheme, 'repo');
-    });
-
-    test('normalize scheme from preferences', async () => {
-      const stub = stubRestApi('getPreferences').returns(
-          Promise.resolve({download_scheme: 'REPO'}));
-      element._loggedIn = true;
-      await flush();
-      assert.isTrue(stub.called);
-      await stub.lastCall.returnValue;
-      assert.equal(element.selectedScheme, 'repo');
-    });
-
     test('saves scheme to preferences', () => {
       element._loggedIn = true;
       const savePrefsStub = stubRestApi('savePreferences').returns(
@@ -121,5 +103,26 @@
           repoTab.getAttribute('data-scheme'));
     });
   });
+  suite('authenticated', () => {
+    test('loads scheme from preferences', async () => {
+      updatePreferences({
+        ...createPreferences(),
+        download_scheme: 'repo',
+      });
+      const element = basicFixture.instantiate();
+      await flush();
+      assert.equal(element.selectedScheme, 'repo');
+    });
+
+    test('normalize scheme from preferences', async () => {
+      updatePreferences({
+        ...createPreferences(),
+        download_scheme: 'REPO',
+      });
+      const element = basicFixture.instantiate();
+      await flush();
+      assert.equal(element.selectedScheme, 'repo');
+    });
+  });
 });
 
diff --git a/polygerrit-ui/app/test/common-test-setup.ts b/polygerrit-ui/app/test/common-test-setup.ts
index 641e4b3..5d2bdaf 100644
--- a/polygerrit-ui/app/test/common-test-setup.ts
+++ b/polygerrit-ui/app/test/common-test-setup.ts
@@ -44,6 +44,8 @@
 } from '../scripts/polymer-resin-install';
 import {_testOnly_allTasks} from '../utils/async-util';
 import {cleanUpStorage} from '../services/storage/gr-storage_mock';
+import {updatePreferences} from '../services/user/user-model';
+import {createDefaultPreferences} from '../constants/constants';
 
 declare global {
   interface Window {
@@ -202,6 +204,8 @@
   removeIronOverlayBackdropStyleEl();
   cancelAllTasks();
   cleanUpStorage();
+  // Reset state
+  updatePreferences(createDefaultPreferences());
   const testTeardownTimestampMs = new Date().getTime();
   const elapsedMs = testTeardownTimestampMs - testSetupTimestampMs;
   if (elapsedMs > 1000) {