Skip to content

Commit

Permalink
Merge pull request NationalBankBelgium#1259 from christophercr/bugfix…
Browse files Browse the repository at this point in the history
…/date-picker-invalid-status

Bugfix/date picker invalid status on initialization + required asterisk not shown
  • Loading branch information
christophercr authored Apr 25, 2019
2 parents a97c7ea + 0fd9fca commit 686c0f7
Show file tree
Hide file tree
Showing 5 changed files with 262 additions and 114 deletions.
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
/* tslint:disable:completed-docs max-inline-declarations no-identical-functions no-big-function */
import { NoopAnimationsModule } from "@angular/platform-browser/animations";
import { By } from "@angular/platform-browser";
import { Component, ViewChild } from "@angular/core";
import { FormControl, FormsModule, ReactiveFormsModule, Validators } from "@angular/forms";
import { async, ComponentFixture, TestBed } from "@angular/core/testing";
import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE } from "@angular/material/core";
import { MatDatepickerModule } from "@angular/material/datepicker";
import { MatFormField, MatFormFieldModule } from "@angular/material/form-field";
import { MatInputModule } from "@angular/material/input";
import { MatMomentDateModule, MomentDateAdapter } from "@angular/material-moment-adapter";
import { TranslateModule } from "@ngx-translate/core";
import { STARK_LOGGING_SERVICE, STARK_ROUTING_SERVICE } from "@nationalbankbelgium/stark-core";
import { MockStarkLoggingService, MockStarkRoutingService } from "@nationalbankbelgium/stark-core/testing";
import { FormControl, FormsModule, ReactiveFormsModule } from "@angular/forms";
import { MatFormFieldModule } from "@angular/material/form-field";
import { DEFAULT_DATE_MASK_CONFIG, StarkDatePickerComponent, StarkDatePickerMaskConfig } from "./date-picker.component";
import { STARK_DATE_FORMATS } from "./date-format.constants";
import { StarkTimestampMaskDirective } from "../../input-mask-directives";
Expand Down Expand Up @@ -106,6 +107,100 @@ describe("DatePickerComponent", () => {
}).compileComponents();
}));

