lfades / next-with-apollo

Apollo HOC for Next.js
MIT License
765 stars 79 forks source link

Loading prop in MockedProvider is always true #101

Open Emiliano-Bucci opened 4 years ago

Emiliano-Bucci commented 4 years ago

Is it possible that with the new version of the withApollo the loading prop is always true? It seems that jest don't await anymore to the promise to be resolved.

lfades commented 4 years ago

@Emiliano-Bucci The API changed in the new version and SSR is no longer enabled by default, if you already checked that please give more details, a reproduction can be great too.

Emiliano-Bucci commented 4 years ago

@lfades Yeah, i think about that a bit later. In any case, i'm using it this way:

import { getDataFromTree } from '@apollo/react-ssr'

export default WithApollo(Index, {
  getDataFromTree,
})

And this is my WithApollo component:

import React from 'react'
import withApollo from 'next-with-apollo'
import ApolloClient from 'apollo-client'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { BatchHttpLink } from 'apollo-link-batch-http'
import { ApolloProvider } from '@apollo/react-hooks'

const httpLink = new BatchHttpLink({
  uri: process.env.graphqlEndpoint,
})

export const WithApollo = withApollo(
  ({ initialState }) => {
    return new ApolloClient({
      link: httpLink,
      cache: new InMemoryCache({
        addTypename: true,
      }).restore(initialState || {}),
    })
  },
  {
    render: ({ Page, props }) => {
      return (
        <ApolloProvider client={props.apollo}>
          <Page {...props} />
        </ApolloProvider>
      )
    },
  },
)

and even removing the getDataFromTree function, the loading prop is still true. About the reproduction i believe i can make one in a few days, in case you still need it :)

lfades commented 4 years ago

@Emiliano-Bucci Could you move httpLink to be inside the function that returns the Apollo Client and see if that changes something? like this:

export const WithApollo = withApollo(
  ({ initialState }) => {
    const httpLink = new BatchHttpLink({
      uri: process.env.graphqlEndpoint,
    })
    return new ApolloClient({
      link: httpLink,
      cache: new InMemoryCache({
        addTypename: true,
      }).restore(initialState || {}),
    })
  },
Emiliano-Bucci commented 4 years ago

@lfades Done but sadly nothing change :/

lfades commented 4 years ago

@Emiliano-Bucci Ok so your example looks very similar to my integration tests, that are currently working, so maybe it's because of the version of your Apollo packages, what versions are you using?. You can check the integration tests to see what versions are working there.

Emiliano-Bucci commented 4 years ago

@lfades Ok thanks, i will take a look :)

Emiliano-Bucci commented 4 years ago

@lfades I've tried to downgrade to the same versions that you have but still no luck; the only thing i've noticed is that you don't have installed @apollo/react-testing form where i take the MockedProvider, though i don't know if this lib is relevant or not. I will keep investigating, thanks for the support :)

Emiliano-Bucci commented 4 years ago

@lfades Don't know if this matters, but i've created a simple test with a simple query, and i'm getting this warning:

A worker process has failed to exit gracefully and has been force exited. This is likely caused by tests leaking due to improper teardown. Try running with --runInBand --detectOpenHandles to find leaks

This is my component file:

import React from 'react'
import gql from 'graphql-tag'
import { useQuery } from '@apollo/react-hooks'
import { render } from '@testing-library/react'
import { MockedProvider } from '@apollo/react-testing'
import { WithApollo } from 'components/WithApollo'

const query = gql`
  query Trekking {
    trekking {
      nodes {
        id
        slug
      }
    }
  }
`

const TestApollo = () => {
  const { data, loading, error } = useQuery(query)

  console.log('Apollo props', {
    data,
    loading,
    error,
  })

  return <div>Test Apollo loading</div>
}

export const TestWithApollo = WithApollo(TestApollo)

const mockResponse = {
  request: {
    query,
  },
  result: {
    data: {},
  },
}

describe('Tests', () => {
  test('Tests', async () => {
    const { container } = render(
      <MockedProvider addTypename={false} mocks={[mockResponse]}>
        <TestWithApollo />
      </MockedProvider>,
    )

    await waitForApolloMocks(1)

    expect(container).toMatchSnapshot()
  })
})

And this is what i get from the console:

 console.log src/testApollo.test.tsx:22
    Apollo props { data: undefined, loading: true, error: undefined }

Can be possibly related?

I've also noticed one really strange thing: If for some reason i change the uri inside my link property inside the withApollo HOC, i get this error:

Network error: only absolute urls are supported

It seems that during tests Apollo is trying to make a network request... :/

Emiliano-Bucci commented 4 years ago

@lfades I continue to investigate; i've made a simple test removing the <MockedProvider /> from the test and, surprisingly jest didn't throw the typical error when you don't include the <MockedProvider />. When you have time, could you please make a simple test by using the <MockedProvider /> in your integration? Thanks :)

Edit: Ok, i can confirm that there's some weird issue happening here: if i remove the WithApollo HOC and normally export the page, and inside the tests i use the <MockedProvider />, the mocked query works correctly; if i add again the WithApollo HOC it seems that, somehow, the <MockedProvider /> is being ignored :/

I've fixed it doing this:

export const WithApollo = withApollo(
  ({ initialState }) => {
    const link = new HttpLink({
      uri: process.env.graphqlEndpoint,
    })
    return new ApolloClient({
      link,
      cache: new InMemoryCache({
        addTypename: true,
      }).restore(initialState || {}),
    })
  },
  {
    render: ({ Page, props }) => {
      if (process.env.NODE_ENV === 'test') {
        return <Page />
      }

      return (
        <ApolloProvider client={props.apollo}>
          <Page />
        </ApolloProvider>
      )
    },
  },
)