1
1
import { h , Fragment , render , hydrate , options } from 'preact' ;
2
- import { useState } from 'preact/hooks' ;
2
+ import { useEffect , useState } from 'preact/hooks' ;
3
3
import * as chai from 'chai' ;
4
4
import * as sinon from 'sinon' ;
5
5
import sinonChai from 'sinon-chai' ;
@@ -510,14 +510,13 @@ describe('Router', () => {
510
510
expect ( loadEnd ) . not . to . have . been . called ;
511
511
} ) ;
512
512
513
- describe . only ( 'intercepted VS external links' , ( ) => {
513
+ // TODO: Relies on upcoming property being added to navigation events
514
+ describe . skip ( 'intercepted VS external links' , ( ) => {
514
515
const shouldIntercept = [ null , '' , '_self' , 'self' , '_SELF' ] ;
515
516
const shouldNavigate = [ '_top' , '_parent' , '_blank' , 'custom' , '_BLANK' ] ;
516
517
517
- const clickHandler = sinon . fake ( e => e . preventDefault ( ) ) ;
518
-
519
- const Route = sinon . fake (
520
- ( ) => < div >
518
+ const Route = ( ) => (
519
+ < div >
521
520
{ [ ...shouldIntercept , ...shouldNavigate ] . map ( ( target , i ) => {
522
521
const url = '/' + i + '/' + target ;
523
522
if ( target === null ) return < a href = { url } > target = { target + '' } </ a > ;
@@ -526,31 +525,32 @@ describe('Router', () => {
526
525
</ div >
527
526
) ;
528
527
529
- let pushState ;
530
-
531
- before ( ( ) => {
532
- pushState = sinon . spy ( history , 'pushState' ) ;
533
- addEventListener ( 'click' , clickHandler ) ;
534
- } ) ;
535
-
536
- after ( ( ) => {
537
- pushState . restore ( ) ;
538
- removeEventListener ( 'click' , clickHandler ) ;
539
- } ) ;
528
+ let triedToNavigate = false ;
529
+ const handler = ( e ) => {
530
+ e . intercept ( ) ;
531
+ if ( e [ 'preact-iso-ignored' ] ) {
532
+ triedToNavigate = true ;
533
+ }
534
+ }
540
535
541
536
beforeEach ( async ( ) => {
542
- render (
543
- < LocationProvider >
544
- < Router >
545
- < Route default />
546
- </ Router >
547
- < ShallowLocation />
548
- </ LocationProvider > ,
549
- scratch
550
- ) ;
551
- Route . resetHistory ( ) ;
552
- clickHandler . resetHistory ( ) ;
553
- pushState . resetHistory ( ) ;
537
+ const App = ( ) => {
538
+ useEffect ( ( ) => {
539
+ navigation . addEventListener ( 'navigate' , handler ) ;
540
+ return ( ) => navigation . removeEventListener ( 'navigate' , handler ) ;
541
+ } , [ ] ) ;
542
+
543
+ return (
544
+ < LocationProvider >
545
+ < Router >
546
+ < Route default />
547
+ </ Router >
548
+ < ShallowLocation />
549
+ </ LocationProvider >
550
+ ) ;
551
+ }
552
+ render ( < App /> , scratch ) ;
553
+ await sleep ( 10 ) ;
554
554
} ) ;
555
555
556
556
const getName = target => ( target == null ? 'no target attribute' : `target="${ target } "` ) ;
@@ -565,9 +565,9 @@ describe('Router', () => {
565
565
el . click ( ) ;
566
566
await sleep ( 1 ) ;
567
567
expect ( loc ) . to . deep . include ( { url } ) ;
568
- expect ( Route ) . to . have . been . calledOnce ;
569
- expect ( pushState ) . to . have . been . calledWith ( null , '' , url ) ;
570
- expect ( clickHandler ) . to . have . been . called ;
568
+ expect ( triedToNavigate ) . to . be . false ;
569
+
570
+ triedToNavigate = false ;
571
571
} ) ;
572
572
}
573
573
@@ -579,9 +579,9 @@ describe('Router', () => {
579
579
if ( ! el ) throw Error ( `Unable to find link: ${ sel } ` ) ;
580
580
el . click ( ) ;
581
581
await sleep ( 1 ) ;
582
- expect ( Route ) . not . to . have . been . called ;
583
- expect ( pushState ) . not . to . have . been . called ;
584
- expect ( clickHandler ) . to . have . been . called ;
582
+ expect ( triedToNavigate ) . to . be . true ;
583
+
584
+ triedToNavigate = false ;
585
585
} ) ;
586
586
}
587
587
} ) ;
@@ -599,69 +599,81 @@ describe('Router', () => {
599
599
</ >
600
600
) ;
601
601
602
- it ( 'should intercept clicks on links matching the `scope` props (string)' , async ( ) => {
603
- render (
604
- < LocationProvider scope = "/app" >
605
- < Links />
606
- < ShallowLocation />
607
- </ LocationProvider > ,
608
- scratch
609
- ) ;
602
+ let triedToNavigate = false ;
603
+ const handler = ( e ) => {
604
+ e . intercept ( ) ;
605
+ if ( e [ 'preact-iso-ignored' ] ) {
606
+ triedToNavigate = true ;
607
+ }
608
+ }
609
+
610
+ it ( 'should support the `scope` prop (string)' , async ( ) => {
611
+ const App = ( ) => {
612
+ useEffect ( ( ) => {
613
+ navigation . addEventListener ( 'navigate' , handler ) ;
614
+ return ( ) => navigation . removeEventListener ( 'navigate' , handler ) ;
615
+ } , [ ] ) ;
616
+
617
+ return (
618
+ < LocationProvider scope = "/app" >
619
+ < Links />
620
+ < ShallowLocation />
621
+ </ LocationProvider >
622
+ ) ;
623
+ }
624
+ render ( < App /> , scratch ) ;
625
+ await sleep ( 10 ) ;
610
626
611
627
for ( const url of shouldIntercept ) {
612
628
scratch . querySelector ( `a[href="${ url } "]` ) . click ( ) ;
613
629
await sleep ( 1 ) ;
614
630
expect ( loc ) . to . deep . include ( { url } ) ;
615
- }
616
- } ) ;
631
+ expect ( triedToNavigate ) . to . be . false ;
617
632
618
- it . skip ( 'should allow default browser navigation for links not matching the `scope` props (string)' , async ( ) => {
619
- render (
620
- < LocationProvider scope = "app" >
621
- < Links />
622
- < ShallowLocation />
623
- </ LocationProvider > ,
624
- scratch
625
- ) ;
633
+ triedToNavigate = false ;
634
+ }
626
635
627
636
for ( const url of shouldNavigate ) {
628
637
scratch . querySelector ( `a[href="${ url } "]` ) . click ( ) ;
629
638
await sleep ( 1 ) ;
639
+ expect ( triedToNavigate ) . to . be . true ;
630
640
631
- // TODO: How to test this?
641
+ triedToNavigate = false ;
632
642
}
633
643
} ) ;
634
644
635
- it ( 'should intercept clicks on links matching the `scope` props (regex)' , async ( ) => {
636
- render (
637
- < LocationProvider scope = { / ^ \/ a p p / } >
638
- < Links />
639
- < ShallowLocation />
640
- </ LocationProvider > ,
641
- scratch
642
- ) ;
645
+ it ( 'should support the `scope` prop (regex)' , async ( ) => {
646
+ const App = ( ) => {
647
+ useEffect ( ( ) => {
648
+ navigation . addEventListener ( 'navigate' , handler ) ;
649
+ return ( ) => navigation . removeEventListener ( 'navigate' , handler ) ;
650
+ } , [ ] ) ;
651
+
652
+ return (
653
+ < LocationProvider scope = { / ^ \/ a p p / } >
654
+ < Links />
655
+ < ShallowLocation />
656
+ </ LocationProvider >
657
+ ) ;
658
+ }
659
+ render ( < App /> , scratch ) ;
660
+ await sleep ( 10 ) ;
643
661
644
662
for ( const url of shouldIntercept ) {
645
663
scratch . querySelector ( `a[href="${ url } "]` ) . click ( ) ;
646
664
await sleep ( 1 ) ;
647
665
expect ( loc ) . to . deep . include ( { url } ) ;
648
- }
649
- } ) ;
666
+ expect ( triedToNavigate ) . to . be . false ;
650
667
651
- it . skip ( 'should allow default browser navigation for links not matching the `scope` props (regex)' , async ( ) => {
652
- render (
653
- < LocationProvider scope = { / ^ \/ a p p / } >
654
- < Links />
655
- < ShallowLocation />
656
- </ LocationProvider > ,
657
- scratch
658
- ) ;
668
+ triedToNavigate = false ;
669
+ }
659
670
660
671
for ( const url of shouldNavigate ) {
661
672
scratch . querySelector ( `a[href="${ url } "]` ) . click ( ) ;
662
673
await sleep ( 1 ) ;
674
+ expect ( triedToNavigate ) . to . be . true ;
663
675
664
- // TODO: How to test this?
676
+ triedToNavigate = false ;
665
677
}
666
678
} ) ;
667
679
} ) ;
0 commit comments