-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Form action attribute async validation (#17)
* Add action attribute fo form and async validation * add npm dev script to start a test browser in dev mode * React Strict Mode fixed for array context * 3.0.0-alpha.0 * clean code comments * Docz styles (#16) * 3.0.0-alpha.0 * DOCZ_STYLES docz styles changes * clean code comments Co-authored-by: Antonio <[email protected]> Co-authored-by: Antonio Pangallo <[email protected]> * fix typo in docz * unit test improved * improve doc * improve doc * improve doc * cover usetheform * remove cover usetheform * update doc * Improve array collection autoIndex * 3.0.0-alpha.1 * improve examples * improve examples * withIndex - auto indexing fields * 3.0.0-alpha.2 * withIndex - auto indexing fields * removing comments * fix index - uniqueid - array collection * 3.0.0-alpha.3 * add ON_RUN_ASYNC status * reducers applied on fields removal from collections * 3.0.0-alpha.4 * adding codesandbox example * optimize Form using useMemo and React.memo * 3.0.0-alpha.5 * fix radios reset feature * 3.0.0-alpha.6 * added unit tests for radio buttons into nested object collection * 3.0.0-alpha.7 * improve FormContext performances * 3.0.0-alpha.8 * fix useNameProp * 3.0.0-alpha.9 * unit test Form dynamic * fix example * refactoring useField * added submitted and submittingAttempts counters * refactoring useForm and useCollection * 3.0.0-alpha.10 * fix number input type * 3.0.0-beta.0 * add validators flag argument to onInit, onChange, onReset funcs * 3.0.0-beta.1 * 3.0.0 * add unit test for some inputs type * removing unused code * fix audit Co-authored-by: Antonio <[email protected]> Co-authored-by: Antonio Pangallo <[email protected]>
- Loading branch information
1 parent
f7c833b
commit 44b8389
Showing
83 changed files
with
23,843 additions
and
17,407 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
**/build/** | ||
**/build/** | ||
**/dev/** | ||
**/node_modules/** |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,5 +5,6 @@ node_modules | |
.DS_Store | ||
dist | ||
build | ||
dev | ||
coverage | ||
_config.yml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,188 @@ | ||
import React from "react"; | ||
import { | ||
render, | ||
cleanup, | ||
fireEvent, | ||
waitForElement, | ||
act | ||
} from "@testing-library/react"; | ||
|
||
import { | ||
SimpleFormWithAsyncStrictMode, | ||
expectedInitialState | ||
} from "./helpers/components/SimpleFormWithAsync"; | ||
|
||
const mountForm = ({ props = {} } = {}) => | ||
render( | ||
<React.StrictMode> | ||
<SimpleFormWithAsyncStrictMode {...props} /> | ||
</React.StrictMode> | ||
); | ||
|
||
const onInit = jest.fn(state => state); | ||
const onChange = jest.fn(state => state); | ||
const onReset = jest.fn(state => state); | ||
const onSubmit = jest.fn(state => state); | ||
|
||
afterEach(cleanup); | ||
|
||
describe("Async Validation Form StrictMode => Async Validation", () => { | ||
beforeEach(() => { | ||
onInit.mockClear(); | ||
onChange.mockClear(); | ||
onReset.mockClear(); | ||
onSubmit.mockClear(); | ||
}); | ||
|
||
it("should run Async validators at Form initialization time", async () => { | ||
const props = { onInit, onSubmit, onChange, onReset }; | ||
|
||
const { getByTestId } = mountForm({ props }); | ||
|
||
const submit = getByTestId("submit"); | ||
|
||
const asyncStartUsername = await waitForElement(() => | ||
getByTestId("asyncStartUsername") | ||
); | ||
expect(asyncStartUsername).toBeDefined(); | ||
|
||
const asyncStartCity = await waitForElement(() => | ||
getByTestId("asyncStartCity") | ||
); | ||
expect(asyncStartCity).toBeDefined(); | ||
|
||
const asyncErrorDetails = await waitForElement(() => | ||
getByTestId("asyncErrorDetails") | ||
); | ||
expect(asyncErrorDetails).toBeDefined(); | ||
|
||
expect(onInit).toHaveReturnedWith(expectedInitialState); | ||
expect(submit.disabled).toBe(true); | ||
}); | ||
|
||
it("should run Async validators on fields or Collections changes", async () => { | ||
const props = { onInit, onSubmit, onChange, onReset }; | ||
|
||
const { getByTestId } = mountForm({ props }); | ||
|
||
const submit = getByTestId("submit"); | ||
const reset = getByTestId("reset"); | ||
|
||
const addInputs = getByTestId("addInput"); | ||
const removeInputs = getByTestId("removeInput"); | ||
|
||
const asyncErrorDetails = await waitForElement(() => | ||
getByTestId("asyncErrorDetails") | ||
); | ||
expect(asyncErrorDetails).toBeDefined(); | ||
|
||
const details = getByTestId("details"); | ||
|
||
act(() => { | ||
details.focus(); | ||
fireEvent.change(details, { target: { value: "3331234567" } }); | ||
details.blur(); | ||
}); | ||
|
||
expect(details.value).toBe("3331234567"); | ||
|
||
const asyncSuccessDetails = await waitForElement(() => | ||
getByTestId("asyncSuccessDetails") | ||
); | ||
|
||
expect(asyncSuccessDetails).toBeDefined(); | ||
|
||
const email = getByTestId("email"); | ||
|
||
act(() => { | ||
email.focus(); | ||
fireEvent.change(email, { target: { value: "[email protected]" } }); | ||
email.blur(); | ||
}); | ||
|
||
expect(email.value).toBe("[email protected]"); | ||
expect(submit.disabled).toBe(false); | ||
|
||
fireEvent.click(submit); | ||
|
||
let asyncErrorCollection = await waitForElement(() => | ||
getByTestId("asyncError") | ||
); | ||
|
||
expect(asyncErrorCollection).toBeDefined(); | ||
|
||
const submittedCounter = getByTestId("submittedCounter"); | ||
expect(submittedCounter.textContent).toBe("0"); | ||
|
||
fireEvent.click(addInputs); | ||
fireEvent.click(addInputs); | ||
fireEvent.click(submit); | ||
|
||
const asyncSuccessCollection = await waitForElement(() => | ||
getByTestId("asyncSuccess") | ||
); | ||
|
||
expect(asyncSuccessCollection).toBeDefined(); | ||
expect(submittedCounter.textContent).toBe("1"); | ||
|
||
fireEvent.click(removeInputs); | ||
fireEvent.click(submit); | ||
|
||
asyncErrorCollection = await waitForElement(() => | ||
getByTestId("asyncError") | ||
); | ||
|
||
expect(asyncErrorCollection).toBeDefined(); | ||
|
||
fireEvent.click(removeInputs); | ||
fireEvent.click(reset); | ||
expect(onReset).toHaveReturnedWith(expectedInitialState); | ||
|
||
const asyncNotStartedYetDetails = getByTestId("asyncNotStartedYetDetails"); | ||
expect(asyncNotStartedYetDetails).toBeDefined(); | ||
|
||
const asyncNotStartedYetCity = getByTestId("asyncNotStartedYetCity"); | ||
expect(asyncNotStartedYetCity).toBeDefined(); | ||
|
||
const asyncNotStartedYetUsername = getByTestId( | ||
"asyncNotStartedYetUsername" | ||
); | ||
expect(asyncNotStartedYetUsername).toBeDefined(); | ||
|
||
act(() => { | ||
details.focus(); | ||
details.blur(); | ||
}); | ||
|
||
const asyncStartDetailsAfterReset = await waitForElement(() => | ||
getByTestId("asyncStartDetails") | ||
); | ||
expect(asyncStartDetailsAfterReset).toBeDefined(); | ||
|
||
const asyncErrorDetailsAfterReset = await waitForElement(() => | ||
getByTestId("asyncErrorDetails") | ||
); | ||
expect(asyncErrorDetailsAfterReset).toBeDefined(); | ||
|
||
const username = getByTestId("username"); | ||
const city = getByTestId("city"); | ||
act(() => { | ||
username.focus(); | ||
username.blur(); | ||
city.focus(); | ||
city.blur(); | ||
}); | ||
|
||
const [ | ||
asyncStartUsernameAfterReset, | ||
asyncStartCityAfterReset | ||
] = await waitForElement(() => | ||
Promise.all([ | ||
getByTestId("asyncStartUsername"), | ||
getByTestId("asyncStartCity") | ||
]) | ||
); | ||
expect(asyncStartUsernameAfterReset).toBeDefined(); | ||
expect(asyncStartCityAfterReset).toBeDefined(); | ||
}); | ||
}); |
Oops, something went wrong.