import { ComponentFixture, TestBed } from '@angular/core/testing'; import { EnterRecipeData } from './enter-recipe-data'; import { provideQueryClient, QueryClient } from '@tanstack/angular-query-experimental'; import { inputBinding } from '@angular/core'; import { RecipeDraftViewModel } from '../../../../shared/models/RecipeDraftView.model'; import { ResourceOwner } from '../../../../shared/models/ResourceOwner.model'; import { ImageService } from '../../../../shared/services/ImageService'; import { of } from 'rxjs'; import { SliceView, SliceViewMeta } from '../../../../shared/models/SliceView.model'; import { ImageViewWithBlobUrl } from '../../../../shared/client-models/ImageViewWithBlobUrl'; import { By } from '@angular/platform-browser'; describe('EnterRecipeData', () => { let component: EnterRecipeData; let fixture: ComponentFixture; beforeEach(async () => { const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false, }, }, }); const imageServiceMock = { getOwnedImagesCount: vi.fn(() => of(0)), getOwnedImageViewsWithBlobUrls: vi.fn(() => of({ count: 0, slice: {} as SliceViewMeta, content: [], } as SliceView), ), } as Partial; await TestBed.configureTestingModule({ imports: [EnterRecipeData], providers: [ provideQueryClient(queryClient), { provide: ImageService, useValue: imageServiceMock, }, ], }).compileComponents(); fixture = TestBed.createComponent(EnterRecipeData, { bindings: [ inputBinding( 'draft', () => ({ id: 'test-id', created: new Date(), state: 'ENTER_DATA', owner: {} as ResourceOwner, }) satisfies RecipeDraftViewModel, ), ], }); component = fixture.componentInstance; await fixture.whenStable(); }); it('should create', () => { expect(component).toBeTruthy(); }); const testTimeInput = ( describeBlockName: string, inputRole: string, errorRole: string, ) => { describe(describeBlockName, () => { it('should accept a number input with no error presented', () => { const preparationTimeInputDebug = fixture.debugElement.query( By.css(`[data-test-role=${inputRole}]`), ); expect(preparationTimeInputDebug).toBeTruthy(); const preparationTimeInput: HTMLInputElement = preparationTimeInputDebug.nativeElement; preparationTimeInput.value = '1234'; preparationTimeInput.dispatchEvent(new Event('input')); preparationTimeInput.dispatchEvent(new Event('blur')); fixture.detectChanges(); expect(fixture.debugElement.query(By.css(`[data-test-role=${errorRole}]`))).toBeFalsy(); }); it('should not output an error if touched but no input', () => { const preparationTimeInput: HTMLInputElement = fixture.debugElement.query( By.css(`[data-test-role=${inputRole}]`), ).nativeElement; preparationTimeInput.dispatchEvent(new Event('blur')); expect(fixture.debugElement.query(By.css(`[data-test-role=${errorRole}]`))).toBeFalsy(); }); it('should display an error if non-number input', () => { const preparationTimeInput: HTMLInputElement = fixture.debugElement.query( By.css(`[data-test-role=${inputRole}]`), ).nativeElement; preparationTimeInput.value = 'abcd'; preparationTimeInput.dispatchEvent(new Event('input')); preparationTimeInput.dispatchEvent(new Event('blur')); fixture.detectChanges(); const errorDebug = fixture.debugElement.query( By.css(`[data-test-role=${errorRole}]`), ); expect(errorDebug).toBeTruthy(); expect(errorDebug.nativeElement.textContent).toContain('Must be a valid number.'); }); }); }; describe('time inputs', () => { testTimeInput('preparation time', 'preparation-time-input', 'preparation-time-error'); testTimeInput('cooking time', 'cooking-time-input', 'cooking-time-error'); testTimeInput('total time', 'total-time-input', 'total-time-error'); }); });