Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Query and QueryVariables type arguments in mockGraphQLQuery and mockGraphQLMutation #5274

Merged
merged 4 commits into from
May 4, 2022

Conversation

pvenable
Copy link
Contributor

@pvenable pvenable commented Apr 21, 2022

When using msw, I find it helpful to supply type arguments to the mock handlers to ensure that my query results are accurate and/or that I am accessing valid variables. This way I can't mess up the result shape or access variables that don't actually exist, and TypeScript catches if these things change so my mocks stay in sync with reality.

This PR adds optional type arguments to mockGraphQLQuery and mockGraphQLMutation to enable such type-safety. When these type arguments are omitted, the types default to what they were before this PR.

Here's an example of how this works in practice:

// Assume e.g. that these are generated Query and QueryVariables types from web/types/graphql.d.ts
type ExampleQuery = {
  id: number
  name: string
}

type ExampleQueryVariables = {
  thisExists: number
}

// In something like web/src/components/Example/Example.test.tsx
describe('Example', () => {
  it('still allows arbitrary Record<string, unknown> data by default', () => {
    mockGraphQLQuery('ExampleQuery', {
      id: '42', // <-- oops!  But still allowed...
      name: 'lol',
    })
  })

  it('still types variables as Record<string, any> by default', () => {
    mockGraphQLQuery('ExampleQuery', (variables) => {
      // oops!  But still allowed...
      const id = variables.thisDoesNotExist

      return {
        id: id,
        name: 'lol',
      }
    })
  })

  it('allows typing Query explicitly for type-safety', () => {
    mockGraphQLQuery<ExampleQuery>('ExampleQuery', {
      id: '42', // Type 'string' is not assignable to type 'number'
      name: 'lol',
    })

    mockGraphQLQuery<ExampleQuery>('ExampleQuery', {
      id: 42, // 👍
      name: 'lol',
    })
  })

  it('allows typing QueryVariables explicitly for type-safety', () => {
    mockGraphQLQuery<ExampleQuery, ExampleQueryVariables>(
      'ExampleQuery',
      (variables) => {
        // Property 'thisDoesNotExist' does not exist on type 'ExampleQueryVariables'.
        const id = variables.thisDoesNotExist

        return {
          id: id,
          name: 'lol',
        }
      }
    )

    mockGraphQLQuery<ExampleQuery, ExampleQueryVariables>(
      'ExampleQuery',
      (variables) => {
        // 👍
        const id = variables.thisExists

        return {
          id: id,
          name: 'lol',
        }
      }
    )
  })
})

@netlify
Copy link

netlify bot commented Apr 21, 2022

Deploy Preview for redwoodjs-docs canceled.

Name Link
🔨 Latest commit e08da05
🔍 Latest deploy log https://app.netlify.com/sites/redwoodjs-docs/deploys/6272b325ed614700094ebb74

@jtoar jtoar added the release:feature This PR introduces a new feature label Apr 21, 2022
export type DataFunction = (
variables: Record<string, any>,
export type DataFunction<
Query extends Record<string, unknown> = Record<string, unknown>,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added the extends Record<string, unknown> constraint this morning as I realized we still need to constrain this when no type argument is passed so that Query isn't inferred as something like number, e.g.:

    // Still does not allow non-Record<string, unknown> data
    // Argument of type 'number' is not assignable to parameter of type
    // 'Record<string, unknown> | DataFunction<Record<string, unknown>, Record<string, any>>'.
    mockGraphQLMutation('ExampleQuery', 42) // ❌

This should align with the previous behavior.

@callingmedic911 callingmedic911 self-requested a review April 25, 2022 17:06
@callingmedic911 callingmedic911 self-assigned this Apr 25, 2022
@jtoar jtoar self-assigned this May 2, 2022
Copy link
Member

@callingmedic911 callingmedic911 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just tried this out locally, looks good! Thanks for the PR @pvenable.

I think we should update documentation for this new support. I can take care of it in separate PR but let me know @pvenable if you want to give it a go. https://redwoodjs.com/docs/testing#mocking-graphql-calls

@pvenable
Copy link
Contributor Author

pvenable commented May 4, 2022

Thanks, @callingmedic911. Please feel free to go ahead with docs, as it may be a while before I would be able to get to that.

@callingmedic911 callingmedic911 enabled auto-merge (squash) May 4, 2022 17:09
@callingmedic911 callingmedic911 merged commit b010a15 into redwoodjs:main May 4, 2022
@jtoar jtoar modified the milestones: next-release, v1.4.0 May 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release:feature This PR introduces a new feature
Projects
No open projects
Status: Done
Development

Successfully merging this pull request may close these issues.

3 participants