Fill account details in mentionedUsersInDrafts

Change 344637 added this for mentionedUsersInUnresolvedDrafts.

Google-bug-id: b/236921879
Release-Notes: skip
Change-Id: I2fb867e11ffa050629c3382303d90231f6e9843a
diff --git a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.ts b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.ts
index a6f33fa..3b2d697 100644
--- a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.ts
+++ b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.ts
@@ -2554,6 +2554,11 @@
     });
 
     test('mentioned user in resolved draft is added to CC', async () => {
+      const account = {
+        ...createAccountWithEmail('abcd@def.com' as EmailAddress),
+        registered_on: '2015-03-12 18:32:08.000000000' as Timestamp,
+      };
+      stubRestApi('getAccountDetails').returns(Promise.resolve(account));
       const draft = {
         ...createDraft(),
         message: 'hey @abcd@def take a look at this',
@@ -2574,10 +2579,8 @@
 
       await element.updateComplete;
 
-      assert.deepEqual(element.mentionedUsers, [
-        {email: 'abcd@def' as EmailAddress},
-      ]);
-      assert.deepEqual(element.ccs, [{email: 'abcd@def' as EmailAddress}]);
+      assert.deepEqual(element.mentionedUsers, [account]);
+      assert.deepEqual(element.ccs, [account]);
 
       // owner(999) is added since (accountId = 1) replied to the change
       assert.sameMembers([...element.newAttentionSet], [999 as AccountId]);
@@ -2615,12 +2618,14 @@
       assert.deepEqual(element.mentionedUsers, [
         {
           email: 'abcd@def.com' as EmailAddress,
-        },
+          registered_on: '2015-03-12 18:32:08.000000000' as Timestamp,
+        } as AccountInfo,
       ]);
       assert.deepEqual(element.ccs, [
         {
           email: 'abcd@def.com' as EmailAddress,
-        },
+          registered_on: '2015-03-12 18:32:08.000000000' as Timestamp,
+        } as AccountInfo,
       ]);
 
       // owner(999) is added since (accountId = 1) replied to the change
@@ -2677,7 +2682,8 @@
       );
       assert.deepEqual(accountsChips[1].account, {
         email: 'abcd@def.com' as EmailAddress,
-      });
+        registered_on: '2015-03-12 18:32:08.000000000' as Timestamp,
+      } as AccountInfo);
       accountsChips[1].click();
 
       await element.updateComplete;
@@ -2686,6 +2692,12 @@
     });
 
     test('mention user who is already CCed', async () => {
+      const account = {
+        ...createAccountWithEmail('abcd@def.com' as EmailAddress),
+        registered_on: '2015-03-12 18:32:08.000000000' as Timestamp,
+      };
+      stubRestApi('getAccountDetails').returns(Promise.resolve(account));
+
       element.getCommentsModel().setState({
         comments: {},
         robotComments: {},
@@ -2704,22 +2716,24 @@
       });
 
       await element.updateComplete;
+      await waitUntil(() => element.mentionedUsers.length > 0);
 
-      assert.deepEqual(element.ccs, [{email: 'abcd@def.com' as EmailAddress}]);
-      assert.deepEqual(element.mentionedUsers, [
-        {email: 'abcd@def.com' as EmailAddress},
-      ]);
+      assert.deepEqual(element.ccs, [account]);
+      assert.deepEqual(element.mentionedUsers, [account]);
       element._ccs = [createAccountWithEmail('abcd@def.com')];
 
       await element.updateComplete;
 
-      assert.deepEqual(element.mentionedUsers, [
-        {email: 'abcd@def.com' as EmailAddress},
-      ]);
+      assert.deepEqual(element.mentionedUsers, [account]);
       assert.deepEqual(element.ccs, [{email: 'abcd@def.com' as EmailAddress}]);
     });
 
     test('mention user who is already a reviewer', async () => {
+      const account = {
+        ...createAccountWithEmail('abcd@def.com' as EmailAddress),
+        registered_on: '2015-03-12 18:32:08.000000000' as Timestamp,
+      };
+      stubRestApi('getAccountDetails').returns(Promise.resolve(account));
       element.getCommentsModel().setState({
         comments: {},
         robotComments: {},
@@ -2736,10 +2750,11 @@
         portedDrafts: {},
         discardedDrafts: [],
       });
+
       await element.updateComplete;
-      assert.deepEqual(element.mentionedUsers, [
-        {email: 'abcd@def.com' as EmailAddress},
-      ]);
+      await waitUntil(() => element.mentionedUsers.length > 0);
+
+      assert.deepEqual(element.mentionedUsers, [account]);
 
       // ensure updates to reviewers is reflected to mentionedUsers property
       element.reviewers = [createAccountWithEmail('abcd@def.com')];
@@ -2748,13 +2763,9 @@
 
       // overall ccs is empty since we filter out existing reviewers
       assert.deepEqual(element.ccs, []);
-      assert.deepEqual(element.mentionedUsers, [
-        {email: 'abcd@def.com' as EmailAddress},
-      ]);
+      assert.deepEqual(element.mentionedUsers, [account]);
       assert.deepEqual(element.reviewers, [
-        {
-          email: 'abcd@def.com' as EmailAddress,
-        },
+        {email: 'abcd@def.com' as EmailAddress},
       ]);
     });
   });
