UNPKG

@carbon/ibm-cloud-cognitive-cdai

Version:
660 lines (655 loc) 23.9 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); var _ = require("."); var _helpers = require("./helpers"); var _carbonComponentsReact = require("carbon-components-react"); var _react = require("@testing-library/react"); var _react2 = _interopRequireDefault(require("react")); var _enzyme = require("enzyme"); var _enzymeAdapterReact = _interopRequireDefault(require("enzyme-adapter-react-16")); var _sleep = _interopRequireDefault(require("../../component_helpers/sleep")); function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } // // Copyright IBM Corp. 2020, 2020 // // This source code is licensed under the Apache-2.0 license found in the // LICENSE file in the root directory of this source tree. // // import {act} from 'react-dom/test-utils'; (0, _enzyme.configure)({ adapter: new _enzymeAdapterReact.default() }); describe('IdeImporting unit tests', function () { it('should render correct contents (both url and file)', function () { var mockHandleFileAdded = jest.fn(); var props = { enableFileDrop: false, validExtensions: ['png'], onFileAdded: mockHandleFileAdded }; var wrapper = new IdeImportingWrapper(props); wrapper.unmount(); }); it('should render correct contents (file only)', function () { var mockHandleFileAdded = jest.fn(); var props = { validExtensions: ['png'], onFileAdded: mockHandleFileAdded, enableUrlInput: false }; var wrapper = new IdeImportingWrapper(props); wrapper.unmount(); }); it('should render correct contents (url only)', function () { var mockHandleFileAdded = jest.fn(); var props = { validExtensions: ['png'], onFileAdded: mockHandleFileAdded, enableFile: false }; var wrapper = new IdeImportingWrapper(props); wrapper.unmount(); }); it('should handle adding a file via drop', function () { var mockHandleFileAdded = jest.fn(); var props = { validExtensions: ['png'], onFileAdded: mockHandleFileAdded }; var wrapper = new IdeImportingWrapper(props); wrapper.simulateDropFiles([{ name: 'test-file.png' }]); wrapper.expectPropCalled('onFileAdded'); }); it('should handle adding a file via drop (single)', function () { var mockHandleFileAdded = jest.fn(); var props = { multiple: false, validExtensions: ['png'], onFileAdded: mockHandleFileAdded }; var wrapper = new IdeImportingWrapper(props); wrapper.simulateDropFiles([{ name: 'test-file.png' }]); wrapper.expectPropCalled('onFileAdded'); }); it('should hide the file drop area after uploading a single file', function () { var mockHandleFileAdded = jest.fn(); var props = { multiple: false, validExtensions: ['png'], hideImport: true, onFileAdded: mockHandleFileAdded }; var wrapper = new IdeImportingWrapper(props); var errorMessage = new Error('FileUploaderDropContainer not found when using strictFind()'); wrapper.simulateDropFiles([{ name: 'test-file.png' }]); wrapper.expectPropCalled('onFileAdded'); expect(function () { wrapper.strictFind('FileUploaderDropContainer'); }).toThrow(errorMessage); wrapper.unmount(); }); it('should handle an initial state value', function () { var mockHandleFileAdded = jest.fn(); var props = { multiple: false, validExtensions: ['yml'], hideImport: true, onFileAdded: mockHandleFileAdded, initialFiles: [{ file: { lastModified: 1606086665265, lastModifiedDate: 'Sun Nov 22 2020 23:11:05 GMT+0000 (Greenwich Mean Time)', name: 'accounts', size: 702, type: 'application/x-yaml', webkitRelativePath: '', index: 0 }, invalid: false, status: 'edit', url: undefined, uuid: 'b4a92c13-10ca' }] }; var wrapper = new IdeImportingWrapper(props); var errorMessage = new Error('FileUploaderDropContainer not found when using strictFind()'); expect(function () { wrapper.strictFind('FileUploaderDropContainer'); }).toThrow(errorMessage); wrapper.unmount(); }); it('should disable the file drop as soon as there is text in the URL field (single)', function () { var mockHandleFileAdded = jest.fn(); var props = { multiple: false, validExtensions: ['png'], onFileAdded: mockHandleFileAdded }; var wrapper = new IdeImportingWrapper(props); wrapper.changeUrl('http://valid.com/image.png'); expect(wrapper.strictFind('FileUploaderDropContainer').prop('disabled')).toBe(true); wrapper.unmount(); }); it('should handle errors thrown by onFileAdded', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee() { var warn, props, wrapper; return _regenerator.default.wrap(function _callee$(_context) { while (1) switch (_context.prev = _context.next) { case 0: warn = jest.spyOn(console, 'warn').mockImplementation(function () {}); props = { validExtensions: ['png'], onFileAdded: jest.fn(function () { throw new Error('Subject: message'); }) }; wrapper = new IdeImportingWrapper(props); wrapper.simulateDropFiles([{ name: 'test-file.png' }]); expect(props.onFileAdded).toBeCalled(); expect(props.onFileAdded).toThrow(); _context.next = 8; return (0, _react.waitFor)(function () { expect(warn).toBeCalledWith(expect.objectContaining({ message: 'Subject: message' })); }); case 8: wrapper.unmount(); warn.mockRestore(); case 10: case "end": return _context.stop(); } }, _callee); }))); it('should handle removing a file', function () { var mockHandleFileAdded = jest.fn(); var props = { validExtensions: ['png'], onFileAdded: mockHandleFileAdded }; var wrapper = new IdeImportingWrapper(props); wrapper.simulateDropFiles([{ name: 'test-file.png' }]); wrapper.expectPropCalled('onFileAdded'); wrapper.removeFirstFile(); wrapper.expectNoFiles(); }); it('should call onFileRemoved when removing a file if supplied', function () { var mockHandleFileAdded = jest.fn(); var mockHandleFileRemoved = jest.fn(); var props = { validExtensions: ['png'], onFileAdded: mockHandleFileAdded, onFileRemoved: mockHandleFileRemoved }; var wrapper = new IdeImportingWrapper(props); wrapper.simulateDropFiles([{ name: 'test-file.png' }]); wrapper.expectPropCalled('onFileAdded'); wrapper.removeFirstFile(); wrapper.expectPropCalled('onFileRemoved'); wrapper.expectNoFiles(); }); it('should handle adding a file larger than the max size via drop', function () { var mockHandleFileAdded = jest.fn(); var props = { validExtensions: ['png'], onFileAdded: mockHandleFileAdded, maxFileSize: 100 }; var wrapper = new IdeImportingWrapper(props); wrapper.simulateDropFiles([{ name: 'test-file.png', size: 200 }]); expect(mockHandleFileAdded).not.toBeCalled(); wrapper.unmount(); }); it('should handle adding a file with no extension via drop', function () { var mockHandleFileAdded = jest.fn(); var props = { validExtensions: ['png'], onFileAdded: mockHandleFileAdded, extensionRequired: true }; var wrapper = new IdeImportingWrapper(props); wrapper.simulateDropFiles([{ name: 'test-file' }]); expect(mockHandleFileAdded).not.toBeCalled(); wrapper.unmount(); }); it('should handle adding a file with an invalid file name via drop', function () { var mockHandleFileAdded = jest.fn(); var props = { validExtensions: ['png'], onFileAdded: mockHandleFileAdded }; var wrapper = new IdeImportingWrapper(props); wrapper.addFileViaUrl('****'); expect(mockHandleFileAdded).not.toBeCalled(); wrapper.unmount(); }); it('should handle adding a file via url', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee2() { var mockHandleFileAdded, props, wrapper; return _regenerator.default.wrap(function _callee2$(_context2) { while (1) switch (_context2.prev = _context2.next) { case 0: mockHandleFileAdded = jest.fn(); props = { validExtensions: ['png'], onFileAdded: mockHandleFileAdded }; wrapper = new IdeImportingWrapper(props); wrapper.addFileViaUrl('http://valid.com/image.png'); wrapper.expectPropCalled('onFileAdded'); case 5: case "end": return _context2.stop(); } }, _callee2); }))); it('should handle custom url validation', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee3() { var mockHandleFileAdded, props, wrapper; return _regenerator.default.wrap(function _callee3$(_context3) { while (1) switch (_context3.prev = _context3.next) { case 0: mockHandleFileAdded = jest.fn(); props = { validExtensions: ['png'], onFileAdded: mockHandleFileAdded, onValidateUrl: jest.fn(function () { return true; }) }; wrapper = new IdeImportingWrapper(props); wrapper.addFileViaUrl('http://valid.com/image.png'); wrapper.expectPropCalled('onFileAdded'); wrapper.expectPropCalled('onValidateUrl'); case 6: case "end": return _context3.stop(); } }, _callee3); }))); it('should handle invalid url extensions', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee4() { var mockHandleFileAdded, props, wrapper; return _regenerator.default.wrap(function _callee4$(_context4) { while (1) switch (_context4.prev = _context4.next) { case 0: mockHandleFileAdded = jest.fn(); props = { validExtensions: ['png'], onFileAdded: mockHandleFileAdded }; wrapper = new IdeImportingWrapper(props); wrapper.addFileViaUrl('http://valid.com/image.notvalid'); expect(mockHandleFileAdded).not.toBeCalled(); wrapper.unmount(); case 6: case "end": return _context4.stop(); } }, _callee4); }))); it('should allow invalid url extensions when enabled', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee5() { var mockHandleFileAdded, props, wrapper; return _regenerator.default.wrap(function _callee5$(_context5) { while (1) switch (_context5.prev = _context5.next) { case 0: mockHandleFileAdded = jest.fn(); props = { validExtensions: ['png'], allowInvalidFilenameInUrl: true, onFileAdded: mockHandleFileAdded }; wrapper = new IdeImportingWrapper(props); wrapper.addFileViaUrl('http://valid.com/image.notvalid'); expect(mockHandleFileAdded).toBeCalled(); case 5: case "end": return _context5.stop(); } }, _callee5); }))); it('should handle invalid url extensions plural', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee6() { var mockHandleFileAdded, props, wrapper; return _regenerator.default.wrap(function _callee6$(_context6) { while (1) switch (_context6.prev = _context6.next) { case 0: mockHandleFileAdded = jest.fn(); props = { validExtensions: ['yml', 'yaml'], onFileAdded: mockHandleFileAdded }; wrapper = new IdeImportingWrapper(props); wrapper.addFileViaUrl('http://valid.com/image.notvalid'); expect(mockHandleFileAdded).not.toBeCalled(); wrapper.unmount(); case 6: case "end": return _context6.stop(); } }, _callee6); }))); it('should allow for FileUploaderItem to call onDelete', function () { var mockHandleFileAdded = jest.fn(); var props = { enableUpload: false, validExtensions: ['png'], onFileAdded: mockHandleFileAdded }; var wrapper = new IdeImportingWrapper(props); wrapper.dropAFewPngFiles(); wrapper.simulateDeleteFile(); }); describe('countFiles', function () { it('should return the correct counts for empty set', function () { var files = []; var counts = (0, _helpers.countFiles)(files); expect(counts).toHaveProperty('finished', 0); expect(counts).toHaveProperty('uploading', 0); expect(counts).toHaveProperty('invalid', 0); expect(counts).toHaveProperty('total', 0); }); it('should return the correct counts for invalid set', function () { var files = [{ invalid: true }]; var counts = (0, _helpers.countFiles)(files); expect(counts).toHaveProperty('finished', 0); expect(counts).toHaveProperty('uploading', 0); expect(counts).toHaveProperty('invalid', 1); expect(counts).toHaveProperty('total', 1); }); }); describe('sortFiles', function () { it('should ensure error files are first', function () { var files = [{ index: 0, status: _helpers.FILE_UPLOAD_STATUS.COMPLETE }, { index: 1, status: _helpers.FILE_UPLOAD_STATUS.EDIT }, { index: 2, status: _helpers.FILE_UPLOAD_STATUS.UPLOADING }]; var sorted = files.sort(function (a, b) { return (0, _helpers.sortFiles)(a, b, files.length); }); expect(sorted[0]).toHaveProperty('status', _helpers.FILE_UPLOAD_STATUS.EDIT); }); it('should ensure invalid files are sorted', function () { var files = [{ index: 1, status: _helpers.FILE_UPLOAD_STATUS.UPLOADING }, { index: 0, status: _helpers.FILE_UPLOAD_STATUS.EDIT, invalid: true }, { index: 2, status: _helpers.FILE_UPLOAD_STATUS.UPLOADING }]; var sorted = files.sort(function (a, b) { return (0, _helpers.sortFiles)(a, b, files.length); }); expect(sorted[0]).toHaveProperty('status', _helpers.FILE_UPLOAD_STATUS.EDIT); }); it('should handle two matching files', function () { var files = [{ index: 1, status: _helpers.FILE_UPLOAD_STATUS.UPLOADING }, { index: 0, status: _helpers.FILE_UPLOAD_STATUS.EDIT }, { index: 1, status: _helpers.FILE_UPLOAD_STATUS.UPLOADING }]; var sorted = files.sort(function (a, b) { return (0, _helpers.sortFiles)(a, b, files.length); }); expect(sorted[0]).toHaveProperty('status', _helpers.FILE_UPLOAD_STATUS.EDIT); }); }); describe('validateFileAdded', function () { it('should validate the file added', function () { var props = { validExtensions: ['png'] }; var testFile = { file: { size: 1000, name: 'foo.png' } }; var result = (0, _helpers.validateFileAdded)(testFile, props, jest.fn()); expect(result).toHaveProperty('invalid', false); }); it('should validate filename', function () { var props = { validExtensions: ['png'] }; var testFile = { file: { size: 1000, name: '*' } }; var result = (0, _helpers.validateFileAdded)(testFile, props, jest.fn()); expect(result).toHaveProperty('invalid', true); }); }); describe('text props', function () { it('should allow overriding all text props', function () { var customTextProps = { verbLabel: 'CUSTOM', uploadDescription: 'CUSTOM Use the inputs below to select file(s) to be uploaded.', importDescription: 'CUSTOM Use the inputs below to select file(s) to be imported.', headingPlural: 'CUSTOM Select Files to import', headingSingular: 'CUSTOM Select a File import', fileTabLabel: 'CUSTOM File', urlTabLabel: 'CUSTOM URL', invalidFileNameText: 'CUSTOM You must provide a valid file name.', fileDropLabelSingular: 'CUSTOM Drag and drop a single file here or click to import', fileDropLabelPlural: 'CUSTOM Drag and drop files here or click to import', filenameRequiredText: 'CUSTOM A filename is required.', invalidUrlText: 'CUSTOM Enter a valid URL', maxFileSizeSubject: 'CUSTOM File size exceeds limit', maxFileSizeMessage: 'CUSTOM File is larger than the max file size.', addUrlBttonLabel: 'CUSTOM Add File', extensionIsRequiredText: 'CUSTOM File must have a valid extension.', extensionIsInvalidText: 'CUSTOM Extension is not valid.', errorTextSingular: 'CUSTOM Failed to import file.', errorTextPlural: 'CUSTOM Failed to import files.', successTextSingular: 'CUSTOM Your file has been imported.', successTextPlural: 'CUSTOM Your files have been imported.', invalidFileText: 'CUSTOM Invalid File', mustBeExtensionTextSingular: 'CUSTOM Must be a $EXT file.', mustBeExtensionTextPlural: 'CUSTOM Must be one of: $EXT.', defaultUncaughtErrorSubject: 'CUSTOM Import Failed', defaultUncaughtErrorBody: 'CUSTOM Failed to import file.', filesToUploadTextPlural: 'CUSTOM Files to import', filesToUploadTextSingular: 'CUSTOM File to import', fileDropHeader: 'CUSTOM Add by File', urlInputHeader: 'CUSTOM Add by URL' }; function testCustomTextProps() { var customProps = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var mockHandleFileAdded = jest.fn(); var props = _objectSpread(_objectSpread({ validExtensions: ['png'], onFileAdded: mockHandleFileAdded }, customTextProps), customProps); var wrapper = new IdeImportingWrapper(props); wrapper.dropAFewPngFiles(); } // simple override testCustomTextProps(); // enableUpload testCustomTextProps({ enableUpload: true }); // default import text testCustomTextProps({ enableUpload: false, verbLabel: undefined }); }); }); }); // This should eventually be used to implement // the gherkin rules var IdeImportingWrapper = /*#__PURE__*/function () { function IdeImportingWrapper(props) { (0, _classCallCheck2.default)(this, IdeImportingWrapper); this.props = props; this.wrapper = (0, _enzyme.mount)(/*#__PURE__*/_react2.default.createElement(_.IdeImporting, props)); } return (0, _createClass2.default)(IdeImportingWrapper, [{ key: "unmount", value: function unmount() { return this.wrapper.unmount(); } }, { key: "resolveAsync", value: function () { var _resolveAsync = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee7() { return _regenerator.default.wrap(function _callee7$(_context7) { while (1) switch (_context7.prev = _context7.next) { case 0: _context7.next = 2; return (0, _sleep.default)(1); case 2: // force a re-render // see https://airbnb.io/enzyme/docs/api/ReactWrapper/update.html this.wrapper.update(); case 3: case "end": return _context7.stop(); } }, _callee7, this); })); function resolveAsync() { return _resolveAsync.apply(this, arguments); } return resolveAsync; }() }, { key: "strictFind", value: function strictFind(selector) { var found = this.wrapper.find(selector); if (found.length === 0) { var name = typeof selector === 'string' ? selector : selector.name; throw new Error("".concat(name, " not found when using strictFind()")); } return found; } }, { key: "findFilenameInput", value: function findFilenameInput() { return this.strictFind(_carbonComponentsReact.TextInput).find('input'); } }, { key: "clickButton", value: function clickButton(selector) { var button = this.strictFind(selector); button.simulate('click'); } }, { key: "changeValue", value: function changeValue(selector, value) { var target = this.strictFind(selector); target.simulate('change', { target: { value: value } }); } }, { key: "expectPropCalled", value: function expectPropCalled(name) { expect(this.props[name]).toBeCalled(); } }, { key: "changeFilename", value: function changeFilename(value) { var input = this.findFilenameInput(); input.simulate('change', { target: { value: value } }); } }, { key: "hasFilename", value: function hasFilename(value) { return this.findFilenameInput().prop('value') === value; } }, { key: "changeUrl", value: function changeUrl(url) { this.changeValue('.ide-importing-flex-input input', url); } }, { key: "addFileViaUrl", value: function addFileViaUrl(url) { this.changeUrl(url); this.clickButton('.ide-importing-flex-button button'); } }, { key: "simulateDropFiles", value: function simulateDropFiles(files) { var e = { stopPropagation: jest.fn() }; this.wrapper.instance().handleFilesAdded(e, { addedFiles: files }); this.wrapper.update(); } }, { key: "dropAFewPngFiles", value: function dropAFewPngFiles() { this.simulateDropFiles([{ name: 'foo.png' }, { name: 'bar.png' }]); } }, { key: "removeFirstFile", value: function removeFirstFile() { var inst = this.wrapper.instance(); var firstFile = inst.state.filesToUpload[0]; inst.handleRemoveFile(firstFile.uuid); } }, { key: "expectNoFiles", value: function expectNoFiles() { expect(this.wrapper.instance().state.filesToUpload).toHaveLength(0); } }, { key: "simulateDeleteFile", value: function simulateDeleteFile() { this.strictFind(_carbonComponentsReact.FileUploaderItem).first().invoke('onDelete'); } }]); }();