Search code examples
next.jsgraphqlapollo-clientgraphql-js

Adding update property to mutation function breaks mocked result in MockProvider


I've got the following function that gets triggered on a form submission

const [register, { loading }] = useMutation(RegisterDocument);

const router = useRouter();

const onSubmit = async (values: FormValues) => {
  const v = { ...values };
  delete v.confirmPassword;
  const res = await register({
    variables: { options: v },
    update: (cache, { data }) => {
      cache.writeQuery<MeQuery>({
        query: MeDocument,
        data: {
          __typename: 'Query',
          me: data?.register.user,
        },
      });
    },
  });
  if (res.data?.register.user) {
    router.push('/');
  }
};

I then have the following test to submit the form

test('it should submit form without error', async () => {
  const firstName = faker.name.firstName();
  const surname = faker.name.lastName();
  const username = faker.internet.userName().replace('@', '');
  const email = faker.internet.email();
  const password = faker.internet.password(6, false, /^[a-zA-Z0-9_.-]*$/);

  const cache = new InMemoryCache().restore({});

  const variables = {
    options: { email, firstName, password, surname, username },
  };

  const user = { email, firstName, surname, username, id: 1, activated: false, photo: null };

  const mocks = [
    {
      request: { query: RegisterDocument, variables },
      result: { data: { register: { errors: null, user } } },
    },
  ];

  const { queryByTestId, container } = renderWithTheme(
    <MockedProvider mocks={mocks} cache={cache}>
      <Register />
    </MockedProvider>,
  );

  await updateRegisterInputs(container); // util function that updates input values for submission

  await submitForm({ queryByTestId, testId: 'register-submit', loadingTestId: 'register-loading' }); // util function that submits form

  await waitFor(() => expect(onPush).toBeCalledWith('/'));
});

When I run this test res returns the following

{ data: { register: {} } }

However, once I remove the update property inside the register mutation function, res returns the following.

{ data: { register: { errors: null, user: [Object] } } }

Any ideas why the mocked return value returns an empty object for the register property only when the update property function is added?

Even just instantiating the update property like so;

update: () => {}

still breaks the response from the mutation.


Solution

  • I realised that the graphql doc required the __typename property in the relevant places in my mocks

    So I have to update the mock to include the typenames.

    const user = { email, firstName, surname, username, id: 1, activated: false, photo: null, __typename: 'User' };
    
    const mocks = [
      {
        request: { query: RegisterDocument, variables },
        result: { data: { register: { errors: null, user, __typename: 'UserResponse' } } },
      },
    ];