upgrade Formik to 2.x; fix some tests with upgrade

This commit is contained in:
Keith Grant
2020-01-16 10:13:19 -08:00
parent f923f07b79
commit 8ef5a6b0e1
14 changed files with 265 additions and 271 deletions

View File

@@ -3015,11 +3015,6 @@
"integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
"dev": true "dev": true
}, },
"asap": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
"integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
},
"asn1": { "asn1": {
"version": "0.2.4", "version": "0.2.4",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
@@ -5193,15 +5188,6 @@
"sha.js": "^2.4.8" "sha.js": "^2.4.8"
} }
}, },
"create-react-context": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.2.3.tgz",
"integrity": "sha512-CQBmD0+QGgTaxDL3OX1IDXYqjkp2It4RIbcb99jS6AEg27Ga+a9G3JtK6SIu0HBwPLZlmwt9F7UwWA4Bn92Rag==",
"requires": {
"fbjs": "^0.8.0",
"gud": "^1.0.0"
}
},
"cross-spawn": { "cross-spawn": {
"version": "5.1.0", "version": "5.1.0",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
@@ -6215,6 +6201,7 @@
"version": "0.1.12", "version": "0.1.12",
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
"integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
"dev": true,
"requires": { "requires": {
"iconv-lite": "~0.4.13" "iconv-lite": "~0.4.13"
} }
@@ -7308,27 +7295,6 @@
"bser": "^2.0.0" "bser": "^2.0.0"
} }
}, },
"fbjs": {
"version": "0.8.17",
"resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz",
"integrity": "sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=",
"requires": {
"core-js": "^1.0.0",
"isomorphic-fetch": "^2.1.1",
"loose-envify": "^1.0.0",
"object-assign": "^4.1.0",
"promise": "^7.1.1",
"setimmediate": "^1.0.5",
"ua-parser-js": "^0.7.18"
},
"dependencies": {
"core-js": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
"integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY="
}
}
},
"fbjs-scripts": { "fbjs-scripts": {
"version": "0.8.3", "version": "0.8.3",
"resolved": "https://registry.npmjs.org/fbjs-scripts/-/fbjs-scripts-0.8.3.tgz", "resolved": "https://registry.npmjs.org/fbjs-scripts/-/fbjs-scripts-0.8.3.tgz",
@@ -7648,19 +7614,47 @@
} }
}, },
"formik": { "formik": {
"version": "1.5.1", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/formik/-/formik-1.5.1.tgz", "resolved": "https://registry.npmjs.org/formik/-/formik-2.1.2.tgz",
"integrity": "sha512-FBWGBKQkcCE4d5b5l2fKccD9d1QxNxw/0bQTRvp3EjzA8Bnjmsm9H/Oy0375UA8P3FPmfJkF4cXLLdEqK7fP5A==", "integrity": "sha512-lbhyV8FQ/hkg4tsVf075Ad9/vDXVbSj6XLW8ooZtAZyNJK8MBYLf1fRJ6iEo2C0pODQneDboYpEUby7nsPW00Q==",
"requires": { "requires": {
"create-react-context": "^0.2.2",
"deepmerge": "^2.1.1", "deepmerge": "^2.1.1",
"hoist-non-react-statics": "^2.5.5", "hoist-non-react-statics": "^3.3.0",
"lodash": "^4.17.11", "lodash": "^4.17.14",
"lodash-es": "^4.17.11", "lodash-es": "^4.17.14",
"prop-types": "^15.6.1",
"react-fast-compare": "^2.0.1", "react-fast-compare": "^2.0.1",
"scheduler": "^0.18.0",
"tiny-warning": "^1.0.2", "tiny-warning": "^1.0.2",
"tslib": "^1.9.3" "tslib": "^1.10.0"
},
"dependencies": {
"hoist-non-react-statics": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
"integrity": "sha512-wbg3bpgA/ZqWrZuMOeJi8+SKMhr7X9TesL/rXMjTzh0p0JUBo3II8DHboYbuIXWRlttrUFxwcu/5kygrCw8fJw==",
"requires": {
"react-is": "^16.7.0"
}
},
"react-is": {
"version": "16.12.0",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz",
"integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q=="
},
"scheduler": {
"version": "0.18.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.18.0.tgz",
"integrity": "sha512-agTSHR1Nbfi6ulI0kYNK0203joW2Y5W4po4l+v03tOoiJKpTBbxpNhWDvqc/4IcOw+KLmSiQLTasZ4cab2/UWQ==",
"requires": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1"
}
},
"tslib": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz",
"integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ=="
}
} }
}, },
"forwarded": { "forwarded": {
@@ -7774,7 +7768,8 @@
"ansi-regex": { "ansi-regex": {
"version": "2.1.1", "version": "2.1.1",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"aproba": { "aproba": {
"version": "1.2.0", "version": "1.2.0",
@@ -7795,12 +7790,14 @@
"balanced-match": { "balanced-match": {
"version": "1.0.0", "version": "1.0.0",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"brace-expansion": { "brace-expansion": {
"version": "1.1.11", "version": "1.1.11",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"balanced-match": "^1.0.0", "balanced-match": "^1.0.0",
"concat-map": "0.0.1" "concat-map": "0.0.1"
@@ -7815,17 +7812,20 @@
"code-point-at": { "code-point-at": {
"version": "1.1.0", "version": "1.1.0",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"concat-map": { "concat-map": {
"version": "0.0.1", "version": "0.0.1",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"console-control-strings": { "console-control-strings": {
"version": "1.1.0", "version": "1.1.0",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"core-util-is": { "core-util-is": {
"version": "1.0.2", "version": "1.0.2",
@@ -7942,7 +7942,8 @@
"inherits": { "inherits": {
"version": "2.0.3", "version": "2.0.3",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"ini": { "ini": {
"version": "1.3.5", "version": "1.3.5",
@@ -7954,6 +7955,7 @@
"version": "1.0.0", "version": "1.0.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"number-is-nan": "^1.0.0" "number-is-nan": "^1.0.0"
} }
@@ -7968,6 +7970,7 @@
"version": "3.0.4", "version": "3.0.4",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"brace-expansion": "^1.1.7" "brace-expansion": "^1.1.7"
} }
@@ -7975,12 +7978,14 @@
"minimist": { "minimist": {
"version": "0.0.8", "version": "0.0.8",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"minipass": { "minipass": {
"version": "2.3.5", "version": "2.3.5",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"safe-buffer": "^5.1.2", "safe-buffer": "^5.1.2",
"yallist": "^3.0.0" "yallist": "^3.0.0"
@@ -7999,6 +8004,7 @@
"version": "0.5.1", "version": "0.5.1",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"minimist": "0.0.8" "minimist": "0.0.8"
} }
@@ -8079,7 +8085,8 @@
"number-is-nan": { "number-is-nan": {
"version": "1.0.1", "version": "1.0.1",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"object-assign": { "object-assign": {
"version": "4.1.1", "version": "4.1.1",
@@ -8091,6 +8098,7 @@
"version": "1.4.0", "version": "1.4.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"wrappy": "1" "wrappy": "1"
} }
@@ -8176,7 +8184,8 @@
"safe-buffer": { "safe-buffer": {
"version": "5.1.2", "version": "5.1.2",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"safer-buffer": { "safer-buffer": {
"version": "2.1.2", "version": "2.1.2",
@@ -8212,6 +8221,7 @@
"version": "1.0.2", "version": "1.0.2",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"code-point-at": "^1.0.0", "code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0", "is-fullwidth-code-point": "^1.0.0",
@@ -8231,6 +8241,7 @@
"version": "3.0.1", "version": "3.0.1",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"ansi-regex": "^2.0.0" "ansi-regex": "^2.0.0"
} }
@@ -8274,12 +8285,14 @@
"wrappy": { "wrappy": {
"version": "1.0.2", "version": "1.0.2",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"yallist": { "yallist": {
"version": "3.0.3", "version": "3.0.3",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
} }
} }
}, },
@@ -8678,7 +8691,8 @@
"hoist-non-react-statics": { "hoist-non-react-statics": {
"version": "2.5.5", "version": "2.5.5",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz",
"integrity": "sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw==" "integrity": "sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw==",
"dev": true
}, },
"home-or-tmp": { "home-or-tmp": {
"version": "2.0.0", "version": "2.0.0",
@@ -9716,7 +9730,8 @@
"is-stream": { "is-stream": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
"dev": true
}, },
"is-string": { "is-string": {
"version": "1.0.4", "version": "1.0.4",
@@ -9787,15 +9802,6 @@
} }
} }
}, },
"isomorphic-fetch": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz",
"integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=",
"requires": {
"node-fetch": "^1.0.1",
"whatwg-fetch": ">=0.10.0"
}
},
"isstream": { "isstream": {
"version": "0.1.2", "version": "0.1.2",
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
@@ -11487,9 +11493,9 @@
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
}, },
"lodash-es": { "lodash-es": {
"version": "4.17.11", "version": "4.17.15",
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.11.tgz", "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.15.tgz",
"integrity": "sha512-DHb1ub+rMjjrxqlB3H56/6MXtm1lSksDp2rA2cNWjG8mlDUYFhUj3Di2Zn5IwSU87xLv8tNIQ7sSwE/YOX/D/Q==" "integrity": "sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ=="
}, },
"lodash.debounce": { "lodash.debounce": {
"version": "4.0.8", "version": "4.0.8",
@@ -12271,6 +12277,7 @@
"version": "1.6.3", "version": "1.6.3",
"resolved": "http://registry.npmjs.org/node-fetch/-/node-fetch-1.6.3.tgz", "resolved": "http://registry.npmjs.org/node-fetch/-/node-fetch-1.6.3.tgz",
"integrity": "sha1-3CNO3WSJmC1Y6PDbT2lQKavNjAQ=", "integrity": "sha1-3CNO3WSJmC1Y6PDbT2lQKavNjAQ=",
"dev": true,
"requires": { "requires": {
"encoding": "^0.1.11", "encoding": "^0.1.11",
"is-stream": "^1.0.1" "is-stream": "^1.0.1"
@@ -13491,14 +13498,6 @@
"integrity": "sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg==", "integrity": "sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg==",
"dev": true "dev": true
}, },
"promise": {
"version": "7.3.1",
"resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
"integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
"requires": {
"asap": "~2.0.3"
}
},
"promise-inflight": { "promise-inflight": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
@@ -14987,7 +14986,8 @@
"setimmediate": { "setimmediate": {
"version": "1.0.5", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
"integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
"dev": true
}, },
"setprototypeof": { "setprototypeof": {
"version": "1.1.0", "version": "1.1.0",
@@ -16385,7 +16385,8 @@
"tslib": { "tslib": {
"version": "1.9.3", "version": "1.9.3",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
"integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==",
"dev": true
}, },
"tty-browserify": { "tty-browserify": {
"version": "0.0.0", "version": "0.0.0",
@@ -16436,11 +16437,6 @@
"integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==", "integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==",
"dev": true "dev": true
}, },
"ua-parser-js": {
"version": "0.7.19",
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.19.tgz",
"integrity": "sha512-T3PVJ6uz8i0HzPxOF9SWzWAlfN/DavlpQqepn22xgve/5QecC+XMCAtmUNnY7C9StehaV6exjUCI801lOI7QlQ=="
},
"uglify-js": { "uglify-js": {
"version": "3.6.0", "version": "3.6.0",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz",
@@ -17608,11 +17604,6 @@
"iconv-lite": "0.4.24" "iconv-lite": "0.4.24"
} }
}, },
"whatwg-fetch": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz",
"integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q=="
},
"whatwg-mimetype": { "whatwg-mimetype": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.2.0.tgz", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.2.0.tgz",

View File

@@ -67,7 +67,7 @@
"codemirror": "^5.47.0", "codemirror": "^5.47.0",
"d3": "^5.12.0", "d3": "^5.12.0",
"dagre": "^0.8.4", "dagre": "^0.8.4",
"formik": "^1.5.1", "formik": "^2.1.2",
"has-ansi": "^3.0.0", "has-ansi": "^3.0.0",
"html-entities": "^1.2.1", "html-entities": "^1.2.1",
"js-yaml": "^3.13.1", "js-yaml": "^3.13.1",

View File

@@ -22,10 +22,8 @@ function FormField(props) {
} = props; } = props;
return ( return (
<Field <Field name={name} validate={validate}>
name={name} {({ field, form }) => {
validate={validate}
render={({ field, form }) => {
const isValid = const isValid =
form && (!form.touched[field.name] || !form.errors[field.name]); form && (!form.touched[field.name] || !form.errors[field.name]);
@@ -59,7 +57,7 @@ function FormField(props) {
</FormGroup> </FormGroup>
); );
}} }}
/> </Field>
); );
} }

View File

@@ -19,6 +19,7 @@ function HostForm({ handleSubmit, handleCancel, host, i18n }) {
const [inventory, setInventory] = useState( const [inventory, setInventory] = useState(
host ? host.summary_fields.inventory : '' host ? host.summary_fields.inventory : ''
); );
console.log('render');
return ( return (
<Formik <Formik

View File

@@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import { act } from 'react-dom/test-utils';
import { mountWithContexts } from '@testUtils/enzymeHelpers'; import { mountWithContexts } from '@testUtils/enzymeHelpers';
import { sleep } from '@testUtils/testUtils'; import { sleep } from '@testUtils/testUtils';
@@ -31,25 +31,32 @@ describe('<HostForm />', () => {
jest.clearAllMocks(); jest.clearAllMocks();
}); });
test('changing inputs should update form values', () => { test('changing inputs should update form values', async () => {
const wrapper = mountWithContexts( let wrapper;
<HostForm await act(async () => {
host={mockData} wrapper = mountWithContexts(
handleSubmit={jest.fn()} <HostForm
handleCancel={jest.fn()} host={mockData}
me={meConfig.me} handleSubmit={jest.fn()}
/> handleCancel={jest.fn()}
); me={meConfig.me}
/>
);
});
const form = wrapper.find('Formik'); await act(async () => {
wrapper.find('input#host-name').simulate('change', { wrapper.find('input#host-name').simulate('change', {
target: { value: 'new foo', name: 'name' }, target: { value: 'new foo', name: 'name' },
});
wrapper.find('input#host-description').simulate('change', {
target: { value: 'new bar', name: 'description' },
});
}); });
expect(form.state('values').name).toEqual('new foo'); wrapper.update();
wrapper.find('input#host-description').simulate('change', { expect(wrapper.find('input#host-name').prop('value')).toEqual('new foo');
target: { value: 'new bar', name: 'description' }, expect(wrapper.find('input#host-description').prop('value')).toEqual(
}); 'new bar'
expect(form.state('values').description).toEqual('new bar'); );
}); });
test('calls handleSubmit when form submitted', async () => { test('calls handleSubmit when form submitted', async () => {
@@ -63,8 +70,9 @@ describe('<HostForm />', () => {
/> />
); );
expect(handleSubmit).not.toHaveBeenCalled(); expect(handleSubmit).not.toHaveBeenCalled();
wrapper.find('button[aria-label="Save"]').simulate('click'); await act(async () => {
await sleep(1); wrapper.find('button[aria-label="Save"]').simulate('click');
});
expect(handleSubmit).toHaveBeenCalled(); expect(handleSubmit).toHaveBeenCalled();
}); });

View File

@@ -3,8 +3,9 @@ import { Route } from 'react-router-dom';
import { act } from 'react-dom/test-utils'; import { act } from 'react-dom/test-utils';
import { createMemoryHistory } from 'history'; import { createMemoryHistory } from 'history';
import { mountWithContexts, waitForElement } from '@testUtils/enzymeHelpers'; import { mountWithContexts, waitForElement } from '@testUtils/enzymeHelpers';
import InventoryHostAdd from './InventoryHostAdd'; import { sleep } from '@testUtils/testUtils';
import { InventoriesAPI } from '@api'; import { InventoriesAPI } from '@api';
import InventoryHostAdd from './InventoryHostAdd';
jest.mock('@api'); jest.mock('@api');
@@ -49,45 +50,42 @@ describe('<InventoryHostAdd />', () => {
data: { ...mockHostData }, data: { ...mockHostData },
}); });
const formik = wrapper.find('Formik').instance();
await act(async () => { await act(async () => {
const changeState = new Promise(resolve => { wrapper.find('FormField[id="host-name"] input').simulate('change', {
formik.setState( target: { value: 'new name', name: 'name' },
{
values: {
...mockHostData,
},
},
() => resolve()
);
}); });
await changeState; wrapper
}); .find('FormField[id="host-description"] input')
await act(async () => { .simulate('change', {
wrapper.find('form').simulate('submit'); target: { value: 'new description', name: 'description' },
});
wrapper.update();
await sleep(0);
wrapper.find('FormActionGroup').invoke('onSubmit')();
}); });
wrapper.update(); wrapper.update();
expect(InventoriesAPI.createHost).toHaveBeenCalledWith('1', mockHostData); expect(InventoriesAPI.createHost).toHaveBeenCalledWith('1', {
name: 'new name',
description: 'new description',
variables: '---\n',
});
}); });
test('handleSubmit should throw an error', async () => { test('handleSubmit should throw an error', async () => {
InventoriesAPI.createHost.mockImplementationOnce(() => InventoriesAPI.createHost.mockImplementationOnce(() =>
Promise.reject(new Error()) Promise.reject(new Error())
); );
const formik = wrapper.find('Formik').instance();
await act(async () => { await act(async () => {
const changeState = new Promise(resolve => { wrapper.find('FormField[id="host-name"] input').simulate('change', {
formik.setState( target: { value: 'new name', name: 'name' },
{
values: {
...mockHostData,
},
},
() => resolve()
);
}); });
await changeState; wrapper
.find('FormField[id="host-description"] input')
.simulate('change', {
target: { value: 'new description', name: 'description' },
});
}); });
wrapper.update();
await act(async () => { await act(async () => {
wrapper.find('form').simulate('submit'); wrapper.find('form').simulate('submit');
}); });

View File

@@ -64,12 +64,15 @@ describe('<InventoryForm />', () => {
/> />
); );
}); });
afterEach(() => { afterEach(() => {
wrapper.unmount(); wrapper.unmount();
}); });
test('Initially renders successfully', () => { test('Initially renders successfully', () => {
expect(wrapper.length).toBe(1); expect(wrapper.length).toBe(1);
}); });
test('should display form fields properly', () => { test('should display form fields properly', () => {
expect(wrapper.find('FormGroup[label="Name"]').length).toBe(1); expect(wrapper.find('FormGroup[label="Name"]').length).toBe(1);
expect(wrapper.find('FormGroup[label="Description"]').length).toBe(1); expect(wrapper.find('FormGroup[label="Description"]').length).toBe(1);
@@ -80,45 +83,37 @@ describe('<InventoryForm />', () => {
); );
expect(wrapper.find('VariablesField[label="Variables"]').length).toBe(1); expect(wrapper.find('VariablesField[label="Variables"]').length).toBe(1);
}); });
test('should update from values onChange', async () => {
const form = wrapper.find('Formik'); test('should update form values', async () => {
act(() => { act(() => {
wrapper.find('OrganizationLookup').invoke('onBlur')(); wrapper.find('OrganizationLookup').invoke('onBlur')();
wrapper.find('OrganizationLookup').invoke('onChange')({ wrapper.find('OrganizationLookup').invoke('onChange')({
id: 3, id: 3,
name: 'organization', name: 'organization',
}); });
});
expect(form.state('values').organization).toEqual({ wrapper.find('input#inventory-name').simulate('change', {
id: 3, target: { value: 'new Foo', name: 'name' },
name: 'organization', });
});
wrapper.find('input#inventory-name').simulate('change', {
target: { value: 'new Foo', name: 'name' },
});
expect(form.state('values').name).toEqual('new Foo');
act(() => {
wrapper.find('CredentialLookup').invoke('onBlur')(); wrapper.find('CredentialLookup').invoke('onBlur')();
wrapper.find('CredentialLookup').invoke('onChange')({ wrapper.find('CredentialLookup').invoke('onChange')({
id: 10, id: 10,
name: 'credential', name: 'credential',
}); });
}); });
expect(form.state('values').insights_credential).toEqual({ wrapper.update();
expect(wrapper.find('OrganizationLookup').prop('value')).toEqual({
id: 3,
name: 'organization',
});
expect(wrapper.find('input#inventory-name').prop('value')).toEqual(
'new Foo'
);
expect(wrapper.find('CredentialLookup').prop('value')).toEqual({
id: 10, id: 10,
name: 'credential', name: 'credential',
}); });
form.find('button[aria-label="Save"]').simulate('click');
await sleep(1);
expect(onSubmit).toHaveBeenCalledWith({
description: '',
insights_credential: { id: 10, name: 'credential' },
instanceGroups: [{ id: 1, name: 'Foo' }, { id: 2, name: 'Bar' }],
name: 'new Foo',
organization: { id: 3, name: 'organization' },
variables: '---',
});
}); });
test('should call handleCancel when Cancel button is clicked', async () => { test('should call handleCancel when Cancel button is clicked', async () => {

View File

@@ -46,7 +46,9 @@ function InventoryHostForm({ handleSubmit, handleCancel, host, i18n }) {
</FormRow> </FormRow>
<FormActionGroup <FormActionGroup
onCancel={handleCancel} onCancel={handleCancel}
onSubmit={formik.handleSubmit} onSubmit={() => {
formik.handleSubmit();
}}
/> />
</Form> </Form>
)} )}

View File

@@ -43,8 +43,9 @@ describe('<InventoryHostform />', () => {
test('should call handleSubmit when Submit button is clicked', async () => { test('should call handleSubmit when Submit button is clicked', async () => {
expect(handleSubmit).not.toHaveBeenCalled(); expect(handleSubmit).not.toHaveBeenCalled();
wrapper.find('button[aria-label="Save"]').simulate('click'); await act(async () => {
await sleep(1); wrapper.find('button[aria-label="Save"]').simulate('click');
});
expect(handleSubmit).toHaveBeenCalled(); expect(handleSubmit).toHaveBeenCalled();
}); });

View File

@@ -97,24 +97,7 @@ describe('<ProjectAdd />', () => {
wrapper = mountWithContexts(<ProjectAdd />); wrapper = mountWithContexts(<ProjectAdd />);
}); });
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0); await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
const formik = wrapper.find('Formik').instance(); wrapper.find('ProjectForm').invoke('handleSubmit')(projectData);
await act(async () => {
const changeState = new Promise(resolve => {
formik.setState(
{
values: {
...projectData,
},
},
() => resolve()
);
});
await changeState;
});
await act(async () => {
wrapper.find('form').simulate('submit');
});
wrapper.update();
expect(ProjectsAPI.create).toHaveBeenCalledTimes(1); expect(ProjectsAPI.create).toHaveBeenCalledTimes(1);
}); });

View File

@@ -130,19 +130,11 @@ describe('<ProjectForm />', () => {
); );
}); });
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0); await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
const formik = wrapper.find('Formik').instance();
await act(async () => { await act(async () => {
const changeState = new Promise(resolve => { await wrapper.find('AnsibleSelect[id="scm_type"]').invoke('onChange')(
formik.setState( null,
{ 'git'
values: { );
...mockData,
},
},
() => resolve()
);
});
await changeState;
}); });
wrapper.update(); wrapper.update();
expect(wrapper.find('FormGroup[label="SCM URL"]').length).toBe(1); expect(wrapper.find('FormGroup[label="SCM URL"]').length).toBe(1);
@@ -166,59 +158,58 @@ describe('<ProjectForm />', () => {
); );
}); });
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0); await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
const form = wrapper.find('Formik');
act(() => { act(() => {
wrapper.find('OrganizationLookup').invoke('onBlur')(); wrapper.find('OrganizationLookup').invoke('onBlur')();
wrapper.find('OrganizationLookup').invoke('onChange')({ wrapper.find('OrganizationLookup').invoke('onChange')({
id: 1, id: 1,
name: 'organization', name: 'organization',
}); });
});
expect(form.state('values').organization).toEqual(1);
act(() => {
wrapper.find('CredentialLookup').invoke('onBlur')(); wrapper.find('CredentialLookup').invoke('onBlur')();
wrapper.find('CredentialLookup').invoke('onChange')({ wrapper.find('CredentialLookup').invoke('onChange')({
id: 10, id: 10,
name: 'credential', name: 'credential',
}); });
}); });
expect(form.state('values').credential).toEqual(10); wrapper.update();
expect(wrapper.find('OrganizationLookup').prop('value')).toEqual({
id: 1,
name: 'organization',
});
expect(wrapper.find('CredentialLookup').prop('value')).toEqual({
id: 10,
name: 'credential',
});
}); });
test('should display insights credential lookup when scm type is "Insights"', async () => { test('should display insights credential lookup when scm type is "insights"', async () => {
await act(async () => { await act(async () => {
wrapper = mountWithContexts( wrapper = mountWithContexts(
<ProjectForm handleSubmit={jest.fn()} handleCancel={jest.fn()} /> <ProjectForm handleSubmit={jest.fn()} handleCancel={jest.fn()} />
); );
}); });
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0); await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
const formik = wrapper.find('Formik').instance();
await act(async () => { await act(async () => {
const changeState = new Promise(resolve => { await wrapper.find('AnsibleSelect[id="scm_type"]').invoke('onChange')(
formik.setState( null,
{ 'insights'
values: { );
...mockData,
scm_type: 'insights',
},
},
() => resolve()
);
});
await changeState;
}); });
wrapper.update(); wrapper.update();
expect(wrapper.find('FormGroup[label="Insights Credential"]').length).toBe( expect(wrapper.find('FormGroup[label="Insights Credential"]').length).toBe(
1 1
); );
act(() => { await act(async () => {
wrapper.find('CredentialLookup').invoke('onBlur')(); wrapper.find('CredentialLookup').invoke('onBlur')();
wrapper.find('CredentialLookup').invoke('onChange')({ wrapper.find('CredentialLookup').invoke('onChange')({
id: 123, id: 123,
name: 'credential', name: 'credential',
}); });
}); });
expect(formik.state.values.credential).toEqual(123); wrapper.update();
expect(wrapper.find('CredentialLookup').prop('value')).toEqual({
id: 123,
name: 'credential',
});
}); });
test('manual subform should display expected fields', async () => { test('manual subform should display expected fields', async () => {
@@ -289,10 +280,8 @@ describe('<ProjectForm />', () => {
const scmTypeSelect = wrapper.find( const scmTypeSelect = wrapper.find(
'FormGroup[label="SCM Type"] FormSelect' 'FormGroup[label="SCM Type"] FormSelect'
); );
const formik = wrapper.find('Formik').instance();
expect(formik.state.values.scm_url).toEqual('');
await act(async () => { await act(async () => {
scmTypeSelect.props().onChange('hg', { target: { name: 'Mercurial' } }); scmTypeSelect.invoke('onChange')('hg', { target: { name: 'Mercurial' } });
}); });
wrapper.update(); wrapper.update();
await act(async () => { await act(async () => {
@@ -300,7 +289,8 @@ describe('<ProjectForm />', () => {
target: { value: 'baz', name: 'scm_url' }, target: { value: 'baz', name: 'scm_url' },
}); });
}); });
expect(formik.state.values.scm_url).toEqual('baz'); wrapper.update();
expect(wrapper.find('input#project-scm-url').prop('value')).toEqual('baz');
await act(async () => { await act(async () => {
scmTypeSelect scmTypeSelect
.props() .props()
@@ -311,7 +301,7 @@ describe('<ProjectForm />', () => {
scmTypeSelect.props().onChange('svn', { target: { name: 'Subversion' } }); scmTypeSelect.props().onChange('svn', { target: { name: 'Subversion' } });
}); });
wrapper.update(); wrapper.update();
expect(formik.state.values.scm_url).toEqual(''); expect(wrapper.find('input#project-scm-url').prop('value')).toEqual('');
}); });
test('should call handleSubmit when Submit button is clicked', async () => { test('should call handleSubmit when Submit button is clicked', async () => {
@@ -327,8 +317,9 @@ describe('<ProjectForm />', () => {
}); });
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0); await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
expect(handleSubmit).not.toHaveBeenCalled(); expect(handleSubmit).not.toHaveBeenCalled();
wrapper.find('button[aria-label="Save"]').simulate('click'); await act(async () => {
await sleep(1); wrapper.find('button[aria-label="Save"]').simulate('click');
});
expect(handleSubmit).toBeCalled(); expect(handleSubmit).toBeCalled();
}); });

