From b7e6bef8cf3ec534f60887a05444dd501bf5e88c Mon Sep 17 00:00:00 2001 From: Shivangi917 Date: Tue, 22 Jul 2025 03:22:05 -0400 Subject: [PATCH] Add test for mat-error on empty search term and handle loading state properly --- .../search-input-control.component.html | 2 +- .../search-input-control.component.spec.ts | 2 +- .../search-input-control.component.ts | 1 - .../search-input/search-input.component.html | 1 - .../search-input.component.spec.ts | 118 +++++++++++++----- .../search-input/search-input.component.ts | 8 +- 6 files changed, 92 insertions(+), 40 deletions(-) diff --git a/projects/aca-content/src/lib/components/search/search-input-control/search-input-control.component.html b/projects/aca-content/src/lib/components/search/search-input-control/search-input-control.component.html index dc1e735c9..4d66e2ba5 100644 --- a/projects/aca-content/src/lib/components/search/search-input-control/search-input-control.component.html +++ b/projects/aca-content/src/lib/components/search/search-input-control/search-input-control.component.html @@ -28,6 +28,6 @@ - + diff --git a/projects/aca-content/src/lib/components/search/search-input-control/search-input-control.component.spec.ts b/projects/aca-content/src/lib/components/search/search-input-control/search-input-control.component.spec.ts index 8153963a8..a1f48111a 100644 --- a/projects/aca-content/src/lib/components/search/search-input-control/search-input-control.component.spec.ts +++ b/projects/aca-content/src/lib/components/search/search-input-control/search-input-control.component.spec.ts @@ -94,5 +94,5 @@ describe('SearchInputControlComponent', () => { component.searchTerm = 'dd'; fixture.detectChanges(); expect(component.isTermTooShort()).toBe(false); - }); + }); }); diff --git a/projects/aca-content/src/lib/components/search/search-input-control/search-input-control.component.ts b/projects/aca-content/src/lib/components/search/search-input-control/search-input-control.component.ts index d5ddbb57a..c4c601830 100644 --- a/projects/aca-content/src/lib/components/search/search-input-control/search-input-control.component.ts +++ b/projects/aca-content/src/lib/components/search/search-input-control/search-input-control.component.ts @@ -90,7 +90,6 @@ export class SearchInputControlComponent implements OnInit { searchSubmit() { this.searchFieldFormControl.markAsTouched(); - const trimmedTerm = this.searchTerm?.trim(); if (this.searchFieldFormControl.valid && trimmedTerm?.length > 0) { this.submit.emit(trimmedTerm); diff --git a/projects/aca-content/src/lib/components/search/search-input/search-input.component.html b/projects/aca-content/src/lib/components/search/search-input/search-input.component.html index aaf78bf39..a5afe4838 100644 --- a/projects/aca-content/src/lib/components/search/search-input/search-input.component.html +++ b/projects/aca-content/src/lib/components/search/search-input/search-input.component.html @@ -50,7 +50,6 @@ *ngIf="searchInputControl.searchFieldFormControl.errors?.required && searchInputControl.searchFieldFormControl.touched" class="app-search-error"> {{ 'SEARCH.INPUT.REQUIRED' | translate }} -
. + */ + import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { SearchInputComponent } from './search-input.component'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { MatError } from '@angular/material/form-field'; +import { AppStore } from '@alfresco/aca-shared/store'; import { By } from '@angular/platform-browser'; import { ReactiveFormsModule } from '@angular/forms'; import { AppTestingModule } from '../../../testing/app-testing.module'; +import { SearchInputComponent } from './search-input.component'; import { SearchInputControlComponent } from '../search-input-control/search-input-control.component'; +import { Store } from '@ngrx/store'; +import { of } from 'rxjs'; describe('SearchInputComponent', () => { let fixture: ComponentFixture; let component: SearchInputComponent; - + let store: jasmine.SpyObj>; beforeEach(async () => { + const storeSpy = jasmine.createSpyObj>('Store', ['dispatch', 'pipe']); + await TestBed.configureTestingModule({ imports: [AppTestingModule, ReactiveFormsModule, SearchInputComponent, SearchInputControlComponent], - schemas: [NO_ERRORS_SCHEMA] + providers: [{ provide: Store, useValue: storeSpy }], + schemas: [NO_ERRORS_SCHEMA] }).compileComponents(); fixture = TestBed.createComponent(SearchInputComponent); component = fixture.componentInstance; - - // (component as any).searchInputControl = mockControl; + store = TestBed.inject(Store) as jasmine.SpyObj>; + store.pipe.and.returnValue(of([])); fixture.detectChanges(); }); - describe('Validation Behavior', () => { - function getFirstError(): string { - const error = fixture.debugElement.query(By.directive(MatError)); - return error?.nativeElement.textContent.trim(); - } + function getFirstError(): string { + const error = fixture.debugElement.query(By.directive(MatError)); + return error?.nativeElement.textContent.trim(); + } - it('should show required error when field is empty and touched', () => { - component.searchInputControl.searchFieldFormControl.setValue(''); - component.searchInputControl.searchFieldFormControl.markAsTouched(); - fixture.detectChanges(); + function openSearchContainer(): void { + const menuButton = fixture.debugElement.query(By.css('.app-search-container')); + menuButton?.nativeElement.click(); + fixture.detectChanges(); + } - const error = getFirstError(); - fixture.detectChanges(); - expect(error).toBe('SEARCH.INPUT.REQUIRED'); - }); + it('should show required error when field is empty and touched', () => { + openSearchContainer(); + component.searchInputControl.searchFieldFormControl.setValue(''); + component.searchInputControl.searchFieldFormControl.markAsTouched(); + fixture.detectChanges(); + expect(getFirstError()).toBe('SEARCH.INPUT.REQUIRED'); + }); - // it('should not show error when field has value', () => { - // mockControl.searchFieldFormControl.setValue('test'); - // mockControl.searchFieldFormControl.markAsTouched(); - // fixture.detectChanges(); + it('should not show error when field has value', () => { + openSearchContainer(); + component.searchInputControl.searchFieldFormControl.setValue('test'); + component.searchInputControl.searchFieldFormControl.markAsTouched(); + fixture.detectChanges(); + const error = fixture.debugElement.query(By.directive(MatError)); + expect(error).toBeNull(); + }); - // const error = fixture.debugElement.query(By.directive(MatError)); - // expect(error).toBeNull(); - // }); + it('should not show error when field is untouched', () => { + openSearchContainer(); + component.searchInputControl.searchFieldFormControl.setValue(''); + component.searchInputControl.searchFieldFormControl.markAsUntouched(); + fixture.detectChanges(); + const error = fixture.debugElement.query(By.directive(MatError)); + expect(error).toBeNull(); + }); - // it('should not show error when field is untouched', () => { - // mockControl.searchFieldFormControl.setValue(''); - // mockControl.searchFieldFormControl.markAsUntouched(); - // fixture.detectChanges(); + it('should dispatch SearchByTermAction when libraries are checked and term is new', () => { + spyOn(component as any, 'isLibrariesChecked').and.returnValue(true); + spyOn(component as any, 'isFoldersChecked').and.returnValue(false); + spyOn(component as any, 'isFilesChecked').and.returnValue(false); + component.searchedWord = 'test'; + component.onSearchSubmit('Enter'); + expect(store.dispatch).toHaveBeenCalled(); + }); - // const error = fixture.debugElement.query(By.directive(MatError)); - // expect(error).toBeNull(); - // }); + it('should not dispatch SearchByTermAction when no checkboxes are selected and term is empty', () => { + store.dispatch.calls.reset(); + + spyOn(component as any, 'isLibrariesChecked').and.returnValue(false); + spyOn(component as any, 'isFoldersChecked').and.returnValue(false); + spyOn(component as any, 'isFilesChecked').and.returnValue(false); + + component.searchedWord = ''; + component.onSearchSubmit({ target: { value: '' } }); + + expect(store.dispatch).not.toHaveBeenCalled(); }); }); diff --git a/projects/aca-content/src/lib/components/search/search-input/search-input.component.ts b/projects/aca-content/src/lib/components/search/search-input/search-input.component.ts index ebec77c0a..39fd00a23 100644 --- a/projects/aca-content/src/lib/components/search/search-input/search-input.component.ts +++ b/projects/aca-content/src/lib/components/search/search-input/search-input.component.ts @@ -213,8 +213,8 @@ export class SearchInputComponent implements OnInit, OnDestroy { this.hasLibrariesConstraint = this.evaluateLibrariesConstraint(); if (this.onLibrariesSearchResults && this.isSameSearchTerm()) { this.queryLibrariesBuilder.update(); - } else if (this.searchedWord) { - this.store.dispatch(new SearchByTermAction(this.searchedWord, this.searchOptions)); + } else if (searchTerm) { + this.store.dispatch(new SearchByTermAction(searchTerm, this.searchOptions)); } } else { if (this.isFoldersChecked() && !this.isFilesChecked()) { @@ -227,8 +227,8 @@ export class SearchInputComponent implements OnInit, OnDestroy { if (this.onSearchResults && this.isSameSearchTerm()) { this.queryBuilder.update(); - } else if (this.searchedWord) { - this.store.dispatch(new SearchByTermAction(this.searchedWord, this.searchOptions)); + } else if (searchTerm) { + this.store.dispatch(new SearchByTermAction(searchTerm, this.searchOptions)); } } }