import { StageComponent , ComponentTester } from 'aurelia-testing' ; import { bootstrap } from 'aurelia-bootstrapper' ; import { RegistrationForm } from './resources/registration-form' ; import { validateTrigger , ValidateEvent } from '../src/aurelia-validation' ; import { configure , blur , change , focusout } from './shared' ; describe ( 'end to end' , ( ) => { it ( 'basic scenarios' , ( done ) => { const component = StageComponent . withResources ( ) . inView ( '<registration-form></registration-form>' ) . boundTo ( { } ) ; component . bootstrap ( configure ) ; let firstName ; let lastName ; let number1 ; let number2 ; let confirmPassword ; let ceInput ; let viewModel ; const renderer = { render : jasmine . createSpy ( ) } ; component . create ( bootstrap as any ) . then ( ( ) => { viewModel = component . viewModel ; viewModel . controller . addRenderer ( renderer ) ; firstName = component . element . querySelector ( '#firstName' ) as HTMLInputElement ; lastName = component . element . querySelector ( '#lastName' ) as HTMLInputElement ; number1 = component . element . querySelector ( '#number1' ) as HTMLInputElement ; number2 = component . element . querySelector ( '#number2' ) as HTMLInputElement ; confirmPassword = component . element . querySelector ( '#confirmPassword' ) as HTMLInputElement ; ceInput = component . element . querySelector ( 'custom-input#ce input' ) as HTMLInputElement ; } ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 0 , 'error1' ) ) . then ( ( ) => blur ( ceInput ) ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 0 , 'error1.1' ) ) . then ( ( ) => focusout ( ceInput ) ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 0 , 'error1.2' ) ) . then ( ( ) => blur ( firstName ) ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 1 , 'error2' ) ) . then ( ( ) => viewModel . firstName = 'test' ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 0 , 'error3' ) ) . then ( ( ) => blur ( firstName ) ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 1 , 'error2.1' ) ) . then ( ( ) => viewModel . firstName = 'foo' ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 0 , 'error3.1' ) ) . then ( ( ) => blur ( lastName ) ) . then ( ( ) => { expect ( viewModel . controller . errors . length ) . toBe ( 1 , 'error4' ) ; const calls = renderer . render . calls ; const renderInstruction = calls . argsFor ( calls . count ( ) - 1 ) [ 0 ] ; expect ( renderInstruction . render [ 0 ] . elements [ 0 ] ) . toBe ( lastName , 'error5' ) ; } ) . then ( ( ) => blur ( number1 ) ) . then ( ( ) => { expect ( viewModel . controller . errors . length ) . toBe ( 2 , 'error6' ) ; const calls = renderer . render . calls ; const renderInstruction = calls . argsFor ( calls . count ( ) - 1 ) [ 0 ] ; expect ( renderInstruction . render [ 0 ] . elements [ 0 ] ) . toBe ( number1 , 'error7' ) ; } ) . then ( ( ) => blur ( number2 ) ) . then ( ( ) => { expect ( viewModel . controller . errors . length ) . toBe ( 3 , 'error8' ) ; const calls = renderer . render . calls ; const renderInstruction = calls . argsFor ( calls . count ( ) - 1 ) [ 0 ] ; expect ( renderInstruction . render [ 0 ] . elements [ 0 ] ) . toBe ( number2 , 'error9' ) ; } ) . then ( ( ) => viewModel . number1 = 1 ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 2 , 'error10' ) ) . then ( ( ) => viewModel . number2 = 2 ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 1 , 'error11' ) ) . then ( ( ) => { viewModel . number1 = 0 ; viewModel . number2 = 0 ; viewModel . firstName = '' ; } ) . then ( ( ) => { viewModel . showForm = false ; viewModel . controller . validateTrigger = validateTrigger . focusout ; } ) . then ( ( ) => viewModel . showForm = true ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 0 , 'error100.1' ) ) . then ( ( ) => focusout ( ceInput ) ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 1 , 'error100.2' ) ) . then ( ( ) => viewModel . ceValue = 'test' ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 0 , 'error100.2.1' ) ) . then ( ( ) => focusout ( firstName ) ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 1 , 'error100.3' ) ) . then ( ( ) => viewModel . firstName = 'test' ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 0 , 'error100.4' ) ) . then ( ( ) => focusout ( firstName ) ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 1 , 'error100.3.1' ) ) . then ( ( ) => viewModel . firstName = 'foo' ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 0 , 'error100.4.1' ) ) . then ( ( ) => focusout ( lastName ) ) . then ( ( ) => { expect ( viewModel . controller . errors . length ) . toBe ( 1 , 'error100.5' ) ; const calls = renderer . render . calls ; const renderInstruction = calls . argsFor ( calls . count ( ) - 1 ) [ 0 ] ; expect ( renderInstruction . render [ 0 ] . elements [ 0 ] ) . toBe ( lastName , 'error100.6' ) ; } ) . then ( ( ) => focusout ( number1 ) ) . then ( ( ) => { expect ( viewModel . controller . errors . length ) . toBe ( 2 , 'error100.7' ) ; const calls = renderer . render . calls ; const renderInstruction = calls . argsFor ( calls . count ( ) - 1 ) [ 0 ] ; expect ( renderInstruction . render [ 0 ] . elements [ 0 ] ) . toBe ( number1 , 'error100.8' ) ; } ) . then ( ( ) => focusout ( number2 ) ) . then ( ( ) => { expect ( viewModel . controller . errors . length ) . toBe ( 3 , 'error100.9' ) ; const calls = renderer . render . calls ; const renderInstruction = calls . argsFor ( calls . count ( ) - 1 ) [ 0 ] ; expect ( renderInstruction . render [ 0 ] . elements [ 0 ] ) . toBe ( number2 , 'error100.10' ) ; } ) . then ( ( ) => viewModel . number1 = 1 ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 2 , 'error100.11' ) ) . then ( ( ) => viewModel . number2 = 2 ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 1 , 'error100.12' ) ) . then ( ( ) => { viewModel . number1 = 0 ; viewModel . number2 = 0 ; viewModel . firstName = '' ; } ) . then ( ( ) => { viewModel . showForm = false ; viewModel . controller . validateTrigger = validateTrigger . change ; } ) . then ( ( ) => viewModel . showForm = true ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 0 , 'error12' ) ) . then ( ( ) => change ( ceInput , 'test' ) ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 0 , 'error13' ) ) . then ( ( ) => change ( ceInput , '' ) ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 1 , 'error14' ) ) . then ( ( ) => change ( firstName , 'foo' ) ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 1 , 'error13' ) ) . then ( ( ) => change ( firstName , '' ) ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 2 , 'error14' ) ) . then ( ( ) => change ( number1 , '-1' ) ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 3 , 'error15' ) ) . then ( ( ) => change ( number2 . firstElementChild as HTMLInputElement , '-1' ) ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 4 , 'error16' ) ) . then ( ( ) => change ( number1 , '32' ) ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 3 , 'error17' ) ) . then ( ( ) => change ( number2 . firstElementChild as HTMLInputElement , '23' ) ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 2 , 'error18' ) ) . then ( ( ) => { viewModel . number1 = 0 ; viewModel . number2 = 0 ; viewModel . password = 'a' ; viewModel . confirmPassword = 'a' ; viewModel . controller . reset ( ) ; } ) . then ( ( ) => change ( confirmPassword , 'b' ) ) . then ( ( ) => expect ( viewModel . controller . errors [ 0 ] . message ) . toBe ( 'Confirm Password must match Password' , 'error19' ) ) . then ( ( ) => { viewModel . showForm = false ; viewModel . controller . validateTrigger = validateTrigger . manual ; } ) . then ( ( ) => viewModel . showForm = true ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 0 , 'error20' ) ) . then ( ( ) => viewModel . controller . validate ( ) ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 7 , 'error21' ) ) . then ( ( ) => viewModel . controller . reset ( ) ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 0 , 'error22' ) ) . then ( ( ) => { viewModel . showForm = false ; viewModel . controller . validateTrigger = validateTrigger . changeOrBlur ; } ) . then ( ( ) => viewModel . showForm = true ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 0 , 'error23' ) ) . then ( ( ) => blur ( ceInput ) ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 0 , 'error24' ) ) . then ( ( ) => change ( ceInput , 'test' ) ) . then ( ( ) => blur ( ceInput ) ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 0 , 'error25' ) ) . then ( ( ) => focusout ( ceInput ) ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 0 , 'error25' ) ) . then ( ( ) => blur ( firstName ) ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 0 , 'error24' ) ) . then ( ( ) => change ( firstName , 'test' ) ) . then ( ( ) => blur ( firstName ) ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 1 , 'error25' ) ) . then ( ( ) => change ( firstName , 'foo' ) ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 0 , 'error25.1' ) ) . then ( ( ) => change ( lastName , 'abcdef' ) ) . then ( ( ) => change ( lastName , '' ) ) . then ( ( ) => blur ( lastName ) ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 1 , 'error26' ) ) . then ( ( ) => change ( lastName , 'ghi' ) ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 0 , 'error27' ) ) . then ( ( ) => { viewModel . number1 = 0 ; viewModel . number2 = 0 ; viewModel . ceValue = '' ; viewModel . firstName = '' ; viewModel . lastName = '' ; viewModel . password = 'a' ; viewModel . controller . reset ( ) ; } ) . then ( ( ) => viewModel . controller . validate ( ) ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 7 , 'error27.1' ) ) . then ( ( ) => change ( ceInput , 'foo' ) ) . then ( ( ) => change ( firstName , 'foo' ) ) . then ( ( ) => change ( lastName , 'test' ) ) . then ( ( ) => { viewModel . number1 = 42 ; viewModel . number2 = 42 ; viewModel . email = 'a@b.com' ; viewModel . password = 'a' ; return change ( confirmPassword , 'a' ) ; } ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 0 , 'error27.2' ) ) . then ( ( ) => { viewModel . number1 = 0 ; viewModel . number2 = 0 ; viewModel . ceValue = '' ; viewModel . firstName = '' ; viewModel . lastName = '' ; } ) . then ( ( ) => { viewModel . showForm = false ; viewModel . controller . validateTrigger = validateTrigger . changeOrFocusout ; } ) . then ( ( ) => viewModel . showForm = true ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 0 , 'error200.1' ) ) . then ( ( ) => focusout ( ceInput ) ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 0 , 'error200.2' ) ) . then ( ( ) => change ( ceInput , 'test' ) ) . then ( ( ) => focusout ( ceInput ) ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 1 , 'error200.3' ) ) . then ( ( ) => change ( ceInput , 'foo' ) ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 0 , 'error200.3.1' ) ) . then ( ( ) => focusout ( firstName ) ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 0 , 'error200.5' ) ) . then ( ( ) => change ( firstName , 'test' ) ) . then ( ( ) => focusout ( firstName ) ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 1 , 'error200.6' ) ) . then ( ( ) => change ( firstName , 'foo' ) ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 0 , 'error200.7' ) ) . then ( ( ) => change ( lastName , 'abcdef' ) ) . then ( ( ) => change ( lastName , '' ) ) . then ( ( ) => focusout ( lastName ) ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 1 , 'error200.8' ) ) . then ( ( ) => change ( lastName , 'ghi' ) ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 0 , 'error200.9' ) ) . then ( ( ) => { viewModel . number1 = 0 ; viewModel . number2 = 0 ; viewModel . ceValue = '' ; viewModel . firstName = '' ; viewModel . lastName = '' ; viewModel . email = '' ; viewModel . password = '' ; viewModel . controller . reset ( ) ; } ) . then ( ( ) => viewModel . controller . validate ( ) ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 7 , 'error200.10' ) ) . then ( ( ) => change ( ceInput , 'foo' ) ) . then ( ( ) => change ( firstName , 'foo' ) ) . then ( ( ) => change ( lastName , 'test' ) ) . then ( ( ) => { viewModel . number1 = 42 ; viewModel . number2 = 42 ; viewModel . email = 'a@b.com' ; viewModel . password = 'a' ; return change ( confirmPassword , 'a' ) ; } ) . then ( ( ) => expect ( viewModel . controller . errors . length ) . toBe ( 0 , 'error200.11' ) ) . then ( ( ) => { const error1 = viewModel . controller . addError ( 'object error' , viewModel ) ; expect ( error1 . message ) . toBe ( 'object error' , 'error28' ) ; expect ( error1 . object ) . toBe ( viewModel , 'error29' ) ; expect ( error1 . propertyName ) . toBe ( null , 'error30' ) ; const error2 = viewModel . controller . addError ( 'string property error' , viewModel , 'lastName' ) ; expect ( error2 . message ) . toBe ( 'string property error' , 'error31' ) ; expect ( error2 . object ) . toBe ( viewModel , 'error32' ) ; expect ( error2 . propertyName ) . toBe ( 'lastName' , 'error33' ) ; const error3 = viewModel . controller . addError ( 'expression property error' , viewModel , vm => vm . firstName ) ; expect ( error3 . message ) . toBe ( 'expression property error' , 'error34' ) ; expect ( error3 . object ) . toBe ( viewModel , 'error35' ) ; expect ( error3 . propertyName ) . toBe ( 'firstName' , 'error36' ) ; expect ( viewModel . controller . errors . length ) . toBe ( 3 , 'error37' ) ; viewModel . controller . removeError ( error1 ) ; expect ( viewModel . controller . errors . length ) . toBe ( 2 , 'error38' ) ; viewModel . controller . removeError ( error2 ) ; expect ( viewModel . controller . errors . length ) . toBe ( 1 , 'error39' ) ; viewModel . controller . removeError ( error3 ) ; expect ( viewModel . controller . errors . length ) . toBe ( 0 , 'error40' ) ; } ) . then ( ( ) => { let event1 ; let event2 ; const spy1 = jasmine . createSpy ( ) . and . callFake ( ( event ) => event1 = event ) ; const spy2 = jasmine . createSpy ( ) . and . callFake ( ( event ) => event2 = event ) ; viewModel . controller . subscribe ( spy1 ) ; viewModel . controller . subscribe ( spy2 ) ; return Promise . resolve ( ) . then ( ( ) => change ( lastName , '' ) ) . then ( ( ) => { expect ( spy1 ) . toHaveBeenCalled ( ) ; expect ( spy2 ) . toHaveBeenCalled ( ) ; expect ( event1 ) . toBeDefined ( ) ; expect ( event2 ) . toBeDefined ( ) ; expect ( event1 ) . toBe ( event2 , 'error43' ) ; expect ( event1 . errors . length ) . toBe ( 1 , 'error44' ) ; spy1 . calls . reset ( ) ; spy2 . calls . reset ( ) ; event1 = null as any ; event2 = null as any ; } ) . then ( ( ) => change ( firstName , '' ) ) . then ( ( ) => { expect ( spy1 ) . toHaveBeenCalled ( ) ; expect ( spy2 ) . toHaveBeenCalled ( ) ; expect ( event1 ) . toBeDefined ( ) ; expect ( event2 ) . toBeDefined ( ) ; expect ( event1 ) . toBe ( event2 , 'error47' ) ; expect ( event1 . errors . length ) . toBe ( 2 , 'error48' ) ; } ) ; } ) . then ( ( ) => component . dispose ( ) ) . then ( done ) ; } ) ; } ) ;