I have a modal component also using the bootstrap. Among the features, I have a @ContentChildren for the CloseModalDirective directive that makes any element be responsible for closing modal when clicked. The problem is that I can not test this functionality.
The component works perfectly in the application, my problem is only with the test
This is my component:
import {
AfterContentInit,
Component,
ContentChildren,
Directive,
ElementRef, EventEmitter,
Input,
OnDestroy,
Output,
QueryList,
ViewChild
} from '@angular/core';
import $ from 'jquery';
import ModalSizes from './modal-size.enum';
@Directive({ selector: '[appCloseModal]' })
export class CloseModalDirective {}
@Component({
selector: 'app-modal',
templateUrl: './modal.component.html',
styleUrls: ['./modal.component.scss']
})
export class ModalComponent implements AfterContentInit, OnDestroy {
@Input() header: string;
@Input() size = ModalSizes.Medium;
@Input() closeable = true;
@Output() openFinished = new EventEmitter();
@Output() closeFinished = new EventEmitter();
@ViewChild('modal') modal: ElementRef;
// FINDING MY ELEMENTS
@ContentChildren(CloseModalDirective, { descendants: true, read: ElementRef })
closeButtons: QueryList<ElementRef> = new QueryList();
show() {
$(this.modal.nativeElement).modal({
backdrop: this.closeable ? true : 'static',
keyboard: this.closeable,
show: true
});
}
hide() {
$(this.modal.nativeElement).modal('hide');
}
ngAfterContentInit() {
$(this.modal.nativeElement).on('shown.bs.modal', () => {
this.openFinished.emit();
});
$(this.modal.nativeElement).on('hide.bs.modal', () => {
this.closeFinished.emit();
});
// ADDING HIDE EVENT
this.closeButtons.forEach(button => {
button.nativeElement.addEventListener('click', this.hide.bind(this), false);
});
}
ngOnDestroy() {
$(this.modal.nativeElement).off('shown.bs.modal');
$(this.modal.nativeElement).off('hide.bs.modal');
this.closeButtons.forEach(button => {
button.nativeElement.removeEventListener('click', this.hide.bind(this));
});
$(this.modal.nativeElement).modal('dispose');
}
}
This is my tests:
import {async, ComponentFixture, fakeAsync, TestBed, tick} from '@angular/core/testing';
import {CloseModalDirective, ModalComponent} from './modal.component';
import {Component} from '@angular/core';
import ModalSize from './modal-size.enum';
import 'bootstrap';
@Component({
selector: 'app-test',
template: `
<app-modal header="Title">
<div class="content">Content</div>
<button appCloseModal footer>Close</button>
</app-modal>
`
})
class TestComponent {}
describe('ModalComponent', () => {
let component: ModalComponent;
let fixture: ComponentFixture<ModalComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ CloseModalDirective, ModalComponent, TestComponent ],
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ModalComponent);
component = fixture.componentInstance;
component.header = 'Titulo';
component.size = ModalSize.Small;
component.closeable = true;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should display title and size', () => {
const title = fixture.nativeElement.querySelector('.modal-title');
expect(title.textContent).toBe(component.header);
const classes = fixture.nativeElement.querySelector('.modal-dialog').classList;
expect(classes).toContain(component.size);
});
it('should show the modal on call show method', fakeAsync(() => {
component.show();
tick(1000);
const modal = fixture.nativeElement.querySelector('.modal');
expect(modal.classList).toContain('show');
component.hide();
tick(1000);
}));
// NOT WORKING!
it('should hide modal on click elements with appCloseModal directive', () => {
spyOn(component, 'hide');
const testFixture: ComponentFixture<TestComponent> = TestBed.createComponent(TestComponent);
const element = testFixture.nativeElement.querySelector('[appCloseModal]');
element.click();
expect(component.hide).toHaveBeenCalled();
});
});
What did I do wrong?
Aucun commentaire:
Enregistrer un commentaire