Skip to content

Commit

Permalink
Testing binding component
Browse files Browse the repository at this point in the history
  • Loading branch information
fdodino committed Jun 11, 2024
1 parent 89f5292 commit d4d6597
Show file tree
Hide file tree
Showing 12 changed files with 113 additions and 42 deletions.
43 changes: 21 additions & 22 deletions src/app/app.component.spec.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,28 @@
import { TestBed } from '@angular/core/testing';
import { AppComponent } from './app.component';
import { ComponentFixture, TestBed } from '@angular/core/testing'
import { AppComponent } from './app.component'
import { ApuestasBindingComponent } from './apuestas-binding/apuestas-binding.component'
import { ApuestasReactiveComponent } from './apuestas-reactive/apuestas-reactive.component'
import { RouterModule } from '@angular/router'

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

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [AppComponent],
}).compileComponents();
});
imports: [AppComponent, ApuestasBindingComponent, ApuestasReactiveComponent, RouterModule.forRoot([])],
}).compileComponents()
fixture = TestBed.createComponent(AppComponent)
component = fixture.componentInstance
fixture.detectChanges()
})

it('should create the app', () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app).toBeTruthy();
});

it(`should have the 'eg-apuestas-angular' title`, () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app.title).toEqual('eg-apuestas-angular');
});
expect(component).toBeTruthy()
})

it('should render title', () => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.nativeElement as HTMLElement;
expect(compiled.querySelector('h1')?.textContent).toContain('Hello, eg-apuestas-angular');
});
});
it('should render two options', () => {
const compiled = fixture.nativeElement as HTMLElement
expect(compiled.querySelectorAll('li').length).toBe(2)
})
})
2 changes: 1 addition & 1 deletion src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { RouterLink, RouterLinkActive, RouterOutlet } from '@angular/router'
standalone: true,
imports: [CommonModule, RouterOutlet, RouterLink, RouterLinkActive],
templateUrl: './app.component.html',
styleUrl: './app.component.css'
styleUrl: './app.component.css',
})
export class AppComponent {
title = 'eg-apuestas-angular'
Expand Down
2 changes: 1 addition & 1 deletion src/app/app.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ import { ApuestasReactiveComponent } from './apuestas-reactive/apuestas-reactive

export const routes: Routes = [
{ path: 'reactive', component: ApuestasReactiveComponent },
{ path: 'binding', component: ApuestasBindingComponent }
{ path: '**', component: ApuestasBindingComponent }
]
83 changes: 82 additions & 1 deletion src/app/apuestas-binding/apuestas-binding.component.spec.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'

import { ApuestasBindingComponent } from './apuestas-binding.component'
import { getByTestId, mensajeDeError, resultado } from '../../utils/test-utils'
import { Apuesta, DOCENA, PLENO, TipoApuesta } from '../domain/apuesta'
import dayjs from 'dayjs'

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

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [ApuestasBindingComponent]
imports: [ApuestasBindingComponent],
}).compileComponents()

fixture = TestBed.createComponent(ApuestasBindingComponent)
Expand All @@ -19,4 +22,82 @@ describe('ApuestasBindingComponent', () => {
it('should create', () => {
expect(component).toBeTruthy()
})
it('should fail if no date is entered', () => {
getByTestId(fixture, 'btnApuesta').click()
fixture.detectChanges()
expect(mensajeDeError(fixture, 'fecha')).toContain('Debe ingresar una fecha de apuesta')
})
it('should fail if previous date is entered', () => {
component.fechaApuesta = '01/01/1900'
component.apuesta = new Apuesta()
getByTestId(fixture, 'btnApuesta').click()
fixture.detectChanges()
expect(mensajeDeError(fixture, 'fecha')).toContain('Debe ingresar una fecha actual o posterior al día de hoy')
})
it('should fail if negative amount is entered', () => {
apostarHoy(component)
component.apuesta = Object.assign(
new Apuesta(),
{
fecha: new Date(),
monto: -10,
}
)
getByTestId(fixture, 'btnApuesta').click()
fixture.detectChanges()
expect(mensajeDeError(fixture, 'monto')).toContain('El monto a apostar debe ser positivo')
})
it('should pass all validations and inform if user wins - single', () => {
apostarHoy(component)
component.apuesta = apostarAl(PLENO, 25)

spyOn(component.apuesta, 'obtenerNumeroGanador').and.returnValue(25)
// se podría hacer a mano pero hay que deshacer esto al final del test
// o produciría efecto colateral => el número ganador sería siempre 24
// component.apuesta.obtenerNumeroGanador = () => 25
getByTestId(fixture, 'btnApuesta').click()
fixture.detectChanges()

expect(resultado(fixture)).toContain('Ganaste $700')
})
it('should pass all validations and inform if user loses - single', () => {
apostarHoy(component)
component.apuesta = apostarAl(PLENO, 25)
spyOn(component.apuesta, 'obtenerNumeroGanador').and.returnValue(24)
getByTestId(fixture, 'btnApuesta').click()
fixture.detectChanges()

expect(resultado(fixture)).toContain('¡¡Perdiste!! Salió el 24')
})
it('should pass all validations and inform if user wins - dozen', () => {
apostarHoy(component)
component.apuesta = apostarAl(DOCENA, 'Primera', 100)
spyOn(component.apuesta, 'obtenerNumeroGanador').and.returnValue(1)
getByTestId(fixture, 'btnApuesta').click()
fixture.detectChanges()

expect(resultado(fixture)).toContain('Ganaste $1100')
})
it('should pass all validations and inform if user loses - dozen', () => {
apostarHoy(component)
component.apuesta = apostarAl(DOCENA, 'Segunda', 100)
spyOn(component.apuesta, 'obtenerNumeroGanador').and.returnValue(1)
getByTestId(fixture, 'btnApuesta').click()
fixture.detectChanges()

expect(resultado(fixture)).toContain('¡¡Perdiste!! Salió el 1')
})

})

