diff --git a/awx/ui_next/package-lock.json b/awx/ui_next/package-lock.json index 57363aa6d9..3eb67251fb 100644 --- a/awx/ui_next/package-lock.json +++ b/awx/ui_next/package-lock.json @@ -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", diff --git a/awx/ui_next/package.json b/awx/ui_next/package.json index b5a104a19d..b885457571 100644 --- a/awx/ui_next/package.json +++ b/awx/ui_next/package.json @@ -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", diff --git a/awx/ui_next/src/components/FormField/FormField.jsx b/awx/ui_next/src/components/FormField/FormField.jsx index f40792cc06..f55eabb131 100644 --- a/awx/ui_next/src/components/FormField/FormField.jsx +++ b/awx/ui_next/src/components/FormField/FormField.jsx @@ -22,10 +22,8 @@ function FormField(props) { } = props; return ( - { + + {({ field, form }) => { const isValid = form && (!form.touched[field.name] || !form.errors[field.name]); @@ -59,7 +57,7 @@ function FormField(props) { ); }} - /> + ); } diff --git a/awx/ui_next/src/screens/Host/shared/HostForm.jsx b/awx/ui_next/src/screens/Host/shared/HostForm.jsx index f7f4e472a7..837f1edc7e 100644 --- a/awx/ui_next/src/screens/Host/shared/HostForm.jsx +++ b/awx/ui_next/src/screens/Host/shared/HostForm.jsx @@ -19,6 +19,7 @@ function HostForm({ handleSubmit, handleCancel, host, i18n }) { const [inventory, setInventory] = useState( host ? host.summary_fields.inventory : '' ); + console.log('render'); return ( ', () => { jest.clearAllMocks(); }); - test('changing inputs should update form values', () => { - const wrapper = mountWithContexts( - - ); + test('changing inputs should update form values', async () => { + let wrapper; + await act(async () => { + wrapper = mountWithContexts( + + ); + }); - 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 +70,9 @@ describe('', () => { /> ); 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(); }); diff --git a/awx/ui_next/src/screens/Inventory/InventoryHostAdd/InventoryHostAdd.test.jsx b/awx/ui_next/src/screens/Inventory/InventoryHostAdd/InventoryHostAdd.test.jsx index d5b6cdc0a2..ac46ae34f4 100644 --- a/awx/ui_next/src/screens/Inventory/InventoryHostAdd/InventoryHostAdd.test.jsx +++ b/awx/ui_next/src/screens/Inventory/InventoryHostAdd/InventoryHostAdd.test.jsx @@ -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('', () => { 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'); }); diff --git a/awx/ui_next/src/screens/Inventory/shared/InventoryForm.test.jsx b/awx/ui_next/src/screens/Inventory/shared/InventoryForm.test.jsx index 4abf6fb98d..36132fdbf5 100644 --- a/awx/ui_next/src/screens/Inventory/shared/InventoryForm.test.jsx +++ b/awx/ui_next/src/screens/Inventory/shared/InventoryForm.test.jsx @@ -64,12 +64,15 @@ describe('', () => { /> ); }); + 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 +83,37 @@ describe('', () => { ); 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 () => { diff --git a/awx/ui_next/src/screens/Inventory/shared/InventoryHostForm.jsx b/awx/ui_next/src/screens/Inventory/shared/InventoryHostForm.jsx index 85e5a901ea..23965bdc8b 100644 --- a/awx/ui_next/src/screens/Inventory/shared/InventoryHostForm.jsx +++ b/awx/ui_next/src/screens/Inventory/shared/InventoryHostForm.jsx @@ -46,7 +46,9 @@ function InventoryHostForm({ handleSubmit, handleCancel, host, i18n }) { { + formik.handleSubmit(); + }} /> )} diff --git a/awx/ui_next/src/screens/Inventory/shared/InventoryHostForm.test.jsx b/awx/ui_next/src/screens/Inventory/shared/InventoryHostForm.test.jsx index f247914420..72a1d3b08e 100644 --- a/awx/ui_next/src/screens/Inventory/shared/InventoryHostForm.test.jsx +++ b/awx/ui_next/src/screens/Inventory/shared/InventoryHostForm.test.jsx @@ -43,8 +43,9 @@ describe('', () => { 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(); }); diff --git a/awx/ui_next/src/screens/Project/ProjectAdd/ProjectAdd.test.jsx b/awx/ui_next/src/screens/Project/ProjectAdd/ProjectAdd.test.jsx index c4d5bc16f1..ebc40aa1d6 100644 --- a/awx/ui_next/src/screens/Project/ProjectAdd/ProjectAdd.test.jsx +++ b/awx/ui_next/src/screens/Project/ProjectAdd/ProjectAdd.test.jsx @@ -97,24 +97,7 @@ describe('', () => { wrapper = mountWithContexts(); }); 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); }); diff --git a/awx/ui_next/src/screens/Project/shared/ProjectForm.test.jsx b/awx/ui_next/src/screens/Project/shared/ProjectForm.test.jsx index d4b901c47c..a4c99a95ad 100644 --- a/awx/ui_next/src/screens/Project/shared/ProjectForm.test.jsx +++ b/awx/ui_next/src/screens/Project/shared/ProjectForm.test.jsx @@ -130,19 +130,11 @@ describe('', () => { ); }); 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 +158,58 @@ describe('', () => { ); }); 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( ); }); 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 +280,8 @@ describe('', () => { 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 +289,8 @@ describe('', () => { 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 +301,7 @@ describe('', () => { 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 +317,9 @@ describe('', () => { }); 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(); }); diff --git a/awx/ui_next/src/screens/Team/shared/TeamForm.test.jsx b/awx/ui_next/src/screens/Team/shared/TeamForm.test.jsx index da8a5d282e..de94757b0d 100644 --- a/awx/ui_next/src/screens/Team/shared/TeamForm.test.jsx +++ b/awx/ui_next/src/screens/Team/shared/TeamForm.test.jsx @@ -42,23 +42,28 @@ describe('', () => { ); }); - 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 +80,9 @@ describe('', () => { }); 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(); }); diff --git a/awx/ui_next/src/screens/Template/shared/JobTemplateForm.test.jsx b/awx/ui_next/src/screens/Template/shared/JobTemplateForm.test.jsx index aa16a8a736..5e6b3ec9b6 100644 --- a/awx/ui_next/src/screens/Template/shared/JobTemplateForm.test.jsx +++ b/awx/ui_next/src/screens/Template/shared/JobTemplateForm.test.jsx @@ -128,43 +128,59 @@ describe('', () => { }); 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', + }, ]); }); diff --git a/awx/ui_next/src/screens/User/shared/UserForm.test.jsx b/awx/ui_next/src/screens/User/shared/UserForm.test.jsx index 4bea4ef649..e9b14f988d 100644 --- a/awx/ui_next/src/screens/User/shared/UserForm.test.jsx +++ b/awx/ui_next/src/screens/User/shared/UserForm.test.jsx @@ -77,15 +77,18 @@ describe('', () => { ); }); 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 +136,9 @@ describe('', () => { }); 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(); });