describe("MatFormFieldControl", () => {
let hostComponent: TestHostFormControlComponent;
let hostFixture: ComponentFixture<TestHostFormControlComponent>;
const formFieldInvalidClass = "mat-form-field-invalid";

beforeEach(() => {
hostFixture = TestBed.createComponent(TestHostFormControlComponent);
hostComponent = hostFixture.componentInstance;
hostFixture.detectChanges(); // trigger initial data binding

component = hostComponent.datePickerComponent;
});

it("if date is initially invalid, the date picker should not be displayed as invalid until the user interacts with it", () => {
// re-create component with a form control with "required" validator
hostFixture = TestBed.createComponent(TestHostFormControlComponent);
hostComponent = hostFixture.componentInstance;
hostComponent.formControl = new FormControl(undefined, Validators.required); // initially invalid
hostFixture.detectChanges(); // trigger initial data binding

const formFieldDebugElement = hostFixture.debugElement.query(By.directive(MatFormField));
expect(formFieldDebugElement.classes[formFieldInvalidClass]).toBe(false);

const blurEvent = document.createEvent("Event");
blurEvent.initEvent("blur", true, true);
const inputDebugElement = hostFixture.debugElement.query(By.css("input"));
inputDebugElement.triggerEventHandler("blur", blurEvent); // simulate that the user has touched the input
hostFixture.detectChanges();

expect(formFieldDebugElement.classes[formFieldInvalidClass]).toBe(true);
});

it("if date is initially invalid, the date picker should not be displayed as invalid until it is marked as 'touched'", () => {
// re-create component with a form control with "required" validator
hostFixture = TestBed.createComponent(TestHostFormControlComponent);
hostComponent = hostFixture.componentInstance;
hostComponent.formControl = new FormControl(undefined, Validators.required); // initially invalid
hostFixture.detectChanges(); // trigger initial data binding

const formFieldDebugElement = hostFixture.debugElement.query(By.directive(MatFormField));
expect(formFieldDebugElement.classes[formFieldInvalidClass]).toBe(false);

hostComponent.formControl.markAsTouched();
hostFixture.detectChanges();

expect(formFieldDebugElement.classes[formFieldInvalidClass]).toBe(true);
});

it("if date is initially invalid, the date picker should not be displayed as invalid until it is marked as 'dirty'", () => {
// re-create component with a form control with "required" validator
hostFixture = TestBed.createComponent(TestHostFormControlComponent);
hostComponent = hostFixture.componentInstance;
hostComponent.formControl = new FormControl(undefined, Validators.required); // initially invalid
hostFixture.detectChanges(); // trigger initial data binding

const formFieldDebugElement = hostFixture.debugElement.query(By.directive(MatFormField));
expect(formFieldDebugElement.classes[formFieldInvalidClass]).toBe(false);

hostComponent.formControl.markAsDirty();
hostFixture.detectChanges();

expect(formFieldDebugElement.classes[formFieldInvalidClass]).toBe(true);
});

it("if marked as required, an asterisk should be appended to the label", () => {
const formFieldLabelSelector = ".mat-form-field-label";
const formFieldRequiredMarkerSelector = ".mat-form-field-required-marker";

hostComponent.placeholder = "this is a placeholder";
hostFixture.detectChanges();

expect(hostFixture.debugElement.query(By.css(formFieldLabelSelector))).toBeTruthy();
expect(hostFixture.debugElement.query(By.css(formFieldRequiredMarkerSelector))).toBeFalsy();

hostComponent.required = <any>""; // coerced to true
hostFixture.detectChanges();

expect(hostFixture.debugElement.query(By.css(formFieldLabelSelector))).toBeTruthy();
expect(hostFixture.debugElement.query(By.css(formFieldRequiredMarkerSelector))).toBeTruthy();

hostComponent.required = false;
hostFixture.detectChanges();

expect(hostFixture.debugElement.query(By.css(formFieldLabelSelector))).toBeTruthy();
expect(hostFixture.debugElement.query(By.css(formFieldRequiredMarkerSelector))).toBeFalsy();

hostComponent.required = true;
hostFixture.detectChanges();

expect(hostFixture.debugElement.query(By.css(formFieldLabelSelector))).toBeTruthy();
expect(hostFixture.debugElement.query(By.css(formFieldRequiredMarkerSelector))).toBeTruthy();
});
});

