UNPKG

igniteui-angular-sovn

Version:

Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps

470 lines (389 loc) 19.6 kB
import { Component, ViewChild, ElementRef, Inject } from '@angular/core'; import { fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { IgxInputGroupComponent } from './input-group.component'; import { DisplayDensityToken, DisplayDensity } from '../core/density'; import { UIInteractions } from '../test-utils/ui-interactions.spec'; import { IgxInputDirective } from '../directives/input/input.directive'; import { configureTestSuite } from '../test-utils/configure-suite'; import { IgxPrefixDirective, IgxSuffixDirective } from '../chips/public_api'; import { IGX_INPUT_GROUP_TYPE, IgxInputGroupType } from './inputGroupType'; const INPUT_GROUP_CSS_CLASS = 'igx-input-group'; const INPUT_GROUP_BOX_CSS_CLASS = 'igx-input-group--box'; const INPUT_GROUP_BORDER_CSS_CLASS = 'igx-input-group--border'; const INPUT_GROUP_SEARCH_CSS_CLASS = 'igx-input-group--search'; const INPUT_GROUP_COMFORTABLE_DENSITY_CSS_CLASS = 'igx-input-group--comfortable'; const INPUT_GROUP_COMPACT_DENSITY_CSS_CLASS = 'igx-input-group--compact'; const INPUT_GROUP_COSY_DENSITY_CSS_CLASS = 'igx-input-group--cosy'; describe('IgxInputGroup', () => { configureTestSuite(); beforeAll(waitForAsync(() => { TestBed.configureTestingModule({ imports: [ InputGroupComponent, InputGroupBoxComponent, InputGroupBorderComponent, InputGroupSearchComponent, InputGroupFileComponent, InputGroupDisabledComponent, InputGroupDisabledByDefaultComponent, InputGroupCosyDisplayDensityComponent, InputGroupDisabledWithoutValueComponent, InputGroupCompactDisplayDensityComponent, InputGroupInputDisplayDensityComponent ] }).compileComponents(); })); it('Initializes an input group.', fakeAsync(() => { const fixture = TestBed.createComponent(InputGroupDisabledComponent); fixture.detectChanges(); const inputGroupElement = fixture.debugElement.query(By.css('igx-input-group')).nativeElement; expect(inputGroupElement.classList.contains(INPUT_GROUP_CSS_CLASS)).toBe(true); const igxInputGroup = fixture.componentInstance.igxInputGroup; tick(); fixture.detectChanges(); // the default type should be line testInputGroupType('line', igxInputGroup, inputGroupElement); })); it('Initializes an input group with type box.', fakeAsync(() => { const fixture = TestBed.createComponent(InputGroupBoxComponent); fixture.detectChanges(); const inputGroupElement = fixture.debugElement.query(By.css('igx-input-group')).nativeElement; expect(inputGroupElement.classList.contains(INPUT_GROUP_CSS_CLASS)).toBe(true); const igxInputGroup = fixture.componentInstance.igxInputGroup; tick(); fixture.detectChanges(); testInputGroupType('box', igxInputGroup, inputGroupElement); })); it('Initializes an input group with type border.', fakeAsync(() => { const fixture = TestBed.createComponent(InputGroupBorderComponent); fixture.detectChanges(); const inputGroupElement = fixture.debugElement.query(By.css('igx-input-group')).nativeElement; expect(inputGroupElement.classList.contains(INPUT_GROUP_CSS_CLASS)).toBe(true); const igxInputGroup = fixture.componentInstance.igxInputGroup; tick(); fixture.detectChanges(); testInputGroupType('border', igxInputGroup, inputGroupElement); })); it('Initializes an input group with type search.', fakeAsync(() => { const fixture = TestBed.createComponent(InputGroupSearchComponent); fixture.detectChanges(); const inputGroupElement = fixture.debugElement.query(By.css('igx-input-group')).nativeElement; expect(inputGroupElement.classList.contains(INPUT_GROUP_CSS_CLASS)).toBe(true); const igxInputGroup = fixture.componentInstance.igxInputGroup; tick(); fixture.detectChanges(); testInputGroupType('search', igxInputGroup, inputGroupElement); })); it('Initializes upload file button with type=\'button\'.', () => { const fixture = TestBed.createComponent(InputGroupFileComponent); fixture.detectChanges(); const uploadFileButton = fixture.debugElement.query(By.css('button')).nativeElement; expect(uploadFileButton.getAttribute('type')).toEqual('button'); }); it('Should respect type Token and be able to change input group type programmatically.', fakeAsync(() => { const fixture = TestBed.createComponent(InputGroupComponent); fixture.detectChanges(); const inputGroupElement = fixture.debugElement.query(By.css('igx-input-group')).nativeElement; const igxInputGroup = fixture.componentInstance.igxInputGroup; tick(); fixture.detectChanges(); // a Token is passed and can be obtained expect(fixture.componentInstance.IGTOKEN).toBe('box'); // type set via Token is 'box' testInputGroupType('box', igxInputGroup, inputGroupElement); // user can override Token passing other igxInputGroup types igxInputGroup.type = 'border'; fixture.detectChanges(); testInputGroupType('border', igxInputGroup, inputGroupElement); igxInputGroup.type = 'box'; fixture.detectChanges(); testInputGroupType('box', igxInputGroup, inputGroupElement); igxInputGroup.type = 'search'; fixture.detectChanges(); testInputGroupType('search', igxInputGroup, inputGroupElement); igxInputGroup.type = 'line'; fixture.detectChanges(); testInputGroupType('line', igxInputGroup, inputGroupElement); // Set type as null, so the Token type should be used again igxInputGroup.type = null; fixture.detectChanges(); testInputGroupType('box', igxInputGroup, inputGroupElement); })); it('disabled input should properly detect changes.', () => { const fixture = TestBed.createComponent(InputGroupDisabledComponent); fixture.detectChanges(); const component = fixture.componentInstance; const igxInputGroup = component.igxInputGroup; expect(igxInputGroup.disabled).toBeFalsy(); component.changeDisableState(); fixture.detectChanges(); expect(igxInputGroup.disabled).toBeTruthy(); component.changeDisableState(); fixture.detectChanges(); expect(igxInputGroup.disabled).toBeFalsy(); }); it('disabled by default should properly work.', () => { const fixture = TestBed.createComponent(InputGroupDisabledByDefaultComponent); fixture.detectChanges(); const component = fixture.componentInstance; const igxInputGroup = component.igxInputGroup; expect(igxInputGroup.disabled).toBeTruthy(); }); it('should handle disabled attribute without value', () => { const fixture = TestBed.createComponent(InputGroupDisabledWithoutValueComponent); fixture.detectChanges(); const component = fixture.componentInstance; const igxInputGroup = component.igxInputGroup; expect(igxInputGroup.disabled).toBeTruthy(); component.changeDisableState(); fixture.detectChanges(); expect(igxInputGroup.disabled).toBeFalsy(); component.changeDisableState(); fixture.detectChanges(); expect(igxInputGroup.disabled).toBeTruthy(); }); it('default Display Density applied', () => { const fixture = TestBed.createComponent(InputGroupDisabledByDefaultComponent); fixture.detectChanges(); const inputGroup = fixture.componentInstance.igxInputGroup; const inputGroupElement = inputGroup.element.nativeElement; expect(inputGroupElement.classList.contains(INPUT_GROUP_COMFORTABLE_DENSITY_CSS_CLASS)).toBe(true); }); it('cosy Display Density applied', () => { const fixture = TestBed.createComponent(InputGroupCosyDisplayDensityComponent); fixture.detectChanges(); const inputGroup = fixture.componentInstance.igxInputGroup; const inputGroupElement = inputGroup.element.nativeElement; expect(inputGroupElement.classList.contains(INPUT_GROUP_COMFORTABLE_DENSITY_CSS_CLASS)).toBeFalsy(); expect(inputGroupElement.classList.contains(INPUT_GROUP_COSY_DENSITY_CSS_CLASS)).toBeTruthy(); }); it('compact Display Density applied', () => { const fixture = TestBed.createComponent(InputGroupCompactDisplayDensityComponent); fixture.detectChanges(); const inputGroup = fixture.componentInstance.igxInputGroup; const inputGroupElement = inputGroup.element.nativeElement; expect(inputGroupElement.classList.contains(INPUT_GROUP_COMFORTABLE_DENSITY_CSS_CLASS)).toBeFalsy(); expect(inputGroupElement.classList.contains(INPUT_GROUP_COMPACT_DENSITY_CSS_CLASS)).toBeTruthy(); }); it('compact Display Density applied via input', () => { const fixture = TestBed.createComponent(InputGroupInputDisplayDensityComponent); fixture.detectChanges(); const inputGroup = fixture.componentInstance.igxInputGroup; const inputGroupElement = inputGroup.element.nativeElement; expect(inputGroupElement.classList.contains(INPUT_GROUP_COMFORTABLE_DENSITY_CSS_CLASS)).toBeFalsy(); expect(inputGroupElement.classList.contains(INPUT_GROUP_COMPACT_DENSITY_CSS_CLASS)).toBeTruthy(); }); it('should correctly prevent default on pointer down', () => { const fixture = TestBed.createComponent(InputGroupComponent); fixture.detectChanges(); const inputGroup = fixture.componentInstance.igxInputGroup; const prefix = fixture.componentInstance.prefix; const input = fixture.componentInstance.igxInput; fixture.componentInstance.suppressInputAutofocus = false; const pointOnPrefix = UIInteractions.getPointFromElement(prefix.nativeElement); const pointerEvent = UIInteractions.createPointerEvent('pointerdown', pointOnPrefix); const preventDefaultSpy = spyOn(pointerEvent, 'preventDefault'); Object.defineProperty(pointerEvent, 'target', { value: input.nativeElement, configurable: true }); const inputGroupDebugElement = fixture.debugElement.query(By.directive(IgxInputGroupComponent)); // input group is not focused we should not prevent default on pointer down inputGroupDebugElement.triggerEventHandler('pointerdown', pointerEvent); expect(preventDefaultSpy).not.toHaveBeenCalled(); expect(preventDefaultSpy).toHaveBeenCalledTimes(0); Object.defineProperty(pointerEvent, 'target', { value: prefix.nativeElement, configurable: true }); // input group is not focused we should not prevent default on pointer down inputGroupDebugElement.triggerEventHandler('pointerdown', pointerEvent); expect(preventDefaultSpy).not.toHaveBeenCalled(); expect(preventDefaultSpy).toHaveBeenCalledTimes(0); // input group is focused we should prevent default on pointer down on prefix/suffix inputGroup.isFocused = true; inputGroupDebugElement.triggerEventHandler('pointerdown', pointerEvent); expect(preventDefaultSpy).toHaveBeenCalled(); expect(preventDefaultSpy).toHaveBeenCalledTimes(1); }); it('should not focus input on prefix/suffix click when group is not focused and suppressInputAutofocus=true', () => { const fixture = TestBed.createComponent(InputGroupComponent); fixture.detectChanges(); const inputGroup = fixture.componentInstance.igxInputGroup; const prefix = fixture.componentInstance.prefix; const input = fixture.componentInstance.igxInput; const pointerEvent = UIInteractions.getMouseEvent('click'); Object.defineProperty(pointerEvent, 'target', { value: prefix.nativeElement }); const inputGroupDebugElement = fixture.debugElement.query(By.directive(IgxInputGroupComponent)); // input group is not focused and suppressInputAutofocus is true - click on prefix/suffix should not focus the input fixture.componentInstance.suppressInputAutofocus = true; inputGroup.isFocused = false; fixture.detectChanges(); inputGroupDebugElement.triggerEventHandler('click', pointerEvent); expect(document.activeElement).not.toEqual(input.nativeElement); // input group is not focused and suppressInputAutofocus is false - click on prefix/suffix should focus the input fixture.componentInstance.suppressInputAutofocus = false; inputGroup.isFocused = false; fixture.detectChanges(); inputGroupDebugElement.triggerEventHandler('click', pointerEvent); expect(document.activeElement).toEqual(input.nativeElement); // input group is focused and suppressInputAutofocus is true - click on prefix/suffix should focus the input fixture.componentInstance.suppressInputAutofocus = true; inputGroup.isFocused = true; fixture.detectChanges(); inputGroupDebugElement.triggerEventHandler('click', pointerEvent); expect(document.activeElement).toEqual(input.nativeElement); }); }); @Component({ template: `<igx-input-group #igxInputGroup [suppressInputAutofocus]="suppressInputAutofocus"> <igx-prefix>PREFIX</igx-prefix> <igx-suffix>SUFFIX</igx-suffix> <input #igxInput igxInput /> </igx-input-group>`, providers: [{ provide: IGX_INPUT_GROUP_TYPE, useValue: 'box' }], standalone: true, imports: [IgxInputGroupComponent, IgxInputDirective, IgxPrefixDirective, IgxSuffixDirective] }) class InputGroupComponent { @ViewChild('igxInputGroup', { static: true }) public igxInputGroup: IgxInputGroupComponent; @ViewChild('igxInput', { read: IgxInputDirective, static: true }) public igxInput: IgxInputDirective; @ViewChild(IgxPrefixDirective, { read: ElementRef }) public prefix: ElementRef; @ViewChild(IgxSuffixDirective, { read: ElementRef }) public suffix: ElementRef; public suppressInputAutofocus = false; constructor(@Inject(IGX_INPUT_GROUP_TYPE) public IGTOKEN: IgxInputGroupType) {} } @Component({ template: `<igx-input-group #igxInputGroup type="box"> <input igxInput /> </igx-input-group>`, standalone: true, imports: [IgxInputGroupComponent, IgxInputDirective] }) class InputGroupBoxComponent { @ViewChild('igxInputGroup', { static: true }) public igxInputGroup: IgxInputGroupComponent; } @Component({ template: `<igx-input-group #igxInputGroup type="border"> <input igxInput /> </igx-input-group>`, standalone: true, imports: [IgxInputGroupComponent, IgxInputDirective] }) class InputGroupBorderComponent { @ViewChild('igxInputGroup', { static: true }) public igxInputGroup: IgxInputGroupComponent; } @Component({ template: `<igx-input-group #igxInputGroup type="search"> <input igxInput /> </igx-input-group>`, standalone: true, imports: [IgxInputDirective, IgxInputGroupComponent] }) class InputGroupSearchComponent { @ViewChild('igxInputGroup', { static: true }) public igxInputGroup: IgxInputGroupComponent; } @Component({ template: `<igx-input-group> <input igxInput type="file" multiple /> </igx-input-group>`, standalone: true, imports: [IgxInputGroupComponent, IgxInputDirective] }) class InputGroupFileComponent { } const testInputGroupType = (type: IgxInputGroupType, component: IgxInputGroupComponent, nativeElement: HTMLInputElement) => { let isLine = false; let isBorder = false; let isBox = false; let isSearch = false; switch (type) { case 'line': isLine = true; break; case 'border': isBorder = true; break; case 'box': isBox = true; break; case 'search': isSearch = true; break; default: break; } expect(nativeElement.classList.contains(INPUT_GROUP_BOX_CSS_CLASS)).toBe(isBox); expect(nativeElement.classList.contains(INPUT_GROUP_BORDER_CSS_CLASS)).toBe(isBorder); expect(nativeElement.classList.contains(INPUT_GROUP_SEARCH_CSS_CLASS)).toBe(isSearch); expect(component.isTypeLine).toBe(isLine); expect(component.isTypeBorder).toBe(isBorder); expect(component.isTypeBox).toBe(isBox); expect(component.isTypeSearch).toBe(isSearch); }; @Component({ template: `<igx-input-group #igxInputGroup> <input igxInput [disabled]="disabled"/> </igx-input-group>`, standalone: true, imports: [IgxInputGroupComponent, IgxInputDirective] }) class InputGroupDisabledComponent { @ViewChild('igxInputGroup', { static: true }) public igxInputGroup: IgxInputGroupComponent; public disabled = false; public changeDisableState() { this.disabled = !this.disabled; } } @Component({ template: `<igx-input-group #igxInputGroup> <input igxInput disabled/> </igx-input-group>`, standalone: true, imports: [IgxInputGroupComponent, IgxInputDirective] }) class InputGroupDisabledWithoutValueComponent { @ViewChild('igxInputGroup') public igxInputGroup: IgxInputGroupComponent; @ViewChild(IgxInputDirective) public inputDir: IgxInputDirective; public changeDisableState() { this.inputDir.disabled = !this.inputDir.disabled; } } @Component({ template: `<igx-input-group #igxInputGroup> <input igxInput [disabled]="disabled"/> </igx-input-group>`, standalone: true, imports: [IgxInputGroupComponent, IgxInputDirective] }) class InputGroupDisabledByDefaultComponent { @ViewChild('igxInputGroup', { static: true }) public igxInputGroup: IgxInputGroupComponent; public disabled = true; } @Component({ template: `<igx-input-group #igxInputGroup> <input igxInput /> </igx-input-group>`, providers: [{ provide: DisplayDensityToken, useValue: { displayDensity: DisplayDensity.cosy } }], standalone: true, imports: [IgxInputGroupComponent, IgxInputDirective] }) class InputGroupCosyDisplayDensityComponent { @ViewChild('igxInputGroup', { static: true }) public igxInputGroup: IgxInputGroupComponent; } @Component({ template: `<igx-input-group #igxInputGroup> <input igxInput /> </igx-input-group>`, providers: [{ provide: DisplayDensityToken, useValue: { displayDensity: DisplayDensity.compact } }], standalone: true, imports: [IgxInputGroupComponent, IgxInputDirective] }) class InputGroupCompactDisplayDensityComponent { @ViewChild('igxInputGroup', { static: true }) public igxInputGroup: IgxInputGroupComponent; } @Component({ template: `<igx-input-group #igxInputGroup displayDensity="compact"> <input igxInput /> </igx-input-group>`, standalone: true, imports: [IgxInputGroupComponent, IgxInputDirective] }) class InputGroupInputDisplayDensityComponent { @ViewChild('igxInputGroup', { static: true }) public igxInputGroup: IgxInputGroupComponent; }