]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: rgw users link user with account e2e failure 66286/head
authorNaman Munet <naman.munet@ibm.com>
Mon, 17 Nov 2025 16:22:01 +0000 (21:52 +0530)
committerNaman Munet <naman.munet@ibm.com>
Mon, 17 Nov 2025 16:22:01 +0000 (21:52 +0530)
Fixes: https://tracker.ceph.com/issues/73835
Changes Include:
Previously, users were initialized without their associated account data,
causing issues in table display and row expansion.

This change ensures that users are initialized only after fetching accounts
and mapping them to each user. If the account API fails, users are still
initialized with a default empty account to prevent errors.

Signed-off-by: Naman Munet <naman.munet@ibm.com>
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts

index dd4c6c92711b8c859fad1a6ac341dd977b5605a8..d62f6ac8b8006f746acf108006c7ef385b9e5728 100644 (file)
@@ -11,12 +11,15 @@ import { TableActionsComponent } from '~/app/shared/datatable/table-actions/tabl
 import { SharedModule } from '~/app/shared/shared.module';
 import { configureTestBed, PermissionHelper } from '~/testing/unit-test-helper';
 import { RgwUserListComponent } from './rgw-user-list.component';
+import { RgwUserAccountsService } from '~/app/shared/api/rgw-user-accounts.service';
 
 describe('RgwUserListComponent', () => {
   let component: RgwUserListComponent;
   let fixture: ComponentFixture<RgwUserListComponent>;
   let rgwUserService: RgwUserService;
   let rgwUserServiceListSpy: jasmine.Spy;
+  let rgwUserAccountService: RgwUserAccountsService;
+  let rgwUserAccountServiceListSpy: jasmine.Spy;
 
   configureTestBed({
     declarations: [RgwUserListComponent],
@@ -26,8 +29,11 @@ describe('RgwUserListComponent', () => {
 
   beforeEach(() => {
     rgwUserService = TestBed.inject(RgwUserService);
+    rgwUserAccountService = TestBed.inject(RgwUserAccountsService);
     rgwUserServiceListSpy = spyOn(rgwUserService, 'list');
+    rgwUserAccountServiceListSpy = spyOn(rgwUserAccountService, 'list');
     rgwUserServiceListSpy.and.returnValue(of([]));
+    rgwUserAccountServiceListSpy.and.returnValue(of([]));
     fixture = TestBed.createComponent(RgwUserListComponent);
     component = fixture.componentInstance;
     spyOn(component, 'setTableRefreshTimeout').and.stub();
@@ -142,6 +148,7 @@ describe('RgwUserListComponent', () => {
     expect(rgwUserServiceListSpy).toHaveBeenCalledTimes(2);
     expect(component.users).toEqual([
       {
+        account: { name: '' },
         user_id: 'testid',
         stats: {
           size_actual: 6,
index 80e29fb8a318c6cd8630999d438b2624153329bc..82178cd7baf995463de8b4117024ed61c7fb6676 100644 (file)
@@ -1,6 +1,6 @@
 import { Component, NgZone, OnInit, TemplateRef, ViewChild } from '@angular/core';
 
-import { forkJoin as observableForkJoin, Observable, Subscriber, Subject } from 'rxjs';
+import { forkJoin as observableForkJoin, Observable, Subscriber, Subject, of } from 'rxjs';
 import { RgwUserAccountsService } from '~/app/shared/api/rgw-user-accounts.service';
 
 import { RgwUserService } from '~/app/shared/api/rgw-user.service';
@@ -20,7 +20,7 @@ import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
 import { ModalCdsService } from '~/app/shared/services/modal-cds.service';
 import { URLBuilderService } from '~/app/shared/services/url-builder.service';
 import { Account } from '../models/rgw-user-accounts';
-import { switchMap } from 'rxjs/operators';
+import { catchError, map, switchMap } from 'rxjs/operators';
 import { RgwUser } from '../models/rgw-user';
 
 const BASE_URL = 'rgw/user';
@@ -43,7 +43,7 @@ export class RgwUserListComponent extends ListWithDetails implements OnInit {
   permission: Permission;
   tableActions: CdTableAction[];
   columns: CdTableColumn[] = [];
-  users: object[] = [];
+  users: RgwUser[] = [];
   userAccounts: Account[];
   selection: CdTableSelection = new CdTableSelection();
   userDataSubject = new Subject();
@@ -121,15 +121,19 @@ export class RgwUserListComponent extends ListWithDetails implements OnInit {
         flexGrow: 0.8
       }
     ];
+
     this.userDataSubject
       .pipe(
-        switchMap((_: object[]) => {
-          return this.rgwUserAccountService.list(true);
-        })
+        switchMap((users: RgwUser[]) =>
+          this.rgwUserAccountService.list(true).pipe(
+            map((accounts: Account[]) => ({ users, accounts })),
+            catchError(() => of({ users, accounts: [] }))
+          )
+        )
       )
-      .subscribe((accounts: Account[]) => {
+      .subscribe(({ users, accounts }) => {
         this.userAccounts = accounts;
-        this.mapUsersWithAccount();
+        this.users = this.mapUsersWithAccount(users);
       });
 
     const getUserUri = () =>
@@ -161,8 +165,7 @@ export class RgwUserListComponent extends ListWithDetails implements OnInit {
   getUserList(context: CdTableFetchDataContext) {
     this.setTableRefreshTimeout();
     this.rgwUserService.list().subscribe(
-      (resp: object[]) => {
-        this.users = resp;
+      (resp: RgwUser[]) => {
         this.userDataSubject.next(resp);
       },
       () => {
@@ -171,9 +174,9 @@ export class RgwUserListComponent extends ListWithDetails implements OnInit {
     );
   }
 
-  mapUsersWithAccount() {
-    this.users = this.users.map((user: RgwUser) => {
-      const account: Account = this.userAccounts.find((acc) => acc.id === user.account_id);
+  mapUsersWithAccount(users: RgwUser[]): RgwUser[] {
+    return users.map((user: RgwUser) => {
+      const account: Account = this.userAccounts.find((acc: Account) => acc.id === user.account_id);
       return {
         account: account ? account : { name: '' }, // adding {name: ''} for sorting account name in user list to work
         ...user