import { TestBed , ComponentFixture , async } from '@angular/core/testing' ; import { Component } from '@angular/core' ; import { FormsModule , ReactiveFormsModule } from '@angular/forms' ; import { createGenericTestComponent , selectElements , dispatchEvent } from '../../../test/util' ; import { NglColorpickerModule } from './module' ; import { getRgbFromHex } from './util' ; import { getPopoverElement } from '../popovers/popover.spec' ; import { NGL_COLORPICKER_CONFIG , NglColorpickerConfig } from './config' ; const createTestComponent = ( html ? , detectChanges ? ) => createGenericTestComponent ( TestComponent , html , detectChanges ) as ComponentFixture < TestComponent > ; function getSummaryInput ( element ) { return element . querySelector ( '.slds-color-picker__summary-input input' ) ; } function getSummaryButton ( element ) { return element . querySelector ( '.slds-color-picker__summary-button' ) ; } function getSummaryButtonColor ( element ) { return getSwatch ( getSummaryButton ( element ) ) . style . background ; } function getSwatch ( element ) { return element . querySelector ( '.slds-swatch' ) ; } function getSwatches ( element ) { return selectElements ( element , '.slds-color-picker__swatch > a' ) ; } function getTabs ( element ) { return selectElements ( element , '.slds-tabs_default__link' ) ; } function getRGBStyle ( hex ) { const { red , green , blue } = getRgbFromHex ( hex ) ; return `rgb(${ red }, ${ green }, ${ blue })` ; } function openPopover ( fixture ) { return fixture . whenStable ( ) . then ( ( ) => { const button = getSummaryButton ( fixture . nativeElement ) ; button . click ( ) ; fixture . detectChanges ( ) ; return getPopoverElement ( ) ; } ) ; } describe ( '`NglColorpicker`' , ( ) => { beforeEach ( ( ) => TestBed . configureTestingModule ( { declarations : [ TestComponent ] , imports : [ NglColorpickerModule , FormsModule , ReactiveFormsModule ] } ) ) ; it ( 'should render correctly' , async ( ( ) => { const fixture = createTestComponent ( ) ; const { nativeElement } = fixture ; expect ( nativeElement . firstElementChild ) . toHaveCssClass ( 'slds-color-picker' ) ; fixture . whenStable ( ) . then ( ( ) => { expect ( getSummaryInput ( nativeElement ) . value ) . toBe ( '#ffddee' ) ; expect ( getSummaryButtonColor ( nativeElement ) ) . toContain ( getRGBStyle ( '#ffddee' ) ) ; } ) ; } ) ) ; it ( 'should support placeholder' , async ( ( ) => { const fixture = createTestComponent ( `<ngl-colorpicker [ngModel]="color" [placeholder]="placeholder"></ngl-colorpicker>` ) ; const { nativeElement , componentInstance } = fixture ; const input = getSummaryInput ( nativeElement ) ; expect ( input . placeholder ) . toEqual ( '' ) ; componentInstance . placeholder = 'my placeholder' ; fixture . detectChanges ( ) ; expect ( input . placeholder ) . toEqual ( 'my placeholder' ) ; componentInstance . placeholder = null ; fixture . detectChanges ( ) ; expect ( input . placeholder ) . toEqual ( '' ) ; } ) ) ; it ( 'should update based on model changes' , async ( ( ) => { const fixture = createTestComponent ( ) ; const { componentInstance , nativeElement } = fixture ; fixture . whenStable ( ) . then ( ( ) => { componentInstance . color = '#111222' ; fixture . detectChanges ( ) ; fixture . whenStable ( ) . then ( ( ) => { expect ( getSummaryInput ( nativeElement ) . value ) . toBe ( '#111222' ) ; expect ( getSummaryButtonColor ( nativeElement ) ) . toContain ( getRGBStyle ( '#111222' ) ) ; } ) ; } ) ; } ) ) ; it ( 'should update appropriately if model is empty' , async ( ( ) => { const fixture = createTestComponent ( null , false ) ; const { componentInstance , nativeElement } = fixture ; componentInstance . color = undefined ; fixture . detectChanges ( ) ; fixture . whenStable ( ) . then ( ( ) => { expect ( getSummaryInput ( nativeElement ) . value ) . toBe ( '' ) ; expect ( getSummaryButtonColor ( nativeElement ) ) . toEqual ( '' ) ; componentInstance . color = null ; fixture . detectChanges ( ) ; fixture . whenStable ( ) . then ( ( ) => { expect ( getSummaryInput ( nativeElement ) . value ) . toBe ( '' ) ; expect ( getSummaryButtonColor ( nativeElement ) ) . toEqual ( '' ) ; } ) ; } ) ; } ) ) ; it ( 'should send updates based on input box value' , async ( ( ) => { const fixture = createTestComponent ( ) ; const { componentInstance , nativeElement } = fixture ; fixture . whenStable ( ) . then ( ( ) => { const inputEl = getSummaryInput ( nativeElement ) ; inputEl . value = '#111222' ; dispatchEvent ( inputEl , 'input' ) ; fixture . detectChanges ( ) ; fixture . whenStable ( ) . then ( ( ) => { expect ( getSummaryButtonColor ( nativeElement ) ) . toContain ( getRGBStyle ( '#111222' ) ) ; expect ( componentInstance . onChange ) . toHaveBeenCalledWith ( '#111222' ) ; } ) ; } ) ; } ) ) ; it ( 'should handle invalid updates of input box value' , async ( ( ) => { const fixture = createTestComponent ( ) ; const { componentInstance , nativeElement } = fixture ; fixture . whenStable ( ) . then ( ( ) => { const inputEl = getSummaryInput ( nativeElement ) ; inputEl . value = 'invalid' ; dispatchEvent ( inputEl , 'input' ) ; fixture . detectChanges ( ) ; fixture . whenStable ( ) . then ( ( ) => { expect ( getSummaryButtonColor ( nativeElement ) ) . toContain ( getRGBStyle ( '#ffddee' ) ) ; expect ( componentInstance . onChange ) . toHaveBeenCalledWith ( null ) ; expect ( nativeElement . querySelector ( '.slds-color-picker__summary' ) ) . toHaveCssClass ( 'slds-has-error' ) ; expect ( nativeElement . querySelector ( '.slds-form-error' ) ) . toHaveText ( 'Please ensure value is correct' ) ; } ) ; } ) ; } ) ) ; it ( 'should handle appropriately disable state' , async ( ( ) => { const fixture = createTestComponent ( `<ngl-colorpicker [ngModel]="color" disabled></ngl-colorpicker>` ) ; const { nativeElement } = fixture ; fixture . whenStable ( ) . then ( ( ) => { expect ( getSummaryInput ( nativeElement ) . disabled ) . toBe ( true ) ; expect ( getSummaryButton ( nativeElement ) . disabled ) . toBe ( true ) ; } ) ; } ) ) ; it ( 'should handle appropriately disable state' , async ( ( ) => { const fixture = createTestComponent ( `<ngl-colorpicker [ngModel]="color" readonlyInput="true"></ngl-colorpicker>` ) ; const { nativeElement } = fixture ; fixture . whenStable ( ) . then ( ( ) => { expect ( getSummaryInput ( nativeElement ) . readOnly ) . toBe ( true ) ; expect ( getSummaryInput ( nativeElement ) . disabled ) . toBe ( false ) ; expect ( getSummaryButton ( nativeElement ) . disabled ) . toBe ( false ) ; } ) ; } ) ) ; describe ( 'popover' , ( ) => { function pressDone ( popover ) { const button = popover . querySelector ( '.slds-color-picker__selector-footer > button.slds-button_brand' ) as HTMLButtonElement ; button . click ( ) ; } function pressCancel ( popover ) { const button = popover . querySelector ( '.slds-color-picker__selector-footer > button.slds-button_neutral' ) as HTMLButtonElement ; button . click ( ) ; } it ( 'should render correctly' , ( ) => { const fixture = createTestComponent ( ) ; openPopover ( fixture ) . then ( ( popover ) => { expect ( popover ) . toHaveCssClass ( 'slds-popover' ) ; expect ( popover ) . toHaveCssClass ( 'slds-color-picker__selector' ) ; } ) ; } ) ; it ( 'should send pressed color from swatches on done' , async ( ( ) => { const fixture = createTestComponent ( ) ; openPopover ( fixture ) . then ( ( popover ) => { const swatches = getSwatches ( popover ) ; expect ( swatches . length ) . toBe ( 28 ) ; swatches [ 0 ] . click ( ) ; swatches [ 1 ] . click ( ) ; pressDone ( popover ) ; expect ( fixture . componentInstance . onChange ) . not . toHaveBeenCalledWith ( '#e3abec' ) ; expect ( fixture . componentInstance . onChange ) . toHaveBeenCalledWith ( '#c2dbf7' ) ; } ) ; } ) ) ; it ( 'should not send pressed color from swatches on cancel' , async ( ( ) => { const fixture = createTestComponent ( ) ; openPopover ( fixture ) . then ( ( popover ) => { const swatches = getSwatches ( popover ) ; swatches [ 0 ] . click ( ) ; swatches [ 1 ] . click ( ) ; pressCancel ( popover ) ; expect ( fixture . componentInstance . onChange ) . not . toHaveBeenCalled ( ) ; } ) ; } ) ) ; it ( 'should send custom color based on hex input' , async ( ( ) => { const fixture = createTestComponent ( ) ; openPopover ( fixture ) . then ( ( popover ) => { const tabs = getTabs ( popover ) ; tabs [ 1 ] . click ( ) ; fixture . detectChanges ( ) ; const hexInput = popover . querySelector ( '.slds-color-picker__input-custom-hex input' ) ; expect ( hexInput . value ) . toEqual ( '#ffddee' ) ; hexInput . value = '#0000ff' ; dispatchEvent ( hexInput , 'input' ) ; fixture . detectChanges ( ) ; fixture . whenStable ( ) . then ( ( ) => { pressDone ( popover ) ; fixture . detectChanges ( ) ; expect ( getSummaryButtonColor ( fixture . nativeElement ) ) . toContain ( getRGBStyle ( '#0000ff' ) ) ; expect ( fixture . componentInstance . onChange ) . toHaveBeenCalledWith ( '#0000ff' ) ; } ) ; } ) ; } ) ) ; it ( 'should send custom color based on RGB inputs' , async ( ( ) => { const fixture = createTestComponent ( ) ; openPopover ( fixture ) . then ( ( popover ) => { const tabs = getTabs ( popover ) ; tabs [ 1 ] . click ( ) ; fixture . detectChanges ( ) ; const rgbInputs = selectElements ( popover , '.slds-input[maxlength="3"]' ) as HTMLInputElement [ ] ; expect ( rgbInputs . length ) . toBe ( 3 ) ; expect ( rgbInputs . map ( e => e . value ) ) . toEqual ( [ '255' , '221' , '238' ] ) ; rgbInputs . forEach ( ( e , index ) => { e . value = `${ index }` ; dispatchEvent ( e , 'input' ) ; } ) ; fixture . detectChanges ( ) ; fixture . whenStable ( ) . then ( ( ) => { pressDone ( popover ) ; fixture . detectChanges ( ) ; expect ( getSummaryButtonColor ( fixture . nativeElement ) ) . toContain ( getRGBStyle ( '#000102' ) ) ; expect ( fixture . componentInstance . onChange ) . toHaveBeenCalledWith ( '#000102' ) ; } ) ; } ) ; } ) ) ; } ) ; describe ( 'custom configuration' , ( ) => { const swatchColors = [ '#000' , '#FF0' , '#FFF' ] ; const variant = 'swatches' ; beforeEach ( ( ) => TestBed . configureTestingModule ( { providers : [ { provide : NGL_COLORPICKER_CONFIG , useValue : < NglColorpickerConfig > { swatchColors , variant } } , ] , } ) ) ; it ( 'should have configurable swatch colors' , async ( ( ) => { const fixture = createTestComponent ( ) ; openPopover ( fixture ) . then ( ( popover ) => { const swatches = getSwatches ( popover ) ; expect ( swatches . map ( s => s . querySelector ( '.slds-assistive-text' ) . textContent ) ) . toEqual ( swatchColors ) ; } ) ; } ) ) ; it ( 'should have configurable variant' , async ( ( ) => { const fixture = createTestComponent ( ) ; openPopover ( fixture ) . then ( ( popover ) => { const tabs = getTabs ( popover ) ; expect ( tabs . length ) . toBe ( 0 ) ; } ) ; } ) ) ; } ) ; } ) ; @ Component ( { template : `
    <ngl-colorpicker [ngModel]="color" (ngModelChange)="onChange($event)"></ngl-colorpicker>
  ` , } ) export class TestComponent { color = '#ffddee' ; placeholder : string ; onChange : jasmine . Spy = jasmine . createSpy ( ) ; }