});
});
+ describe('edit mode CephFS subvolume fields', () => {
+ it('should populate subvolume group and subvolume from export path', () => {
+ component.isEdit = true;
+ spyOn(component['subvolgrpService'], 'get').and.returnValue(of([{ name: 'g1' }]));
+ spyOn(component['subvolService'], 'get').and.returnValue(of([{ name: 'sv1' }]));
+
+ component.resolveModel({
+ fsal: { name: 'CEPH', fs_name: 'testfs' },
+ path: '/volumes/g1/sv1',
+ protocols: [3, 4],
+ transports: ['TCP'],
+ clients: [],
+ squash: 'none'
+ });
+
+ expect(component.nfsForm.get('subvolume_group').value).toBe('g1');
+ expect(component.nfsForm.get('subvolume').value).toBe('sv1');
+ expect(component['subvolgrpService'].get).toHaveBeenCalledWith('testfs');
+ expect(component['subvolService'].get).toHaveBeenCalledWith('testfs', 'g1');
+ expect(component.allsubvols).toEqual([{ name: 'sv1' }]);
+ });
+ });
+
describe('pathExistence', () => {
beforeEach(() => {
component['nfsService']['lsDir'] = jest.fn((): Observable<Directory> =>
(params: { cluster_id: string; export_id: string; rgw_export_type?: string }) => {
this.cluster_id = decodeURIComponent(params.cluster_id);
this.export_id = decodeURIComponent(params.export_id);
- if (params.rgw_export_type) {
+ if (params.rgw_export_type && this.storageBackend === SUPPORTED_FSAL.RGW) {
this.nfsForm.get('rgw_export_type').setValue(params.rgw_export_type);
if (params.rgw_export_type === RgwExportType.BUCKET) {
this.setBucket();
this.isDefaultSubvolumeGroup();
}
- async getSubVol() {
- const fs_name = this.nfsForm.getValue('fsal').fs_name;
+ async getSubVol(fsName?: string) {
+ const fs_name = fsName ?? this.nfsForm.getRawValue()?.fsal?.fs_name;
const subvolgrp = this.nfsForm.getValue('subvolume_group');
- await this.setSubVolGrpPath();
+ if (!fs_name || !subvolgrp) {
+ return;
+ }
+
+ if (!this.isEdit) {
+ await this.setSubVolGrpPath();
+ }
(subvolgrp === this.defaultSubVolGroup
? this.subvolService.get(fs_name)
this.nfsForm.patchValue({
fsal: {
- ...this.nfsForm.get('fsal').value,
+ ...this.nfsForm.getRawValue()?.fsal,
fs_name: fsName
},
- subvolumeGroup,
+ subvolume_group: subvolumeGroup,
subvolume
});
+ this.setUpVolumeValidation();
+ this.getSubVol(fsName);
}
resolveClusters(clusters: string[]) {
if (control.pristine || !control.value) {
return of({ required: true });
}
- const fsName = this.nfsForm.getValue('fsal').fs_name;
+ const fsName = this.nfsForm.getRawValue()?.fsal?.fs_name;
return this.nfsService.lsDir(fsName, control.value).pipe(
map((directory: Directory) =>
directory.paths.includes(control.value) === requiredExistenceResult
import { SharedModule } from '~/app/shared/shared.module';
import { configureTestBed, expectItemTasks, PermissionHelper } from '~/testing/unit-test-helper';
import { NfsDetailsComponent } from '../nfs-details/nfs-details.component';
-import { NfsListComponent } from './nfs-list.component';
-import { SUPPORTED_FSAL } from '../models/nfs.fsal';
+import { NfsListComponent, RgwExportType } from './nfs-list.component';
+import { RGW_USER_EXPORT_PATH, SUPPORTED_FSAL } from '../models/nfs.fsal';
+import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
describe('NfsListComponent', () => {
let component: NfsListComponent;
expect(component).toBeTruthy();
});
+ describe('edit action routerLink', () => {
+ let editRouterLink: () => string | [string, { rgw_export_type: RgwExportType }];
+
+ beforeEach(() => {
+ editRouterLink = component.tableActions.find((action) => action.permission === 'update')
+ .routerLink as () => string | [string, { rgw_export_type: RgwExportType }];
+ });
+
+ it('should return a plain string for CephFS edit (no route params)', () => {
+ component.fsal = SUPPORTED_FSAL.CEPH;
+ component.selection = new CdTableSelection([
+ { cluster_id: 'mycluster', export_id: '42', path: '/volumes/g1/sv1' }
+ ]);
+
+ const link = editRouterLink();
+
+ expect(typeof link).toBe('string');
+ expect(link).toBe('/cephfs/nfs/edit/mycluster/42');
+ });
+
+ it('should return array with rgw_export_type for RGW bucket edit', () => {
+ component.fsal = SUPPORTED_FSAL.RGW;
+ component.selection = new CdTableSelection([
+ { cluster_id: 'rgw-cluster', export_id: '7', path: '/my-bucket' }
+ ]);
+
+ const link = editRouterLink();
+
+ expect(Array.isArray(link)).toBe(true);
+ expect(link[0]).toBe('/rgw/nfs/edit/rgw-cluster/7');
+ expect(link[1]).toEqual({ rgw_export_type: RgwExportType.BUCKET });
+ });
+
+ it('should return array with rgw_export_type user for RGW user-level edit', () => {
+ component.fsal = SUPPORTED_FSAL.RGW;
+ component.selection = new CdTableSelection([
+ { cluster_id: 'rgw-cluster', export_id: '8', path: RGW_USER_EXPORT_PATH }
+ ]);
+
+ const link = editRouterLink();
+
+ expect(Array.isArray(link)).toBe(true);
+ expect(link[0]).toBe('/rgw/nfs/edit/rgw-cluster/8');
+ expect(link[1]).toEqual({ rgw_export_type: RgwExportType.USER });
+ });
+ });
+
describe('after ngOnInit', () => {
beforeEach(() => {
fixture.detectChanges();
const editAction: CdTableAction = {
permission: 'update',
icon: Icons.edit,
- routerLink: () => [
- `/${prefix}/nfs/edit/${getNfsUri()}`,
- {
- rgw_export_type:
- this.fsal === SUPPORTED_FSAL.RGW &&
- !_.isEmpty(this.selection?.first()?.path) &&
- this.selection?.first()?.path !== RGW_USER_EXPORT_PATH
- ? RgwExportType.BUCKET
- : RgwExportType.USER
+ routerLink: () => {
+ const currentPrefix = getPathfromFsal(this.fsal);
+ const editUrl = `/${currentPrefix}/nfs/edit/${getNfsUri()}`;
+ if (this.fsal !== SUPPORTED_FSAL.RGW) {
+ return editUrl;
}
- ],
+ return [
+ editUrl,
+ {
+ rgw_export_type:
+ !_.isEmpty(this.selection?.first()?.path) &&
+ this.selection?.first()?.path !== RGW_USER_EXPORT_PATH
+ ? RgwExportType.BUCKET
+ : RgwExportType.USER
+ }
+ ];
+ },
name: this.actionLabels.EDIT
};