Skip to content

Commit

Permalink
Add additional pageProps check (vercel#15667)
Browse files Browse the repository at this point in the history
`pageProps` should always be defined to ensure everything is working as expected although to prevent a breaking change this adds an additional check before attempting to access `pageProps` before hydration. It also adds tests to prevent regressing on this

Closes: vercel#15647
  • Loading branch information
ijjk authored and LauraBeatris committed Sep 1, 2020
1 parent 47661ad commit 85038cf
Show file tree
Hide file tree
Showing 6 changed files with 172 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/next/client/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ if (
!(
page === '/_error' &&
hydrateProps &&
hydrateProps.pageProps &&
hydrateProps.pageProps.statusCode === '404'
)
) {
Expand Down
24 changes: 24 additions & 0 deletions test/integration/no-page-props/pages/_app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
function App({ Component, pageProps }) {
return <Component {...pageProps} />
}

if (typeof window !== 'undefined') {
window.uncaughtErrors = []
window.addEventListener('error', (err) => {
window.uncaughtErrors.push(err)
})
window.addEventListener('unhandledrejection', (err) => {
window.uncaughtErrors.push(err)
})
}

App.getInitialProps = async ({ Component, ctx }) => {
const props = {}

if (Component.getInitialProps) {
props.initialProps = await Component.getInitialProps(ctx)
}
return props
}

export default App
11 changes: 11 additions & 0 deletions test/integration/no-page-props/pages/gsp.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export default function Gsp() {
return <p id="gsp">getStaticProps</p>
}

export const getStaticProps = () => {
return {
props: {
hello: 'world',
},
}
}
11 changes: 11 additions & 0 deletions test/integration/no-page-props/pages/gssp.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export default function Gssp() {
return <p id="gssp">getServerSideProps</p>
}

export const getServerSideProps = () => {
return {
props: {
hello: 'world',
},
}
}
21 changes: 21 additions & 0 deletions test/integration/no-page-props/pages/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import Link from 'next/link'

export default function Index() {
return (
<>
<p id="index">index</p>
<Link href="/gsp">
<a id="to-gsp">to gsp</a>
</Link>
<br />
<Link href="/gssp">
<a id="to-gssp">to gssp</a>
</Link>
<br />
<Link href="/non-existent">
<a id="to-404">to non-existent</a>
</Link>
<br />
</>
)
}
104 changes: 104 additions & 0 deletions test/integration/no-page-props/test/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/* eslint-env jest */

import { join } from 'path'
import webdriver from 'next-webdriver'
import {
nextBuild,
nextStart,
findPort,
killApp,
launchApp,
} from 'next-test-utils'

jest.setTimeout(1000 * 60 * 1)
const appDir = join(__dirname, '..')
let app
let appPort

const runTests = () => {
it('should load auto-export page correctly', async () => {
const browser = await webdriver(appPort, '/')
expect(await browser.elementByCss('#index').text()).toBe('index')
expect(await browser.eval('window.uncaughtErrors')).toEqual([])
})

it('should load getStaticProps page correctly', async () => {
const browser = await webdriver(appPort, '/gsp')
expect(await browser.elementByCss('#gsp').text()).toBe('getStaticProps')
expect(await browser.eval('window.uncaughtErrors')).toEqual([])
})

it('should load getServerSideProps page correctly', async () => {
const browser = await webdriver(appPort, '/gssp')
expect(await browser.elementByCss('#gssp').text()).toBe(
'getServerSideProps'
)
expect(await browser.eval('window.uncaughtErrors')).toEqual([])
})

it('should load 404 page correctly', async () => {
const browser = await webdriver(appPort, '/non-existent')
expect(await browser.elementByCss('h2').text()).toBe(
'An unexpected error has occurred.'
)
expect(await browser.eval('window.uncaughtErrors')).toEqual([])
})

it('should navigate between pages correctly', async () => {
const browser = await webdriver(appPort, '/')

await browser.eval('window.beforeNav = "hi"')
await browser.elementByCss('#to-gsp').click()
await browser.waitForElementByCss('#gsp')

expect(await browser.elementByCss('#gsp').text()).toBe('getStaticProps')
expect(await browser.eval('window.beforeNav')).toBe('hi')

await browser.back()
await browser.waitForElementByCss('#index')
expect(await browser.eval('window.beforeNav')).toBe('hi')

await browser.elementByCss('#to-gssp').click()
await browser.waitForElementByCss('#gssp')

expect(await browser.elementByCss('#gssp').text()).toBe(
'getServerSideProps'
)
expect(await browser.eval('window.beforeNav')).toBe('hi')

await browser.back()
await browser.waitForElementByCss('#index')
expect(await browser.eval('window.beforeNav')).toBe('hi')

await browser.elementByCss('#to-404').click()
await browser.waitForElementByCss('h2')
expect(await browser.eval('window.beforeNav')).toBe(null)
expect(await browser.elementByCss('h2').text()).toBe(
'An unexpected error has occurred.'
)
expect(await browser.eval('window.uncaughtErrors')).toEqual([])
})
}

describe('Error no pageProps', () => {
describe('dev mode', () => {
beforeAll(async () => {
appPort = await findPort()
app = await launchApp(appDir, appPort)
})
afterAll(() => killApp(app))

runTests()
})

describe('production mode', () => {
beforeAll(async () => {
await nextBuild(appDir)
appPort = await findPort()
app = await nextStart(appDir, appPort)
})
afterAll(() => killApp(app))

runTests()
})
})

0 comments on commit 85038cf

Please sign in to comment.