View File

@@ -42,23 +42,28 @@ describe('<TeamForm />', () => {
); );
}); });
const form = wrapper.find('Formik');
wrapper.find('input#team-name').simulate('change', {
target: { value: 'new foo', name: 'name' },
});
expect(form.state('values').name).toEqual('new foo');
wrapper.find('input#team-description').simulate('change', {
target: { value: 'new bar', name: 'description' },
});
expect(form.state('values').description).toEqual('new bar');
act(() => { act(() => {
wrapper.find('input#team-name').simulate('change', {
target: { value: 'new foo', name: 'name' },
});
wrapper.find('input#team-description').simulate('change', {
target: { value: 'new bar', name: 'description' },
});
wrapper.find('OrganizationLookup').invoke('onBlur')(); wrapper.find('OrganizationLookup').invoke('onBlur')();
wrapper.find('OrganizationLookup').invoke('onChange')({ wrapper.find('OrganizationLookup').invoke('onChange')({
id: 2, id: 2,
name: 'Other Org', name: 'Other Org',
}); });
}); });
expect(form.state('values').organization).toEqual(2); wrapper.update();
expect(wrapper.find('input#team-name').prop('value')).toEqual('new foo');
expect(wrapper.find('input#team-description').prop('value')).toEqual(
'new bar'
);
expect(wrapper.find('OrganizationLookup').prop('value')).toEqual({
id: 2,
name: 'Other Org',
});
}); });
test('should call handleSubmit when Submit button is clicked', async () => { test('should call handleSubmit when Submit button is clicked', async () => {
@@ -75,8 +80,9 @@ describe('<TeamForm />', () => {
}); });
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0); await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
expect(handleSubmit).not.toHaveBeenCalled(); expect(handleSubmit).not.toHaveBeenCalled();
wrapper.find('button[aria-label="Save"]').simulate('click'); await act(async () => {
await sleep(1); wrapper.find('button[aria-label="Save"]').simulate('click');
});
expect(handleSubmit).toBeCalled(); expect(handleSubmit).toBeCalled();
}); });

