Skip to content
This repository has been archived by the owner on May 6, 2022. It is now read-only.

Commit

Permalink
feat(apollo): add apollo client and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Kevin Danikowski authored and Kevin Danikowski committed Jan 15, 2020
1 parent 1c68116 commit 7aee390
Show file tree
Hide file tree
Showing 21 changed files with 765 additions and 176 deletions.
290 changes: 231 additions & 59 deletions package-lock.json

Large diffs are not rendered by default.

9 changes: 8 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"build": "next build",
"dev": "next",
"lint": "npm run lint:eslint",
"lint:eslint": "eslint --ignore-path .gitignore \"**/*.{jsx,js}\"",
"lint:eslint": "eslint \"**/*.{jsx,js}\"",
"lint:prettier": "pretty-quick",
"pretest": "npm run lint",
"semantic-release": "npx --package semantic-release@^16.0.1 semantic-release",
Expand Down Expand Up @@ -167,13 +167,20 @@
"node 10"
],
"dependencies": {
"@apollo/react-hooks": "^3.1.3",
"apollo-cache-inmemory": "^1.6.5",
"apollo-client": "^2.6.8",
"apollo-link-http": "^1.5.16",
"chalk": "3.0.0",
"commander": "4.1.0",
"cpy": "8.0.0",
"cross-spawn": "7.0.1",
"deepmerge": "^4.1.1",
"git-user-name": "^2.0.0",
"got": "10.2.2",
"graphql": "^14.5.8",
"graphql-tag": "^2.10.1",
"isomorphic-unfetch": "^3.0.0",
"make-dir": "3.0.0",
"promisepipe": "3.0.0",
"prompts": "2.3.0",
Expand Down
18 changes: 17 additions & 1 deletion templates/default.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
{
"dependencies": ["next@^9.2.0", "react@^16.12.0", "react-dom@^16.12.0", "prop-types", "dotenv"],
"dependencies": [
"next@^9.2.0",
"react",
"react-dom",
"prop-types",
"@apollo/react-hooks",
"apollo-cache-inmemory",
"apollo-client",
"apollo-link-http",
"isomorphic-unfetch",
"graphql",
"graphql-tag",
"dotenv"
],
"devDependencies": [
"@babel/core",
"@babel/preset-env",
Expand All @@ -14,6 +27,7 @@
"@semantic-release/npm",
"babel-eslint",
"babel-jest",
"babel-plugin-graphql-tag",
"babel-plugin-jsx-remove-data-test-id",
"eslint",
"eslint-config-airbnb",
Expand Down Expand Up @@ -68,6 +82,8 @@
"<rootDir>/.next/",
"<rootDir>/node_modules/",
"<rootDir>/coverage/",
"<rootDir>/src/utils/apollo.jsx",
"<rootDir>/src/pages/_app.jsx",
"/__mocks__/"
],
"coverageReporters": ["clover", "json", "json-summary", "lcov", "text"],
Expand Down
7 changes: 6 additions & 1 deletion templates/default/babelrc
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,10 @@
}
]
],
"plugins": ["jsx-remove-data-test-id"]
"plugins": ["graphql-tag"],
"env": {
"production": {
"plugins": ["jsx-remove-data-test-id"]
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`App controls the root NextJS app 1`] = `
<App
Component={[Function]}
pageProps={Object {}}
/>
`;
23 changes: 23 additions & 0 deletions templates/default/src/__tests__/pages/_app.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react'
import App from '../../pages/_app'

App.displayName = 'App'

jest.mock('../../utils/apollo', () => ({
withApollo: () => async Component => {
const props = await Component.getInitialProps({ Component })

// eslint-disable-next-line
return <Component {...props} />
}
}))

const mockComponent = () => {
return <div>Ok!</div>
}

describe('App', () => {
it('controls the root NextJS app', () => {
expect(<App Component={mockComponent} pageProps={{}} />).toMatchSnapshot()
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
exports[`Pages:Homepage renders the homepage 1`] = `
<DocumentFragment>
<div
class="jsx-3583494339 text-center"
class="jsx-2781750882 text-center"
>
<p
class="jsx-3583494339"
class="jsx-2781750882"
>
Welcome to the boilerplate React app using NextJS!
</p>
<p
class="jsx-3583494339"
class="jsx-2781750882"
>
Try navigating to 
<a
Expand All @@ -22,47 +22,10 @@ exports[`Pages:Homepage renders the homepage 1`] = `
 and observe the URL changing
</p>
<div
class="jsx-2836699520 country-selector"
class="country-selector"
data-testid="loading-div"
>
<div
class="jsx-2836699520"
>
Choose a country!
</div>
<select
class="jsx-2836699520"
data-testid="countries"
>
<option
class="jsx-2836699520"
data-testid="country-option"
value="US"
>
United States
</option>
<option
class="jsx-2836699520"
data-testid="country-option"
value="FR"
>
France
</option>
</select>
<div
class="jsx-2836699520"
>
Your chosen country is:
</div>
<div
class="jsx-563423332 country"
>
<div
class="jsx-563423332"
data-testid="country-name"
>
United States
</div>
</div>
Loading Countries...
</div>
</div>
</DocumentFragment>
Expand Down
4 changes: 4 additions & 0 deletions templates/default/src/__tests__/pages/index/index.test.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import React from 'react'
import { render } from '@testing-library/react'
import { useQuery } from '@apollo/react-hooks'
import App from '../../../pages/index'

jest.mock('@apollo/react-hooks')
useQuery.mockReturnValue({ loading: true })

describe('Pages:Homepage', () => {
it('renders the homepage', () => {
const { asFragment } = render(<App />)
Expand Down
57 changes: 42 additions & 15 deletions templates/default/src/components/atoms/Country/Country.jsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,57 @@
import React from 'react'
import { useQuery } from '@apollo/react-hooks'
import PropTypes from 'prop-types'
import COUNTRY_QUERY from '../../../graphql/queries/country'

const Country = ({ name }) => {
const Country = ({ code }) => {
const { loading, error, data } = useQuery(COUNTRY_QUERY, {
variables: { code }
})

if (!code) {
return (
<div data-testid="no-code-div" className="country">
No country selected
</div>
)
}
if (error) {
return (
<div data-testid="error-div" className="country">
Error!
</div>
)
}
if (loading) {
return (
<div data-testid="loading-div" className="country">
Loading...
</div>
)
}
if (data.country) {
const { name, emoji } = data.country

return (
<div className="country">
<div data-testid="country-name">{name}</div>
<div data-testid="country-emoji">{emoji}</div>
</div>
)
}
return (
<div className="country">
<div data-testid="country-name">{name}</div>
<style jsx>
{`
.country {
border: dashed 1px gray;
padding: 10px;
font-weight: 600;
font-size: 16px;
}
`}
</style>
<div data-testid="no-data-div" className="country">
No Country Data
</div>
)
}

Country.propTypes = {
name: PropTypes.string
code: PropTypes.string
}

Country.defaultProps = {
name: ''
code: ''
}

export default Country
63 changes: 61 additions & 2 deletions templates/default/src/components/atoms/Country/Country.test.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,72 @@
import React from 'react'
import { render } from '@testing-library/react'
import { useQuery } from '@apollo/react-hooks'
import Country from '.'

jest.mock('@apollo/react-hooks')

describe('Country', () => {
let mockQueryResponse = {}

it('should render no country output when no code provided', () => {
mockQueryResponse = {
loading: true
}
useQuery.mockReturnValue(mockQueryResponse)
const { getByTestId } = render(<Country />)

expect(getByTestId('no-code-div').textContent).toBe('No country selected')
})
it('should render error output on error', () => {
mockQueryResponse = {
error: {
graphQLErrors: []
}
}
useQuery.mockReturnValue(mockQueryResponse)
const { getByTestId } = render(<Country code="US" />)

expect(getByTestId('error-div').textContent).toBe('Error!')
})
it('should render loading output when loading', () => {
mockQueryResponse = {
loading: true
}
useQuery.mockReturnValue(mockQueryResponse)
const { getByTestId } = render(<Country code="US" />)

expect(getByTestId('loading-div').textContent).toBe('Loading...')
})

it('should render empty country output when no data', () => {
mockQueryResponse = {
loading: false,
data: {}
}
useQuery.mockReturnValue(mockQueryResponse)
const { getByTestId } = render(<Country code="NONE" />)

expect(getByTestId('no-data-div').textContent).toBe('No Country Data')
})

it('should render a Country', () => {
const { asFragment, getByTestId } = render(<Country name="United States" />)
mockQueryResponse = {
loading: false,
data: {
country: {
name: 'United States',
code: 'US',
emoji: 'E'
}
}
}
useQuery.mockReturnValue(mockQueryResponse)
const { asFragment, getByTestId } = render(<Country code="US" />)
const name = getByTestId('country-name')
const emoji = getByTestId('country-emoji')

expect(name.textContent).toBe('United States')
expect(name.textContent).toBe(mockQueryResponse.data.country.name)
expect(emoji.textContent).toBe(mockQueryResponse.data.country.emoji)
expect(asFragment()).toMatchSnapshot()
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@
exports[`Country should render a Country 1`] = `
<DocumentFragment>
<div
class="jsx-563423332 country"
class="country"
>
<div
class="jsx-563423332"
data-testid="country-name"
>
United States
</div>
<div
data-testid="country-emoji"
>
E
</div>
</div>
</DocumentFragment>
`;
Loading

0 comments on commit 7aee390

Please sign in to comment.