meals-made-easy-app/src/app/pages/recipe-upload-page/steps/enter-recipe-data/enter-recipe-data.spec.ts
2026-02-11 13:55:04 -06:00

124 lines
4.9 KiB
TypeScript

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<EnterRecipeData>;
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<ImageViewWithBlobUrl>),
),
} as Partial<ImageService>;
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');
});
});