View File

@@ -128,43 +128,59 @@ describe('<JobTemplateForm />', () => {
}); });
await waitForElement(wrapper, 'EmptyStateBody', el => el.length === 0); await waitForElement(wrapper, 'EmptyStateBody', el => el.length === 0);
const form = wrapper.find('Formik');
wrapper.find('input#template-name').simulate('change', {
target: { value: 'new foo', name: 'name' },
});
expect(form.state('values').name).toEqual('new foo');
wrapper.find('input#template-description').simulate('change', {
target: { value: 'new bar', name: 'description' },
});
expect(form.state('values').description).toEqual('new bar');
wrapper.find('AnsibleSelect[name="job_type"]').simulate('change', {
target: { value: 'new job type', name: 'job_type' },
});
expect(form.state('values').job_type).toEqual('new job type');
wrapper.find('InventoryLookup').invoke('onChange')({
id: 3,
name: 'inventory',
});
expect(form.state('values').inventory).toEqual(3);
await act(async () => { await act(async () => {
wrapper.find('input#template-name').simulate('change', {
target: { value: 'new foo', name: 'name' },
});
wrapper.find('input#template-description').simulate('change', {
target: { value: 'new bar', name: 'description' },
});
wrapper.find('AnsibleSelect[name="job_type"]').simulate('change', {
target: { value: 'new job type', name: 'job_type' },
});
wrapper.find('InventoryLookup').invoke('onChange')({
id: 3,
name: 'inventory',
});
wrapper.find('ProjectLookup').invoke('onChange')({ wrapper.find('ProjectLookup').invoke('onChange')({
id: 4, id: 4,
name: 'project', name: 'project',
}); });
}); wrapper.find('AnsibleSelect[name="playbook"]').simulate('change', {
expect(form.state('values').project).toEqual(4); target: { value: 'new baz type', name: 'playbook' },
wrapper.find('AnsibleSelect[name="playbook"]').simulate('change', { });
target: { value: 'new baz type', name: 'playbook' },
});
expect(form.state('values').playbook).toEqual('new baz type');
await act(async () => {
wrapper wrapper
.find('CredentialChip') .find('CredentialChip')
.at(0) .at(0)
.prop('onClick')(); .prop('onClick')();
}); });
expect(form.state('values').credentials).toEqual([ wrapper.update();
{ id: 2, kind: 'ssh', name: 'Bar' }, expect(wrapper.find('input#template-name').prop('value')).toEqual(
'new foo'
);
expect(wrapper.find('input#template-description').prop('value')).toEqual(
'new bar'
);
expect(
wrapper.find('AnsibleSelect[name="job_type"]').prop('value')
).toEqual('new job type');
expect(wrapper.find('InventoryLookup').prop('value')).toEqual({
id: 3,
name: 'inventory',
});
expect(wrapper.find('ProjectLookup').prop('value')).toEqual({
id: 4,
name: 'project',
});
expect(
wrapper.find('AnsibleSelect[name="playbook"]').prop('value')
).toEqual('new baz type');
expect(wrapper.find('MultiCredentialsLookup').prop('value')).toEqual([
{
id: 2,
kind: 'ssh',
name: 'Bar',
},
]); ]);
}); });

