cros-preview: Initialize to set active destination

- Move fetch destination into helper function and call from initialize
  session.
- Check if manager is initialized before setting active destination.
- Update select test to ensure initializeSession called.
- Test active destination is not set if getLocalDestinations resolves
  before initializeSession is called.

Bug: b:323421684
Test: browser_test --gtest_filter=*PrintPreviewCros*
Change-Id: Idc41241f398cd54307dff5647ebc503ddd65dbaf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5530980
Reviewed-by: Gavin Williams <gavinwill@chromium.org>
Commit-Queue: Ashley Prasad <ashleydp@google.com>
Cr-Commit-Position: refs/heads/main@{#1302848}
diff --git a/ash/webui/print_preview_cros/resources/js/data/destination_manager.ts b/ash/webui/print_preview_cros/resources/js/data/destination_manager.ts
index 58b38a96..af53a665 100644
--- a/ash/webui/print_preview_cros/resources/js/data/destination_manager.ts
+++ b/ash/webui/print_preview_cros/resources/js/data/destination_manager.ts
@@ -71,6 +71,7 @@
     assert(
         !this.sessionContext, 'SessionContext should only be configured once');
     this.sessionContext = sessionContext;
+    this.fetchInitialDestinations();
     this.dispatchEvent(
         createCustomEvent(DESTINATION_MANAGER_SESSION_INITIALIZED));
   }
@@ -92,20 +93,6 @@
     // Digital destinations can be added at creation and will be removed during
     // session initialization if not supported by policy.
     this.insertDigitalDestinations();
-
-    // Request initial data.
-    this.updateState(DestinationManagerState.FETCHING);
-    // TODO(b/323421684): Once the initial local destinations fetch completes
-    // update has initial destination set, determine relevant initial
-    // destination, and create the initial print ticket. If policy restricts
-    // fetching a destination type an empty destination list will be returned.
-    this.destinationProvider.getLocalDestinations().then(
-        (destinations: Destination[]): void => {
-          this.addOrUpdateDestinations(destinations);
-          this.updateActiveDestination(PDF_DESTINATION.id);
-          this.initialDestinationsLoaded = true;
-          this.updateState(DestinationManagerState.LOADED);
-        });
   }
 
   // TODO(b/323421684): Returns true if initial fetch has returned
@@ -184,6 +171,26 @@
     this.destinations[index] = destination;
   }
 
+  // Requests destinations from backend and updates manager state to `FETCHING`.
+  // Once destinations have been stored, the state is updated to `LOADED` and
+  // attempts to select an initial destination.
+  private fetchInitialDestinations(): void {
+    assert(this.isSessionInitialized);
+    // Request initial data.
+    this.updateState(DestinationManagerState.FETCHING);
+    // TODO(b/323421684): Once the initial local destinations fetch completes
+    // update has initial destination set, determine relevant initial
+    // destination, and create the initial print ticket. If policy restricts
+    // fetching a destination type an empty destination list will be returned.
+    this.destinationProvider.getLocalDestinations().then(
+        (destinations: Destination[]): void => {
+          this.addOrUpdateDestinations(destinations);
+          this.initialDestinationsLoaded = true;
+          this.updateActiveDestination(PDF_DESTINATION.id);
+          this.updateState(DestinationManagerState.LOADED);
+        });
+  }
+
   // Insert hard-coded digital destinations into set of known destinations.
   // Function should only be called once per session.
   private insertDigitalDestinations(): void {
diff --git a/chrome/test/data/webui/chromeos/print_preview_cros/capabilities_manager_test.ts b/chrome/test/data/webui/chromeos/print_preview_cros/capabilities_manager_test.ts
index b7ec6b6d..08070e69 100644
--- a/chrome/test/data/webui/chromeos/print_preview_cros/capabilities_manager_test.ts
+++ b/chrome/test/data/webui/chromeos/print_preview_cros/capabilities_manager_test.ts
@@ -40,6 +40,7 @@
   // Initialize the DestinationManager and wait for it to send all events.
   async function waitForDestinationManagerLoad(): Promise<void> {
     const destinationManager = DestinationManager.getInstance();
+    destinationManager.initializeSession(FAKE_PRINT_SESSION_CONTEXT_SUCCESSFUL);
     const activeDestinationChangedEvent = eventToPromise(
         DESTINATION_MANAGER_ACTIVE_DESTINATION_CHANGED, destinationManager);
     return activeDestinationChangedEvent;
diff --git a/chrome/test/data/webui/chromeos/print_preview_cros/destination_manager_test.ts b/chrome/test/data/webui/chromeos/print_preview_cros/destination_manager_test.ts
index fb0e0b3..bf6152b 100644
--- a/chrome/test/data/webui/chromeos/print_preview_cros/destination_manager_test.ts
+++ b/chrome/test/data/webui/chromeos/print_preview_cros/destination_manager_test.ts
@@ -72,13 +72,21 @@
     assertNotEquals(notFoundIndex, pdfIndex, 'PDF destination available');
   });
 
