Skip to content

Commit

Permalink
Don't read from cache with network-only and no-cache policy
Browse files Browse the repository at this point in the history
  • Loading branch information
stoically committed Oct 23, 2020
1 parent d470c96 commit 3789574
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 10 deletions.
14 changes: 4 additions & 10 deletions src/core/QueryManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -836,23 +836,17 @@ export class QueryManager<TStore> {
context = {},
} = options;

const mightUseNetwork =
const mightUseCacheAndNetwork =
fetchPolicy === "cache-first" ||
fetchPolicy === "cache-and-network" ||
fetchPolicy === "network-only" ||
fetchPolicy === "no-cache";
fetchPolicy === "cache-and-network";

if (mightUseNetwork &&
if (mightUseCacheAndNetwork &&
notifyOnNetworkStatusChange &&
typeof oldNetworkStatus === "number" &&
oldNetworkStatus !== networkStatus &&
isNetworkRequestInFlight(networkStatus)) {
// In order to force delivery of an incomplete cache result with
// loading:true, we tweak the fetchPolicy to include the cache, and
// pretend that returnPartialData was enabled.
if (fetchPolicy !== "cache-first") {
fetchPolicy = "cache-and-network";
}
// loading:true, we pretend that returnPartialData was enabled.
returnPartialData = true;
}

Expand Down
104 changes: 104 additions & 0 deletions src/react/hooks/__tests__/useQuery.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1546,6 +1546,110 @@ describe('useQuery Hook', () => {
expect(renderCount).toBe(6);
}).then(resolve, reject);
});

itAsync('should properly handle refetching with different variables and network-only fetchPolicy', (resolve, reject) => {
const carQuery: DocumentNode = gql`
query cars($id: Int) {
cars(id: $id) {
id
make
model
vin
__typename
}
}
`;

const carData1 = {
cars: [
{
id: 1,
make: 'Audi',
model: 'RS8',
vin: 'DOLLADOLLABILL',
__typename: 'Car'
}
]
};

const carData2 = {
cars: [
{
id: 2,
make: 'Audi',
model: 'eTron',
vin: 'TREESRGOOD',
__typename: 'Car'
}
]
};

const mocks = [
{
request: { query: carQuery, variables: { id: 1 } },
result: { data: carData1 }
},
{
request: { query: carQuery, variables: { id: 2 } },
result: { data: carData2 }
},
{
request: { query: carQuery, variables: { id: 1 } },
result: { data: carData1 }
}
];

let renderCount = 0;
function App() {
const { loading, data, refetch } = useQuery(carQuery, {
variables: { id: 1 },
notifyOnNetworkStatusChange: true,
fetchPolicy: "network-only",
});

switch (renderCount) {
case 0:
expect(loading).toBeTruthy();
expect(data).toBeUndefined();
break;
case 1:
expect(loading).toBeFalsy();
expect(data).toEqual(carData1);
refetch({ id: 2 });
break;

// without modifying `QueryManager.ts` this assertion would be true
// case 2:
// expect(data).toEqual({});
// expect(loading).toBeTruthy();
// break;

case 2:
expect(loading).toBeFalsy();
expect(data).toEqual(carData2);
refetch({ id: 1 });
break;
case 3:
expect(loading).toBeFalsy();
expect(data).toEqual(carData1);
break;
default:
}

renderCount += 1;
return null;
}

render(
<MockedProvider mocks={mocks}>
<App />
</MockedProvider>
);

return wait(() => {
expect(renderCount).toBe(4);
}).then(resolve, reject);
});
});

describe('Partial refetching', () => {
Expand Down

0 comments on commit 3789574

Please sign in to comment.