View File

@@ -77,15 +77,18 @@ describe('<UserForm />', () => {
); );
}); });
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0); await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
const form = wrapper.find('Formik'); await act(async () => {
act(() => {
wrapper.find('OrganizationLookup').invoke('onBlur')(); wrapper.find('OrganizationLookup').invoke('onBlur')();
wrapper.find('OrganizationLookup').invoke('onChange')({ wrapper.find('OrganizationLookup').invoke('onChange')({
id: 1, id: 1,
name: 'organization', name: 'organization',
}); });
}); });
expect(form.state('values').organization).toEqual(1); wrapper.update();
expect(wrapper.find('OrganizationLookup').prop('value')).toEqual({
id: 1,
name: 'organization',
});
}); });
test('password fields are required on add', async () => { test('password fields are required on add', async () => {
@@ -133,8 +136,9 @@ describe('<UserForm />', () => {
}); });
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0); await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
expect(handleSubmit).not.toHaveBeenCalled(); expect(handleSubmit).not.toHaveBeenCalled();
wrapper.find('button[aria-label="Save"]').simulate('click'); await act(async () => {
await sleep(1); wrapper.find('button[aria-label="Save"]').simulate('click');
});
expect(handleSubmit).toBeCalled(); expect(handleSubmit).toBeCalled();
}); });