@@ -22,6 +22,7 @@ import {
22
22
MockSubscriptionLink ,
23
23
mockSingleLink ,
24
24
tick ,
25
+ wait ,
25
26
} from "../../../testing" ;
26
27
import { QueryResult } from "../../types/types" ;
27
28
import { useQuery } from "../useQuery" ;
@@ -1887,6 +1888,86 @@ describe("useQuery Hook", () => {
1887
1888
requestSpy . mockRestore ( ) ;
1888
1889
} ) ;
1889
1890
1891
+ // https://github.com/apollographql/apollo-client/issues/9431
1892
+ // https://github.com/apollographql/apollo-client/issues/11750
1893
+ it ( "stops polling when component unmounts with cache-and-network fetch policy" , async ( ) => {
1894
+ const query : TypedDocumentNode < { hello : string } > = gql `
1895
+ query {
1896
+ hello
1897
+ }
1898
+ ` ;
1899
+
1900
+ const mocks = [
1901
+ {
1902
+ request : { query } ,
1903
+ result : { data : { hello : "world 1" } } ,
1904
+ } ,
1905
+ {
1906
+ request : { query } ,
1907
+ result : { data : { hello : "world 2" } } ,
1908
+ } ,
1909
+ {
1910
+ request : { query } ,
1911
+ result : { data : { hello : "world 3" } } ,
1912
+ } ,
1913
+ ] ;
1914
+
1915
+ const cache = new InMemoryCache ( ) ;
1916
+
1917
+ const link = new MockLink ( mocks ) ;
1918
+ const requestSpy = jest . spyOn ( link , "request" ) ;
1919
+ const onErrorFn = jest . fn ( ) ;
1920
+ link . setOnError ( onErrorFn ) ;
1921
+
1922
+ const ProfiledHook = profileHook ( ( ) =>
1923
+ useQuery ( query , { pollInterval : 10 , fetchPolicy : "cache-and-network" } )
1924
+ ) ;
1925
+
1926
+ const client = new ApolloClient ( {
1927
+ queryDeduplication : false ,
1928
+ link,
1929
+ cache,
1930
+ } ) ;
1931
+
1932
+ const { unmount } = render ( < ProfiledHook /> , {
1933
+ wrapper : ( { children } : any ) => (
1934
+ < ApolloProvider client = { client } > { children } </ ApolloProvider >
1935
+ ) ,
1936
+ } ) ;
1937
+
1938
+ {
1939
+ const snapshot = await ProfiledHook . takeSnapshot ( ) ;
1940
+
1941
+ expect ( snapshot . loading ) . toBe ( true ) ;
1942
+ expect ( snapshot . data ) . toBeUndefined ( ) ;
1943
+ }
1944
+
1945
+ {
1946
+ const snapshot = await ProfiledHook . takeSnapshot ( ) ;
1947
+
1948
+ expect ( snapshot . loading ) . toBe ( false ) ;
1949
+ expect ( snapshot . data ) . toEqual ( { hello : "world 1" } ) ;
1950
+ expect ( requestSpy ) . toHaveBeenCalledTimes ( 1 ) ;
1951
+ }
1952
+
1953
+ await wait ( 10 ) ;
1954
+
1955
+ {
1956
+ const snapshot = await ProfiledHook . takeSnapshot ( ) ;
1957
+
1958
+ expect ( snapshot . loading ) . toBe ( false ) ;
1959
+ expect ( snapshot . data ) . toEqual ( { hello : "world 2" } ) ;
1960
+ expect ( requestSpy ) . toHaveBeenCalledTimes ( 2 ) ;
1961
+ }
1962
+
1963
+ unmount ( ) ;
1964
+
1965
+ await expect ( ProfiledHook ) . not . toRerender ( { timeout : 50 } ) ;
1966
+
1967
+ expect ( requestSpy ) . toHaveBeenCalledTimes ( 2 ) ;
1968
+ expect ( onErrorFn ) . toHaveBeenCalledTimes ( 0 ) ;
1969
+ } ) ;
1970
+
1890
1971
it ( "should stop polling when component is unmounted in Strict Mode" , async ( ) => {
1891
1972
const query = gql `
1892
1973
{
@@ -1960,6 +2041,84 @@ describe("useQuery Hook", () => {
1960
2041
requestSpy . mockRestore ( ) ;
1961
2042
} ) ;
1962
2043
2044
+ // https://github.com/apollographql/apollo-client/issues/9431
2045
+ // https://github.com/apollographql/apollo-client/issues/11750
2046
+ it ( "stops polling when component unmounts in strict mode with cache-and-network fetch policy" , async ( ) => {
2047
+ const query : TypedDocumentNode < { hello : string } > = gql `
2048
+ query {
2049
+ hello
2050
+ }
2051
+ ` ;
2052
+
2053
+ const mocks = [
2054
+ {
2055
+ request : { query } ,
2056
+ result : { data : { hello : "world 1" } } ,
2057
+ } ,
2058
+ {
2059
+ request : { query } ,
2060
+ result : { data : { hello : "world 2" } } ,
2061
+ } ,
2062
+ {
2063
+ request : { query } ,
2064
+ result : { data : { hello : "world 3" } } ,
2065
+ } ,
2066
+ ] ;
2067
+
2068
+ const cache = new InMemoryCache ( ) ;
2069
+
2070
+ const link = new MockLink ( mocks ) ;
2071
+ const requestSpy = jest . spyOn ( link , "request" ) ;
2072
+ const onErrorFn = jest . fn ( ) ;
2073
+ link . setOnError ( onErrorFn ) ;
2074
+
2075
+ const ProfiledHook = profileHook ( ( ) =>
2076
+ useQuery ( query , { pollInterval : 10 , fetchPolicy : "cache-and-network" } )
2077
+ ) ;
2078
+
2079
+ const client = new ApolloClient ( { link, cache } ) ;
2080
+
2081
+ const { unmount } = render ( < ProfiledHook /> , {
2082
+ wrapper : ( { children } : any ) => (
2083
+ < React . StrictMode >
2084
+ < ApolloProvider client = { client } > { children } </ ApolloProvider >
2085
+ </ React . StrictMode >
2086
+ ) ,
2087
+ } ) ;
2088
+
2089
+ {
2090
+ const snapshot = await ProfiledHook . takeSnapshot ( ) ;
2091
+
2092
+ expect ( snapshot . loading ) . toBe ( true ) ;
2093
+ expect ( snapshot . data ) . toBeUndefined ( ) ;
2094
+ }
2095
+
2096
+ {
2097
+ const snapshot = await ProfiledHook . takeSnapshot ( ) ;
2098
+
2099
+ expect ( snapshot . loading ) . toBe ( false ) ;
2100
+ expect ( snapshot . data ) . toEqual ( { hello : "world 1" } ) ;
2101
+ expect ( requestSpy ) . toHaveBeenCalledTimes ( 1 ) ;
2102
+ }
2103
+
2104
+ await wait ( 10 ) ;
2105
+
2106
+ {
2107
+ const snapshot = await ProfiledHook . takeSnapshot ( ) ;
2108
+
2109
+ expect ( snapshot . loading ) . toBe ( false ) ;
2110
+ expect ( snapshot . data ) . toEqual ( { hello : "world 2" } ) ;
2111
+ expect ( requestSpy ) . toHaveBeenCalledTimes ( 2 ) ;
2112
+ }
2113
+
2114
+ unmount ( ) ;
2115
+
2116
+ await expect ( ProfiledHook ) . not . toRerender ( { timeout : 50 } ) ;
2117
+
2118
+ expect ( requestSpy ) . toHaveBeenCalledTimes ( 2 ) ;
2119
+ expect ( onErrorFn ) . toHaveBeenCalledTimes ( 0 ) ;
2120
+ } ) ;
2121
+
1963
2122
it ( "should start and stop polling in Strict Mode" , async ( ) => {
1964
2123
const query = gql `
1965
2124
{
0 commit comments