1/* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17import {ComponentFixture, TestBed} from '@angular/core/testing'; 18import {FormsModule} from '@angular/forms'; 19import {MatButtonModule} from '@angular/material/button'; 20import {MatFormFieldModule} from '@angular/material/form-field'; 21import {MatIconModule} from '@angular/material/icon'; 22import {MatInputModule} from '@angular/material/input'; 23import {MatTooltipModule} from '@angular/material/tooltip'; 24import {BrowserAnimationsModule} from '@angular/platform-browser/animations'; 25import {assertDefined} from 'common/assert_utils'; 26import {FilterFlag} from 'common/filter_flag'; 27import {TextFilter} from 'viewers/common/text_filter'; 28import {SearchBoxComponent} from './search_box_component'; 29 30describe('SearchBoxComponent', () => { 31 let fixture: ComponentFixture<SearchBoxComponent>; 32 let component: SearchBoxComponent; 33 let htmlElement: HTMLElement; 34 35 beforeEach(async () => { 36 await TestBed.configureTestingModule({ 37 imports: [ 38 MatFormFieldModule, 39 MatInputModule, 40 FormsModule, 41 MatButtonModule, 42 BrowserAnimationsModule, 43 MatIconModule, 44 MatTooltipModule, 45 ], 46 declarations: [SearchBoxComponent], 47 }).compileComponents(); 48 fixture = TestBed.createComponent(SearchBoxComponent); 49 component = fixture.componentInstance; 50 htmlElement = fixture.nativeElement; 51 component.textFilter = new TextFilter(); 52 fixture.detectChanges(); 53 }); 54 55 it('can be created', () => { 56 expect(component).toBeTruthy(); 57 }); 58 59 it('shows custom label', () => { 60 const label = htmlElement.querySelector('.search-box mat-label'); 61 expect(label?.textContent).toEqual('Search'); 62 63 component.label = 'custom label'; 64 fixture.detectChanges(); 65 expect(label?.textContent).toEqual('custom label'); 66 }); 67 68 it('handles change in filter', () => { 69 const spy = spyOn(component.filterChange, 'emit'); 70 expect(component.textFilter?.filterString).toEqual(''); 71 expect(htmlElement.querySelector('.highlighted')).toBeNull(); 72 changeFilterString('Test'); 73 expect(component.textFilter?.filterString).toEqual('Test'); 74 expect(spy).toHaveBeenCalledWith(new TextFilter('Test')); 75 expect(htmlElement.querySelector('.highlighted')).toBeTruthy(); 76 }); 77 78 it('handles change in flags', () => { 79 const spy = spyOn(component.filterChange, 'emit'); 80 const buttons = 81 htmlElement.querySelectorAll<HTMLElement>('.search-box button'); 82 expect(buttons.length).toEqual(3); 83 84 buttons.item(0).click(); 85 fixture.detectChanges(); 86 expect(spy).toHaveBeenCalledWith( 87 new TextFilter('', [FilterFlag.MATCH_CASE]), 88 ); 89 90 buttons.item(0).click(); 91 fixture.detectChanges(); 92 expect(spy).toHaveBeenCalledWith(new TextFilter()); 93 94 buttons.item(2).click(); 95 fixture.detectChanges(); 96 expect(spy).toHaveBeenCalledWith( 97 new TextFilter('', [FilterFlag.USE_REGEX]), 98 ); 99 100 buttons.item(1).click(); 101 fixture.detectChanges(); 102 expect(spy).toHaveBeenCalledWith( 103 new TextFilter('', [FilterFlag.USE_REGEX, FilterFlag.MATCH_WORD]), 104 ); 105 }); 106 107 function changeFilterString( 108 newString: string, 109 el = htmlElement, 110 f = fixture, 111 ) { 112 const inputEl = assertDefined( 113 el.querySelector<HTMLInputElement>('.search-box input'), 114 ); 115 inputEl.value = newString; 116 inputEl.dispatchEvent(new Event('input')); 117 f.detectChanges(); 118 } 119}); 120