-  // Verify getLocalDestinations is called on construction of manager.
-  test('on create getLocalDestinations is called', () => {
-    const expectedCallCount = 1;
+  // Verify getLocalDestinations is called during initializeSession.
+  test('initializeSession calls getLocalDestinations', () => {
+    let expectedCallCount = 0;
     assertEquals(
         expectedCallCount,
         destinationProvider.getCallCount(GET_LOCAL_DESTINATIONS_METHOD),
-        `${GET_LOCAL_DESTINATIONS_METHOD} called in construction of manager`);
+        `${GET_LOCAL_DESTINATIONS_METHOD} not called`);
+
+    // Initialize destination manager.
+    instance.initializeSession(FAKE_PRINT_SESSION_CONTEXT_SUCCESSFUL);
+    ++expectedCallCount;
+    assertEquals(
+        expectedCallCount,
+        destinationProvider.getCallCount(GET_LOCAL_DESTINATIONS_METHOD),
+        `${GET_LOCAL_DESTINATIONS_METHOD} called`);
   });
 
   // Verify destination manager state updated called when getLocalDestinations
@@ -86,14 +94,18 @@
   test(
       'starting and resolving getLocalDestinations triggers state update',
       async () => {
+        let stateChange =
+            eventToPromise(DESTINATION_MANAGER_STATE_CHANGED, instance);
+        instance.initializeSession(FAKE_PRINT_SESSION_CONTEXT_SUCCESSFUL);
+        await stateChange;
         assertEquals(
             DestinationManagerState.FETCHING, instance.getState(),
             'Fetch in progress');
 
-        const stateChanged =
+        stateChange =
             eventToPromise(DESTINATION_MANAGER_STATE_CHANGED, instance);
         mockTimer.tick(testDelay);
-        await stateChanged;
+        await stateChange;
 
         assertEquals(
             DestinationManagerState.LOADED, instance.getState(),
@@ -101,28 +113,23 @@
       });
 
   // Verify destination manager sets fallback destination to PDF if no other
-  // destinations are returned in local printer fetch.
+  // destinations are returned in local printer fetch and session is
+  // initialized.
   test(
       'starting and resolving getLocalDestinations triggers state active' +
           ' destination update',
       async () => {
         assertEquals(
-            DestinationManagerState.FETCHING, instance.getState(),
-            'Fetch in progress');
-        assertEquals(
             null, instance.getActiveDestination(),
             'Fallback destination is not set before loading local printers');
 
-        const stateChanged = eventToPromise(
+        // Resolve local printers fetch and initialize session.
+        const activeDestChange = eventToPromise(
             DESTINATION_MANAGER_ACTIVE_DESTINATION_CHANGED, instance);
-
-        // Resolve local printers fetch.
+        instance.initializeSession(FAKE_PRINT_SESSION_CONTEXT_SUCCESSFUL);
         mockTimer.tick(testDelay);
-        await stateChanged;
+        await activeDestChange;
 
-        assertEquals(
-            DestinationManagerState.LOADED, instance.getState(),
-            'Fetch complete');
         assertDeepEquals(
             PDF_DESTINATION, instance.getActiveDestination(),
             `Fallback destination is ${PDF_DESTINATION.displayName}`);
@@ -265,6 +272,7 @@
       async () => {
         const destinations = [createTestDestination()];
         destinationProvider.setLocalDestinationResult(destinations);
+        instance.initializeSession(FAKE_PRINT_SESSION_CONTEXT_SUCCESSFUL);
         const stateChanged =
             eventToPromise(DESTINATION_MANAGER_STATE_CHANGED, instance);
 
@@ -286,7 +294,7 @@
         const testDestination = createTestDestination();
         testDestination.printerManuallySelected = true;
         instance.setDestinationForTesting(testDestination);
-
+        instance.initializeSession(FAKE_PRINT_SESSION_CONTEXT_SUCCESSFUL);
         let managerDestinations = instance.getDestinations();
         let expectedDestinations = [PDF_DESTINATION, testDestination];
         assertDeepEquals(expectedDestinations, managerDestinations);
diff --git a/chrome/test/data/webui/chromeos/print_preview_cros/destination_select_test.ts b/chrome/test/data/webui/chromeos/print_preview_cros/destination_select_test.ts
index 9448f456..9aec8a7 100644
--- a/chrome/test/data/webui/chromeos/print_preview_cros/destination_select_test.ts
+++ b/chrome/test/data/webui/chromeos/print_preview_cros/destination_select_test.ts
@@ -41,6 +41,7 @@
 
     DestinationManager.resetInstanceForTesting();
     destinationManager = DestinationManager.getInstance();
+    destinationManager.initializeSession(FAKE_PRINT_SESSION_CONTEXT_SUCCESSFUL);
 
     element = document.createElement(DestinationSelectElement.is) as
         DestinationSelectElement;
@@ -125,10 +126,7 @@
             isChildVisible(element, loadingSelector),
             `${loadingSelector} should be visible`);
 
-        // Move time forward to resolve getLocalDestinations in manager and
-        // ensure manager is initialized.
-        destinationManager.initializeSession(
-            FAKE_PRINT_SESSION_CONTEXT_SUCCESSFUL);
+        // Move time forward to resolve getLocalDestinations in manager.
         const changeEvent =
             eventToPromise(DESTINATION_SELECT_SHOW_LOADING_CHANGED, controller);
         mockTimer.tick(testDelay);