@carbon/ibm-cloud-cognitive-cdai
Version:
Carbon for Cloud & Cognitive CD&AI UI components
660 lines (655 loc) • 23.9 kB
JavaScript
;
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');
}
}]);
}();