1
1
import { h , Fragment , render , Component , 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' ;
@@ -549,14 +549,13 @@ describe('Router', () => {
549
549
expect ( loadEnd ) . not . to . have . been . called ;
550
550
} ) ;
551
551
552
- describe . only ( 'intercepted VS external links' , ( ) => {
552
+ // TODO: Relies on upcoming property being added to navigation events
553
+ describe . skip ( 'intercepted VS external links' , ( ) => {
553
554
const shouldIntercept = [ null , '' , '_self' , 'self' , '_SELF' ] ;
554
555
const shouldNavigate = [ '_top' , '_parent' , '_blank' , 'custom' , '_BLANK' ] ;
555
556
556
- const clickHandler = sinon . fake ( e => e . preventDefault ( ) ) ;
557
-
558
- const Route = sinon . fake (
559
- ( ) => < div >
557
+ const Route = ( ) => (
558
+ < div >
560
559
{ [ ...shouldIntercept , ...shouldNavigate ] . map ( ( target , i ) => {
561
560
const url = '/' + i + '/' + target ;
562
561
if ( target === null ) return < a href = { url } > target = { target + '' } </ a > ;
@@ -565,31 +564,32 @@ describe('Router', () => {
565
564
</ div >
566
565
) ;
567
566
568
- let pushState ;
569
-
570
- before ( ( ) => {
571
- pushState = sinon . spy ( history , 'pushState' ) ;
572
- addEventListener ( 'click' , clickHandler ) ;
573
- } ) ;
574
-
575
- after ( ( ) => {
576
- pushState . restore ( ) ;
577
- removeEventListener ( 'click' , clickHandler ) ;
578
- } ) ;
567
+ let triedToNavigate = false ;
568
+ const handler = ( e ) => {
569
+ e . intercept ( ) ;
570
+ if ( e [ 'preact-iso-ignored' ] ) {
571
+ triedToNavigate = true ;
572
+ }
573
+ }
579
574
580
575
beforeEach ( async ( ) => {
581
- render (
582
- < LocationProvider >
583
- < Router >
584
- < Route default />
585
- </ Router >
586
- < ShallowLocation />
587
- </ LocationProvider > ,
588
- scratch
589
- ) ;
590
- Route . resetHistory ( ) ;
591
- clickHandler . resetHistory ( ) ;
592
- pushState . resetHistory ( ) ;
576
+ const App = ( ) => {
577
+ useEffect ( ( ) => {
578
+ navigation . addEventListener ( 'navigate' , handler ) ;
579
+ return ( ) => navigation . removeEventListener ( 'navigate' , handler ) ;
580
+ } , [ ] ) ;
581
+
582
+ return (
583
+ < LocationProvider >
584
+ < Router >
585
+ < Route default />
586
+ </ Router >
587
+ < ShallowLocation />
588
+ </ LocationProvider >
589
+ ) ;
590
+ }
591
+ render ( < App /> , scratch ) ;
592
+ await sleep ( 10 ) ;
593
593
} ) ;
594
594
595
595
const getName = target => ( target == null ? 'no target attribute' : `target="${ target } "` ) ;
@@ -604,9 +604,9 @@ describe('Router', () => {
604
604
el . click ( ) ;
605
605
await sleep ( 1 ) ;
606
606
expect ( loc ) . to . deep . include ( { url } ) ;
607
- expect ( Route ) . to . have . been . calledOnce ;
608
- expect ( pushState ) . to . have . been . calledWith ( null , '' , url ) ;
609
- expect ( clickHandler ) . to . have . been . called ;
607
+ expect ( triedToNavigate ) . to . be . false ;
608
+
609
+ triedToNavigate = false ;
610
610
} ) ;
611
611
}
612
612
@@ -618,9 +618,9 @@ describe('Router', () => {
618
618
if ( ! el ) throw Error ( `Unable to find link: ${ sel } ` ) ;
619
619
el . click ( ) ;
620
620
await sleep ( 1 ) ;
621
- expect ( Route ) . not . to . have . been . called ;
622
- expect ( pushState ) . not . to . have . been . called ;
623
- expect ( clickHandler ) . to . have . been . called ;
621
+ expect ( triedToNavigate ) . to . be . true ;
622
+
623
+ triedToNavigate = false ;
624
624
} ) ;
625
625
}
626
626
} ) ;
@@ -638,69 +638,81 @@ describe('Router', () => {
638
638
</ >
639
639
) ;
640
640
641
- it ( 'should intercept clicks on links matching the `scope` props (string)' , async ( ) => {
642
- render (
643
- < LocationProvider scope = "/app" >
644
- < Links />
645
- < ShallowLocation />
646
- </ LocationProvider > ,
647
- scratch
648
- ) ;
641
+ let triedToNavigate = false ;
642
+ const handler = ( e ) => {
643
+ e . intercept ( ) ;
644
+ if ( e [ 'preact-iso-ignored' ] ) {
645
+ triedToNavigate = true ;
646
+ }
647
+ }
648
+
649
+ it ( 'should support the `scope` prop (string)' , async ( ) => {
650
+ const App = ( ) => {
651
+ useEffect ( ( ) => {
652
+ navigation . addEventListener ( 'navigate' , handler ) ;
653
+ return ( ) => navigation . removeEventListener ( 'navigate' , handler ) ;
654
+ } , [ ] ) ;
655
+
656
+ return (
657
+ < LocationProvider scope = "/app" >
658
+ < Links />
659
+ < ShallowLocation />
660
+ </ LocationProvider >
661
+ ) ;
662
+ }
663
+ render ( < App /> , scratch ) ;
664
+ await sleep ( 10 ) ;
649
665
650
666
for ( const url of shouldIntercept ) {
651
667
scratch . querySelector ( `a[href="${ url } "]` ) . click ( ) ;
652
668
await sleep ( 1 ) ;
653
669
expect ( loc ) . to . deep . include ( { url } ) ;
654
- }
655
- } ) ;
670
+ expect ( triedToNavigate ) . to . be . false ;
656
671
657
- it . skip ( 'should allow default browser navigation for links not matching the `scope` props (string)' , async ( ) => {
658
- render (
659
- < LocationProvider scope = "app" >
660
- < Links />
661
- < ShallowLocation />
662
- </ LocationProvider > ,
663
- scratch
664
- ) ;
672
+ triedToNavigate = false ;
673
+ }
665
674
666
675
for ( const url of shouldNavigate ) {
667
676
scratch . querySelector ( `a[href="${ url } "]` ) . click ( ) ;
668
677
await sleep ( 1 ) ;
678
+ expect ( triedToNavigate ) . to . be . true ;
669
679
670
- // TODO: How to test this?
680
+ triedToNavigate = false ;
671
681
}
672
682
} ) ;
673
683
674
- it ( 'should intercept clicks on links matching the `scope` props (regex)' , async ( ) => {
675
- render (
676
- < LocationProvider scope = { / ^ \/ a p p / } >
677
- < Links />
678
- < ShallowLocation />
679
- </ LocationProvider > ,
680
- scratch
681
- ) ;
684
+ it ( 'should support the `scope` prop (regex)' , async ( ) => {
685
+ const App = ( ) => {
686
+ useEffect ( ( ) => {
687
+ navigation . addEventListener ( 'navigate' , handler ) ;
688
+ return ( ) => navigation . removeEventListener ( 'navigate' , handler ) ;
689
+ } , [ ] ) ;
690
+
691
+ return (
692
+ < LocationProvider scope = { / ^ \/ a p p / } >
693
+ < Links />
694
+ < ShallowLocation />
695
+ </ LocationProvider >
696
+ ) ;
697
+ }
698
+ render ( < App /> , scratch ) ;
699
+ await sleep ( 10 ) ;
682
700
683
701
for ( const url of shouldIntercept ) {
684
702
scratch . querySelector ( `a[href="${ url } "]` ) . click ( ) ;
685
703
await sleep ( 1 ) ;
686
704
expect ( loc ) . to . deep . include ( { url } ) ;
687
- }
688
- } ) ;
705
+ expect ( triedToNavigate ) . to . be . false ;
689
706
690
- it . skip ( 'should allow default browser navigation for links not matching the `scope` props (regex)' , async ( ) => {
691
- render (
692
- < LocationProvider scope = { / ^ \/ a p p / } >
693
- < Links />
694
- < ShallowLocation />
695
- </ LocationProvider > ,
696
- scratch
697
- ) ;
707
+ triedToNavigate = false ;
708
+ }
698
709
699
710
for ( const url of shouldNavigate ) {
700
711
scratch . querySelector ( `a[href="${ url } "]` ) . click ( ) ;
701
712
await sleep ( 1 ) ;
713
+ expect ( triedToNavigate ) . to . be . true ;
702
714
703
- // TODO: How to test this?
715
+ triedToNavigate = false ;
704
716
}
705
717
} ) ;
706
718
} ) ;
0 commit comments