Skip to content

Commit

Permalink
feat: formulário de autenticação
Browse files Browse the repository at this point in the history
  • Loading branch information
ortegavan committed Jun 29, 2024
1 parent 503d85f commit 451bfd0
Show file tree
Hide file tree
Showing 10 changed files with 150 additions and 9 deletions.
26 changes: 25 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Projeto criado na Mentoria Angular Pro

![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/ortegavan/ecommerce/ci.yml) ![GitHub last commit](https://img.shields.io/github/last-commit/ortegavan/ecommerce) ![GitHub Tag](https://img.shields.io/github/v/tag/ortegavan/ecommerce) ![Sonar Quality Gate](https://img.shields.io/sonar/quality_gate/ortegavan_ecommerce?server=https%3A%2F%2Fsonarcloud.io) ![Static Badge](https://img.shields.io/badge/code_style-prettier-ff69b4)
![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/ortegavan/ecommerce/ci.yml) ![Sonar Quality Gate](https://img.shields.io/sonar/quality_gate/ortegavan_ecommerce?server=https%3A%2F%2Fsonarcloud.io) ![GitHub last commit](https://img.shields.io/github/last-commit/ortegavan/ecommerce) ![GitHub Tag](https://img.shields.io/github/v/tag/ortegavan/ecommerce) ![Static Badge](https://img.shields.io/badge/code_style-prettier-ff69b4)

Este documento contém os exercícios feitos em aula + minhas notas pessoais sobre a Mentoria Angular Pro de Paolo Almeida e Andrew Rosário.

Expand Down Expand Up @@ -473,3 +473,27 @@ Os componentes filhos conseguem acessar o componente pai via injeção de depend
Para cenários mais genéricos, é possível criar uma classe abstrata que os orquestradores implementam para serem injetadas nos componentes filhos. Para saber mais, acesse [este link](https://netbasal.com/create-a-multi-step-form-in-angular-44cdc5b75cdc).

Formulários complexos também podem ser divididos com [ControlContainer](https://andrewrosario.medium.com/dividindo-formulários-complexos-no-angular-com-controlcontainer-1b107d59c8be) e com [ControlValueAccessor](https://andrewrosario.medium.com/form-controls-customizados-no-angular-com-controlvalueaccessor-367e773e3fec).

## ✨ Aula 22

Finalizamos o formulário iniciado na aula anterior e implementamos os testes. Foi necessário fornecer rotas com `provideRouter` e importar o `NoopAnimationsModule` para os testes passarem. Para testarmos a interação com o HTML do form, substituímos a manipulação do `FormControl` como mostrado a seguir:

```typescript
it('should display email error message', () => {
// component.control.setValue('teste');
const input: HTMLInputElement =
fixture.nativeElement.querySelector('input');
input.value = 'teste';
input.dispatchEvent(new Event('input'));

component.control.markAllAsTouched();
fixture.detectChanges();
const error = fixture.nativeElement.querySelector(
'[data-testid="error-email"]'
);

expect(error).toBeTruthy();
});
```

Onde `data-testid` é um atributo customizado que usamos para identificar elementos no HTML.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.form-field {
width: 100%;
}

.container {
display: flex;
justify-content: end;
}
Original file line number Diff line number Diff line change
@@ -1 +1,30 @@
<p>auth-form-email works!</p>
<mat-form-field appearance="outline" class="form-field">
<mat-label>Informe seu email</mat-label>
<input
[formControl]="control"
autofocus
matInput
placeholder="Ex: [email protected]"
type="email"
/>
@if (control.hasError('email') && !control.hasError('required')) {
<mat-error data-testid="error-email"
>Por favor, informe um e-mail válido</mat-error
>
} @if (control.hasError('required')) {
<mat-error data-testid="error-required"
>O e-mail é <strong>obrigatório</strong></mat-error
>
}
</mat-form-field>

<div class="container">
<button
[disabled]="control.invalid"
mat-raised-button
color="primary"
[routerLink]="['../', 'password']"
>
Próximo
</button>
</div>
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { AuthFormEmailComponent } from './auth-form-email.component';
import { AuthFormComponent } from '../auth-form.component';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { provideRouter } from '@angular/router';

describe('AuthFormEmailComponent', () => {
let component: AuthFormEmailComponent;
let fixture: ComponentFixture<AuthFormEmailComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [AuthFormEmailComponent],
providers: [AuthFormComponent],
imports: [AuthFormEmailComponent, NoopAnimationsModule],
providers: [AuthFormComponent, provideRouter([])],
}).compileComponents();

fixture = TestBed.createComponent(AuthFormEmailComponent);
Expand All @@ -20,4 +22,40 @@ describe('AuthFormEmailComponent', () => {
it('should create', () => {
expect(component).toBeTruthy();
});

it('should enable button when control is valid', () => {
const button = fixture.nativeElement.querySelector('button');
expect(button.disabled).toBe(true);

component.control.setValue('[email protected]');
fixture.detectChanges();

expect(button.disabled).toBe(false);
});

it('should display required error message', () => {
component.control.markAllAsTouched();
fixture.detectChanges();
const error = fixture.nativeElement.querySelector(
'[data-testid="error-required"]'
);

expect(error).toBeTruthy();
});

it('should display email error message', () => {
// component.control.setValue('teste');
const input: HTMLInputElement =
fixture.nativeElement.querySelector('input');
input.value = 'teste';
input.dispatchEvent(new Event('input'));

component.control.markAllAsTouched();
fixture.detectChanges();
const error = fixture.nativeElement.querySelector(
'[data-testid="error-email"]'
);

expect(error).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
import { Component, inject } from '@angular/core';
import { CommonModule } from '@angular/common';
import { AuthFormComponent } from '../auth-form.component';
import { ReactiveFormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { MatInputModule } from '@angular/material/input';
import { RouterModule } from '@angular/router';

@Component({
selector: 'ecommerce-auth-form-email',
standalone: true,
imports: [CommonModule],
imports: [
CommonModule,
MatButtonModule,
MatInputModule,
ReactiveFormsModule,
RouterModule,
],
templateUrl: './auth-form-email.component.html',
styleUrl: './auth-form-email.component.css',
})
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.form-field {
width: 100%;
}

.container {
display: flex;
justify-content: end;
}
Original file line number Diff line number Diff line change
@@ -1 +1,14 @@
<p>auth-form-password works!</p>
<mat-form-field appearance="outline" class="form-field">
<mat-label>Informe sua senha</mat-label>
<input
[formControl]="control"
autofocus
matInput
placeholder="Mínimo de 6 caracteres"
type="password"
/>
</mat-form-field>

<div class="container">
<button mat-raised-button color="primary">Entrar</button>
</div>
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { AuthFormPasswordComponent } from './auth-form-password.component';
import { AuthFormComponent } from '../auth-form.component';
import { provideRouter } from '@angular/router';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';

describe('AuthFormPasswordComponent', () => {
let component: AuthFormPasswordComponent;
let fixture: ComponentFixture<AuthFormPasswordComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [AuthFormPasswordComponent],
providers: [AuthFormComponent],
imports: [AuthFormPasswordComponent, NoopAnimationsModule],
providers: [AuthFormComponent, provideRouter([])],
}).compileComponents();

fixture = TestBed.createComponent(AuthFormPasswordComponent);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
import { Component, inject } from '@angular/core';
import { CommonModule } from '@angular/common';
import { AuthFormComponent } from '../auth-form.component';
import { ReactiveFormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { MatInputModule } from '@angular/material/input';

@Component({
selector: 'ecommerce-auth-form-password',
standalone: true,
imports: [CommonModule],
imports: [
CommonModule,
MatButtonModule,
MatInputModule,
ReactiveFormsModule,
],
templateUrl: './auth-form-password.component.html',
styleUrl: './auth-form-password.component.css',
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<form class="form" [formGroup]="form">
<mat-card class="form__card">
<h1>Entrar</h1>
<router-outlet />
</mat-card>
</form>

0 comments on commit 451bfd0

Please sign in to comment.