Align landlord profile validation (#47)
This commit is contained in:
1 parent
d1cdc6eaeb
commit
66fa95dabd
13 files changed
+462
-32
No files matched your search
@@ -69,6 +69,8 @@
|
||||
[profile]="profileModel()"
|
||||
[saving]="saving()"
|
||||
[saveError]="saveError()"
|
||||
[saveFieldErrors]="saveFieldErrors()"
|
||||
(fieldChanged)="clearSaveFieldError($event)"
|
||||
(saveRequested)="save($event)"
|
||||
/>
|
||||
}
|
||||
|
||||
@@ -97,4 +97,43 @@ describe('SettingsPage', () => {
|
||||
'alex@example.com',
|
||||
);
|
||||
});
|
||||
|
||||
it('keeps structured profile errors beside their field until that field changes', async () => {
|
||||
profile.updateProfile.mockReturnValue(
|
||||
throwError(
|
||||
() =>
|
||||
new HttpErrorResponse({
|
||||
error: {
|
||||
code: 'validation_failed',
|
||||
errors: [{ field: 'phoneValid', code: 'assert_true' }],
|
||||
},
|
||||
status: 400,
|
||||
}),
|
||||
),
|
||||
);
|
||||
const fixture = TestBed.createComponent(SettingsPage);
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
fixture.nativeElement.querySelector('button.primary-action').click();
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(fixture.nativeElement.textContent).toContain(
|
||||
'Saisissez un numéro de téléphone valide.',
|
||||
);
|
||||
expect(fixture.nativeElement.textContent).not.toContain(
|
||||
'Veuillez corriger les champs signalés.',
|
||||
);
|
||||
const phone = fixture.nativeElement.querySelector(
|
||||
'input#profile-phone',
|
||||
) as HTMLInputElement;
|
||||
phone.value = '+33612345678';
|
||||
phone.dispatchEvent(new Event('input'));
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(fixture.nativeElement.textContent).not.toContain(
|
||||
'Saisissez un numéro de téléphone valide.',
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -6,7 +6,7 @@ import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||
import { MatRadioModule } from '@angular/material/radio';
|
||||
import { LandlordProfileForm } from '../landlord-profile-form/landlord-profile-form';
|
||||
import { httpErrorMessage } from '../../services/http-error-message';
|
||||
import { FieldValidationError, saveFailure } from '../../services/http-error-message';
|
||||
import { LandlordProfile, LandlordProfileService } from '../../services/landlord-profile.service';
|
||||
import { SessionService } from '../../services/session.service';
|
||||
import { ThemeService } from '../../services/theme.service';
|
||||
@@ -45,6 +45,7 @@ export class SettingsPage {
|
||||
|
||||
readonly profileError = signal('');
|
||||
readonly saveError = signal('');
|
||||
readonly saveFieldErrors = signal<FieldValidationError[]>([]);
|
||||
readonly saveSuccess = signal('');
|
||||
|
||||
constructor() {
|
||||
@@ -79,6 +80,7 @@ export class SettingsPage {
|
||||
if (this.saving()) return;
|
||||
this.saveSuccess.set('');
|
||||
this.saveError.set('');
|
||||
this.saveFieldErrors.set([]);
|
||||
this.saving.set(true);
|
||||
this.landlordProfile
|
||||
.updateProfile(profile)
|
||||
@@ -90,14 +92,21 @@ export class SettingsPage {
|
||||
this.saving.set(false);
|
||||
},
|
||||
error: (error: unknown) => {
|
||||
this.saveError.set(
|
||||
httpErrorMessage(
|
||||
error,
|
||||
'Impossible d’enregistrer votre profil bailleur. Réessayez.',
|
||||
),
|
||||
const failure = saveFailure(
|
||||
error,
|
||||
'Impossible d’enregistrer votre profil bailleur. Réessayez.',
|
||||
);
|
||||
this.saveError.set(failure.message);
|
||||
this.saveFieldErrors.set(failure.fieldErrors);
|
||||
this.saving.set(false);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
clearSaveFieldError(field: string): void {
|
||||
const remaining = this.saveFieldErrors().filter((error) => error.field !== field);
|
||||
if (remaining.length === this.saveFieldErrors().length) return;
|
||||
this.saveFieldErrors.set(remaining);
|
||||
if (!remaining.length) this.saveError.set('');
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user