0

I am testing a component with React testing library and Jest.

The component:

import { useMutation, useFragment } from 'react-relay';
import PropTypes from 'prop-types';
import { useState } from 'react';

const fragment = graphql`
  fragment UserForm_user on User {
    id
    firstName
    lastName
    role
  }
`;

const mutation = graphql`
  mutation UserFormMutation($input: UpdateUserInput!) {
    updateUser(input: $input) {
      user {
        id
        databaseId
        role
        firstName
        lastName
      }
      errors {
        field
        messages
      }
    }
  }
`;

Component.displayName = 'UserForm';
export default function Component(props) {
  const data = useFragment(fragment, props.user);

  const [commit, isInFlight] = useMutation(mutation);
  const [errors, setErrors] = useState([]);

  const [user, setUser] = useState(data);

  const onChange = ({ target: { name, value } }) => {
    setUser((user) => ({ ...user, [name]: value }));
  };

  const onBlur = () => {
    commit({
      variables: {
        input: {
          id: user.id,
          ...user,
        },
      },
      onCompleted: ({ updateUser: { errors } }) => {
        if (errors.length > 0) {
          setErrors(errors);
        }
      },
    });
  };

  return (
    <>
      <Table.Col>
        <Form.Group>
          <Form.Input
            id="firstName"
            name="firstName"
            errors={errors}
            onChange={onChange}
            onBlur={onBlur}
            value={user.firstName}
          />
        </Form.Group>
      </Table.Col>
      <Table.Col>
        <Form.Group>
          <Form.Input
            id="lastName"
            name="lastName"
            errors={errors}
            onChange={onChange}
            onBlur={onBlur}
            value={user.lastName}
          />
        </Form.Group>
      </Table.Col>
      <Table.Col></Table.Col>
      <Table.Col></Table.Col>
      <Table.Col>
        <Form.Group>
          <Form.Select id="role" name="role" errors={errors} onChange={onChange} onBlur={onBlur} value={user.role}>
            <option value="admin">Admin</option>
            <option value="consultant">Consultant</option>
          </Form.Select>
        </Form.Group>
      </Table.Col>
    </>
  );
}

Component.propTypes = {
 

The test :

import { describe, expect, it } from 'vitest';
import { act, render, screen } from '@testing-library/react';
import { RelayEnvironmentProvider } from 'react-relay/hooks';
import { MockPayloadGenerator, createMockEnvironment } from 'relay-test-utils';
import userEvent from '@testing-library/user-event';

import Component from '../../src/components/UserForm';

describe('UserForm', () => {
  it('submit the form fields', async () => {
    const environment = createMockEnvironment();
    environment.mock.queueOperationResolver((operation) => {
      return MockPayloadGenerator.generate(operation, {
        User() {
          return {
            id: 'user-1',
            firstName: 'Chris',
            lastName: 'Koo',
            role: 'admin',
          };
        },
      });
    });

    const user = {
      id: 'user-1',
      firstName: 'Chris',
      lastName: 'Koo',
      role: 'admin',
    };

    render(
      <RelayEnvironmentProvider environment={environment}>
        <Component user={user} />
      </RelayEnvironmentProvider>,
    );

    await userEvent.type(screen.getByLabelText('Voornaam'), 'Chris');
    await userEvent.type(screen.getByLabelText('Achternaam'), 'Koo');
    await userEvent.type(screen.getByLabelText('Gebruiker type'), 'admin');
    await userEvent.click(screen.getByRole('button', { name: 'Opslaan' }));

    const mutationOperation = environment.mock.getMostRecentOperation();
    expect(mutationOperation.request.variables.input).toEqual({
      id: 'user-1',
      firstName: 'Chris',
      lastName: 'Koo',
      role: 'admin',
    });

    act(() => {
      environment.mock.resolveMostRecentOperation((operation) =>
        MockPayloadGenerator.generate(operation, {
          UpdateUser() {
            return {
              user: {
                id: 'user-1',
                databaseId: 1,
                firstName: 'Chris',
                lastName: 'Koo',
                role: 'admin',
              },
              errors: [],
            };
          },
        }),
      );
    });
  });
});

I am getting this error :

Invariant Violation: Relay: Expected to receive an object where ...UserForm_user was spread, but the fragment reference was not found`. This is most likely the result of:

  • Forgetting to spread UserForm_user in useFragment()'s parent's fragment.
  • Conditionally fetching UserForm_user but unconditionally passing a fragment reference prop to useFragment(). If the parent fragment only fetches the fragment conditionally - with e.g. @include, @skip, or inside a ... on SomeType { } spread - then the fragment reference will not exist. In this case, pass null if the conditions for evaluating the fragment are not met (e.g. if the @include(if) value is false.)

can you help with it?

0

Browse other questions tagged or ask your own question.