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