React GraphQL mutation is not leaving the loading state

14 Views Asked by At

I don't understand what is going on with the mutation. It works fine in the browser, but when I try to test it using vitest/react-testing-library, the mutation is never returned, it always times out. I've tried extending the time and adding timers, none of it is making a difference.

The component is a modal where a user can create their group. getCreateGroupPayload fromats the data from the HTMLForm to what we want to send to the server. Here is my mutation call from the component:

  const [createGroupGQL, { loading, error }] = useMutation(CREATE_GROUP, {
    onCompleted: (data) => {
      const groupId = data.createGroup.response?.oid;
      handleClose();
      navigate(`/group/${groupId}`);
    },
    onError: (error) => {
      console.error(`CreateGroup error: ${error?.message}`);
    },
    refetchQueries: [GET_GROUP_LIST]
  });

 const onSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    const formData = new FormData(event.currentTarget);
    const formJson = Object.fromEntries(formData.entries());

    const payload = getCreateGroupPayload(formJson);

    createGroupGQL({ variables: { body: payload } });
  };

Here is the test case:

it('closes after creating successfully', async () => {
    const user = userEvent.setup();
    const getCreateGroupPayloadSpy = vi
      .spyOn(utils, 'getCreateGroupPayload')
      .mockReturnValue(payload);
    const onClose = vi.fn();
    const mock = {
      request: {
        query: CREATE_GROUP,
        variables: {
          body: 'payload'
        }
      },
      result: {
        data: {
          createGroup: {
            id: 1
          }
        }
      }
    };

    render(
      <MockedProvider mocks={[mock]} addTypename={false}>
        <CreateGroupModal isOpen onClose={onClose} />
      </MockedProvider>
    );
    // renderCreateGroupModal([getCreateGroupMock()]);

    const createButton = screen.getByRole('button', { name: 'Create' });
    await user.click(createButton);

    const loadingIndicator = screen.findByRole('progressbar');
    expect(loadingIndicator).toBeInTheDocument();
    await waitForElementToBeRemoved(() => loadingIndicator);

    expect(getCreateGroupPayloadSpy).toHaveBeenCalled();
    await waitFor(() => {
      expect(onClose).toHaveBeenCalled();
    });
  });

It doesn't seem to matter if I do the await waitFor() on the results or not.

0

There are 0 best solutions below