[BUG] useSubscription onSubscriptionData triggering infinitely via tests
See original GitHub issueIntended outcome:
I have two subscriptions, the first one gets the info from a notifications list and the second one gets the aggregate of the notifications to handle an infinite scroll
const {
loading: loading_content,
error: error_content,
data: data_content,
} = useSubscription(GET_NOTIFICATIONS_CONTENT, {
variables: {
offset: 0,
limit,
user_id,
},
onSubscriptionData: () => {
setFetchingMore(false);
},
});
const {
loading: loading_aggregate,
error: error_aggregate,
data: data_aggregate,
} = useSubscription(GET_NOTIFICATIONS_AGGREGATE, {
variables: {
user_id,
},
});
test("Renders notification content ", async () => {
useGlobalWorkspace.mockImplementation(() => ({
globalWorkspace: ADMIN_GLOBAL_WORKSPACE_RESPONSE_MOCK,
}));
const route = "/home";
let history = createMemoryHistory({ initialEntries: [route] });
renderWithRouterMatch(
<MockProvider mocks={mocks} addTypename={true}>
<NotificationContent/>
</MockProvider>,
{ route, path: "/home", history }
);
await act(async () => {
await new Promise(resolve => setTimeout(resolve, 0));
});
});
I have on my .test.js file an MockedProvider as the documentation explains, with the needed mocks for the subscriptions to work, i expect the subscriptions data to update once i indicate it on the test.
The mocks passed to the MockedProvider:
const GET_NOTIFICATIONS_CONTENT = loader(
"graphql/Notifications/get_notifications_content.graphql"
);
export const getNotificationContentVariables = {
offset: 0,
limit: 10,
user_id: "test-uid",
};
const getNotificationContentResult = { data: NOTIFICATION_CONTENT_RESULT };
export const getNotificationContent = {
request: {
query: GET_NOTIFICATIONS_CONTENT,
variables: getNotificationContentVariables,
},
result: getNotificationContentResult,
newData: () => getNotificationContentResult,
};
const GET_NOTIFICATIONS_AGGREGATE = loader(
"graphql/Notifications/get_notifications_aggregate.graphql"
);
export const getNotificationAggregateVariables = {
offset: 0,
limit: 10,
user_id: "test-uid",
};
const getNotificationAggregateResult = { data: NOTIFICATION_AGGREGATE_RESULT };
export const getNotificationAggregate = {
request: {
query: GET_NOTIFICATIONS_Aggregate,
variables: getNotificationAggregateVariables,
},
result: getNotificationAggregateResult,
newData: () => getNotificationAggregateResult,
};
Actual outcome:
When i have two subscriptions running at once, they return infinitely data triggering infinite renders on the component. I tested this adding a console log on an onSubscriptionData for each subscription and they return data forever. Once i comment any of the two subscriptions, they start working correctly.
How to reproduce the issue: add two subscriptions using useSubscription on a component and mock the responses on the test via MockedProvider.
NOTE
This isn’t the first time i find an issue like this, i had to do a few workarounds on other subscriptions that were alone and were showing this same behaviour, like moving state changes from the onSubscriptionData to useEffects, but this time i can’t find any way to make this work.
Versions System: OS: Windows 10 10.0.19041 Binaries: Node: 12.16.1 - C:\Program Files\nodejs\node.EXE Yarn: 1.22.4 - C:\Program Files (x86)\Yarn\bin\yarn.CMD npm: 6.13.4 - C:\Program Files\nodejs\npm.CMD Browsers: Chrome: 87.0.4280.88 Edge: Spartan (44.19041.423.0), Chromium (87.0.664.60) npmPackages: @apollo/react-hooks: ^4.0.0 => 4.0.0 @apollo/react-testing: ^4.0.0 => 4.0.0 apollo-boost: ^0.4.9 => 0.4.9 apollo-link-context: ^1.0.20 => 1.0.20 apollo-link-ws: ^1.0.20 => 1.0.20
Issue Analytics
- State:
- Created 3 years ago
- Reactions:13
- Comments:16 (6 by maintainers)
Top GitHub Comments
I’m also experiencing this same issue and i haven’t found any docs or info on about how to test subscription with the MockedProvider or any other way to do it. It’s happening to me whenever i have 2 or more subscriptions via useSubscription hook on the same component and then i try to test it via react-testing-library.
I’m on a bit of a deadline right now
@hwillson @benjamn any help on this?
https://github.com/martdavidson/7493-recreation
yarn install
, thenyarn test
. You’ll see a console log of the current timestamp every 3 seconds until the global react-testing-library timeout is hit.If you remove the
useEffect
inApp.tsx
, you’ll see that it only happens once, and never repeats, as expected.So it sure looks like re-renders will trigger whatever is in your
onSubscriptionData
in tests.Unfortunately you can’t
yarn start
this project - there’s no backend with real subscriptions - but in our production app the re-renders do not cause theonSubscriptionData
to re-trigger, only in the tests does that happen.Let me know if this actually demonstrates a bug, or if I’m misunderstanding things, or if you need any clarification at all on what I’m doing in the recreation.