describe("using formControl", () => {
let hostComponent: TestHostFormControlComponent;
let hostFixture: ComponentFixture<TestHostFormControlComponent>;
Expand All @@ -122,7 +217,6 @@ describe("DatePickerComponent", () => {
it("should set internal component properties", () => {
expect(hostFixture).toBeDefined();
expect(component).toBeDefined();

expect(component.logger).not.toBeNull();
expect(component.logger).toBeDefined();
});
Expand All @@ -131,7 +225,7 @@ describe("DatePickerComponent", () => {
expect(component.value).toBeNull();
expect(component.dateFilter).toBeUndefined();
expect(component.disabled).toBe(false);
expect(component.required).toBeUndefined();
expect(component.required).toBe(false);
expect(component.max).toBeUndefined();
expect(component.min).toBeUndefined();
expect(component.pickerId).toBeDefined();
Expand All @@ -144,59 +238,46 @@ describe("DatePickerComponent", () => {
});
});

describe("mat-datepicker properties binding", () => {
it("the id of the MatDatepicker should be pickerId", () => {
describe("mat-datepicker properties", () => {
it("should be set correctly according to the given inputs", () => {
component.pickerId = "test-id";
hostFixture.detectChanges();
const input: HTMLElement = hostFixture.nativeElement.querySelector("#test-id");
expect(input).not.toBeNull();
});

it("the id of the MatDatepickerInput should be pickerId + '-input'", () => {
component.pickerId = "test-id";
hostFixture.detectChanges();
const input: HTMLElement = hostFixture.nativeElement.querySelector("#test-id-input");
expect(input).not.toBeNull();
});

it("the name of the MatDatepickerInput should be pickerName", () => {
component.pickerName = "test-name";
hostFixture.detectChanges();
const input: HTMLElement = hostFixture.nativeElement.querySelector('[name="test-name"]');
expect(input).not.toBeNull();
});

it("the MatDatepickerInput should be disabled when isDisabled is true", () => {
hostComponent.formControl.disable();
hostFixture.detectChanges();
expect(component.pickerInput.disabled).toBe(true);
});

it("the MatDatepickerInput min date should be minDate", () => {
const minDate = new Date(2018, 6, 1);
component.min = minDate;
const maxDate = new Date(2018, 6, 2);
component.max = maxDate;
hostFixture.detectChanges();

expect(hostFixture.nativeElement.querySelector("mat-datepicker#test-id")).not.toBeNull();
expect(hostFixture.nativeElement.querySelector("input#test-id-input")).not.toBeNull(); // the "-input" suffix is appended to the pickerId
expect(hostFixture.nativeElement.querySelector("input[name='test-name']")).not.toBeNull();
expect(component.pickerInput.min).not.toBeNull();
expect((<moment.Moment>component.pickerInput.min).toDate()).toEqual(minDate);
expect(component.pickerInput.max).not.toBeNull();
expect((<moment.Moment>component.pickerInput.max).toDate()).toEqual(maxDate);
});

it("the MatDatepickerInput max date should be maxDate", () => {
const maxDate = new Date(2018, 6, 2);
component.max = maxDate;
it("the MatDatepickerInput should be disabled when the form control is disabled", () => {
hostComponent.formControl.disable();
hostFixture.detectChanges();
expect(component.pickerInput.max).not.toBeNull();
expect((<moment.Moment>component.pickerInput.max).toDate()).toEqual(maxDate);
expect(component.pickerInput.disabled).toBe(true);

hostComponent.formControl.enable();
hostFixture.detectChanges();
expect(component.pickerInput.disabled).toBe(false);
});

it("the MatDatepickerInput value should be date", () => {
it("the MatDatepickerInput value should be the same as the form control's value", () => {
const date = new Date(2018, 6, 3);
hostComponent.formControl.setValue(date);
hostFixture.detectChanges();
expect(component.pickerInput.value).not.toBeNull();
expect((<moment.Moment>component.pickerInput.value).toDate()).toEqual(date);
});
});

it("the MatDatepickerInput dateMaskConfig should be DEFAULT_DATE_MASK_CONFIG when dateMask is TRUE or empty string", () => {
describe("date mask", () => {
it("the dateMaskConfig should be DEFAULT_DATE_MASK_CONFIG when 'dateMask' is TRUE or empty string", () => {
hostComponent.dateMask = true;
hostFixture.detectChanges();
expect(component.dateMaskConfig).toBe(DEFAULT_DATE_MASK_CONFIG);
Expand All @@ -206,24 +287,22 @@ describe("DatePickerComponent", () => {
expect(component.dateMaskConfig).toBe(DEFAULT_DATE_MASK_CONFIG);
});

it("the MatDatepickerInput dateMaskConfig should be undefined when dateMask is FALSE", () => {
it("the dateMaskConfig should be undefined when 'dateMask' is FALSE", () => {
hostComponent.dateMask = false;
hostFixture.detectChanges();
expect(component.dateMaskConfig).toBeUndefined();
});

it("the MatDatepickerInput dateMaskConfig should be dateMaskConfig", () => {
const dateMaskConfig: StarkDatePickerMaskConfig = {
format: "DD-MM-YYYY"
};
it("the dateMaskConfig should be the same as 'dateMask'", () => {
const dateMaskConfig: StarkDatePickerMaskConfig = { format: "DD-MM-YYYY" };

hostComponent.dateMask = dateMaskConfig;
hostFixture.detectChanges();
expect(component.dateMaskConfig).toBe(dateMaskConfig);
});
});

describe("Dates filter", () => {
describe("Date filters", () => {
it("filterOnlyWeekdays() should filter week days", () => {
expect(component.filterOnlyWeekdays(new Date(2018, 6, 16))).toBe(true);
expect(component.filterOnlyWeekdays(new Date(2018, 6, 17))).toBe(true);
Expand All @@ -244,7 +323,7 @@ describe("DatePickerComponent", () => {
expect(component.filterOnlyWeekends(new Date(2018, 6, 22))).toBe(true);
});

it("dateFilter should be filterOnlyWeekdays() when dateFilter is OnlyWeekdays", () => {
it("dateFilter should be filterOnlyWeekdays() when dateFilter is 'OnlyWeekdays'", () => {
component.dateFilter = "OnlyWeekdays";
hostFixture.detectChanges();
expect(typeof component.dateFilter).toBe("function");
Expand All @@ -253,7 +332,7 @@ describe("DatePickerComponent", () => {
}
});

it("dateFilter should be filterOnlyWeekends() when dateFilter is OnlyWeekends", () => {
it("dateFilter should be filterOnlyWeekends() when dateFilter is 'OnlyWeekends'", () => {
component.dateFilter = "OnlyWeekends";
expect(typeof component.dateFilter).toBe("function");
if (typeof component.dateFilter === "function") {
Expand Down Expand Up @@ -298,7 +377,7 @@ describe("DatePickerComponent", () => {
expect(component.value).toBeUndefined();
expect(component.dateFilter).toBeUndefined();
expect(component.disabled).toBeUndefined();
expect(component.required).toBeUndefined();
expect(component.required).toBe(false);
expect(component.max).toBeUndefined();
expect(component.min).toBeUndefined();
expect(component.pickerId).toBeDefined();
Expand All @@ -311,51 +390,36 @@ describe("DatePickerComponent", () => {
});
});

describe("mat-datepicker properties binding", () => {
it("the id of the MatDatepicker should be pickerId", () => {
component.pickerId = "test-id";
hostFixture.detectChanges();
const input: HTMLElement = hostFixture.nativeElement.querySelector("#test-id");
expect(input).not.toBeNull();
});

it("the id of the MatDatepickerInput should be pickerId + '-input'", () => {
describe("mat-datepicker properties", () => {
it("should be set correctly according to the given inputs", () => {
component.pickerId = "test-id";
hostFixture.detectChanges();
const input: HTMLElement = hostFixture.nativeElement.querySelector("#test-id-input");
expect(input).not.toBeNull();
});

it("the name of the MatDatepickerInput should be pickerName", () => {
component.pickerName = "test-name";
hostFixture.detectChanges();
const input: HTMLElement = hostFixture.nativeElement.querySelector('[name="test-name"]');
expect(input).not.toBeNull();
});

it("the MatDatepickerInput should be disabled when isDisabled is true", () => {
hostComponent.isDisabled = true;
hostFixture.detectChanges();
expect(component.pickerInput.disabled).toBe(true);
});

it("the MatDatepickerInput min date should be minDate", () => {
const minDate = new Date(2018, 6, 1);
component.min = minDate;
const maxDate = new Date(2018, 6, 2);
component.max = maxDate;
hostFixture.detectChanges();

expect(hostFixture.nativeElement.querySelector("mat-datepicker#test-id")).not.toBeNull();
expect(hostFixture.nativeElement.querySelector("input#test-id-input")).not.toBeNull(); // the "-input" suffix is appended to the pickerId
expect(hostFixture.nativeElement.querySelector("input[name='test-name']")).not.toBeNull();
expect(component.pickerInput.min).not.toBeNull();
expect((<moment.Moment>component.pickerInput.min).toDate()).toEqual(minDate);
expect(component.pickerInput.max).not.toBeNull();
expect((<moment.Moment>component.pickerInput.max).toDate()).toEqual(maxDate);
});

it("the MatDatepickerInput max date should be maxDate", () => {
const maxDate = new Date(2018, 6, 2);
component.max = maxDate;
it("the MatDatepickerInput should be disabled when 'disabled' is true", () => {
hostComponent.isDisabled = true;
hostFixture.detectChanges();
expect(component.pickerInput.max).not.toBeNull();
expect((<moment.Moment>component.pickerInput.max).toDate()).toEqual(maxDate);
expect(component.pickerInput.disabled).toBe(true);

hostComponent.isDisabled = false;
hostFixture.detectChanges();
expect(component.pickerInput.disabled).toBe(false);
});

it("the MatDatepickerInput value should be date", () => {
it("the MatDatepickerInput value should be the same as 'value'", () => {
const date = new Date(2018, 6, 3);
hostComponent.value = date;
hostFixture.detectChanges();
Expand Down
Loading

0 comments on commit 686c0f7

Please sign in to comment.