Skip to content

Commit

Permalink
Repro for queryCacheExpirationTime not working in hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
josephsavona committed Aug 2, 2023
1 parent 6aa6866 commit 1f3ea7b
Show file tree
Hide file tree
Showing 3 changed files with 281 additions and 6 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
* @oncall relay
*/

'use strict';

import type {CacheConfig, RequestParameters, Variables} from 'relay-runtime';

const RelayEnvironmentProvider = require('../RelayEnvironmentProvider');
const useLazyLoadQuery = require('../useLazyLoadQuery');
const React = require('react');
const ReactTestRenderer = require('react-test-renderer');
const {
Environment,
Network,
Observable,
RecordSource,
Store,
graphql,
} = require('relay-runtime');

describe('useLazyLoadQuery with queryCacheExpirationTime', () => {
let environment;
let ParentQuery;
let source;
let store;
let fetchTime;
let fetch;
let networkSource;
let render;
const QUERY_CACHE_EXPIRATION_TIME = 1000;
const GC_RELEASE_BUFFER_SIZE = 1;

beforeEach(() => {
fetchTime = Date.now();
jest.spyOn(global.Date, 'now').mockImplementation(() => fetchTime);

ParentQuery = graphql`
query useLazyLoadQueryQueryCacheExpirationTimeTestQuery {
me {
id
name
}
}
`;

source = RecordSource.create();
store = new Store(source, {
queryCacheExpirationTime: QUERY_CACHE_EXPIRATION_TIME,
gcReleaseBufferSize: GC_RELEASE_BUFFER_SIZE,
});
fetch = jest.fn(
(
_query: RequestParameters,
_variables: Variables,
_cacheConfig: CacheConfig,
) => {
return Observable.create<$FlowFixMe>(sink => {
networkSource = sink;
});
},
);
environment = new Environment({
network: Network.create((fetch: $FlowFixMe)),
store,
});

render = (env: Environment, children: React.Node) => {
const instance = ReactTestRenderer.create(
<RelayEnvironmentProvider environment={env}>
<React.Suspense fallback="Fallback">{children}</React.Suspense>
</RelayEnvironmentProvider>,
);
return [
instance,
(nextChildren: React.Node) => {
instance.update(
<RelayEnvironmentProvider environment={env}>
<React.Suspense fallback="Fallback">
{nextChildren}
</React.Suspense>
</RelayEnvironmentProvider>,
);
},
];
};
});

afterEach(() => {
jest.clearAllMocks();
});

it('does not refetch if the previous query has not expired', () => {
let data: string | void;
function Component() {
data = useLazyLoadQuery(
ParentQuery,
{},
{
fetchPolicy: 'store-or-network',
},
);
return data.me.name;
}
const [instance, rerender] = render(environment, <Component />);
expect(instance.toJSON()).toEqual('Fallback');
expect(data).toEqual(undefined);

ReactTestRenderer.act(() => {
networkSource.next({
data: {
me: {
id: '4',
name: 'Zuck',
},
},
});
jest.runAllTimers();
});
expect(instance.toJSON()).toEqual('Zuck');
expect(data).toEqual({
me: {
id: '4',
name: 'Zuck',
},
});
expect(fetch).toBeCalledTimes(1);
ReactTestRenderer.act(() => {
jest.runAllTimers();
rerender(<div />); // unmount the component
jest.runAllTimers();
});

// Advance time to just before query expiration
jest
.spyOn(global.Date, 'now')
.mockImplementation(() => fetchTime + (QUERY_CACHE_EXPIRATION_TIME - 1));

rerender(<Component />);
expect(instance.toJSON()).toEqual('Zuck');
expect(fetch).toBeCalledTimes(1);
rerender(<div />); // unmount the component
jest.runAllTimers();

// Advance time to just after query expiration
jest
.spyOn(global.Date, 'now')
.mockImplementation(() => fetchTime + (QUERY_CACHE_EXPIRATION_TIME + 1));

rerender(<Component />);
// TODO: This should suspend again and show the fallback.
// The fetchQueryInternal instance is incorrectly reused when it should have
// been cleared on unmount of the previous component.
expect(instance.toJSON()).toEqual('Zuck');
// TODO: This should fetch again, per above the previous cache entry should be
// cleared and this should fetch again (call count 2, not 1)
expect(fetch).toBeCalledTimes(1);
});
});
24 changes: 18 additions & 6 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4092,27 +4092,39 @@ hash.js@^1.0.0, hash.js@^1.0.3:
inherits "^2.0.3"
minimalistic-assert "^1.0.1"

