Skip to content

Commit

Permalink
NAS-131802: Error with some dataset paths in pool creation
Browse files Browse the repository at this point in the history
  • Loading branch information
undsoft committed Oct 21, 2024
1 parent 4f96b53 commit 2d15fae
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 141 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,13 @@ <h1 mat-dialog-title>{{ 'Create Dataset' | translate }}</h1>
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
}
</div>
<div mat-dialog-content>
<form [formGroup]="form">
<ix-input
formControlName="name"
[label]="'Name' | translate"
[required]="true"
></ix-input>
</form>
</div>
<form [formGroup]="form">
<ix-input
formControlName="name"
[label]="'Name' | translate"
[required]="true"
></ix-input>
</form>
<ix-form-actions mat-dialog-actions class="form-actions">
<button mat-button matDialogClose ixTest="cancel">{{ 'Cancel' | translate }}</button>
<button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,52 +36,70 @@ describe('CreateDatasetDialogComponent', () => {
mockCall('pool.dataset.create', { name: 'created_dataset' } as Dataset),
]),
mockProvider(MatDialogRef),
{
provide: MAT_DIALOG_DATA,
useValue: {
parentId: 'pool/parent-dataset',
dataset: { acltype: DatasetAclType.Nfsv4 } as DatasetCreate,
},
},
],
});

beforeEach(() => {
spectator = createComponent();
function setupTest(parentId = 'pool/parent-dataset'): void {
spectator = createComponent({
providers: [
{
provide: MAT_DIALOG_DATA,
useValue: {
parentId,
dataset: { acltype: DatasetAclType.Nfsv4 } as DatasetCreate,
},
},
],
});
loader = TestbedHarnessEnvironment.loader(spectator.fixture);
});
}

it('checks validation error when dataset name already in use', async () => {
const datasetName = await loader.getHarness(IxInputHarness.with({ label: 'Name' }));
const form = await loader.getHarness(IxFormHarness);
await form.fillForm({
Name: 'SoMe_DaTaSeT',
});
describe('normal operation', () => {
beforeEach(() => setupTest());

expect(await datasetName.getErrorText()).toBe('The name "some_dataset" is already in use.');
it('checks validation error when dataset name already in use', async () => {
const datasetName = await loader.getHarness(IxInputHarness.with({ label: 'Name' }));
const form = await loader.getHarness(IxFormHarness);
await form.fillForm({
Name: 'SoMe_DaTaSeT',
});

await form.fillForm({
Name: 'new_some_dataset',
});
expect(await datasetName.getErrorText()).toBe('');
});
expect(await datasetName.getErrorText()).toBe('The name "some_dataset" is already in use.');

it('creates new dataset when Create button is pressed', async () => {
const form = await loader.getHarness(IxFormHarness);
await form.fillForm({
Name: 'new_dataset',
await form.fillForm({
Name: 'new_some_dataset',
});
expect(await datasetName.getErrorText()).toBe('');
});

const createButton = await loader.getHarness(MatButtonHarness.with({ text: 'Create' }));
await createButton.click();
it('creates new dataset when Create button is pressed', async () => {
const form = await loader.getHarness(IxFormHarness);
await form.fillForm({
Name: 'new_dataset',
});

const createButton = await loader.getHarness(MatButtonHarness.with({ text: 'Create' }));
await createButton.click();

expect(spectator.inject(WebSocketService).call).toHaveBeenCalledWith('pool.dataset.create', [{
name: 'parent_name/new_dataset',
acltype: DatasetAclType.Nfsv4,
}]);

expect(spectator.inject(MatDialogRef).close).toHaveBeenCalledWith({
name: 'created_dataset',
});
});
});

expect(spectator.inject(WebSocketService).call).toHaveBeenCalledWith('pool.dataset.create', [{
name: 'parent_name/new_dataset',
acltype: DatasetAclType.Nfsv4,
}]);
describe('special cases', () => {
it('loads correct parent dataset even if parent id was passed in with leading slash', () => {
setupTest('/pool/parent-dataset-with-slash/');

expect(spectator.inject(MatDialogRef).close).toHaveBeenCalledWith({
name: 'created_dataset',
expect(spectator.inject(WebSocketService).call).toHaveBeenCalledWith(
'pool.dataset.query',
[[['id', '=', '/pool/parent-dataset-with-slash']]],
);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Validators } from '@angular/forms';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { FormBuilder } from '@ngneat/reactive-forms';
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
import { BehaviorSubject } from 'rxjs';
import { BehaviorSubject, tap } from 'rxjs';
import { nameValidatorRegex } from 'app/constants/name-validator.constant';
import { DatasetCaseSensitivity } from 'app/enums/dataset.enum';
import { Role } from 'app/enums/role.enum';
Expand Down Expand Up @@ -74,13 +74,27 @@ export class CreateDatasetDialogComponent implements OnInit {

loadParentDataset(): void {
this.isLoading$.next(true);
this.ws.call('pool.dataset.query', [[['id', '=', this.data.parentId]]])
.pipe(untilDestroyed(this)).subscribe((parent) => {
const normalizedParentId = this.data.parentId.replace(/\/$/, '');
this.ws.call('pool.dataset.query', [[['id', '=', normalizedParentId]]]).pipe(
tap((parent) => {
if (!parent.length) {
throw new Error(`Parent dataset ${normalizedParentId} not found`);
}
}),
untilDestroyed(this),
).subscribe({
next: (parent) => {
this.isLoading$.next(false);
this.parent = parent[0];
this.cdr.markForCheck();
this.addNameValidators();
});
},
error: (error) => {
this.isLoading$.next(false);
this.dialog.error(this.errorHandler.parseError(error));
this.dialogRef.close(false);
},
});
}

private addNameValidators(): void {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
<h1 matDialogTitle>{{ 'Manual S.M.A.R.T. Test' | translate }}</h1>
@if (!hasStartedTests) {
<form
class="ix-form-container"
[formGroup]="form"
(submit)="onSubmit()"
>
<div class="disks-list">
@if (supportedDisks.length) {
<form
class="ix-form-container"
[formGroup]="form"
(submit)="onSubmit()"
>
<div class="disks-list">
@if (supportedDisks.length) {
<div class="prompt">{{ 'Run manual test on disks:' }}</div>
<ul class="disks">
@for (disk of supportedDisks; track disk) {
<li>{{ disk.name }} ({{ disk.serial }})</li>
}
</ul>
}
@if (unsupportedDisks.length) {
<div class="prompt">
{{ 'These disks do not support S.M.A.R.T. tests:' | translate }}
</div>
<ul class="disks">
@for (disk of unsupportedDisks; track disk) {
<ul class="disks">
@for (disk of supportedDisks; track disk) {
<li>{{ disk.name }} ({{ disk.serial }})</li>
}
</ul>
}
@if (unsupportedDisks.length) {
<div class="prompt">
{{ 'These disks do not support S.M.A.R.T. tests:' | translate }}
</div>
<ul class="disks">
@for (disk of unsupportedDisks; track disk) {
<li>{{ disk.name }} ({{ disk.serial }})</li>
}
</ul>
}
</div>
}
</ul>
}
</div>

<ix-select
formControlName="type"
Expand Down Expand Up @@ -88,7 +88,7 @@ <h4 class="device-name">{{ test.disk }}</h4>
<ix-form-actions>
<button mat-button type="button" ixTest="close" [matDialogClose]="true">
{{ 'Close' | translate }}
</button>
</ix-form-actions>
</div>
</button>
</ix-form-actions>
</div>
}
Loading

0 comments on commit 2d15fae

Please sign in to comment.