feat: async validate() (#3797)

This commit is contained in:
Jonas Galvez 2018-08-25 06:42:00 -03:00 committed by Pooya Parsa
parent a2168ae4f9
commit 608b913b8a
5 changed files with 84 additions and 10 deletions

View File

@ -292,11 +292,28 @@ async function render (to, from, next) {
// Call .validate() // Call .validate()
let isValid = true let isValid = true
Components.forEach((Component) => { let validationError
if (!isValid) return try {
if (typeof Component.options.validate !== 'function') return for (const Component of Components) {
isValid = Component.options.validate(app.context) if (typeof Component.options.validate !== 'function') {
continue
}
isValid = await Component.options.validate(app.context)
if (!isValid) {
break
}
}
} catch (validationError) {
// ...If .validate() threw an error
this.error({
statusCode: validationError.statusCode || '500',
message: validationError.message
}) })
return next()
}
// ...If .validate() returned false // ...If .validate() returned false
if (!isValid) { if (!isValid) {
this.error({ statusCode: 404, message: `<%= messages.error_404 %>` }) this.error({ statusCode: 404, message: `<%= messages.error_404 %>` })

View File

@ -154,11 +154,28 @@ export default async (ssrContext) => {
** Call .validate() ** Call .validate()
*/ */
let isValid = true let isValid = true
Components.forEach((Component) => { let validationError
if (!isValid) return try {
if (typeof Component.options.validate !== 'function') return for (const Component of Components) {
isValid = Component.options.validate(app.context) if (typeof Component.options.validate !== 'function') {
continue
}
isValid = await Component.options.validate(app.context)
if (!isValid) {
break
}
}
} catch (validationError) {
// ...If .validate() threw an error
app.context.error({
statusCode: validationError.statusCode || '500',
message: validationError.message
}) })
return renderErrorPage()
}
// ...If .validate() returned false // ...If .validate() returned false
if (!isValid) { if (!isValid) {
// Don't server-render the page in generate mode // Don't server-render the page in generate mode

View File

@ -123,12 +123,27 @@ describe('basic browser', () => {
expect(error.message).toBe('This page could not be found') expect(error.message).toBe('This page could not be found')
}) })
test('/validate-async should display a 404', async () => {
await page.nuxt.navigate('/validate-async')
const error = await page.nuxt.errorData()
expect(error.statusCode).toBe(404)
expect(error.message).toBe('This page could not be found')
})
test('/validate?valid=true', async () => { test('/validate?valid=true', async () => {
await page.nuxt.navigate('/validate?valid=true') await page.nuxt.navigate('/validate?valid=true')
expect(await page.$text('h1')).toBe('I am valid') expect(await page.$text('h1')).toBe('I am valid')
}) })
test('/validate-async?valid=true', async () => {
await page.nuxt.navigate('/validate-async?valid=true')
expect(await page.$text('h1')).toBe('I am valid')
})
test('/redirect', async () => { test('/redirect', async () => {
await page.nuxt.navigate('/redirect') await page.nuxt.navigate('/redirect')

View File

@ -0,0 +1,15 @@
<template>
<h1>I am valid</h1>
</template>
<script>
export default {
validate({ query }) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(Boolean(query.valid))
}, 500)
})
}
}
</script>

View File

@ -96,11 +96,21 @@ describe('basic ssr', () => {
expect(html.includes('This page could not be found')).toBe(true) expect(html.includes('This page could not be found')).toBe(true)
}) })
test('/validate-async should display a 404', async () => {
const { html } = await nuxt.renderRoute('/validate-async')
expect(html.includes('This page could not be found')).toBe(true)
})
test('/validate?valid=true', async () => { test('/validate?valid=true', async () => {
const { html } = await nuxt.renderRoute('/validate?valid=true') const { html } = await nuxt.renderRoute('/validate?valid=true')
expect(html.includes('<h1>I am valid</h1>')).toBe(true) expect(html.includes('<h1>I am valid</h1>')).toBe(true)
}) })
test('/validate-async?valid=true', async () => {
const { html } = await nuxt.renderRoute('/validate-async?valid=true')
expect(html.includes('<h1>I am valid</h1>')).toBe(true)
})
test('/before-enter', async () => { test('/before-enter', async () => {
const { html } = await nuxt.renderRoute('/before-enter') const { html } = await nuxt.renderRoute('/before-enter')
expect(html.includes('<h1>Index page</h1>')).toBe(true) expect(html.includes('<h1>Index page</h1>')).toBe(true)