hermes-eslint@0.14.0:
version "0.14.0"
resolved "https://registry.yarnpkg.com/hermes-eslint/-/hermes-eslint-0.14.0.tgz#d56426b0931a7ced99d08b4b6a06f798064b13ba"
integrity sha512-ORk7znDabvALzTbI3QRIQefCkxF1ukDm3dVut3e+cVmwdtsTC71BJetSvdh1jtgK10czwck1QiPZOVOVolhiqQ==
hermes-eslint@0.15.0:
version "0.15.0"
resolved "https://registry.yarnpkg.com/hermes-eslint/-/hermes-eslint-0.15.0.tgz#4d7495cb5e0e9275a1fb0b465b88fccf0b6d8840"
integrity sha512-Rd12uW9FZdOTDDwpVdYUxZGEApskUzBfKYy9RMtczm2uprX8yviPb9QVSVn2hl+xuRTA7Z0FnqDwOwXGiinsRQ==
dependencies:
esrecurse "^4.3.0"
hermes-estree "0.14.0"
hermes-parser "0.14.0"
hermes-estree "0.15.0"
hermes-parser "0.15.0"

hermes-estree@0.14.0:
version "0.14.0"
resolved "https://registry.yarnpkg.com/hermes-estree/-/hermes-estree-0.14.0.tgz#c663eea1400980802283338a09d0087c448729e7"
integrity sha512-L6M67+0/eSEbt6Ha2XOBFXL++7MR34EOJMgm+j7YCaI4L/jZqrVAg6zYQKzbs1ZCFDLvEQpOgLlapTX4gpFriA==

hermes-estree@0.15.0:
version "0.15.0"
resolved "https://registry.yarnpkg.com/hermes-estree/-/hermes-estree-0.15.0.tgz#e32f6210ab18c7b705bdcb375f7700f2db15d6ba"
integrity sha512-lLYvAd+6BnOqWdnNbP/Q8xfl8LOGw4wVjfrNd9Gt8eoFzhNBRVD95n4l2ksfMVOoxuVyegs85g83KS9QOsxbVQ==

hermes-parser@0.14.0:
version "0.14.0"
resolved "https://registry.yarnpkg.com/hermes-parser/-/hermes-parser-0.14.0.tgz#edb2e7172fce996d2c8bbba250d140b70cc1aaaf"
integrity sha512-pt+8uRiJhVlErY3fiXB3gKhZ72RxM6E1xRMpvfZ5n6Z5TQKQQXKorgRCRzoe02mmvLKBJFP5nPDGv75MWAgCTw==
dependencies:
hermes-estree "0.14.0"

hermes-parser@0.15.0:
version "0.15.0"
resolved "https://registry.yarnpkg.com/hermes-parser/-/hermes-parser-0.15.0.tgz#f611a297c2a2dbbfbce8af8543242254f604c382"
integrity sha512-Q1uks5rjZlE9RjMMjSUCkGrEIPI5pKJILeCtK1VmTj7U4pf3wVPoo+cxfu+s4cBAPy2JzikIIdCZgBoR6x7U1Q==
dependencies:
hermes-estree "0.15.0"

hmac-drbg@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
Expand Down

0 comments on commit 1f3ea7b

Please sign in to comment.