Repository: tannerlinsley/react-query (ts)

Issue:
Default makeQueryCache server behaviour does not match Readme
**Describe the bug**

This is either a bug or an error in the Readme.

**To Reproduce**

Readme says:

> If you create a queryCache manually with `makeQueryCache`, queries will be cached during SSR. Make sure you create a separate cache per request to avoid leaking data.

This is not true however, you have to explicitly call `makeQueryCache({ frozen: false })` to enable caching on the server.

**Expected behavior**

One of:

* Update Readme to match actual behaviour
* Update default behaviour to match Readme

**Additional context**

Release notes says:

> - `makeQueryCache` now accepts an optional configuration object. The `defaultConfig` object is used to override the default query configuration config to use inside of this cache. The `frozen` option if set to `true` will simulate React Query being run on the server, where no queries are cached for privacy and safety concerns. This is the default when using React Query on the server and is optional. You can also set it to `true` on the server and have it work as it would on the client. More information on this coming soon!

I'm guessing this behaviour was changed between #584 being merged and the release, but the info in the Readme was unintentionally not updated?

I don't have any strong feelings on this and would be happy to fix it either way, but I'd argue that creating a cache manually on the server only makes sense if you intend to use it for caching, making unfrozen a good default (but not for the global cache of course). I also don't see a security risk in this, since the developer is intentionally creating the cache.

Changing the default behaviour would kind of be a small breaking change though (intended for v2), but could also be considered a fix to match the Readme, depending. It would not affect people using `{ frozen: true/false }` explicitly, so should be fine.

I'd be happy to just update the Readme as well of course. 😄 

Pull request:
Fix makeQueryCache default caching behaviour in node
Closes #706

This PR makes it so caches returned from `makeQueryCache` will always be unfrozen, and therefor cache data, by default. This now includes on the server.

The global cache on the server is still frozen by default and does not cache data, this is to avoid leaking data across requests as per #70.

This makes it so the behaviour of `makeQueryCache` matches the one described in the Readme.

I also made the tests around this more explicit.

Patch:
diff --git a/src/core/queryCache.js b/src/core/queryCache.js
index 0134dda77..5b59c38c8 100644
--- a/src/core/queryCache.js
+++ b/src/core/queryCache.js
@@ -8,11 +8,11 @@ import {
 import { defaultConfigRef } from './config'
 import { makeQuery } from './query'
 
-export const queryCache = makeQueryCache()
+export const queryCache = makeQueryCache({ frozen: isServer })
 
 export const queryCaches = [queryCache]
 
-export function makeQueryCache({ frozen = isServer, defaultConfig } = {}) {
+export function makeQueryCache({ frozen = false, defaultConfig } = {}) {
   // A frozen cache does not add new queries to the cache
   const globalListeners = []
 


Test patch:
diff --git a/src/react/tests/ssr.test.js b/src/react/tests/ssr.test.js
index f7e1f60e9..99aa31e6c 100644
--- a/src/react/tests/ssr.test.js
+++ b/src/react/tests/ssr.test.js
@@ -8,19 +8,44 @@ import {
   usePaginatedQuery,
   ReactQueryCacheProvider,
   queryCache,
-  queryCaches,
   makeQueryCache,
   useQuery,
 } from '../index'
 import { sleep } from './utils'
 
 describe('Server Side Rendering', () => {
-  describe('global cache', () => {
-    afterEach(() => {
-      queryCaches.forEach(cache => cache.clear({ notify: false }))
-    })
+  // A frozen cache does not cache any data. This is the default
+  // for the global cache in a node-environment, since it's
+  // otherwise easy to cache data between separate requests,
+  // which is a security risk.
+  //
+  // See https://github.com/tannerlinsley/react-query/issues/70
+  it('global cache should be frozen by default', async () => {
+    const fetchFn = () => Promise.resolve('data')
+    const data = await queryCache.prefetchQuery('key', fetchFn)
+
+    expect(data).toBe('data')
+    expect(queryCache.getQuery('key')).toBeFalsy()
+
+    queryCache.clear({ notify: false })
+  })
+
+  // When consumers of the library create a cache explicitly by
+  // calling makeQueryCache, they take on the responsibility of
+  // not using that cache to cache data between requests or do so
+  // in a safe way.
+  it('created caches should be unfrozen by default', async () => {
+    const queryCache = makeQueryCache()
+    const fetchFn = () => Promise.resolve('data')
+    const data = await queryCache.prefetchQuery('key', fetchFn)
+
+    expect(data).toBe('data')
+    expect(queryCache.getQuery('key')).toBeTruthy()
+  })
 
+  describe('frozen cache', () => {
     it('should not trigger fetch', () => {
+      const queryCache = makeQueryCache({ frozen: true })
       const queryFn = jest.fn()
 
       function Page() {
@@ -35,14 +60,19 @@ describe('Server Side Rendering', () => {
         )
       }
 
-      const markup = renderToString(<Page />)
+      const markup = renderToString(
+        <ReactQueryCacheProvider queryCache={queryCache}>
+          <Page />
+        </ReactQueryCacheProvider>
+      )
 
       expect(markup).toContain('status loading')
       expect(queryFn).toHaveBeenCalledTimes(0)
     })
 
-    // See https://github.com/tannerlinsley/react-query/issues/70
     it('should not add initialData to the cache', () => {
+      const queryCache = makeQueryCache({ frozen: true })
+
       function Page() {
         const [page, setPage] = React.useState(1)
         const { resolvedData } = usePaginatedQuery(
@@ -54,10 +84,10 @@ describe('Server Side Rendering', () => {
         )
 
         return (
-          <div>
+          <ReactQueryCacheProvider queryCache={queryCache}>
             <h1 data-testid="title">{resolvedData}</h1>
             <button onClick={() => setPage(page + 1)}>next</button>
-          </div>
+          </ReactQueryCacheProvider>
         )
       }
 
@@ -67,6 +97,7 @@ describe('Server Side Rendering', () => {
     })
 
     it('should not add prefetched data to the cache', async () => {
+      const queryCache = makeQueryCache({ frozen: true })
       const fetchFn = () => Promise.resolve('data')
       const data = await queryCache.prefetchQuery('key', fetchFn)