#863 Add Unit Test for ClickOutside Directive

This commit is contained in:
Sebastian
2020-07-21 22:51:24 +02:00
parent c885942690
commit 7fd7c2625b
5 changed files with 85 additions and 5 deletions

View File

@@ -8,6 +8,8 @@
(search)="triggerSearch($event)"
(scan)="openScanner()"
(reset)="reset()"
clickOutside
(clickOutside)="onClickOutside()"
></app-shelf-searchbar>
<app-autocomplete-results
*ngIf="(searchMode$ | async) === 'autocomplete'"

View File

@@ -178,6 +178,11 @@ export class ShelfSearchInputComponent
}
}
onClickOutside() {
// TODO handle close autocompete
console.log('Close Autocomplete');
}
private updateSearchQuery(searchQuery: string) {
this.autocompleteQueryString$.next(searchQuery);
}

View File

@@ -4,6 +4,7 @@ import { ShelfSearchBarModule } from '../../../components';
import { AutocompleteResultsModule } from '../../../components/autocomplete-results';
import { ShelfSearchInputComponent } from './search-input.component';
import { CollectingShelfScannerModule } from 'shared/lib/collecting-shelf-scanner/collecting-shelf-scanner.module';
import { SharedModule } from 'apps/sales/src/app/shared/shared.module';
@NgModule({
imports: [
@@ -11,6 +12,7 @@ import { CollectingShelfScannerModule } from 'shared/lib/collecting-shelf-scanne
CollectingShelfScannerModule,
ShelfSearchBarModule,
AutocompleteResultsModule,
SharedModule,
],
exports: [ShelfSearchInputComponent],
declarations: [ShelfSearchInputComponent],

View File

@@ -0,0 +1,61 @@
import { TestBed, ComponentFixture } from '@angular/core/testing';
import { Component, DebugElement } from '@angular/core';
import { ClickOutsideDirective } from './click-outside.directive';
import { By } from '@angular/platform-browser';
@Component({
template: `<section id="section">
<div id="outside">Outside</div>
<div>
Inside<input id="inside" clickOutside (clickOutside)="onClickOutside()" />
</div>
</section>`,
})
export class TestWrapperComponent {
constructor() {}
onClickOutside() {}
}
fdescribe('Directive: ClickOutsideDirective', () => {
let fixture: ComponentFixture<TestWrapperComponent>;
let component: TestWrapperComponent;
let outsideEl: DebugElement;
let insideEl: DebugElement;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [TestWrapperComponent, ClickOutsideDirective],
});
fixture = TestBed.createComponent(TestWrapperComponent);
component = fixture.componentInstance;
outsideEl = fixture.debugElement.query(By.css('#outside'));
insideEl = fixture.debugElement.query(By.css('#inside'));
spyOn(component, 'onClickOutside').and.callThrough();
fixture.detectChanges();
});
it('shoud emit an event if the clicked element is outside', () => {
// Event fires twice
document.dispatchEvent(new Event('click'));
document.dispatchEvent(new Event('click'));
fixture.detectChanges();
expect(component.onClickOutside).toHaveBeenCalled();
});
it('shoud not emit an event if the clicked element is inside', () => {
insideEl.triggerEventHandler('click', { target: insideEl.nativeElement });
fixture.detectChanges();
insideEl.triggerEventHandler('click', { target: insideEl.nativeElement });
expect(component.onClickOutside).not.toHaveBeenCalled();
});
});

View File

@@ -1,10 +1,18 @@
import { Directive, ElementRef, Output, EventEmitter, HostListener, OnInit, OnDestroy } from '@angular/core';
import {
Directive,
ElementRef,
Output,
EventEmitter,
HostListener,
OnInit,
OnDestroy,
} from '@angular/core';
import { Subject } from 'rxjs';
import { skip, takeUntil } from 'rxjs/operators';
@Directive({ selector: '[clickOutside]' })
export class ClickOutsideDirective implements OnInit, OnDestroy {
clickedInside$ = new Subject();
clickedOutside$ = new Subject();
destroy$ = new Subject();
@Output() clickOutside = new EventEmitter<void>();
@@ -15,14 +23,16 @@ export class ClickOutsideDirective implements OnInit, OnDestroy {
const isClickedInside = this.elementRef.nativeElement.contains(target);
if (!isClickedInside) {
this.clickedInside$.next();
this.clickedOutside$.next();
}
}
constructor(private elementRef: ElementRef) { }
constructor(private elementRef: ElementRef) {}
ngOnInit() {
this.clickedInside$.pipe(takeUntil(this.destroy$), skip(1)).subscribe(_ => this.clickOutside.emit());
this.clickedOutside$
.pipe(takeUntil(this.destroy$), skip(1))
.subscribe((_) => this.clickOutside.emit());
}
ngOnDestroy() {