From 3b3fa4f643ca96e81216963018b826d8989545ec Mon Sep 17 00:00:00 2001 From: andreaNeki Date: Thu, 31 Oct 2024 11:27:10 -0300 Subject: [PATCH] Dynamic aria-describedby attribute (cherry picked from commit e629d9edf0d2177953950f5e145bf49ff1203f88) --- .../register-email-form.component.html | 2 +- .../register-email-form.component.spec.ts | 35 +++++++++++++++++++ .../register-email-form.component.ts | 26 ++++++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/src/app/register-email-form/register-email-form.component.html b/src/app/register-email-form/register-email-form.component.html index 9192226b1e..a3ccc4bce8 100644 --- a/src/app/register-email-form/register-email-form.component.html +++ b/src/app/register-email-form/register-email-form.component.html @@ -16,7 +16,7 @@
diff --git a/src/app/register-email-form/register-email-form.component.spec.ts b/src/app/register-email-form/register-email-form.component.spec.ts index 9e852d9491..67b87a974c 100644 --- a/src/app/register-email-form/register-email-form.component.spec.ts +++ b/src/app/register-email-form/register-email-form.component.spec.ts @@ -192,4 +192,39 @@ describe('RegisterEmailFormComponent', () => { expect(router.navigate).not.toHaveBeenCalled(); })); }); + describe('ariaDescribedby', () => { + it('should have required error message when email is empty', () => { + comp.form.patchValue({ email: '' }); + comp.checkEmailValidity(); + + expect(comp.ariaDescribedby).toContain('email-errors-required'); + }); + + it('should have invalid email error message when email is invalid', () => { + comp.form.patchValue({ email: 'invalid-email' }); + comp.checkEmailValidity(); + + expect(comp.ariaDescribedby).toContain('email-error-not-valid'); + }); + + it('should clear ariaDescribedby when email is valid', () => { + comp.form.patchValue({ email: 'valid@email.com' }); + comp.checkEmailValidity(); + + expect(comp.ariaDescribedby).toBe(''); + }); + + it('should update ariaDescribedby on value changes', () => { + spyOn(comp, 'checkEmailValidity').and.callThrough(); + + comp.form.patchValue({ email: '' }); + expect(comp.ariaDescribedby).toContain('email-errors-required'); + + comp.form.patchValue({ email: 'invalid-email' }); + expect(comp.ariaDescribedby).toContain('email-error-not-valid'); + + comp.form.patchValue({ email: 'valid@email.com' }); + expect(comp.ariaDescribedby).toBe(''); + }); + }); }); diff --git a/src/app/register-email-form/register-email-form.component.ts b/src/app/register-email-form/register-email-form.component.ts index df7e9bea5e..0ba37a9090 100644 --- a/src/app/register-email-form/register-email-form.component.ts +++ b/src/app/register-email-form/register-email-form.component.ts @@ -66,6 +66,11 @@ export class RegisterEmailFormComponent implements OnDestroy, OnInit { subscriptions: Subscription[] = []; + /** + * Stores error messages related to the email field + */ + ariaDescribedby: string = ''; + captchaVersion(): Observable { return this.googleRecaptchaService.captchaVersion(); } @@ -135,6 +140,13 @@ export class RegisterEmailFormComponent implements OnDestroy, OnInit { this.disableUntilChecked = res; this.changeDetectorRef.detectChanges(); })); + + /** + * Subscription to email field value changes + */ + this.subscriptions.push(this.email.valueChanges.subscribe(() => { + this.checkEmailValidity(); + })); } /** @@ -248,4 +260,18 @@ export class RegisterEmailFormComponent implements OnDestroy, OnInit { } } + checkEmailValidity() { + const descriptions = []; + + if (this.email.errors?.required) { + descriptions.push('email-errors-required'); + } + + if (this.email.errors?.pattern || this.email.errors?.email) { + descriptions.push('email-error-not-valid'); + } + + this.ariaDescribedby = descriptions.join(' '); + } + }