diff --git a/polygerrit-ui/app/models/comments/comments-model.ts b/polygerrit-ui/app/models/comments/comments-model.ts
index 9957c66..debb1b8 100644
--- a/polygerrit-ui/app/models/comments/comments-model.ts
+++ b/polygerrit-ui/app/models/comments/comments-model.ts
@@ -279,17 +279,26 @@
       )
   );
 
-  public readonly mentionedUsersInDrafts$ = select(this.drafts$, drafts => {
-    const users: AccountInfo[] = [];
-    const comments = Object.values(drafts ?? {}).flat();
-    for (const comment of comments) {
-      users.push(...extractMentionedUsers(comment.message));
-    }
-    return users.filter(
-      (user, index) =>
-        index === users.findIndex(u => getUserId(u) === getUserId(user))
+  public readonly mentionedUsersInDrafts$: Observable<AccountInfo[]> =
+    this.drafts$.pipe(
+      switchMap(drafts => {
+        const users: AccountInfo[] = [];
+        const comments = Object.values(drafts ?? {}).flat();
+        for (const comment of comments) {
+          users.push(...extractMentionedUsers(comment.message));
+        }
+        const uniqueUsers = users.filter(
+          (user, index) =>
+            index === users.findIndex(u => getUserId(u) === getUserId(user))
+        );
+        const filledUsers$: Observable<AccountInfo | undefined>[] =
+          uniqueUsers.map(user => from(this.accountsModel.fillDetails(user)));
+        return forkJoin(filledUsers$);
+      }),
+      map(users => users.filter(notUndefined)),
+      distinctUntilChanged(deepEqual),
+      shareReplay(1)
     );
-  });
 
   public readonly mentionedUsersInUnresolvedDrafts$: Observable<AccountInfo[]> =
     this.drafts$.pipe(
diff --git a/polygerrit-ui/app/models/comments/comments-model_test.ts b/polygerrit-ui/app/models/comments/comments-model_test.ts
index ba7bd2d..3bc84be 100644
--- a/polygerrit-ui/app/models/comments/comments-model_test.ts
+++ b/polygerrit-ui/app/models/comments/comments-model_test.ts
@@ -4,10 +4,14 @@
  * SPDX-License-Identifier: Apache-2.0
  */
 import '../../test/common-test-setup';
-import {createDraft} from '../../test/test-data-generators';
+import {
+  createAccountWithEmail,
+  createDraft,
+} from '../../test/test-data-generators';
 import {
   AccountInfo,
   EmailAddress,
+  Timestamp,
   UrlEncodedCommentId,
 } from '../../types/common';
 import {CommentsModel, deleteDraft} from './comments-model';
@@ -120,6 +124,11 @@
   });
 
   test('duplicate mentions are filtered out', async () => {
+    const account = {
+      ...createAccountWithEmail('abcd@def.com' as EmailAddress),
+      registered_on: '2015-03-12 18:32:08.000000000' as Timestamp,
+    };
+    stubRestApi('getAccountDetails').returns(Promise.resolve(account));
     const model = new CommentsModel(
       getAppContext().routerModel,
       testResolver(changeModelToken),
@@ -139,6 +148,6 @@
 
     await waitUntil(() => mentionedUsers.length > 0);
 
-    assert.deepEqual(mentionedUsers, [{email: 'abc@def.com' as EmailAddress}]);
+    assert.deepEqual(mentionedUsers, [account]);
   });
 });