license import { ifEnvSupports , ifEnvSupportsWithDone , isFirefox , isSafari } from '../test-util' ; declare const global ; describe ( 'fetch' , ifEnvSupports ( 'fetch' , function ( ) { let testZone ; beforeEach ( ( ) => { testZone = Zone . current . fork ( { name : 'TestZone' } ) ; } ) ; it ( 'should work for text response' , function ( done ) { testZone . run ( function ( ) { global [ 'fetch' ] ( '/base/test/assets/sample.json' ) . then ( function ( response ) { const fetchZone = Zone . current ; expect ( fetchZone . name ) . toBe ( testZone . name ) ; response . text ( ) . then ( function ( text ) { expect ( Zone . current . name ) . toBe ( fetchZone . name ) ; expect ( text . trim ( ) ) . toEqual ( '{"hello": "world"}' ) ; done ( ) ; } ) ; } ) ; } ) ; } ) ; it ( 'should work for json response' , function ( done ) { testZone . run ( function ( ) { global [ 'fetch' ] ( '/base/test/assets/sample.json' ) . then ( function ( response ) { const fetchZone = Zone . current ; expect ( fetchZone . name ) . toBe ( testZone . name ) ; response . json ( ) . then ( function ( obj ) { expect ( Zone . current . name ) . toBe ( fetchZone . name ) ; expect ( obj . hello ) . toEqual ( 'world' ) ; done ( ) ; } ) ; } ) ; } ) ; } ) ; it ( 'should work for blob response' , function ( done ) { testZone . run ( function ( ) { global [ 'fetch' ] ( '/base/test/assets/sample.json' ) . then ( function ( response ) { const fetchZone = Zone . current ; expect ( fetchZone . name ) . toBe ( testZone . name ) ; if ( response . blob ) { response . blob ( ) . then ( function ( blob ) { expect ( Zone . current . name ) . toBe ( fetchZone . name ) ; expect ( blob instanceof Blob ) . toEqual ( true ) ; done ( ) ; } ) ; } else { done ( ) ; } } ) ; } ) ; } ) ; it ( 'should work for arrayBuffer response' , function ( done ) { testZone . run ( function ( ) { global [ 'fetch' ] ( '/base/test/assets/sample.json' ) . then ( function ( response ) { const fetchZone = Zone . current ; expect ( fetchZone . name ) . toBe ( testZone . name ) ; if ( response . arrayBuffer ) { response . arrayBuffer ( ) . then ( function ( blob ) { expect ( Zone . current ) . toBe ( fetchZone ) ; expect ( blob instanceof ArrayBuffer ) . toEqual ( true ) ; done ( ) ; } ) ; } else { done ( ) ; } } ) ; } ) ; } ) ; it ( 'should throw error when send crendential' , ifEnvSupportsWithDone ( isFirefox , function ( done ) { testZone . run ( function ( ) { global [ 'fetch' ] ( 'http://user:password@example.com' ) . then ( function ( response ) { fail ( 'should not success' ) ; } , ( error ) => { expect ( Zone . current . name ) . toEqual ( testZone . name ) ; expect ( error . constructor . name ) . toEqual ( 'TypeError' ) ; done ( ) ; } ) ; } ) ; } ) ) ; describe ( 'macroTask' , ( ) => { const logs = [ ] ; let fetchZone ; let fetchTask = null ; beforeEach ( ( ) => { logs . splice ( 0 ) ; fetchZone = Zone . current . fork ( { name : 'fetch' , onScheduleTask : ( delegate , curr , target , task ) => { if ( task . type !== 'eventTask' ) { logs . push ( `scheduleTask:${ task . source }:${ task . type }` ) ; } if ( task . source === 'fetch' ) { fetchTask = task ; } return delegate . scheduleTask ( target , task ) ; } , onInvokeTask : ( delegate , curr , target , task , applyThis , applyArgs ) => { if ( task . type !== 'eventTask' ) { logs . push ( `invokeTask:${ task . source }:${ task . type }` ) ; } return delegate . invokeTask ( target , task , applyThis , applyArgs ) ; } , onCancelTask : ( delegate , curr , target , task ) => { if ( task . type !== 'eventTask' ) { logs . push ( `cancelTask:${ task . source }:${ task . type }` ) ; } return delegate . cancelTask ( target , task ) ; } } ) ; } ) ; it ( 'fetch should be considered as macroTask' , ( done ) => { fetchZone . run ( ( ) => { global [ 'fetch' ] ( '/base/test/assets/sample.json' ) . then ( function ( response ) { expect ( Zone . current . name ) . toBe ( fetchZone . name ) ; expect ( logs ) . toEqual ( [ 'scheduleTask:fetch:macroTask' , 'scheduleTask:Promise.then:microTask' , 'invokeTask:Promise.then:microTask' , 'invokeTask:fetch:macroTask' , 'scheduleTask:Promise.then:microTask' , 'invokeTask:Promise.then:microTask' ] ) ; done ( ) ; } ) ; } ) ; } ) ; it ( 'cancel fetch should invoke onCancelTask' , ifEnvSupportsWithDone ( 'AbortController' , ( done ) => { if ( isSafari ) { done ( ) ; return ; } fetchZone . run ( ( ) => { const AbortController = global [ 'AbortController' ] ; const abort = new AbortController ( ) ; const signal = abort . signal ; global [ 'fetch' ] ( '/base/test/assets/sample.json' , { signal } ) . then ( function ( response ) { fail ( 'should not get response' ) ; } ) . catch ( function ( error ) { expect ( error . name ) . toEqual ( 'AbortError' ) ; expect ( logs ) . toEqual ( [ 'scheduleTask:fetch:macroTask' , 'cancelTask:fetch:macroTask' , 'scheduleTask:Promise.then:microTask' , 'invokeTask:Promise.then:microTask' , 'scheduleTask:Promise.then:microTask' , 'invokeTask:Promise.then:microTask' , 'scheduleTask:Promise.then:microTask' , 'invokeTask:Promise.then:microTask' ] ) ; done ( ) ; } ) ; abort . abort ( ) ; } ) ; } ) ) ; it ( 'cancel fetchTask should trigger abort' , ifEnvSupportsWithDone ( 'AbortController' , ( done ) => { if ( isSafari ) { done ( ) ; return ; } fetchZone . run ( ( ) => { const AbortController = global [ 'AbortController' ] ; const abort = new AbortController ( ) ; const signal = abort . signal ; global [ 'fetch' ] ( '/base/test/assets/sample.json' , { signal } ) . then ( function ( response ) { fail ( 'should not get response' ) ; } ) . catch ( function ( error ) { expect ( error . name ) . toEqual ( 'AbortError' ) ; expect ( logs ) . toEqual ( [ 'scheduleTask:fetch:macroTask' , 'cancelTask:fetch:macroTask' , 'scheduleTask:Promise.then:microTask' , 'invokeTask:Promise.then:microTask' , 'scheduleTask:Promise.then:microTask' , 'invokeTask:Promise.then:microTask' , 'scheduleTask:Promise.then:microTask' , 'invokeTask:Promise.then:microTask' ] ) ; done ( ) ; } ) ; fetchTask . zone . cancelTask ( fetchTask ) ; } ) ; } ) ) ; } ) ; } ) ) ;