mirror of
https://github.com/ansible/awx.git
synced 2024-10-30 22:21:13 +03:00
Merge pull request #5688 from keithjgrant/5235-variables-field-json
Upgrade to Formik 2.1.2 Reviewed-by: John Mitchell https://github.com/jlmitch5
This commit is contained in:
commit
5e4c997c41
169
awx/ui_next/package-lock.json
generated
169
awx/ui_next/package-lock.json
generated
@ -3015,11 +3015,6 @@
|
||||
"integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
|
||||
"dev": true
|
||||
},
|
||||
"asap": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
|
||||
"integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
|
||||
},
|
||||
"asn1": {
|
||||
"version": "0.2.4",
|
||||
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
|
||||
@ -5193,15 +5188,6 @@
|
||||
"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": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
|
||||
@ -6215,6 +6201,7 @@
|
||||
"version": "0.1.12",
|
||||
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
|
||||
"integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"iconv-lite": "~0.4.13"
|
||||
}
|
||||
@ -7308,27 +7295,6 @@
|
||||
"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": {
|
||||
"version": "0.8.3",
|
||||
"resolved": "https://registry.npmjs.org/fbjs-scripts/-/fbjs-scripts-0.8.3.tgz",
|
||||
@ -7648,19 +7614,47 @@
|
||||
}
|
||||
},
|
||||
"formik": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/formik/-/formik-1.5.1.tgz",
|
||||
"integrity": "sha512-FBWGBKQkcCE4d5b5l2fKccD9d1QxNxw/0bQTRvp3EjzA8Bnjmsm9H/Oy0375UA8P3FPmfJkF4cXLLdEqK7fP5A==",
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/formik/-/formik-2.1.2.tgz",
|
||||
"integrity": "sha512-lbhyV8FQ/hkg4tsVf075Ad9/vDXVbSj6XLW8ooZtAZyNJK8MBYLf1fRJ6iEo2C0pODQneDboYpEUby7nsPW00Q==",
|
||||
"requires": {
|
||||
"create-react-context": "^0.2.2",
|
||||
"deepmerge": "^2.1.1",
|
||||
"hoist-non-react-statics": "^2.5.5",
|
||||
"lodash": "^4.17.11",
|
||||
"lodash-es": "^4.17.11",
|
||||
"prop-types": "^15.6.1",
|
||||
"hoist-non-react-statics": "^3.3.0",
|
||||
"lodash": "^4.17.14",
|
||||
"lodash-es": "^4.17.14",
|
||||
"react-fast-compare": "^2.0.1",
|
||||
"scheduler": "^0.18.0",
|
||||
"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": {
|
||||
@ -7774,7 +7768,8 @@
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"aproba": {
|
||||
"version": "1.2.0",
|
||||
@ -7795,12 +7790,14 @@
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
@ -7815,17 +7812,20 @@
|
||||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
@ -7942,7 +7942,8 @@
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.5",
|
||||
@ -7954,6 +7955,7 @@
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"number-is-nan": "^1.0.0"
|
||||
}
|
||||
@ -7968,6 +7970,7 @@
|
||||
"version": "3.0.4",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
@ -7975,12 +7978,14 @@
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"minipass": {
|
||||
"version": "2.3.5",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.2",
|
||||
"yallist": "^3.0.0"
|
||||
@ -7999,6 +8004,7 @@
|
||||
"version": "0.5.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
@ -8079,7 +8085,8 @@
|
||||
"number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
@ -8091,6 +8098,7 @@
|
||||
"version": "1.4.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
@ -8176,7 +8184,8 @@
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
@ -8212,6 +8221,7 @@
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"code-point-at": "^1.0.0",
|
||||
"is-fullwidth-code-point": "^1.0.0",
|
||||
@ -8231,6 +8241,7 @@
|
||||
"version": "3.0.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
@ -8274,12 +8285,14 @@
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"yallist": {
|
||||
"version": "3.0.3",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -8678,7 +8691,8 @@
|
||||
"hoist-non-react-statics": {
|
||||
"version": "2.5.5",
|
||||
"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": {
|
||||
"version": "2.0.0",
|
||||
@ -9716,7 +9730,8 @@
|
||||
"is-stream": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
|
||||
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
|
||||
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
|
||||
"dev": true
|
||||
},
|
||||
"is-string": {
|
||||
"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": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
||||
@ -11487,9 +11493,9 @@
|
||||
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
|
||||
},
|
||||
"lodash-es": {
|
||||
"version": "4.17.11",
|
||||
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.11.tgz",
|
||||
"integrity": "sha512-DHb1ub+rMjjrxqlB3H56/6MXtm1lSksDp2rA2cNWjG8mlDUYFhUj3Di2Zn5IwSU87xLv8tNIQ7sSwE/YOX/D/Q=="
|
||||
"version": "4.17.15",
|
||||
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.15.tgz",
|
||||
"integrity": "sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ=="
|
||||
},
|
||||
"lodash.debounce": {
|
||||
"version": "4.0.8",
|
||||
@ -12271,6 +12277,7 @@
|
||||
"version": "1.6.3",
|
||||
"resolved": "http://registry.npmjs.org/node-fetch/-/node-fetch-1.6.3.tgz",
|
||||
"integrity": "sha1-3CNO3WSJmC1Y6PDbT2lQKavNjAQ=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"encoding": "^0.1.11",
|
||||
"is-stream": "^1.0.1"
|
||||
@ -13491,14 +13498,6 @@
|
||||
"integrity": "sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg==",
|
||||
"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": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
|
||||
@ -14987,7 +14986,8 @@
|
||||
"setimmediate": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
|
||||
"integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU="
|
||||
"integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
|
||||
"dev": true
|
||||
},
|
||||
"setprototypeof": {
|
||||
"version": "1.1.0",
|
||||
@ -16385,7 +16385,8 @@
|
||||
"tslib": {
|
||||
"version": "1.9.3",
|
||||
"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": {
|
||||
"version": "0.0.0",
|
||||
@ -16436,11 +16437,6 @@
|
||||
"integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==",
|
||||
"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": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz",
|
||||
@ -17608,11 +17604,6 @@
|
||||
"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": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.2.0.tgz",
|
||||
|
@ -67,7 +67,7 @@
|
||||
"codemirror": "^5.47.0",
|
||||
"d3": "^5.12.0",
|
||||
"dagre": "^0.8.4",
|
||||
"formik": "^1.5.1",
|
||||
"formik": "^2.1.2",
|
||||
"has-ansi": "^3.0.0",
|
||||
"html-entities": "^1.2.1",
|
||||
"js-yaml": "^3.13.1",
|
||||
|
@ -13,9 +13,8 @@ function VariablesField({ id, name, label, readOnly }) {
|
||||
const [mode, setMode] = useState(YAML_MODE);
|
||||
|
||||
return (
|
||||
<Field
|
||||
name={name}
|
||||
render={({ field, form }) => (
|
||||
<Field name={name}>
|
||||
{({ field, form }) => (
|
||||
<div className="pf-c-form__group">
|
||||
<Split gutter="sm">
|
||||
<SplitItem>
|
||||
@ -60,7 +59,7 @@ function VariablesField({ id, name, label, readOnly }) {
|
||||
) : null}
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
</Field>
|
||||
);
|
||||
}
|
||||
VariablesField.propTypes = {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { mount } from 'enzyme';
|
||||
import { Formik } from 'formik';
|
||||
import { sleep } from '../../../testUtils/testUtils';
|
||||
import VariablesField from './VariablesField';
|
||||
|
||||
describe('VariablesField', () => {
|
||||
@ -12,52 +12,52 @@ describe('VariablesField', () => {
|
||||
it('should render code mirror input', () => {
|
||||
const value = '---\n';
|
||||
const wrapper = mount(
|
||||
<Formik
|
||||
initialValues={{ variables: value }}
|
||||
render={() => (
|
||||
<Formik initialValues={{ variables: value }}>
|
||||
{() => (
|
||||
<VariablesField id="the-field" name="variables" label="Variables" />
|
||||
)}
|
||||
/>
|
||||
</Formik>
|
||||
);
|
||||
const codemirror = wrapper.find('Controlled');
|
||||
expect(codemirror.prop('value')).toEqual(value);
|
||||
});
|
||||
|
||||
it('should render yaml/json toggles', () => {
|
||||
it('should render yaml/json toggles', async () => {
|
||||
const value = '---\n';
|
||||
const wrapper = mount(
|
||||
<Formik
|
||||
initialValues={{ variables: value }}
|
||||
render={() => (
|
||||
<Formik initialValues={{ variables: value }}>
|
||||
{() => (
|
||||
<VariablesField id="the-field" name="variables" label="Variables" />
|
||||
)}
|
||||
/>
|
||||
</Formik>
|
||||
);
|
||||
const buttons = wrapper.find('Button');
|
||||
expect(buttons).toHaveLength(2);
|
||||
expect(buttons.at(0).prop('variant')).toEqual('primary');
|
||||
expect(buttons.at(1).prop('variant')).toEqual('secondary');
|
||||
|
||||
buttons.at(1).simulate('click');
|
||||
wrapper.update(0);
|
||||
await act(async () => {
|
||||
buttons.at(1).simulate('click');
|
||||
});
|
||||
wrapper.update();
|
||||
expect(wrapper.find('CodeMirrorInput').prop('mode')).toEqual('javascript');
|
||||
const buttons2 = wrapper.find('Button');
|
||||
expect(buttons2.at(0).prop('variant')).toEqual('secondary');
|
||||
expect(buttons2.at(1).prop('variant')).toEqual('primary');
|
||||
buttons2.at(0).simulate('click');
|
||||
wrapper.update(0);
|
||||
await act(async () => {
|
||||
buttons2.at(0).simulate('click');
|
||||
});
|
||||
wrapper.update();
|
||||
expect(wrapper.find('CodeMirrorInput').prop('mode')).toEqual('yaml');
|
||||
});
|
||||
|
||||
it('should set Formik error if yaml is invalid', () => {
|
||||
it('should set Formik error if yaml is invalid', async () => {
|
||||
const value = '---\nfoo bar\n';
|
||||
const wrapper = mount(
|
||||
<Formik
|
||||
initialValues={{ variables: value }}
|
||||
render={() => (
|
||||
<Formik initialValues={{ variables: value }}>
|
||||
{() => (
|
||||
<VariablesField id="the-field" name="variables" label="Variables" />
|
||||
)}
|
||||
/>
|
||||
</Formik>
|
||||
);
|
||||
wrapper
|
||||
.find('Button')
|
||||
@ -74,10 +74,8 @@ describe('VariablesField', () => {
|
||||
const value = '---\nfoo: bar\n';
|
||||
const handleSubmit = jest.fn();
|
||||
const wrapper = mount(
|
||||
<Formik
|
||||
initialValues={{ variables: value }}
|
||||
onSubmit={handleSubmit}
|
||||
render={formik => (
|
||||
<Formik initialValues={{ variables: value }} onSubmit={handleSubmit}>
|
||||
{formik => (
|
||||
<form onSubmit={formik.handleSubmit}>
|
||||
<VariablesField id="the-field" name="variables" label="Variables" />
|
||||
<button type="submit" id="submit">
|
||||
@ -85,12 +83,14 @@ describe('VariablesField', () => {
|
||||
</button>
|
||||
</form>
|
||||
)}
|
||||
/>
|
||||
</Formik>
|
||||
);
|
||||
wrapper.find('CodeMirrorInput').prop('onChange')('---\nnewval: changed');
|
||||
wrapper.find('form').simulate('submit');
|
||||
await sleep(1);
|
||||
await sleep(1);
|
||||
await act(async () => {
|
||||
wrapper.find('CodeMirrorInput').invoke('onChange')(
|
||||
'---\nnewval: changed'
|
||||
);
|
||||
wrapper.find('form').simulate('submit');
|
||||
});
|
||||
|
||||
expect(handleSubmit).toHaveBeenCalled();
|
||||
expect(handleSubmit.mock.calls[0][0]).toEqual({
|
||||
|
@ -11,10 +11,8 @@ const QuestionCircleIcon = styled(PFQuestionCircleIcon)`
|
||||
|
||||
function CheckboxField({ id, name, label, tooltip, validate, ...rest }) {
|
||||
return (
|
||||
<Field
|
||||
name={name}
|
||||
validate={validate}
|
||||
render={({ field }) => (
|
||||
<Field name={name} validate={validate}>
|
||||
{({ field }) => (
|
||||
<Checkbox
|
||||
aria-label={label}
|
||||
label={
|
||||
@ -37,7 +35,7 @@ function CheckboxField({ id, name, label, tooltip, validate, ...rest }) {
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</Field>
|
||||
);
|
||||
}
|
||||
CheckboxField.propTypes = {
|
||||
|
@ -22,10 +22,8 @@ function FormField(props) {
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<Field
|
||||
name={name}
|
||||
validate={validate}
|
||||
render={({ field, form }) => {
|
||||
<Field name={name} validate={validate}>
|
||||
{({ field, form }) => {
|
||||
const isValid =
|
||||
form && (!form.touched[field.name] || !form.errors[field.name]);
|
||||
|
||||
@ -59,7 +57,7 @@ function FormField(props) {
|
||||
</FormGroup>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</Field>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -22,10 +22,8 @@ function PasswordField(props) {
|
||||
};
|
||||
|
||||
return (
|
||||
<Field
|
||||
name={name}
|
||||
validate={validate}
|
||||
render={({ field, form }) => {
|
||||
<Field name={name} validate={validate}>
|
||||
{({ field, form }) => {
|
||||
const isValid =
|
||||
form && (!form.touched[field.name] || !form.errors[field.name]);
|
||||
return (
|
||||
@ -65,7 +63,7 @@ function PasswordField(props) {
|
||||
</FormGroup>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</Field>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -11,10 +11,11 @@ describe('PasswordField', () => {
|
||||
initialValues={{
|
||||
password: '',
|
||||
}}
|
||||
render={() => (
|
||||
>
|
||||
{() => (
|
||||
<PasswordField id="test-password" name="password" label="Password" />
|
||||
)}
|
||||
/>
|
||||
</Formik>
|
||||
);
|
||||
expect(wrapper).toHaveLength(1);
|
||||
});
|
||||
@ -25,10 +26,11 @@ describe('PasswordField', () => {
|
||||
initialValues={{
|
||||
password: '',
|
||||
}}
|
||||
render={() => (
|
||||
>
|
||||
{() => (
|
||||
<PasswordField id="test-password" name="password" label="Password" />
|
||||
)}
|
||||
/>
|
||||
</Formik>
|
||||
);
|
||||
expect(wrapper.find('input').prop('type')).toBe('password');
|
||||
expect(wrapper.find('EyeSlashIcon').length).toBe(1);
|
||||
|
@ -29,7 +29,8 @@ function HostForm({ handleSubmit, handleCancel, host, i18n }) {
|
||||
variables: host.variables,
|
||||
}}
|
||||
onSubmit={handleSubmit}
|
||||
render={formik => (
|
||||
>
|
||||
{formik => (
|
||||
<Form autoComplete="off" onSubmit={formik.handleSubmit}>
|
||||
<FormRow>
|
||||
<FormField
|
||||
@ -53,7 +54,8 @@ function HostForm({ handleSubmit, handleCancel, host, i18n }) {
|
||||
i18n._(t`Select a value for this field`),
|
||||
i18n
|
||||
)}
|
||||
render={({ form }) => (
|
||||
>
|
||||
{({ form }) => (
|
||||
<InventoryLookup
|
||||
value={inventory}
|
||||
onBlur={() => form.setFieldTouched('inventory')}
|
||||
@ -71,7 +73,7 @@ function HostForm({ handleSubmit, handleCancel, host, i18n }) {
|
||||
error={form.errors.inventory}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</Field>
|
||||
)}
|
||||
</FormRow>
|
||||
<FormRow>
|
||||
@ -87,7 +89,7 @@ function HostForm({ handleSubmit, handleCancel, host, i18n }) {
|
||||
/>
|
||||
</Form>
|
||||
)}
|
||||
/>
|
||||
</Formik>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
import React from 'react';
|
||||
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { mountWithContexts } from '@testUtils/enzymeHelpers';
|
||||
import { sleep } from '@testUtils/testUtils';
|
||||
|
||||
import HostForm from './HostForm';
|
||||
|
||||
@ -31,25 +30,32 @@ describe('<HostForm />', () => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
test('changing inputs should update form values', () => {
|
||||
const wrapper = mountWithContexts(
|
||||
<HostForm
|
||||
host={mockData}
|
||||
handleSubmit={jest.fn()}
|
||||
handleCancel={jest.fn()}
|
||||
me={meConfig.me}
|
||||
/>
|
||||
);
|
||||
test('changing inputs should update form values', async () => {
|
||||
let wrapper;
|
||||
await act(async () => {
|
||||
wrapper = mountWithContexts(
|
||||
<HostForm
|
||||
host={mockData}
|
||||
handleSubmit={jest.fn()}
|
||||
handleCancel={jest.fn()}
|
||||
me={meConfig.me}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
const form = wrapper.find('Formik');
|
||||
wrapper.find('input#host-name').simulate('change', {
|
||||
target: { value: 'new foo', name: 'name' },
|
||||
await act(async () => {
|
||||
wrapper.find('input#host-name').simulate('change', {
|
||||
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.find('input#host-description').simulate('change', {
|
||||
target: { value: 'new bar', name: 'description' },
|
||||
});
|
||||
expect(form.state('values').description).toEqual('new bar');
|
||||
wrapper.update();
|
||||
expect(wrapper.find('input#host-name').prop('value')).toEqual('new foo');
|
||||
expect(wrapper.find('input#host-description').prop('value')).toEqual(
|
||||
'new bar'
|
||||
);
|
||||
});
|
||||
|
||||
test('calls handleSubmit when form submitted', async () => {
|
||||
@ -63,8 +69,9 @@ describe('<HostForm />', () => {
|
||||
/>
|
||||
);
|
||||
expect(handleSubmit).not.toHaveBeenCalled();
|
||||
wrapper.find('button[aria-label="Save"]').simulate('click');
|
||||
await sleep(1);
|
||||
await act(async () => {
|
||||
wrapper.find('button[aria-label="Save"]').simulate('click');
|
||||
});
|
||||
expect(handleSubmit).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
|
@ -3,8 +3,9 @@ import { Route } from 'react-router-dom';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { createMemoryHistory } from 'history';
|
||||
import { mountWithContexts, waitForElement } from '@testUtils/enzymeHelpers';
|
||||
import InventoryHostAdd from './InventoryHostAdd';
|
||||
import { sleep } from '@testUtils/testUtils';
|
||||
import { InventoriesAPI } from '@api';
|
||||
import InventoryHostAdd from './InventoryHostAdd';
|
||||
|
||||
jest.mock('@api');
|
||||
|
||||
@ -49,45 +50,42 @@ describe('<InventoryHostAdd />', () => {
|
||||
data: { ...mockHostData },
|
||||
});
|
||||
|
||||
const formik = wrapper.find('Formik').instance();
|
||||
await act(async () => {
|
||||
const changeState = new Promise(resolve => {
|
||||
formik.setState(
|
||||
{
|
||||
values: {
|
||||
...mockHostData,
|
||||
},
|
||||
},
|
||||
() => resolve()
|
||||
);
|
||||
wrapper.find('FormField[id="host-name"] input').simulate('change', {
|
||||
target: { value: 'new name', name: 'name' },
|
||||
});
|
||||
await changeState;
|
||||
});
|
||||
await act(async () => {
|
||||
wrapper.find('form').simulate('submit');
|
||||
wrapper
|
||||
.find('FormField[id="host-description"] input')
|
||||
.simulate('change', {
|
||||
target: { value: 'new description', name: 'description' },
|
||||
});
|
||||
wrapper.update();
|
||||
await sleep(0);
|
||||
wrapper.find('FormActionGroup').invoke('onSubmit')();
|
||||
});
|
||||
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 () => {
|
||||
InventoriesAPI.createHost.mockImplementationOnce(() =>
|
||||
Promise.reject(new Error())
|
||||
);
|
||||
const formik = wrapper.find('Formik').instance();
|
||||
await act(async () => {
|
||||
const changeState = new Promise(resolve => {
|
||||
formik.setState(
|
||||
{
|
||||
values: {
|
||||
...mockHostData,
|
||||
},
|
||||
},
|
||||
() => resolve()
|
||||
);
|
||||
wrapper.find('FormField[id="host-name"] input').simulate('change', {
|
||||
target: { value: 'new name', name: 'name' },
|
||||
});
|
||||
await changeState;
|
||||
wrapper
|
||||
.find('FormField[id="host-description"] input')
|
||||
.simulate('change', {
|
||||
target: { value: 'new description', name: 'description' },
|
||||
});
|
||||
});
|
||||
wrapper.update();
|
||||
await act(async () => {
|
||||
wrapper.find('form').simulate('submit');
|
||||
});
|
||||
|
@ -41,7 +41,8 @@ function InventoryForm({
|
||||
onSubmit={values => {
|
||||
onSubmit(values);
|
||||
}}
|
||||
render={formik => (
|
||||
>
|
||||
{formik => (
|
||||
<Form autoComplete="off" onSubmit={formik.handleSubmit}>
|
||||
<FormRow>
|
||||
<FormField
|
||||
@ -66,7 +67,8 @@ function InventoryForm({
|
||||
i18n._(t`Select a value for this field`),
|
||||
i18n
|
||||
)}
|
||||
render={({ form, field }) => (
|
||||
>
|
||||
{({ form, field }) => (
|
||||
<OrganizationLookup
|
||||
helperTextInvalid={form.errors.organization}
|
||||
isValid={
|
||||
@ -82,12 +84,13 @@ function InventoryForm({
|
||||
required
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</Field>
|
||||
<Field
|
||||
id="inventory-insights_credential"
|
||||
label={i18n._(t`Insights Credential`)}
|
||||
name="insights_credential"
|
||||
render={({ field, form }) => (
|
||||
>
|
||||
{({ field, form }) => (
|
||||
<CredentialLookup
|
||||
label={i18n._(t`Insights Credential`)}
|
||||
credentialTypeId={credentialTypeId}
|
||||
@ -97,14 +100,15 @@ function InventoryForm({
|
||||
value={field.value}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</Field>
|
||||
</FormRow>
|
||||
<FormRow>
|
||||
<Field
|
||||
id="inventory-instanceGroups"
|
||||
label={i18n._(t`Instance Groups`)}
|
||||
name="instanceGroups"
|
||||
render={({ field, form }) => (
|
||||
>
|
||||
{({ field, form }) => (
|
||||
<InstanceGroupsLookup
|
||||
value={field.value}
|
||||
onChange={value => {
|
||||
@ -112,7 +116,7 @@ function InventoryForm({
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</Field>
|
||||
</FormRow>
|
||||
<FormRow>
|
||||
<VariablesField
|
||||
@ -132,7 +136,7 @@ function InventoryForm({
|
||||
</FormRow>
|
||||
</Form>
|
||||
)}
|
||||
/>
|
||||
</Formik>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
import React from 'react';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { mountWithContexts } from '@testUtils/enzymeHelpers';
|
||||
import { sleep } from '@testUtils/testUtils';
|
||||
|
||||
import InventoryForm from './InventoryForm';
|
||||
|
||||
@ -64,12 +63,15 @@ describe('<InventoryForm />', () => {
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
wrapper.unmount();
|
||||
});
|
||||
|
||||
test('Initially renders successfully', () => {
|
||||
expect(wrapper.length).toBe(1);
|
||||
});
|
||||
|
||||
test('should display form fields properly', () => {
|
||||
expect(wrapper.find('FormGroup[label="Name"]').length).toBe(1);
|
||||
expect(wrapper.find('FormGroup[label="Description"]').length).toBe(1);
|
||||
@ -80,45 +82,37 @@ describe('<InventoryForm />', () => {
|
||||
);
|
||||
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(() => {
|
||||
wrapper.find('OrganizationLookup').invoke('onBlur')();
|
||||
wrapper.find('OrganizationLookup').invoke('onChange')({
|
||||
id: 3,
|
||||
name: 'organization',
|
||||
});
|
||||
});
|
||||
expect(form.state('values').organization).toEqual({
|
||||
id: 3,
|
||||
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('input#inventory-name').simulate('change', {
|
||||
target: { value: 'new Foo', name: 'name' },
|
||||
});
|
||||
|
||||
wrapper.find('CredentialLookup').invoke('onBlur')();
|
||||
wrapper.find('CredentialLookup').invoke('onChange')({
|
||||
id: 10,
|
||||
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,
|
||||
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 () => {
|
||||
|
@ -28,10 +28,8 @@ function InventoryGroupForm({
|
||||
return (
|
||||
<Card className="awx-c-card">
|
||||
<CardBody>
|
||||
<Formik
|
||||
initialValues={initialValues}
|
||||
onSubmit={handleSubmit}
|
||||
render={formik => (
|
||||
<Formik initialValues={initialValues} onSubmit={handleSubmit}>
|
||||
{formik => (
|
||||
<Form autoComplete="off" onSubmit={formik.handleSubmit}>
|
||||
<FormRow css="grid-template-columns: repeat(auto-fit, minmax(300px, 500px));">
|
||||
<FormField
|
||||
@ -63,7 +61,7 @@ function InventoryGroupForm({
|
||||
{error ? <div>error</div> : null}
|
||||
</Form>
|
||||
)}
|
||||
/>
|
||||
</Formik>
|
||||
</CardBody>
|
||||
</Card>
|
||||
);
|
||||
|
@ -19,7 +19,8 @@ function InventoryHostForm({ handleSubmit, handleCancel, host, i18n }) {
|
||||
variables: host.variables,
|
||||
}}
|
||||
onSubmit={handleSubmit}
|
||||
render={formik => (
|
||||
>
|
||||
{formik => (
|
||||
<Form autoComplete="off" onSubmit={formik.handleSubmit}>
|
||||
<FormRow>
|
||||
<FormField
|
||||
@ -46,11 +47,13 @@ function InventoryHostForm({ handleSubmit, handleCancel, host, i18n }) {
|
||||
</FormRow>
|
||||
<FormActionGroup
|
||||
onCancel={handleCancel}
|
||||
onSubmit={formik.handleSubmit}
|
||||
onSubmit={() => {
|
||||
formik.handleSubmit();
|
||||
}}
|
||||
/>
|
||||
</Form>
|
||||
)}
|
||||
/>
|
||||
</Formik>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -43,8 +43,9 @@ describe('<InventoryHostform />', () => {
|
||||
|
||||
test('should call handleSubmit when Submit button is clicked', async () => {
|
||||
expect(handleSubmit).not.toHaveBeenCalled();
|
||||
wrapper.find('button[aria-label="Save"]').simulate('click');
|
||||
await sleep(1);
|
||||
await act(async () => {
|
||||
wrapper.find('button[aria-label="Save"]').simulate('click');
|
||||
});
|
||||
expect(handleSubmit).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
|
@ -91,7 +91,8 @@ function OrganizationForm({ organization, i18n, me, onCancel, onSubmit }) {
|
||||
max_hosts: organization.max_hosts || '0',
|
||||
}}
|
||||
onSubmit={handleSubmit}
|
||||
render={formik => (
|
||||
>
|
||||
{formik => (
|
||||
<Form autoComplete="off" onSubmit={formik.handleSubmit}>
|
||||
<FormRow>
|
||||
<FormField
|
||||
@ -132,9 +133,8 @@ function OrganizationForm({ organization, i18n, me, onCancel, onSubmit }) {
|
||||
isDisabled={!me.is_superuser}
|
||||
/>
|
||||
{custom_virtualenvs && custom_virtualenvs.length > 1 && (
|
||||
<Field
|
||||
name="custom_virtualenv"
|
||||
render={({ field }) => (
|
||||
<Field name="custom_virtualenv">
|
||||
{({ field }) => (
|
||||
<FormGroup
|
||||
fieldId="org-custom-virtualenv"
|
||||
label={i18n._(t`Ansible Environment`)}
|
||||
@ -151,7 +151,7 @@ function OrganizationForm({ organization, i18n, me, onCancel, onSubmit }) {
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
/>
|
||||
</Field>
|
||||
)}
|
||||
</FormRow>
|
||||
<InstanceGroupsLookup
|
||||
@ -167,7 +167,7 @@ function OrganizationForm({ organization, i18n, me, onCancel, onSubmit }) {
|
||||
/>
|
||||
</Form>
|
||||
)}
|
||||
/>
|
||||
</Formik>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -97,24 +97,7 @@ describe('<ProjectAdd />', () => {
|
||||
wrapper = mountWithContexts(<ProjectAdd />);
|
||||
});
|
||||
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
|
||||
const formik = wrapper.find('Formik').instance();
|
||||
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();
|
||||
wrapper.find('ProjectForm').invoke('handleSubmit')(projectData);
|
||||
expect(ProjectsAPI.create).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
|
@ -201,7 +201,8 @@ function ProjectForm({ project, ...props }) {
|
||||
scm_url: project.scm_url || '',
|
||||
}}
|
||||
onSubmit={handleSubmit}
|
||||
render={formik => (
|
||||
>
|
||||
{formik => (
|
||||
<Form
|
||||
autoComplete="off"
|
||||
onSubmit={formik.handleSubmit}
|
||||
@ -228,7 +229,8 @@ function ProjectForm({ project, ...props }) {
|
||||
i18n._(t`Select a value for this field`),
|
||||
i18n
|
||||
)}
|
||||
render={({ form }) => (
|
||||
>
|
||||
{({ form }) => (
|
||||
<OrganizationLookup
|
||||
helperTextInvalid={form.errors.organization}
|
||||
isValid={
|
||||
@ -243,14 +245,15 @@ function ProjectForm({ project, ...props }) {
|
||||
required
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</Field>
|
||||
<Field
|
||||
name="scm_type"
|
||||
validate={required(
|
||||
i18n._(t`Select a value for this field`),
|
||||
i18n
|
||||
)}
|
||||
render={({ field, form }) => (
|
||||
>
|
||||
{({ field, form }) => (
|
||||
<FormGroup
|
||||
fieldId="project-scm-type"
|
||||
helperTextInvalid={form.errors.scm_type}
|
||||
@ -286,7 +289,7 @@ function ProjectForm({ project, ...props }) {
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
/>
|
||||
</Field>
|
||||
{formik.values.scm_type !== '' && (
|
||||
<ScmTypeFormRow>
|
||||
<SubFormTitle size="md">
|
||||
@ -345,9 +348,8 @@ function ProjectForm({ project, ...props }) {
|
||||
{({ custom_virtualenvs }) =>
|
||||
custom_virtualenvs &&
|
||||
custom_virtualenvs.length > 1 && (
|
||||
<Field
|
||||
name="custom_virtualenv"
|
||||
render={({ field }) => (
|
||||
<Field name="custom_virtualenv">
|
||||
{({ field }) => (
|
||||
<FormGroup
|
||||
fieldId="project-custom-virtualenv"
|
||||
label={i18n._(t`Ansible Environment`)}
|
||||
@ -378,7 +380,7 @@ function ProjectForm({ project, ...props }) {
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
/>
|
||||
</Field>
|
||||
)
|
||||
}
|
||||
</Config>
|
||||
@ -389,7 +391,7 @@ function ProjectForm({ project, ...props }) {
|
||||
/>
|
||||
</Form>
|
||||
)}
|
||||
/>
|
||||
</Formik>
|
||||
)}
|
||||
</Config>
|
||||
);
|
||||
|
@ -1,7 +1,6 @@
|
||||
import React from 'react';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { mountWithContexts, waitForElement } from '@testUtils/enzymeHelpers';
|
||||
import { sleep } from '@testUtils/testUtils';
|
||||
import ProjectForm from './ProjectForm';
|
||||
import { CredentialTypesAPI, ProjectsAPI } from '@api';
|
||||
|
||||
@ -130,19 +129,11 @@ describe('<ProjectForm />', () => {
|
||||
);
|
||||
});
|
||||
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
|
||||
const formik = wrapper.find('Formik').instance();
|
||||
await act(async () => {
|
||||
const changeState = new Promise(resolve => {
|
||||
formik.setState(
|
||||
{
|
||||
values: {
|
||||
...mockData,
|
||||
},
|
||||
},
|
||||
() => resolve()
|
||||
);
|
||||
});
|
||||
await changeState;
|
||||
await wrapper.find('AnsibleSelect[id="scm_type"]').invoke('onChange')(
|
||||
null,
|
||||
'git'
|
||||
);
|
||||
});
|
||||
wrapper.update();
|
||||
expect(wrapper.find('FormGroup[label="SCM URL"]').length).toBe(1);
|
||||
@ -166,59 +157,58 @@ describe('<ProjectForm />', () => {
|
||||
);
|
||||
});
|
||||
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
|
||||
const form = wrapper.find('Formik');
|
||||
act(() => {
|
||||
wrapper.find('OrganizationLookup').invoke('onBlur')();
|
||||
wrapper.find('OrganizationLookup').invoke('onChange')({
|
||||
id: 1,
|
||||
name: 'organization',
|
||||
});
|
||||
});
|
||||
expect(form.state('values').organization).toEqual(1);
|
||||
act(() => {
|
||||
wrapper.find('CredentialLookup').invoke('onBlur')();
|
||||
wrapper.find('CredentialLookup').invoke('onChange')({
|
||||
id: 10,
|
||||
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 () => {
|
||||
wrapper = mountWithContexts(
|
||||
<ProjectForm handleSubmit={jest.fn()} handleCancel={jest.fn()} />
|
||||
);
|
||||
});
|
||||
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
|
||||
const formik = wrapper.find('Formik').instance();
|
||||
await act(async () => {
|
||||
const changeState = new Promise(resolve => {
|
||||
formik.setState(
|
||||
{
|
||||
values: {
|
||||
...mockData,
|
||||
scm_type: 'insights',
|
||||
},
|
||||
},
|
||||
() => resolve()
|
||||
);
|
||||
});
|
||||
await changeState;
|
||||
await wrapper.find('AnsibleSelect[id="scm_type"]').invoke('onChange')(
|
||||
null,
|
||||
'insights'
|
||||
);
|
||||
});
|
||||
wrapper.update();
|
||||
expect(wrapper.find('FormGroup[label="Insights Credential"]').length).toBe(
|
||||
1
|
||||
);
|
||||
act(() => {
|
||||
await act(async () => {
|
||||
wrapper.find('CredentialLookup').invoke('onBlur')();
|
||||
wrapper.find('CredentialLookup').invoke('onChange')({
|
||||
id: 123,
|
||||
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 () => {
|
||||
@ -289,10 +279,8 @@ describe('<ProjectForm />', () => {
|
||||
const scmTypeSelect = wrapper.find(
|
||||
'FormGroup[label="SCM Type"] FormSelect'
|
||||
);
|
||||
const formik = wrapper.find('Formik').instance();
|
||||
expect(formik.state.values.scm_url).toEqual('');
|
||||
await act(async () => {
|
||||
scmTypeSelect.props().onChange('hg', { target: { name: 'Mercurial' } });
|
||||
scmTypeSelect.invoke('onChange')('hg', { target: { name: 'Mercurial' } });
|
||||
});
|
||||
wrapper.update();
|
||||
await act(async () => {
|
||||
@ -300,7 +288,8 @@ describe('<ProjectForm />', () => {
|
||||
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 () => {
|
||||
scmTypeSelect
|
||||
.props()
|
||||
@ -311,7 +300,7 @@ describe('<ProjectForm />', () => {
|
||||
scmTypeSelect.props().onChange('svn', { target: { name: 'Subversion' } });
|
||||
});
|
||||
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 () => {
|
||||
@ -327,8 +316,9 @@ describe('<ProjectForm />', () => {
|
||||
});
|
||||
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
|
||||
expect(handleSubmit).not.toHaveBeenCalled();
|
||||
wrapper.find('button[aria-label="Save"]').simulate('click');
|
||||
await sleep(1);
|
||||
await act(async () => {
|
||||
wrapper.find('button[aria-label="Save"]').simulate('click');
|
||||
});
|
||||
expect(handleSubmit).toBeCalled();
|
||||
});
|
||||
|
||||
|
@ -16,7 +16,8 @@ const InsightsSubForm = ({
|
||||
<Field
|
||||
name="credential"
|
||||
validate={required(i18n._(t`Select a value for this field`), i18n)}
|
||||
render={({ form }) => (
|
||||
>
|
||||
{({ form }) => (
|
||||
<CredentialLookup
|
||||
credentialTypeId={credential.typeId}
|
||||
label={i18n._(t`Insights Credential`)}
|
||||
@ -31,7 +32,7 @@ const InsightsSubForm = ({
|
||||
required
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</Field>
|
||||
<ScmTypeOptions hideAllowOverride scmUpdateOnLaunch={scmUpdateOnLaunch} />
|
||||
</>
|
||||
);
|
||||
|
@ -76,7 +76,8 @@ const ManualSubForm = ({
|
||||
<Field
|
||||
name="local_path"
|
||||
validate={required(i18n._(t`Select a value for this field`), i18n)}
|
||||
render={({ field, form }) => (
|
||||
>
|
||||
{({ field, form }) => (
|
||||
<FormGroup
|
||||
fieldId="project-local-path"
|
||||
helperTextInvalid={form.errors.local_path}
|
||||
@ -99,7 +100,7 @@ const ManualSubForm = ({
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
/>
|
||||
</Field>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
@ -42,9 +42,8 @@ export const BranchFormField = withI18n()(({ i18n, label }) => (
|
||||
|
||||
export const ScmCredentialFormField = withI18n()(
|
||||
({ i18n, credential, onCredentialSelection }) => (
|
||||
<Field
|
||||
name="credential"
|
||||
render={({ form }) => (
|
||||
<Field name="credential">
|
||||
{({ form }) => (
|
||||
<CredentialLookup
|
||||
credentialTypeId={credential.typeId}
|
||||
label={i18n._(t`SCM Credential`)}
|
||||
@ -55,7 +54,7 @@ export const ScmCredentialFormField = withI18n()(
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</Field>
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -24,7 +24,8 @@ function TeamForm(props) {
|
||||
organization: team.organization || '',
|
||||
}}
|
||||
onSubmit={handleSubmit}
|
||||
render={formik => (
|
||||
>
|
||||
{formik => (
|
||||
<Form
|
||||
autoComplete="off"
|
||||
onSubmit={formik.handleSubmit}
|
||||
@ -51,7 +52,8 @@ function TeamForm(props) {
|
||||
i18n._(t`Select a value for this field`),
|
||||
i18n
|
||||
)}
|
||||
render={({ form }) => (
|
||||
>
|
||||
{({ form }) => (
|
||||
<OrganizationLookup
|
||||
helperTextInvalid={form.errors.organization}
|
||||
isValid={
|
||||
@ -66,7 +68,7 @@ function TeamForm(props) {
|
||||
required
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</Field>
|
||||
</FormRow>
|
||||
<FormActionGroup
|
||||
onCancel={handleCancel}
|
||||
@ -74,7 +76,7 @@ function TeamForm(props) {
|
||||
/>
|
||||
</Form>
|
||||
)}
|
||||
/>
|
||||
</Formik>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
import React from 'react';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { mountWithContexts, waitForElement } from '@testUtils/enzymeHelpers';
|
||||
import { sleep } from '@testUtils/testUtils';
|
||||
|
||||
import TeamForm from './TeamForm';
|
||||
|
||||
@ -42,23 +41,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(() => {
|
||||
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('onChange')({
|
||||
id: 2,
|
||||
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 () => {
|
||||
@ -75,8 +79,9 @@ describe('<TeamForm />', () => {
|
||||
});
|
||||
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
|
||||
expect(handleSubmit).not.toHaveBeenCalled();
|
||||
wrapper.find('button[aria-label="Save"]').simulate('click');
|
||||
await sleep(1);
|
||||
await act(async () => {
|
||||
wrapper.find('button[aria-label="Save"]').simulate('click');
|
||||
});
|
||||
expect(handleSubmit).toBeCalled();
|
||||
});
|
||||
|
||||
|
@ -2,7 +2,6 @@ import React from 'react';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { createMemoryHistory } from 'history';
|
||||
import { mountWithContexts, waitForElement } from '@testUtils/enzymeHelpers';
|
||||
import { sleep } from '@testUtils/testUtils';
|
||||
import JobTemplateAdd from './JobTemplateAdd';
|
||||
import { JobTemplatesAPI, LabelsAPI } from '@api';
|
||||
|
||||
@ -100,25 +99,37 @@ describe('<JobTemplateAdd />', () => {
|
||||
wrapper = mountWithContexts(<JobTemplateAdd />);
|
||||
});
|
||||
await waitForElement(wrapper, 'EmptyStateBody', el => el.length === 0);
|
||||
const formik = wrapper.find('Formik').instance();
|
||||
await act(async () => {
|
||||
const changeState = new Promise(resolve => {
|
||||
formik.setState(
|
||||
{
|
||||
values: {
|
||||
...jobTemplateData,
|
||||
labels: [],
|
||||
instanceGroups: [],
|
||||
},
|
||||
},
|
||||
() => resolve()
|
||||
);
|
||||
act(() => {
|
||||
wrapper.find('input#template-name').simulate('change', {
|
||||
target: { value: 'Foo', name: 'name' },
|
||||
});
|
||||
await changeState;
|
||||
wrapper.find('AnsibleSelect#template-job-type').invoke('onChange')('run');
|
||||
wrapper.find('InventoryLookup').invoke('onChange')({
|
||||
id: 1,
|
||||
organization: 1,
|
||||
});
|
||||
wrapper.find('ProjectLookup').invoke('onChange')({
|
||||
id: 2,
|
||||
name: 'project',
|
||||
});
|
||||
wrapper.update();
|
||||
wrapper
|
||||
.find('PlaybookSelect')
|
||||
.prop('field')
|
||||
.onChange({
|
||||
target: { value: 'Bar', name: 'playbook' },
|
||||
});
|
||||
});
|
||||
wrapper.update();
|
||||
await act(async () => {
|
||||
wrapper.find('form').simulate('submit');
|
||||
});
|
||||
wrapper.update();
|
||||
expect(JobTemplatesAPI.create).toHaveBeenCalledWith({
|
||||
...jobTemplateData,
|
||||
description: '',
|
||||
become_enabled: false,
|
||||
});
|
||||
wrapper.find('form').simulate('submit');
|
||||
await sleep(1);
|
||||
expect(JobTemplatesAPI.create).toHaveBeenCalledWith(jobTemplateData);
|
||||
});
|
||||
|
||||
test('should navigate to job template detail after form submission', async () => {
|
||||
@ -136,36 +147,34 @@ describe('<JobTemplateAdd />', () => {
|
||||
context: { router: { history } },
|
||||
});
|
||||
});
|
||||
await waitForElement(wrapper, 'EmptyStateBody', el => el.length === 0);
|
||||
act(() => {
|
||||
wrapper.find('input#template-name').simulate('change', {
|
||||
target: { value: 'Foo', name: 'name' },
|
||||
});
|
||||
wrapper.find('AnsibleSelect#template-job-type').invoke('onChange')('run');
|
||||
wrapper.find('InventoryLookup').invoke('onChange')({
|
||||
id: 1,
|
||||
organization: 1,
|
||||
});
|
||||
wrapper.find('ProjectLookup').invoke('onChange')({
|
||||
id: 2,
|
||||
name: 'project',
|
||||
});
|
||||
wrapper.update();
|
||||
wrapper
|
||||
.find('PlaybookSelect')
|
||||
.prop('field')
|
||||
.onChange({
|
||||
target: { value: 'Bar', name: 'playbook' },
|
||||
});
|
||||
});
|
||||
wrapper.update();
|
||||
await act(async () => {
|
||||
wrapper.find('form').simulate('submit');
|
||||
});
|
||||
wrapper.update();
|
||||
|
||||
const updatedTemplateData = {
|
||||
name: 'new name',
|
||||
description: 'new description',
|
||||
job_type: 'check',
|
||||
};
|
||||
const labels = [
|
||||
{ id: 3, name: 'Foo', isNew: true },
|
||||
{ id: 4, name: 'Bar', isNew: true },
|
||||
{ id: 5, name: 'Maple' },
|
||||
{ id: 6, name: 'Tree' },
|
||||
];
|
||||
JobTemplatesAPI.update.mockResolvedValue({
|
||||
data: { ...updatedTemplateData },
|
||||
});
|
||||
const formik = wrapper.find('Formik').instance();
|
||||
const changeState = new Promise(resolve => {
|
||||
const values = {
|
||||
...jobTemplateData,
|
||||
...updatedTemplateData,
|
||||
labels,
|
||||
instanceGroups: [],
|
||||
};
|
||||
formik.setState({ values }, () => resolve());
|
||||
});
|
||||
await changeState;
|
||||
await wrapper.find('JobTemplateForm').invoke('handleSubmit')(
|
||||
jobTemplateData
|
||||
);
|
||||
await sleep(0);
|
||||
expect(history.location.pathname).toEqual(
|
||||
'/templates/job_template/1/details'
|
||||
);
|
||||
|
@ -184,11 +184,9 @@ describe('<JobTemplateEdit />', () => {
|
||||
<JobTemplateEdit template={mockJobTemplate} />
|
||||
);
|
||||
});
|
||||
await waitForElement(wrapper, 'JobTemplateForm', e => e.length === 1);
|
||||
const updatedTemplateData = {
|
||||
name: 'new name',
|
||||
description: 'new description',
|
||||
job_type: 'check',
|
||||
inventory: 1,
|
||||
};
|
||||
const labels = [
|
||||
{ id: 3, name: 'Foo', isNew: true },
|
||||
@ -196,32 +194,35 @@ describe('<JobTemplateEdit />', () => {
|
||||
{ id: 5, name: 'Maple' },
|
||||
{ id: 6, name: 'Tree' },
|
||||
];
|
||||
JobTemplatesAPI.update.mockResolvedValue({
|
||||
data: { ...updatedTemplateData },
|
||||
await waitForElement(wrapper, 'EmptyStateBody', el => el.length === 0);
|
||||
act(() => {
|
||||
wrapper.find('input#template-name').simulate('change', {
|
||||
target: { value: 'new name', name: 'name' },
|
||||
});
|
||||
wrapper.find('AnsibleSelect#template-job-type').invoke('onChange')(
|
||||
'check'
|
||||
);
|
||||
wrapper.find('InventoryLookup').invoke('onChange')({
|
||||
id: 1,
|
||||
organization: 1,
|
||||
});
|
||||
wrapper.find('LabelSelect').invoke('onChange')(labels);
|
||||
});
|
||||
const formik = wrapper.find('Formik').instance();
|
||||
const changeState = await act(
|
||||
() =>
|
||||
new Promise(resolve => {
|
||||
const values = {
|
||||
...mockJobTemplate,
|
||||
...updatedTemplateData,
|
||||
labels,
|
||||
instanceGroups: [],
|
||||
};
|
||||
formik.setState({ values }, () => resolve());
|
||||
})
|
||||
);
|
||||
await changeState;
|
||||
wrapper.update();
|
||||
await act(async () => {
|
||||
wrapper.find('button[aria-label="Save"]').simulate('click');
|
||||
});
|
||||
await sleep(0);
|
||||
|
||||
expect(JobTemplatesAPI.update).toHaveBeenCalledWith(1, {
|
||||
const expected = {
|
||||
...mockJobTemplate,
|
||||
...updatedTemplateData,
|
||||
});
|
||||
become_enabled: false,
|
||||
};
|
||||
delete expected.summary_fields;
|
||||
delete expected.id;
|
||||
delete expected.type;
|
||||
expect(JobTemplatesAPI.update).toHaveBeenCalledWith(1, expected);
|
||||
expect(JobTemplatesAPI.disassociateLabel).toHaveBeenCalledTimes(2);
|
||||
expect(JobTemplatesAPI.associateLabel).toHaveBeenCalledTimes(2);
|
||||
expect(JobTemplatesAPI.generateLabel).toHaveBeenCalledTimes(2);
|
||||
|
@ -205,7 +205,8 @@ class JobTemplateForm extends Component {
|
||||
name="job_type"
|
||||
validate={required(null, i18n)}
|
||||
onBlur={handleBlur}
|
||||
render={({ form, field }) => {
|
||||
>
|
||||
{({ form, field }) => {
|
||||
const isValid = !form.touched.job_type || !form.errors.job_type;
|
||||
return (
|
||||
<FormGroup
|
||||
@ -230,11 +231,12 @@ class JobTemplateForm extends Component {
|
||||
</FormGroup>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</Field>
|
||||
<Field
|
||||
name="inventory"
|
||||
validate={required(i18n._(t`Select a value for this field`), i18n)}
|
||||
render={({ form }) => (
|
||||
>
|
||||
{({ form }) => (
|
||||
<InventoryLookup
|
||||
value={inventory}
|
||||
onBlur={() => form.setFieldTouched('inventory')}
|
||||
@ -252,11 +254,9 @@ class JobTemplateForm extends Component {
|
||||
error={form.errors.inventory}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<Field
|
||||
name="project"
|
||||
validate={this.handleProjectValidation()}
|
||||
render={({ form }) => (
|
||||
</Field>
|
||||
<Field name="project" validate={this.handleProjectValidation()}>
|
||||
{({ form }) => (
|
||||
<ProjectLookup
|
||||
value={project}
|
||||
onBlur={() => form.setFieldTouched('project')}
|
||||
@ -268,12 +268,13 @@ class JobTemplateForm extends Component {
|
||||
required
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</Field>
|
||||
<Field
|
||||
name="playbook"
|
||||
validate={required(i18n._(t`Select a value for this field`), i18n)}
|
||||
onBlur={handleBlur}
|
||||
render={({ field, form }) => {
|
||||
>
|
||||
{({ field, form }) => {
|
||||
const isValid = !form.touched.playbook || !form.errors.playbook;
|
||||
return (
|
||||
<FormGroup
|
||||
@ -299,12 +300,11 @@ class JobTemplateForm extends Component {
|
||||
</FormGroup>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</Field>
|
||||
</FormRow>
|
||||
<FormRow>
|
||||
<Field
|
||||
name="labels"
|
||||
render={({ field }) => (
|
||||
<Field name="labels">
|
||||
{({ field }) => (
|
||||
<FormGroup label={i18n._(t`Labels`)} fieldId="template-labels">
|
||||
<FieldTooltip
|
||||
content={i18n._(t`Optional labels that describe this job template,
|
||||
@ -318,13 +318,11 @@ class JobTemplateForm extends Component {
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
/>
|
||||
</Field>
|
||||
</FormRow>
|
||||
<FormRow>
|
||||
<Field
|
||||
name="credentials"
|
||||
fieldId="template-credentials"
|
||||
render={({ field }) => (
|
||||
<Field name="credentials" fieldId="template-credentials">
|
||||
{({ field }) => (
|
||||
<MultiCredentialsLookup
|
||||
value={field.value}
|
||||
onChange={newCredentials =>
|
||||
@ -336,7 +334,7 @@ class JobTemplateForm extends Component {
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</Field>
|
||||
</FormRow>
|
||||
<AdvancedFieldsWrapper label="Advanced">
|
||||
<FormRow>
|
||||
@ -369,9 +367,8 @@ class JobTemplateForm extends Component {
|
||||
playbook. Multiple patterns are allowed. Refer to Ansible
|
||||
documentation for more information and examples on patterns.`)}
|
||||
/>
|
||||
<Field
|
||||
name="verbosity"
|
||||
render={({ field }) => (
|
||||
<Field name="verbosity">
|
||||
{({ field }) => (
|
||||
<FormGroup
|
||||
fieldId="template-verbosity"
|
||||
label={i18n._(t`Verbosity`)}
|
||||
@ -387,7 +384,7 @@ class JobTemplateForm extends Component {
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
/>
|
||||
</Field>
|
||||
<FormField
|
||||
id="template-job-slicing"
|
||||
name="job_slice_count"
|
||||
@ -408,9 +405,8 @@ class JobTemplateForm extends Component {
|
||||
before the task is canceled. Defaults to 0 for no job
|
||||
timeout.`)}
|
||||
/>
|
||||
<Field
|
||||
name="diff_mode"
|
||||
render={({ field, form }) => (
|
||||
<Field name="diff_mode">
|
||||
{({ field, form }) => (
|
||||
<FormGroup
|
||||
fieldId="template-show-changes"
|
||||
label={i18n._(t`Show Changes`)}
|
||||
@ -432,11 +428,10 @@ class JobTemplateForm extends Component {
|
||||
</div>
|
||||
</FormGroup>
|
||||
)}
|
||||
/>
|
||||
</Field>
|
||||
</FormRow>
|
||||
<Field
|
||||
name="instanceGroups"
|
||||
render={({ field, form }) => (
|
||||
<Field name="instanceGroups">
|
||||
{({ field, form }) => (
|
||||
<InstanceGroupsLookup
|
||||
css="margin-top: 20px"
|
||||
value={field.value}
|
||||
@ -445,10 +440,9 @@ class JobTemplateForm extends Component {
|
||||
to run on.`)}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<Field
|
||||
name="job_tags"
|
||||
render={({ field, form }) => (
|
||||
</Field>
|
||||
<Field name="job_tags">
|
||||
{({ field, form }) => (
|
||||
<FormGroup
|
||||
label={i18n._(t`Job Tags`)}
|
||||
css="margin-top: 20px"
|
||||
@ -467,10 +461,9 @@ class JobTemplateForm extends Component {
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
/>
|
||||
<Field
|
||||
name="skip_tags"
|
||||
render={({ field, form }) => (
|
||||
</Field>
|
||||
<Field name="skip_tags">
|
||||
{({ field, form }) => (
|
||||
<FormGroup
|
||||
label={i18n._(t`Skip Tags`)}
|
||||
css="margin-top: 20px"
|
||||
@ -489,7 +482,7 @@ class JobTemplateForm extends Component {
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
/>
|
||||
</Field>
|
||||
<GridFormGroup
|
||||
fieldId="template-option-checkboxes"
|
||||
isInline
|
||||
|
@ -128,43 +128,59 @@ describe('<JobTemplateForm />', () => {
|
||||
});
|
||||
|
||||
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 () => {
|
||||
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')({
|
||||
id: 4,
|
||||
name: 'project',
|
||||
});
|
||||
});
|
||||
expect(form.state('values').project).toEqual(4);
|
||||
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.find('AnsibleSelect[name="playbook"]').simulate('change', {
|
||||
target: { value: 'new baz type', name: 'playbook' },
|
||||
});
|
||||
wrapper
|
||||
.find('CredentialChip')
|
||||
.at(0)
|
||||
.prop('onClick')();
|
||||
});
|
||||
expect(form.state('values').credentials).toEqual([
|
||||
{ id: 2, kind: 'ssh', name: 'Bar' },
|
||||
wrapper.update();
|
||||
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',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
|
@ -76,7 +76,8 @@ function UserForm(props) {
|
||||
user_type: userType,
|
||||
}}
|
||||
onSubmit={handleValidateAndSubmit}
|
||||
render={formik => (
|
||||
>
|
||||
{formik => (
|
||||
<Form
|
||||
autoComplete="off"
|
||||
onSubmit={formik.handleSubmit}
|
||||
@ -141,7 +142,8 @@ function UserForm(props) {
|
||||
i18n._(t`Select a value for this field`),
|
||||
i18n
|
||||
)}
|
||||
render={({ form }) => (
|
||||
>
|
||||
{({ form }) => (
|
||||
<OrganizationLookup
|
||||
helperTextInvalid={form.errors.organization}
|
||||
isValid={
|
||||
@ -156,11 +158,10 @@ function UserForm(props) {
|
||||
required
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</Field>
|
||||
)}
|
||||
<Field
|
||||
name="user_type"
|
||||
render={({ form, field }) => {
|
||||
<Field name="user_type">
|
||||
{({ form, field }) => {
|
||||
const isValid =
|
||||
!form.touched.user_type || !form.errors.user_type;
|
||||
return (
|
||||
@ -180,7 +181,7 @@ function UserForm(props) {
|
||||
</FormGroup>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</Field>
|
||||
</FormRow>
|
||||
<FormActionGroup
|
||||
onCancel={handleCancel}
|
||||
@ -188,7 +189,7 @@ function UserForm(props) {
|
||||
/>
|
||||
</Form>
|
||||
)}
|
||||
/>
|
||||
</Formik>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
import React from 'react';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { mountWithContexts, waitForElement } from '@testUtils/enzymeHelpers';
|
||||
import { sleep } from '@testUtils/testUtils';
|
||||
import UserForm from './UserForm';
|
||||
import { UsersAPI } from '@api';
|
||||
import mockData from '../data.user.json';
|
||||
@ -77,15 +76,18 @@ describe('<UserForm />', () => {
|
||||
);
|
||||
});
|
||||
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
|
||||
const form = wrapper.find('Formik');
|
||||
act(() => {
|
||||
await act(async () => {
|
||||
wrapper.find('OrganizationLookup').invoke('onBlur')();
|
||||
wrapper.find('OrganizationLookup').invoke('onChange')({
|
||||
id: 1,
|
||||
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 () => {
|
||||
@ -133,8 +135,9 @@ describe('<UserForm />', () => {
|
||||
});
|
||||
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
|
||||
expect(handleSubmit).not.toHaveBeenCalled();
|
||||
wrapper.find('button[aria-label="Save"]').simulate('click');
|
||||
await sleep(1);
|
||||
await act(async () => {
|
||||
wrapper.find('button[aria-label="Save"]').simulate('click');
|
||||
});
|
||||
expect(handleSubmit).toBeCalled();
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user