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();
  });
});
