@@ -370,6 +370,43 @@ describe('queries', () => {
370370 } , 25 ) ;
371371 } ) ;
372372
373+ it ( 'continues to not subscribe to a skipped query when props change' , ( done ) => {
374+ const query = gql `query people { allPeople(first: 1) { people { name } } }` ;
375+ const networkInterface = mockNetworkInterface ( ) ;
376+ const oldQuery = networkInterface . query ;
377+
378+ networkInterface . query = function ( request ) {
379+ fail ( new Error ( 'query ran even though skip present' ) ) ;
380+ return oldQuery . call ( this , request ) ;
381+ } ;
382+ const client = new ApolloClient ( { networkInterface } ) ;
383+
384+ @graphql ( query , { skip : true } )
385+ class Container extends React . Component < any , any > { 8
386+ componentWillReceiveProps ( props ) {
387+ done ( ) ;
388+ }
389+ render ( ) {
390+ return null ;
391+ }
392+ } ;
393+
394+ class Parent extends React . Component < any , any > {
395+ constructor ( ) {
396+ super ( ) ;
397+ this . state = { foo : 42 } ;
398+ }
399+ componentDidMount ( ) {
400+ this . setState ( { foo : 43 } ) ;
401+ }
402+ render ( ) {
403+ return < Container foo = { this . state . foo } /> ;
404+ }
405+ } ;
406+
407+ renderer . create ( < ProviderMock client = { client } > < Parent /> </ ProviderMock > ) ;
408+ } ) ;
409+
373410 it ( 'doesn\'t run options or props when skipped' , ( done ) => {
374411 const query = gql `query people { allPeople(first: 1) { people { name } } }` ;
375412 const data = { allPeople : { people : [ { name : 'Luke Skywalker' } ] } } ;
@@ -426,6 +463,106 @@ describe('queries', () => {
426463 } , 25 ) ;
427464 } ) ;
428465
466+ // test the case of skip:false -> skip:true -> skip:false to make sure things
467+ // are cleaned up properly
468+ it ( 'allows you to skip then unskip a query with top-level syntax' , ( done ) => {
469+ const query = gql `query people { allPeople(first: 1) { people { name } } }` ;
470+ const data = { allPeople : { people : [ { name : 'Luke Skywalker' } ] } } ;
471+ const networkInterface = mockNetworkInterface ( { request : { query } , result : { data } } ) ;
472+ const client = new ApolloClient ( { networkInterface } ) ;
473+
474+ let hasSkipped = false ;
475+ @graphql ( query , { skip : ( { skip } ) => skip } )
476+ class Container extends React . Component < any , any > { 8
477+ componentWillReceiveProps ( newProps ) {
478+ if ( newProps . skip ) {
479+ hasSkipped = true ;
480+ this . props . setSkip ( false ) ;
481+ } else {
482+ if ( hasSkipped ) {
483+ done ( ) ;
484+ } else {
485+ this . props . setSkip ( true ) ;
486+ }
487+ }
488+ }
489+ render ( ) {
490+ return null ;
491+ }
492+ } ;
493+
494+ class Parent extends React . Component < any , any > {
495+ constructor ( ) {
496+ super ( ) ;
497+ this . state = { skip : false } ;
498+ }
499+ render ( ) {
500+ return < Container skip = { this . state . skip } setSkip = { ( skip ) => this . setState ( { skip } ) } /> ;
501+ }
502+ } ;
503+
504+ renderer . create ( < ProviderMock client = { client } > < Parent /> </ ProviderMock > ) ;
505+ } ) ;
506+
507+ it ( 'allows you to skip then unskip a query with opts syntax' , ( done ) => {
508+ const query = gql `query people { allPeople(first: 1) { people { name } } }` ;
509+ const data = { allPeople : { people : [ { name : 'Luke Skywalker' } ] } } ;
510+ const nextData = { allPeople : { people : [ { name : 'Anakin Skywalker' } ] } } ;
511+ const networkInterface = mockNetworkInterface ( {
512+ request : { query } , result : { data } , newData : ( ) => ( { data : nextData } ) } ) ;
513+ const oldQuery = networkInterface . query ;
514+
515+ let ranQuery = 0 ;
516+ networkInterface . query = function ( request ) {
517+ ranQuery ++ ;
518+ return oldQuery . call ( this , request ) ;
519+ } ;
520+ const client = new ApolloClient ( { networkInterface } ) ;
521+
522+ let hasSkipped = false ;
523+ let hasRequeried = false ;
524+ @graphql ( query , { options : ( { skip } ) => ( { skip, forceFetch : true } ) } )
525+ class Container extends React . Component < any , any > { 8
526+ componentWillReceiveProps ( newProps ) {
527+ if ( newProps . skip ) {
528+ // Step 2. We shouldn't query again.
529+ expect ( ranQuery ) . toBe ( 1 ) ;
530+ hasSkipped = true ;
531+ this . props . setSkip ( false ) ;
532+ } else if ( hasRequeried ) {
533+ // Step 4. We need to actually get the data from the query into the component!
534+ expect ( newProps . data . loading ) . toBe ( false ) ;
535+ done ( ) ;
536+ } else if ( hasSkipped ) {
537+ // Step 3. We need to query again!
538+ expect ( newProps . data . loading ) . toBe ( true ) ;
539+ expect ( ranQuery ) . toBe ( 2 ) ;
540+ hasRequeried = true ;
541+ } else {
542+ // Step 1. We've queried once.
543+ expect ( ranQuery ) . toBe ( 1 ) ;
544+ this . props . setSkip ( true ) ;
545+ }
546+ }
547+ render ( ) {
548+ return null ;
549+ }
550+ } ;
551+
552+ class Parent extends React . Component < any , any > {
553+ constructor ( ) {
554+ super ( ) ;
555+ this . state = { skip : false } ;
556+ }
557+ render ( ) {
558+ return < Container skip = { this . state . skip } setSkip = { ( skip ) => this . setState ( { skip } ) } /> ;
559+ }
560+ } ;
561+
562+ renderer . create ( < ProviderMock client = { client } > < Parent /> </ ProviderMock > ) ;
563+ } ) ;
564+
565+
429566 it ( 'removes the injected props if skip becomes true' , ( done ) => {
430567 let count = 0 ;
431568 const query = gql `
@@ -495,6 +632,44 @@ describe('queries', () => {
495632 renderer . create ( < ProviderMock client = { client } > < ChangingProps /> </ ProviderMock > ) ;
496633 } ) ;
497634
635+
636+ it ( 'allows you to unmount a skipped query' , ( done ) => {
637+ const query = gql `query people { allPeople(first: 1) { people { name } } }` ;
638+ const networkInterface = mockNetworkInterface ( ) ;
639+ const client = new ApolloClient ( { networkInterface } ) ;
640+
641+ @graphql ( query , {
642+ skip : true ,
643+ } )
644+ class Container extends React . Component < any , any > {
645+ componentDidMount ( ) {
646+ this . props . hide ( ) ;
647+ }
648+ componentWillUnmount ( ) {
649+ done ( ) ;
650+ }
651+ render ( ) {
652+ return null ;
653+ }
654+ } ;
655+
656+ class Hider extends React . Component < any , any > {
657+ constructor ( ) {
658+ super ( ) ;
659+ this . state = { hide : false } ;
660+ }
661+ render ( ) {
662+ if ( this . state . hide ) {
663+ return null ;
664+ }
665+ return < Container hide = { ( ) => this . setState ( { hide : true } ) } /> ;
666+ }
667+ }
668+
669+ renderer . create ( < ProviderMock client = { client } > < Hider /> </ ProviderMock > ) ;
670+ } ) ;
671+
672+
498673 it ( 'reruns the query if it changes' , ( done ) => {
499674 let count = 0 ;
500675 const query = gql `
0 commit comments