|
1 | 1 | import {async, TestBed, inject, ComponentFixture} from '@angular/core/testing'; |
2 | 2 | import {Component, ViewChild} from '@angular/core'; |
3 | | -import {FormsModule, ReactiveFormsModule, FormControl, NgForm, Validators} from '@angular/forms'; |
| 3 | +import { |
| 4 | + FormsModule, |
| 5 | + ReactiveFormsModule, |
| 6 | + FormControl, |
| 7 | + NgForm, |
| 8 | + Validators, |
| 9 | + FormGroupDirective, |
| 10 | + FormGroup, |
| 11 | +} from '@angular/forms'; |
4 | 12 | import {By} from '@angular/platform-browser'; |
5 | 13 | import {NoopAnimationsModule} from '@angular/platform-browser/animations'; |
6 | 14 | import {MdInputModule} from './index'; |
@@ -54,7 +62,8 @@ describe('MdInputContainer', function () { |
54 | 62 | MdInputContainerMultipleHintTestController, |
55 | 63 | MdInputContainerMultipleHintMixedTestController, |
56 | 64 | MdInputContainerWithDynamicPlaceholder, |
57 | | - MdInputContainerWithErrorMessages |
| 65 | + MdInputContainerWithFormErrorMessages, |
| 66 | + MdInputContainerWithFormGroupErrorMessages |
58 | 67 | ], |
59 | 68 | }); |
60 | 69 |
|
@@ -556,19 +565,19 @@ describe('MdInputContainer', function () { |
556 | 565 | }); |
557 | 566 |
|
558 | 567 | describe('error messages', () => { |
559 | | - let fixture: ComponentFixture<MdInputContainerWithErrorMessages>; |
560 | | - let testComponent: MdInputContainerWithErrorMessages; |
| 568 | + let fixture: ComponentFixture<MdInputContainerWithFormErrorMessages>; |
| 569 | + let testComponent: MdInputContainerWithFormErrorMessages; |
561 | 570 | let containerEl: HTMLElement; |
562 | 571 |
|
563 | 572 | beforeEach(() => { |
564 | | - fixture = TestBed.createComponent(MdInputContainerWithErrorMessages); |
| 573 | + fixture = TestBed.createComponent(MdInputContainerWithFormErrorMessages); |
565 | 574 | fixture.detectChanges(); |
566 | 575 | testComponent = fixture.componentInstance; |
567 | 576 | containerEl = fixture.debugElement.query(By.css('md-input-container')).nativeElement; |
568 | 577 | }); |
569 | 578 |
|
570 | 579 | it('should not show any errors if the user has not interacted', () => { |
571 | | - expect(testComponent.formControl.pristine).toBe(true, 'Expected untouched form control'); |
| 580 | + expect(testComponent.formControl.untouched).toBe(true, 'Expected untouched form control'); |
572 | 581 | expect(containerEl.querySelectorAll('md-error').length).toBe(0, 'Expected no error messages'); |
573 | 582 | }); |
574 | 583 |
|
@@ -604,6 +613,34 @@ describe('MdInputContainer', function () { |
604 | 613 | }); |
605 | 614 | })); |
606 | 615 |
|
| 616 | + it('should display an error message when the parent form group is submitted', async(() => { |
| 617 | + fixture.destroy(); |
| 618 | + |
| 619 | + let groupFixture = TestBed.createComponent(MdInputContainerWithFormGroupErrorMessages); |
| 620 | + let component: MdInputContainerWithFormGroupErrorMessages; |
| 621 | + |
| 622 | + groupFixture.detectChanges(); |
| 623 | + component = groupFixture.componentInstance; |
| 624 | + containerEl = groupFixture.debugElement.query(By.css('md-input-container')).nativeElement; |
| 625 | + |
| 626 | + expect(component.formControl.invalid).toBe(true, 'Expected form control to be invalid'); |
| 627 | + expect(containerEl.querySelectorAll('md-error').length).toBe(0, 'Expected no error messages'); |
| 628 | + expect(component.formGroupDirective.submitted) |
| 629 | + .toBe(false, 'Expected form not to have been submitted'); |
| 630 | + |
| 631 | + dispatchFakeEvent(groupFixture.debugElement.query(By.css('form')).nativeElement, 'submit'); |
| 632 | + groupFixture.detectChanges(); |
| 633 | + |
| 634 | + groupFixture.whenStable().then(() => { |
| 635 | + expect(component.formGroupDirective.submitted) |
| 636 | + .toBe(true, 'Expected form to have been submitted'); |
| 637 | + expect(containerEl.classList) |
| 638 | + .toContain('mat-input-invalid', 'Expected container to have the invalid CSS class.'); |
| 639 | + expect(containerEl.querySelectorAll('md-error').length) |
| 640 | + .toBe(1, 'Expected one error message to have been rendered.'); |
| 641 | + }); |
| 642 | + })); |
| 643 | + |
607 | 644 | it('should hide the error messages once the input becomes valid', async(() => { |
608 | 645 | testComponent.formControl.markAsTouched(); |
609 | 646 | fixture.detectChanges(); |
@@ -909,8 +946,27 @@ class MdInputContainerMissingMdInputTestController {} |
909 | 946 | </form> |
910 | 947 | ` |
911 | 948 | }) |
912 | | -class MdInputContainerWithErrorMessages { |
| 949 | +class MdInputContainerWithFormErrorMessages { |
913 | 950 | @ViewChild('form') form: NgForm; |
914 | 951 | formControl = new FormControl('', Validators.required); |
915 | 952 | renderError = true; |
916 | 953 | } |
| 954 | + |
| 955 | + |
| 956 | +@Component({ |
| 957 | + template: ` |
| 958 | + <form [formGroup]="formGroup" (ngSubmit)="onSubmit()" novalidate> |
| 959 | + <md-input-container> |
| 960 | + <input mdInput [formControl]="formControl"> |
| 961 | + <md-hint>Please type something</md-hint> |
| 962 | + <md-error>This field is required</md-error> |
| 963 | + </md-input-container> |
| 964 | + </form> |
| 965 | + ` |
| 966 | +}) |
| 967 | +class MdInputContainerWithFormGroupErrorMessages { |
| 968 | + @ViewChild(FormGroupDirective) formGroupDirective: FormGroupDirective; |
| 969 | + onSubmit() { } |
| 970 | + formControl = new FormControl('', Validators.required); |
| 971 | + formGroup = new FormGroup({ name: this.formControl }); |
| 972 | +} |
0 commit comments