|
1 |
| -import { Component, ViewChild, ElementRef } from '@angular/core'; |
| 1 | +import { Component, ViewChild, ElementRef, EventEmitter } from '@angular/core'; |
2 | 2 | import { async, fakeAsync, TestBed, tick, flush, ComponentFixture } from '@angular/core/testing';
|
3 |
| -import { FormsModule, FormGroup, FormBuilder, FormControl, ReactiveFormsModule} from '@angular/forms'; |
| 3 | +import { FormsModule, FormGroup, FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms'; |
4 | 4 | import { By } from '@angular/platform-browser';
|
5 | 5 | import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
6 | 6 | import { IgxDatePickerComponent, IgxDatePickerModule } from './date-picker.component';
|
7 | 7 | import { IgxLabelDirective } from '../directives/label/label.directive';
|
8 |
| -import { IgxInputDirective } from '../directives/input/input.directive'; |
| 8 | +import { IgxInputDirective, IgxInputState } from '../directives/input/input.directive'; |
9 | 9 | import { UIInteractions, wait } from '../test-utils/ui-interactions.spec';
|
10 |
| -import { IgxInputGroupModule } from '../input-group'; |
| 10 | +import { IgxInputGroupModule, IgxInputGroupComponent } from '../input-group'; |
11 | 11 | import { IgxTextSelectionModule } from '../directives/text-selection/text-selection.directive';
|
12 | 12 | import { configureTestSuite } from '../test-utils/configure-suite';
|
13 |
| -import { DateRangeType } from 'igniteui-angular'; |
14 | 13 | import { IgxButtonModule } from '../directives/button/button.directive';
|
15 | 14 | import { IgxCalendarModule } from '../calendar';
|
16 | 15 | import { InteractionMode } from '../core/enums';
|
| 16 | +import { DateRangeType } from '../core/dates/dateRange'; |
| 17 | +import { OverlayCancelableEventArgs, OverlayEventArgs, OverlayClosingEventArgs, HorizontalAlignment, VerticalAlignment } from '../services'; |
17 | 18 |
|
18 | 19 | describe('IgxDatePicker', () => {
|
19 | 20 | configureTestSuite();
|
@@ -1262,38 +1263,133 @@ describe('IgxDatePicker', () => {
|
1262 | 1263 |
|
1263 | 1264 | describe('Reactive form', () => {
|
1264 | 1265 | let fixture: ComponentFixture<IgxDatePickerReactiveFormComponent>;
|
1265 |
| - let datePicker: IgxDatePickerComponent; |
| 1266 | + let datePickerOnChangeComponent: IgxDatePickerComponent; |
| 1267 | + let datePickerOnBlurComponent: IgxDatePickerComponent; |
1266 | 1268 |
|
1267 | 1269 | beforeEach(() => {
|
1268 | 1270 | fixture = TestBed.createComponent(IgxDatePickerReactiveFormComponent);
|
1269 |
| - datePicker = fixture.componentInstance.datePicker; |
| 1271 | + datePickerOnChangeComponent = fixture.componentInstance.datePickerOnChangeComponent; |
| 1272 | + datePickerOnBlurComponent = fixture.componentInstance.datePickerOnBlurComponent; |
1270 | 1273 | fixture.detectChanges();
|
1271 | 1274 | });
|
1272 | 1275 |
|
1273 |
| - // Bug #6025 Date picker does not disable in reactive form |
1274 |
| - it('Should disable when form is disabled', fakeAsync(() => { |
| 1276 | + it('Should set date picker status to invalid when it is required and has no value', fakeAsync(() => { |
| 1277 | + const inputGroupsElements = fixture.debugElement.queryAll(By.directive(IgxInputDirective)); |
| 1278 | + const inputGroupElement = inputGroupsElements.find(d => d.componentInstance === datePickerOnChangeComponent); |
| 1279 | + const inputDirective = inputGroupElement.injector.get(IgxInputDirective) as IgxInputDirective; |
| 1280 | + |
| 1281 | + expect(inputDirective.valid).toEqual(IgxInputState.INITIAL); |
| 1282 | + |
| 1283 | + datePickerOnChangeComponent.value = null; |
1275 | 1284 | fixture.detectChanges();
|
1276 |
| - const formGroup: FormGroup = fixture.componentInstance.reactiveForm; |
1277 |
| - const inputGroup = fixture.debugElement.query(By.css('.igx-input-group')); |
1278 | 1285 |
|
1279 |
| - inputGroup.nativeElement.click(); |
1280 |
| - tick(); |
| 1286 | + expect(inputDirective.valid).toEqual(IgxInputState.INVALID); |
| 1287 | + })); |
| 1288 | + |
| 1289 | + it('Should set date picker status to invalid when it is required and has no value onBlur', fakeAsync(() => { |
| 1290 | + datePickerOnBlurComponent.mode = InteractionMode.DropDown; |
| 1291 | + datePickerOnBlurComponent.mask = 'dd/mm/yyyy'; |
| 1292 | + datePickerOnBlurComponent.inputMask = 'dd/mm/yyyy'; |
1281 | 1293 | fixture.detectChanges();
|
1282 |
| - expect(datePicker.collapsed).toBeFalsy(); |
1283 | 1294 |
|
1284 |
| - datePicker.closeCalendar(); |
| 1295 | + const inputDirectiveElements = fixture.debugElement.queryAll(By.directive(IgxInputDirective)); |
| 1296 | + const inputDirectiveElement = inputDirectiveElements.find(d => d.componentInstance === datePickerOnBlurComponent); |
| 1297 | + const inputDirective = inputDirectiveElement.injector.get(IgxInputDirective) as IgxInputDirective; |
| 1298 | + |
| 1299 | + expect(inputDirective.valid).toEqual(IgxInputState.INITIAL); |
| 1300 | + |
| 1301 | + inputDirectiveElement.triggerEventHandler('focus', {}); |
1285 | 1302 | fixture.detectChanges();
|
1286 | 1303 |
|
1287 |
| - formGroup.disable(); |
1288 |
| - tick(); |
| 1304 | + expect(inputDirective.valid).toEqual(IgxInputState.INITIAL); |
| 1305 | + |
| 1306 | + datePickerOnBlurComponent.value = null; |
1289 | 1307 | fixture.detectChanges();
|
| 1308 | + expect(inputDirective.valid).toEqual(IgxInputState.INITIAL); |
1290 | 1309 |
|
1291 |
| - inputGroup.nativeElement.click(); |
1292 |
| - tick(); |
| 1310 | + inputDirectiveElement.triggerEventHandler('blur', { target: { value: ''}}); |
1293 | 1311 | fixture.detectChanges();
|
1294 |
| - const dateDropDown = document.getElementsByClassName('igx-date-picker--dropdown'); |
1295 |
| - expect(dateDropDown.length).toEqual(0); |
| 1312 | + |
| 1313 | + expect(inputDirective.valid).toEqual(IgxInputState.INVALID); |
1296 | 1314 | }));
|
| 1315 | + |
| 1316 | + // Bug #6025 Date picker does not disable in reactive form |
| 1317 | + it('Should disable when form is disabled', () => { |
| 1318 | + const formGroup: FormGroup = fixture.componentInstance.reactiveForm; |
| 1319 | + const inputGroupsElements = fixture.debugElement.queryAll(By.directive(IgxInputDirective)); |
| 1320 | + const inputGroupElement = inputGroupsElements.find(d => d.componentInstance === datePickerOnBlurComponent); |
| 1321 | + const inputDirective = inputGroupElement.injector.get(IgxInputDirective) as IgxInputDirective; |
| 1322 | + expect(inputDirective.disabled).toBeFalsy(); |
| 1323 | + |
| 1324 | + formGroup.disable(); |
| 1325 | + fixture.detectChanges(); |
| 1326 | + expect(inputDirective.disabled).toBeTruthy(); |
| 1327 | + }); |
| 1328 | + }); |
| 1329 | + |
| 1330 | + describe('Control value accessor unit tests', () => { |
| 1331 | + let ngModel; |
| 1332 | + let overlay; |
| 1333 | + let element; |
| 1334 | + let cdr; |
| 1335 | + let moduleRef; |
| 1336 | + let injector; |
| 1337 | + let inputGroup: IgxInputGroupComponent; |
| 1338 | + |
| 1339 | + beforeEach(() => { |
| 1340 | + ngModel = { |
| 1341 | + control: { touched: false, dirty: false, validator: null }, |
| 1342 | + valid: false, |
| 1343 | + statusChanges: new EventEmitter(), |
| 1344 | + }; |
| 1345 | + overlay = { |
| 1346 | + onOpening: new EventEmitter<OverlayCancelableEventArgs>(), |
| 1347 | + onOpened: new EventEmitter<OverlayEventArgs>(), |
| 1348 | + onClosed: new EventEmitter<OverlayEventArgs>(), |
| 1349 | + onClosing: new EventEmitter<OverlayClosingEventArgs>() |
| 1350 | + }; |
| 1351 | + element = {}; |
| 1352 | + cdr = { |
| 1353 | + markForCheck: () => {}, |
| 1354 | + detectChanges: () => {}, |
| 1355 | + detach: () => {}, |
| 1356 | + reattach: () => {} |
| 1357 | + }; |
| 1358 | + moduleRef = {}; |
| 1359 | + injector = { get: () => ngModel }; |
| 1360 | + inputGroup = new IgxInputGroupComponent(null, null); |
| 1361 | + }); |
| 1362 | + |
| 1363 | + it('should initialize date picker with required correctly', () => { |
| 1364 | + const datePicker = new IgxDatePickerComponent(overlay, element, cdr, moduleRef, injector); |
| 1365 | + datePicker['inputGroup'] = inputGroup; |
| 1366 | + ngModel.control.validator = () => ({ required: true}); |
| 1367 | + datePicker.ngOnInit(); |
| 1368 | + datePicker.ngAfterViewInit(); |
| 1369 | + datePicker.ngAfterViewChecked(); |
| 1370 | + |
| 1371 | + expect(datePicker).toBeDefined(); |
| 1372 | + expect(inputGroup.isRequired).toBeTruthy(); |
| 1373 | + }); |
| 1374 | + |
| 1375 | + it('should update inputGroup isRequired correctly', () => { |
| 1376 | + const datePicker = new IgxDatePickerComponent(overlay, element, cdr, moduleRef, injector); |
| 1377 | + datePicker['inputGroup'] = inputGroup; |
| 1378 | + datePicker.ngOnInit(); |
| 1379 | + datePicker.ngAfterViewInit(); |
| 1380 | + datePicker.ngAfterViewChecked(); |
| 1381 | + |
| 1382 | + expect(datePicker).toBeDefined(); |
| 1383 | + expect(inputGroup.isRequired).toBeFalsy(); |
| 1384 | + |
| 1385 | + ngModel.control.validator = () => ({ required: true}); |
| 1386 | + ngModel.statusChanges.emit(); |
| 1387 | + expect(inputGroup.isRequired).toBeTruthy(); |
| 1388 | + |
| 1389 | + ngModel.control.validator = () => ({ required: false}); |
| 1390 | + ngModel.statusChanges.emit(); |
| 1391 | + expect(inputGroup.isRequired).toBeFalsy(); |
| 1392 | + }); |
1297 | 1393 | });
|
1298 | 1394 | });
|
1299 | 1395 |
|
@@ -1444,23 +1540,27 @@ export class IgxDatePickerOpeningComponent {
|
1444 | 1540 | @Component({
|
1445 | 1541 | template: `
|
1446 | 1542 | <form [formGroup]="reactiveForm">
|
1447 |
| - <p> |
1448 |
| - <igx-date-picker formControlName="datePickerReactive" #datePickerReactive></igx-date-picker> |
1449 |
| - </p> |
1450 |
| -</form> |
| 1543 | + <igx-date-picker formControlName="datePickerOnChange" #datePickerOnChangeComponent></igx-date-picker> |
| 1544 | + <igx-date-picker formControlName="datePickerOnBlur" #datePickerOnBlurComponent></igx-date-picker> |
| 1545 | + </form> |
1451 | 1546 | `
|
1452 | 1547 | })
|
1453 | 1548 | class IgxDatePickerReactiveFormComponent {
|
1454 |
| - @ViewChild('datePickerReactive', { read: IgxDatePickerComponent, static: true }) |
1455 |
| - public datePicker: IgxDatePickerComponent; |
| 1549 | + @ViewChild('datePickerOnChangeComponent', { read: IgxDatePickerComponent, static: true }) |
| 1550 | + public datePickerOnChangeComponent: IgxDatePickerComponent; |
| 1551 | + |
| 1552 | + @ViewChild('datePickerOnBlurComponent', { read: IgxDatePickerComponent, static: true }) |
| 1553 | + public datePickerOnBlurComponent: IgxDatePickerComponent; |
| 1554 | + |
1456 | 1555 | reactiveForm: FormGroup;
|
1457 | 1556 |
|
1458 | 1557 | constructor(fb: FormBuilder) {
|
| 1558 | + const date = new Date(2000, 10, 15); |
1459 | 1559 | this.reactiveForm = fb.group({
|
1460 |
| - datePickerReactive: new FormControl(''), |
| 1560 | + datePickerOnChange: [date, Validators.required], |
| 1561 | + datePickerOnBlur: [date, { updateOn: 'blur', validators: Validators.required}] |
1461 | 1562 | });
|
1462 | 1563 | }
|
1463 |
| - onSubmitReactive() { } |
1464 | 1564 | }
|
1465 | 1565 |
|
1466 | 1566 | @Component({
|
|
0 commit comments