11import { Component , ViewChild } from '@angular/core' ;
22import { fakeAsync , TestBed , tick , waitForAsync } from '@angular/core/testing' ;
3- import { UntypedFormBuilder , FormsModule , ReactiveFormsModule } from '@angular/forms' ;
3+ import { UntypedFormBuilder , FormsModule , ReactiveFormsModule , Validators , NgForm } from '@angular/forms' ;
44import { By } from '@angular/platform-browser' ;
55import { IgxRippleModule } from '../directives/ripple/ripple.directive' ;
66import { IgxCheckboxComponent } from './checkbox.component' ;
@@ -21,6 +21,7 @@ describe('IgxCheckbox', () => {
2121 CheckboxExternalLabelComponent ,
2222 CheckboxInvisibleLabelComponent ,
2323 CheckboxDisabledTransitionsComponent ,
24+ CheckboxFormComponent ,
2425 CheckboxFormGroupComponent ,
2526 IgxCheckboxComponent
2627 ] ,
@@ -275,6 +276,7 @@ describe('IgxCheckbox', () => {
275276 expect ( nativeCheckbox . required ) . toBeTruthy ( ) ;
276277
277278 checkboxInstance . required = false ;
279+ nativeCheckbox . required = false ;
278280 fixture . detectChanges ( ) ;
279281
280282 expect ( checkboxInstance . required ) . toBe ( false ) ;
@@ -316,6 +318,79 @@ describe('IgxCheckbox', () => {
316318 expect ( testInstance . clickCounter ) . toEqual ( 2 ) ;
317319 } ) ;
318320
321+ it ( 'Should update style when required checkbox\'s value is set.' , ( ) => {
322+ const fixture = TestBed . createComponent ( CheckboxRequiredComponent ) ;
323+ fixture . detectChanges ( ) ;
324+
325+ const checkboxInstance = fixture . componentInstance . cb ;
326+ const domCheckbox = fixture . debugElement . query ( By . css ( 'igx-checkbox' ) ) . nativeElement ;
327+
328+ expect ( domCheckbox . classList . contains ( 'igx-checkbox--invalid' ) ) . toBe ( false ) ;
329+ expect ( checkboxInstance . invalid ) . toBe ( false ) ;
330+ expect ( checkboxInstance . checked ) . toBe ( false ) ;
331+ expect ( checkboxInstance . required ) . toBe ( true ) ;
332+
333+ dispatchCbEvent ( 'keyup' , domCheckbox , fixture ) ;
334+ expect ( domCheckbox . classList . contains ( 'igx-checkbox--focused' ) ) . toBe ( true ) ;
335+ dispatchCbEvent ( 'blur' , domCheckbox , fixture ) ;
336+
337+ expect ( checkboxInstance . invalid ) . toBe ( true ) ;
338+ expect ( domCheckbox . classList . contains ( 'igx-checkbox--invalid' ) ) . toBe ( true ) ;
339+
340+ dispatchCbEvent ( 'keyup' , domCheckbox , fixture ) ;
341+ expect ( domCheckbox . classList . contains ( 'igx-checkbox--focused' ) ) . toBe ( true ) ;
342+ dispatchCbEvent ( 'click' , domCheckbox , fixture ) ;
343+
344+ expect ( domCheckbox . classList . contains ( 'igx-checkbox--checked' ) ) . toBe ( true ) ;
345+ expect ( checkboxInstance . checked ) . toBe ( true ) ;
346+ expect ( checkboxInstance . invalid ) . toBe ( false ) ;
347+ expect ( domCheckbox . classList . contains ( 'igx-checkbox--invalid' ) ) . toBe ( false ) ;
348+
349+ dispatchCbEvent ( 'click' , domCheckbox , fixture ) ;
350+ dispatchCbEvent ( 'keyup' , domCheckbox , fixture ) ;
351+ expect ( domCheckbox . classList . contains ( 'igx-checkbox--focused' ) ) . toBe ( true ) ;
352+ dispatchCbEvent ( 'blur' , domCheckbox , fixture ) ;
353+
354+ expect ( checkboxInstance . checked ) . toBe ( false ) ;
355+ expect ( checkboxInstance . invalid ) . toBe ( true ) ;
356+ expect ( domCheckbox . classList . contains ( 'igx-checkbox--invalid' ) ) . toBe ( true ) ;
357+ } ) ;
358+
359+ it ( 'Should work properly with ngModel' , fakeAsync ( ( ) => {
360+ const fixture = TestBed . createComponent ( CheckboxFormComponent ) ;
361+ fixture . detectChanges ( ) ;
362+ tick ( ) ;
363+
364+ const checkbox = fixture . componentInstance . checkbox ;
365+ expect ( checkbox . invalid ) . toEqual ( false ) ;
366+
367+ checkbox . onBlur ( ) ;
368+ expect ( checkbox . invalid ) . toEqual ( true ) ;
369+
370+ fixture . componentInstance . ngForm . resetForm ( ) ;
371+ tick ( ) ;
372+ expect ( checkbox . invalid ) . toEqual ( false ) ;
373+ } ) ) ;
374+
375+ it ( 'Should work properly with reactive forms validation.' , ( ) => {
376+ const fixture = TestBed . createComponent ( CheckboxFormGroupComponent ) ;
377+ fixture . detectChanges ( ) ;
378+
379+ const checkbox = fixture . componentInstance . cb ;
380+ checkbox . checked = false ;
381+ expect ( checkbox . required ) . toBe ( true ) ;
382+ expect ( checkbox . nativeElement . getAttribute ( 'aria-required' ) ) . toEqual ( 'true' ) ;
383+ expect ( checkbox . nativeElement . getAttribute ( 'aria-invalid' ) ) . toEqual ( 'false' ) ;
384+
385+ fixture . debugElement . componentInstance . markAsTouched ( ) ;
386+ fixture . detectChanges ( ) ;
387+
388+ const invalidCheckbox = fixture . debugElement . nativeElement . querySelectorAll ( `.igx-checkbox--invalid` ) ;
389+ expect ( invalidCheckbox . length ) . toBe ( 1 ) ;
390+ expect ( checkbox . invalid ) . toBe ( true ) ;
391+ expect ( checkbox . nativeElement . getAttribute ( 'aria-invalid' ) ) . toEqual ( 'true' ) ;
392+ } ) ;
393+
319394 describe ( 'EditorProvider' , ( ) => {
320395 it ( 'Should return correct edit element' , ( ) => {
321396 const fixture = TestBed . createComponent ( CheckboxSimpleComponent ) ;
@@ -410,7 +485,37 @@ class CheckboxDisabledTransitionsComponent {
410485class CheckboxFormGroupComponent {
411486 @ViewChild ( 'cb' , { static : true } ) public cb : IgxCheckboxComponent ;
412487
413- public myForm = this . fb . group ( { checkbox : [ null ] } ) ;
488+ public myForm = this . fb . group ( { checkbox : [ '' , Validators . required ] } ) ;
414489
415490 constructor ( private fb : UntypedFormBuilder ) { }
491+
492+ public markAsTouched ( ) {
493+ if ( ! this . myForm . valid ) {
494+ for ( const key in this . myForm . controls ) {
495+ if ( this . myForm . controls [ key ] ) {
496+ this . myForm . controls [ key ] . markAsTouched ( ) ;
497+ this . myForm . controls [ key ] . updateValueAndValidity ( ) ;
498+ }
499+ }
500+ }
501+ }
416502}
503+ @Component ( {
504+ template : `
505+ <form #form="ngForm">
506+ <igx-checkbox #checkbox [(ngModel)]="subscribed" name="checkbox" required>Checkbox</igx-checkbox>
507+ </form>
508+ `
509+ } )
510+ class CheckboxFormComponent {
511+ @ViewChild ( 'checkbox' , { read : IgxCheckboxComponent , static : true } )
512+ public checkbox : IgxCheckboxComponent ;
513+ @ViewChild ( NgForm , { static : true } )
514+ public ngForm : NgForm ;
515+ public subscribed : string ;
516+ }
517+
518+ const dispatchCbEvent = ( eventName , cbNativeElement , fixture ) => {
519+ cbNativeElement . dispatchEvent ( new Event ( eventName ) ) ;
520+ fixture . detectChanges ( ) ;
521+ } ;
0 commit comments