MockedProvider newData() is always being returned on first query
Intended outcome: When a Query with the same variables is executed a second time against a MockedProvider, NewData() will return new data results. This was the outcome that was happening before doing the apollo hook migration.
Actual outcome: After the Apollo hook migration, When the first time Query is executed against MockedProvider, it returns the results of newData() instead of the results data first defined in the mocked provider.
How to reproduce the issue:
Invite.tsx
import React, { Component } from 'react';
import gql from 'graphql-tag';
import { Query } from 'react-apollo';
export const GET_INVITE = gql`
query Invite($inviteToken: String!, $inviteContext: InviteContext!) {
invite(inviteToken: $inviteToken, inviteContext: $inviteContext) {
email
isExpired
firstName
lastName
uuid
inviteToken
}
}
`;
interface Variables {
inviteToken: string;
inviteContext: string;
}
interface matchParams {
token: string;
}
interface inviteProps {
context: InviteContext;
}
class Invite extends Component<RouteComponentProps<matchParams> & inviteProps> {
render(): JSX.Element {
return (
<div className="inviteContainer">
<Query<Data, Variables>
query={GET_INVITE}
variables={{ inviteToken: token, inviteContext: context }}
>
{({ loading, error, data, refetch, networkStatus }) => {
if (data.invite.isExpired)
return (
<div
data-testid="expiredInvite"
className="inviteFormAnimation"
>
<Lottie options={invalidInviteOptions} />
<Typography.Title className="animationMessage" level={3}>
Oops!...Looks like this Invite expired or was already used
</Typography.Title>
<Typography.Title className="animationMessage" level={4}>
If you think you recieved this in error, Send us an email to
request a new one
</Typography.Title>
</div>
);
return (
<div>
<UserSignUpForm
firstName={data ? data.invite.firstName : ''}
lastName={data ? data.invite.lastName : ''}
email={data ? data.invite.email : ''}
refetch={refetch}
submitForm={this.handleSubmit}
subTitle={this.handleFormSubtitle(this.props.context)}
countryCode={this.handleCountryCode(this.props.context)}
data-testid="signupform"
/>
<Button onClick={() => refetch()}>Create my account</Button>
</div>
);
}
}
</Query>
</div>
);
}
}
export default Invite;
Invite.test.tsx
test('should display expired invite animation when user tries creates account when invite is expired', async () => {
const validThenExpiredInviteMocks = [
{
request: {
query: GET_INVITE,
variables: {
inviteToken: '1234',
inviteContext: 'DESIGNER_BUSINESS'
}
},
result: {
data: {
invite: {
email: '[email protected]',
firstName: 'Jake',
isExpired: false,
lastName: null,
uuid: '123ff43',
inviteToken: '1234'
}
}
},
newData: () => ({
data: {
invite: {
email: '[email protected]',
firstName: 'Jake',
isExpired: true,
lastName: null,
uuid: '123ff43',
inviteToken: '1234'
}
}
})
}
];
const { getByTestId, getByText, getByLabelText, debug } = render(
<MockedProvider mocks={validThenExpiredInviteMocks} addTypename={false}>
<Invite
context={InviteContext.DESIGNER_BUSINESS}
match={matchMock}
location={mock}
history={mock}
/>
</MockedProvider>
);
await act(async () => {
await wait();
});
fireEvent.change(getByLabelText('lastname-input'), {
target: { value: 'mylastname' }
});
fireEvent.change(getByLabelText('password-input'), {
target: { value: 'Som3randompassword' }
});
fireEvent.change(getByLabelText('passwordconfirm-input'), {
target: { value: 'Som3randompassword' }
});
fireEvent.change(getByLabelText('phone-input'), {
target: { value: '1234567890' }
});
fireEvent.submit(getByText('Create my account'));
await act(async () => {
await wait();
});
expect(getByTestId('expiredInvite')).toHaveTextContent(
'Oops!...Looks like this Invite expired or was already used'
);
});
^^ The test fails because when it is trying to change the lastname input it can't find it because the expired Invite animation is displayed. This tells me that newData() is getting returned in the mockedProvider on the initial first Query instead of the second time the Query is executed when the 'create my 'account' button is clicked.
I also checked to see if the component was getting rendered twice for some reason but via print statements I could see it only being rendered once on the initial render.
Version
"dependencies": { "react": "^16.12.0", "react-apollo": "^3.1.3", "react-dom": "^16.12.0", "react-scripts": "^3.2.0", ... }
"devDependencies": { "@apollo/react-testing": "^3.1.3", "@testing-library/jest-dom": "^4.2.4", "@testing-library/react": "^9.4.0", ... }
Any update on this?
having the same problem. any solutions?