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

fix: don't reject asyncErrors #4675

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
120 changes: 70 additions & 50 deletions src/__tests__/handleSubmit.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { noop } from 'lodash'

describe('handleSubmit', () => {
it('should stop if sync validation fails', () => {
expect.assertions(7)

const values = { foo: 'bar', baz: 42 }
const submit = jest.fn().mockImplementation(() => 69)
const startSubmit = jest.fn()
Expand Down Expand Up @@ -33,6 +35,8 @@ describe('handleSubmit', () => {
})

it('should stop and return errors if sync validation fails', () => {
expect.assertions(8)

const values = { foo: 'bar', baz: 42 }
const submit = jest.fn().mockImplementation(() => 69)
const syncErrors = { foo: 'error' }
Expand Down Expand Up @@ -65,6 +69,8 @@ describe('handleSubmit', () => {
})

it('should return result of sync submit', () => {
expect.assertions(7)

const values = { foo: 'bar', baz: 42 }
const submit = jest.fn().mockImplementation(() => 69)
const dispatch = noop
Expand Down Expand Up @@ -95,6 +101,8 @@ describe('handleSubmit', () => {
})

it('should not submit if async validation fails', () => {
expect.assertions(8)

const values = { foo: 'bar', baz: 42 }
const submit = jest.fn().mockImplementation(() => 69)
const dispatch = noop
Expand All @@ -114,23 +122,21 @@ describe('handleSubmit', () => {
values
}

return handleSubmit(submit, props, true, asyncValidate, ['foo', 'baz'])
.then(() => {
throw new Error('Expected to fail')
})
.catch(result => {
expect(result).toBe(values)
expect(asyncValidate).toHaveBeenCalledWith()
expect(submit).not.toHaveBeenCalled()
expect(startSubmit).not.toHaveBeenCalled()
expect(stopSubmit).not.toHaveBeenCalled()
expect(touch).toHaveBeenCalledWith('foo', 'baz')
expect(setSubmitSucceeded).not.toHaveBeenCalled()
expect(setSubmitFailed).toHaveBeenCalledWith('foo', 'baz')
})
return handleSubmit(submit, props, true, asyncValidate, ['foo', 'baz']).then(result => {
expect(result).toBe(values)
expect(asyncValidate).toHaveBeenCalledWith()
expect(submit).not.toHaveBeenCalled()
expect(startSubmit).not.toHaveBeenCalled()
expect(stopSubmit).not.toHaveBeenCalled()
expect(touch).toHaveBeenCalledWith('foo', 'baz')
expect(setSubmitSucceeded).not.toHaveBeenCalled()
expect(setSubmitFailed).toHaveBeenCalledWith('foo', 'baz')
})
})

it('should call onSubmitFail with async errors and dispatch if async validation fails and onSubmitFail is defined', () => {
expect.assertions(13)

const values = { foo: 'bar', baz: 42 }
const submit = jest.fn().mockImplementation(() => 69)
const dispatch = noop
Expand All @@ -152,28 +158,26 @@ describe('handleSubmit', () => {
values
}

return handleSubmit(submit, props, true, asyncValidate, ['foo', 'baz'])
.then(() => {
throw new Error('Expected to fail')
})
.catch(result => {
expect(result).toBe(values)
expect(asyncValidate).toHaveBeenCalledWith()
expect(submit).not.toHaveBeenCalled()
expect(startSubmit).not.toHaveBeenCalled()
expect(stopSubmit).not.toHaveBeenCalled()
expect(onSubmitFail).toHaveBeenCalled()
expect(onSubmitFail.mock.calls[0][0]).toEqual(values)
expect(onSubmitFail.mock.calls[0][1]).toEqual(dispatch)
expect(onSubmitFail.mock.calls[0][2]).toBe(null)
expect(onSubmitFail.mock.calls[0][3]).toEqual(props)
expect(touch).toHaveBeenCalledWith('foo', 'baz')
expect(setSubmitSucceeded).not.toHaveBeenCalled()
expect(setSubmitFailed).toHaveBeenCalledWith('foo', 'baz')
})
return handleSubmit(submit, props, true, asyncValidate, ['foo', 'baz']).then(result => {
expect(result).toBe(values)
expect(asyncValidate).toHaveBeenCalledWith()
expect(submit).not.toHaveBeenCalled()
expect(startSubmit).not.toHaveBeenCalled()
expect(stopSubmit).not.toHaveBeenCalled()
expect(onSubmitFail).toHaveBeenCalled()
expect(onSubmitFail.mock.calls[0][0]).toEqual(values)
expect(onSubmitFail.mock.calls[0][1]).toEqual(dispatch)
expect(onSubmitFail.mock.calls[0][2]).toBe(null)
expect(onSubmitFail.mock.calls[0][3]).toEqual(props)
expect(touch).toHaveBeenCalledWith('foo', 'baz')
expect(setSubmitSucceeded).not.toHaveBeenCalled()
expect(setSubmitFailed).toHaveBeenCalledWith('foo', 'baz')
})
})

it('should not submit if async validation fails and return rejected promise', () => {
it('should not submit if async validation fails and returns errors', () => {
expect.assertions(8)

const values = { foo: 'bar', baz: 42 }
const submit = jest.fn().mockImplementation(() => 69)
const dispatch = noop
Expand All @@ -194,23 +198,21 @@ describe('handleSubmit', () => {
values
}

return handleSubmit(submit, props, true, asyncValidate, ['foo', 'baz'])
.then(() => {
throw new Error('Expected to fail')
})
.catch(result => {
expect(result).toBe(asyncErrors)
expect(asyncValidate).toHaveBeenCalledWith()
expect(submit).not.toHaveBeenCalled()
expect(startSubmit).not.toHaveBeenCalled()
expect(stopSubmit).not.toHaveBeenCalled()
expect(touch).toHaveBeenCalledWith('foo', 'baz')
expect(setSubmitSucceeded).not.toHaveBeenCalled()
expect(setSubmitFailed).toHaveBeenCalledWith('foo', 'baz')
})
return handleSubmit(submit, props, true, asyncValidate, ['foo', 'baz']).then(result => {
expect(result).toBe(asyncErrors)
expect(asyncValidate).toHaveBeenCalledWith()
expect(submit).not.toHaveBeenCalled()
expect(startSubmit).not.toHaveBeenCalled()
expect(stopSubmit).not.toHaveBeenCalled()
expect(touch).toHaveBeenCalledWith('foo', 'baz')
expect(setSubmitSucceeded).not.toHaveBeenCalled()
expect(setSubmitFailed).toHaveBeenCalledWith('foo', 'baz')
})
})

it('should sync submit if async validation passes', () => {
expect.assertions(8)

const values = { foo: 'bar', baz: 42 }
const submit = jest.fn().mockImplementation(() => 69)
const dispatch = noop
Expand Down Expand Up @@ -243,6 +245,8 @@ describe('handleSubmit', () => {
})

it('should async submit if async validation passes', () => {
expect.assertions(8)

const values = { foo: 'bar', baz: 42 }
const submit = jest.fn().mockImplementation(() => Promise.resolve(69))
const dispatch = noop
Expand Down Expand Up @@ -275,6 +279,8 @@ describe('handleSubmit', () => {
})

it('should set submit errors if async submit fails', () => {
expect.assertions(8)

const values = { foo: 'bar', baz: 42 }
const submitErrors = { foo: 'submit error' }
const submit = jest
Expand Down Expand Up @@ -310,6 +316,8 @@ describe('handleSubmit', () => {
})

it('should not set errors if rejected value not a SubmissionError', () => {
expect.assertions(9)

const values = { foo: 'bar', baz: 42 }
const submitErrors = { foo: 'submit error' }
const submit = jest.fn().mockImplementation(() => Promise.reject(submitErrors))
Expand All @@ -336,8 +344,8 @@ describe('handleSubmit', () => {
return handleSubmit(submit, props, true, asyncValidate, ['foo', 'baz'])
.then(resolveSpy, errorSpy)
.then(() => {
expect(resolveSpy).not.toHaveBeenCalled()
expect(errorSpy).toHaveBeenCalledWith(submitErrors)
expect(resolveSpy).toHaveBeenCalledWith(submitErrors)
expect(errorSpy).not.toHaveBeenCalled()
expect(asyncValidate).toHaveBeenCalledWith()
expect(submit).toHaveBeenCalledWith(values, dispatch, props)
expect(startSubmit).toHaveBeenCalled()
Expand All @@ -349,6 +357,8 @@ describe('handleSubmit', () => {
})

it('should set submit errors if async submit fails and return rejected promise', () => {
expect.assertions(8)

const values = { foo: 'bar', baz: 42 }
const submitErrors = { foo: 'submit error' }
const submit = jest
Expand Down Expand Up @@ -384,6 +394,8 @@ describe('handleSubmit', () => {
})

it('should submit when there are old submit errors and persistentSubmitErrors is enabled', () => {
expect.assertions(1)

const values = { foo: 'bar', baz: 42 }
const submit = jest.fn().mockImplementation(() => 69)
const startSubmit = jest.fn()
Expand All @@ -408,6 +420,8 @@ describe('handleSubmit', () => {
})

it('should not swallow errors', () => {
expect.assertions(2)

const values = { foo: 'bar', baz: 42 }
const submit = jest.fn().mockImplementation(() => {
throw new Error('spline reticulation failed')
Expand All @@ -434,6 +448,8 @@ describe('handleSubmit', () => {
})

it('should not swallow async errors', () => {
expect.assertions(3)

const values = { foo: 'bar', baz: 42 }
const submit = jest
.fn()
Expand Down Expand Up @@ -466,6 +482,8 @@ describe('handleSubmit', () => {
})

it('should not swallow async errors when form is invalid', () => {
expect.assertions(8)

const values = { foo: 'bar', baz: 42 }
const submit = jest.fn().mockImplementation(() => 69)
const syncErrors = { baz: 'sync error' }
Expand Down Expand Up @@ -500,6 +518,8 @@ describe('handleSubmit', () => {
})

it('should dispatch submission', () => {
expect.assertions(8)

const values = { foo: 'bar', baz: 42 }
const mockAction = {}
const submit = jest.fn().mockImplementation(() => mockAction)
Expand Down
2 changes: 1 addition & 1 deletion src/handleSubmit.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ const handleSubmit = (
if (onSubmitFail) {
onSubmitFail(asyncErrors, dispatch, null, props)
}
return Promise.reject(asyncErrors)
return asyncErrors
})
} else {
return executeSubmit(submit, fields, props)
Expand Down