blob: 784093178508686648cd249c5dd3d057d584ddf9 [file] [log] [blame]
/********************************************************************************
* Copyright (c) 2020 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
import {Component, ViewChild} from "@angular/core";
import {async, ComponentFixture, TestBed} from "@angular/core/testing";
import {FormsModule, NgForm, NgModel} from "@angular/forms";
import {MatIcon} from "@angular/material/icon";
import {By} from "@angular/platform-browser";
import {BrowserAnimationsModule} from "@angular/platform-browser/animations";
import {Calendar} from "primeng/calendar";
import {EKeyboardKeys} from "../../../../util/events";
import {DateControlModule} from "../date-control.module";
import {DateControlComponent} from "./date-control.component";
describe("DateControlComponent", () => {
let component: DateControlSpecComponent;
let fixture: ComponentFixture<DateControlSpecComponent>;
let textInput: HTMLInputElement;
let matIcon: HTMLElement;
function getCalendar(): Calendar {
try {
const componentInstance = fixture.debugElement.query(By.directive(Calendar)).componentInstance;
return componentInstance instanceof Calendar ? componentInstance : undefined;
} catch (e) {
return;
}
}
function getCalendarDayElement(index: number): HTMLElement {
try {
return fixture?.debugElement == null ? [] : fixture.debugElement
.queryAll(By.css(".ui-state-default:not(.ui-state-disabled)"))
.map((debugElement) => debugElement.nativeElement)[index];
} catch (e) {
return undefined;
}
}
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
DateControlSpecComponent
],
imports: [
DateControlModule,
BrowserAnimationsModule,
FormsModule
]
}).compileComponents();
}));
beforeEach(async () => {
fixture = TestBed.createComponent(DateControlSpecComponent);
component = fixture.componentInstance;
fixture.detectChanges();
await fixture.whenStable();
textInput = fixture.debugElement.query(By.css("input")).nativeElement;
matIcon = fixture.debugElement.query(By.directive(MatIcon)).nativeElement;
});
it("should register to Angular forms", async () => {
expect(component).toBeDefined();
expect(component?.ngForm?.value).toBeDefined();
expect(component.ngForm.value.date).toBe("2020-05-01");
});
it("should update value via text input", async () => {
expect(textInput?.value).toBe("01.05.2020");
textInput.value = "02.05.2020";
textInput.dispatchEvent(new InputEvent("input"));
fixture.detectChanges();
expect(component.value).toBe("2020-05-02");
expect(component.ngForm.value.date).toBe("2020-05-02");
});
it("should handle faulty user input", async () => {
expect(textInput?.value).toBe("01.05.2020");
textInput.value = "19.05.2020abcdef";
textInput.dispatchEvent(new InputEvent("input"));
fixture.detectChanges();
expect(component.value).toBe("2020-05-19");
expect(component.ngForm.value.date).toBe("2020-05-19");
expect(textInput.value).toBe("19.05.2020abcdef");
textInput.dispatchEvent(new Event("blur"));
fixture.detectChanges();
expect(component.value).toBe("2020-05-19");
expect(component.ngForm.value.date).toBe("2020-05-19");
expect(textInput.value).toBe("19.05.2020");
});
it("should update value via calendar", async () => {
expect(component.value).toBe("2020-05-01");
component.dateControlComponent.toggle(true);
await fixture.whenStable();
fixture.detectChanges();
const dayElement = getCalendarDayElement(19);
dayElement.dispatchEvent(new Event("click"));
expect(component.value).toBe("2020-05-20");
expect(component.ngForm.value.date).toBe("2020-05-20");
await fixture.whenStable();
fixture.detectChanges();
expect(getCalendar()).not.toBeDefined();
});
it("should toggle overlay", async () => {
expect(getCalendar()).not.toBeDefined();
textInput.dispatchEvent(new Event("mousedown"));
expect(getCalendar()).toBeDefined();
textInput.dispatchEvent(new Event("mousedown"));
expect(getCalendar()).toBeDefined();
document.dispatchEvent(new Event("click"));
expect(getCalendar()).not.toBeDefined();
matIcon.dispatchEvent(new Event("mousedown"));
expect(getCalendar()).toBeDefined();
matIcon.dispatchEvent(new Event("mousedown"));
expect(getCalendar()).not.toBeDefined();
});
it("should close overlay when tabbing or pressing enter from the text input", async () => {
textInput.dispatchEvent(new Event("mousedown"));
fixture.detectChanges();
await fixture.whenStable();
expect(getCalendar()).toBeDefined();
textInput.dispatchEvent(new KeyboardEvent("keydown", {key: EKeyboardKeys.TAB}));
fixture.detectChanges();
await fixture.whenStable();
expect(getCalendar()).not.toBeDefined();
textInput.dispatchEvent(new Event("mousedown"));
fixture.detectChanges();
await fixture.whenStable();
expect(getCalendar()).toBeDefined();
textInput.dispatchEvent(new KeyboardEvent("keydown", {key: "Enter"}));
fixture.detectChanges();
await fixture.whenStable();
expect(getCalendar()).not.toBeDefined();
});
it("should close overlay when tabbing from the calendar", async () => {
component.dateControlComponent.toggle(true);
fixture.detectChanges();
await fixture.whenStable();
expect(getCalendar()).toBeDefined();
getCalendar().el.nativeElement.dispatchEvent(new KeyboardEvent("keydown", {key: EKeyboardKeys.TAB}));
fixture.detectChanges();
await fixture.whenStable();
expect(getCalendar()).not.toBeDefined();
});
it("should allow no interactions when disabled", async () => {
component.dateControlComponent.toggle(true);
fixture.detectChanges();
await fixture.whenStable();
expect(getCalendar()).toBeDefined();
component.ngModel.control.disable();
fixture.detectChanges();
await fixture.whenStable();
expect(textInput.disabled).toBeTrue();
expect(getCalendar()).not.toBeDefined();
textInput.dispatchEvent(new Event("click"));
fixture.detectChanges();
await fixture.whenStable();
expect(textInput.disabled).toBeTrue();
expect(getCalendar()).not.toBeDefined();
});
});
@Component({
selector: "app-date-control-spec",
template: `
<form>
<app-date-control [(appValue)]="value" [ngModel]="value" name="date">
</app-date-control>
</form>
`
})
class DateControlSpecComponent {
public value = "2020-05-01";
@ViewChild(NgForm)
public ngForm: NgForm;
@ViewChild(NgModel)
public ngModel: NgModel;
@ViewChild(DateControlComponent)
public dateControlComponent: DateControlComponent;
}