function apostarAl(tipoApuesta: TipoApuesta, numero: number | string, monto = 20): Apuesta {
const apuesta = new Apuesta()
apuesta.monto = monto
apuesta.tipoApuesta = tipoApuesta
apuesta.valorApostado = numero
return apuesta
}

const apostarHoy = (component: ApuestasBindingComponent) => {
component.fechaApuesta = dayjs(new Date()).format('DD/MM/YYYY')
}
2 changes: 1 addition & 1 deletion src/app/apuestas-binding/apuestas-binding.component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Component } from '@angular/core'
import { Apuesta, DOCENA, PLENO } from './apuesta'
import { Apuesta, DOCENA, PLENO } from '../domain/apuesta'
import { ValidationFieldComponent } from './validationField/validationField.component'
import { FormsModule } from '@angular/forms'
import dayjs from 'dayjs'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Apuesta } from './../apuesta'
import { Component, Input } from '@angular/core'
import { Apuesta } from '../../domain/apuesta'

@Component({
selector: 'validation-field',
Expand Down
7 changes: 0 additions & 7 deletions src/app/apuestas-reactive/apuestas-reactive.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,6 @@
<div class="row">
<label for="fecha" class="form-label">Fecha</label>
<input type="date" data-testid="fechaApuesta" id="fecha" name="fecha" formControlName="fecha" placeholder="Fecha de apuesta">
@if (errorMessage('fecha', 'required')) {
<div class="validation-row">
<div [attr.data-testid]="'errorMessage-fecha'" class="validation">
{{errorMessage('fecha', 'required')}}
</div>
</div>
}
@if (errorMessage('fecha', 'dateShouldBeGreaterThanToday')) {
<div class="validation-row">
<div [attr.data-testid]="'errorMessage-fecha'" class="validation">
Expand Down
5 changes: 2 additions & 3 deletions src/app/apuestas-reactive/apuestas-reactive.component.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Component } from '@angular/core'
import { AbstractControl, FormBuilder, Validators } from '@angular/forms'
import { ReactiveFormsModule } from '@angular/forms'
import { Apuesta, MONTO_MINIMO_PLENO } from '../apuestas-binding/apuesta'
import dayjs from 'dayjs'
import { Apuesta, MONTO_MINIMO_PLENO } from '../domain/apuesta'

@Component({
selector: 'app-apuestas-reactive',
Expand All @@ -17,7 +17,6 @@ export class ApuestasReactiveComponent {
// - valores como el resultado
apuestaForm = this.formBuilder.group({
fecha: ['', [
Validators.required,
DateValidator.greaterThanToday
]
],
Expand Down Expand Up @@ -70,7 +69,7 @@ export class DateValidator {
// Number only validation
static greaterThanToday(control: AbstractControl) {
const value = control.value
if (value === null || value === '') return null
if (value === null || value === '') return { dateShouldBeGreaterThanToday: { message: 'Debe ingresar fecha' } }

const date = dayjs(value).toDate()
return date < new Date() ? { dateShouldBeGreaterThanToday: { message: 'Debe ingresar fecha de hoy o futura' } } : null
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Resultado } from './resultado'
import { Resultado } from "./resultado"

export const MONTO_MINIMO_PLENO = 10

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { AppComponent } from './app.component'
import { ComponentFixture } from '@angular/core/testing'

export const getByTestId = (appComponent: ComponentFixture<AppComponent>, testId: string) => {
export const getByTestId = (appComponent: ComponentFixture<unknown>, testId: string) => {
const compiled = appComponent.debugElement.nativeElement
return compiled.querySelector(`[data-testid="${testId}"]`)
}

export const mensajeDeError = (fixture: ComponentFixture<AppComponent>, field: string) => {
export const mensajeDeError = (fixture: ComponentFixture<unknown>, field: string) => {
return getByTestId(fixture, `errorMessage-${field}`).textContent
}

export const resultado = (fixture: ComponentFixture<AppComponent>) => {
export const resultado = (fixture: ComponentFixture<unknown>) => {
return getByTestId(fixture, 'resultado').textContent
}

0 comments on commit d4d6597

Please sign in to comment.