updated tests, reuse utils for Form and FormWrapper

This commit is contained in:
Eric Burel 2018-10-29 22:34:29 +01:00
parent 284cdbae18
commit 08b9cf5c5e
8 changed files with 70 additions and 93 deletions

View file

@ -61,8 +61,9 @@ import mergeWithComponents from '../modules/mergeWithComponents';
import {
getEditableFields,
getInsertableFields
} from '../modules/fieldsUtils.js';
} from '../modules/schema_utils.js';
import withCollectionProps from './withCollectionProps';
import { callbackProps } from './propTypes';
const compactParent = (object, path) => {
const parentPath = getParentPath(path);
@ -82,8 +83,7 @@ const getDefaultValues = convertedSchema => {
};
const getInitialStateFromProps = nextProps => {
const collection =
nextProps.collection || getCollection(nextProps.collectionName);
const collection = nextProps.collection;
const schema = nextProps.schema
? new SimpleSchema(nextProps.schema)
: collection.simpleSchema();
@ -148,36 +148,14 @@ class SmartForm extends Component {
// --------------------------------------------------------------------- //
/*
Get the current collection
*/
getCollection = () => {
return this.props.collection || getCollection(this.props.collectionName);
};
/*
Get current typeName
*/
getTypeName = () => {
return this.getCollection().options.typeName;
};
/*
If a document is being passed, this is an edit form
*/
getFormType = () => {
return this.props.document ? 'edit' : 'new';
};
/*
Get a list of all insertable fields
*/
getInsertableFields = schema => {
return getInsertableFields(
@ -187,9 +165,7 @@ class SmartForm extends Component {
};
/*
Get a list of all editable fields
*/
getEditableFields = schema => {
return getEditableFields(
@ -521,7 +497,7 @@ class SmartForm extends Component {
*/
getLabel = (fieldName, fieldLocale) => {
const collectionName = this.getCollection().options.collectionName.toLowerCase();
const collectionName = this.props.collectionName.toLowerCase();
const defaultMessage = '|*|*|';
let id = `${collectionName}.${fieldName}`;
let intlLabel;
@ -947,13 +923,13 @@ class SmartForm extends Component {
if (this.getFormType() === 'new') {
// create document form
this.props[`create${this.getTypeName()}`]({ data })
this.props[`create${this.props.typeName}`]({ data })
.then(this.newMutationSuccessCallback)
.catch(error => this.mutationErrorCallback(document, error));
} else {
// update document form
const documentId = this.getDocument()._id;
this.props[`update${this.getTypeName()}`]({
this.props[`update${this.props.typeName}`]({
selector: { documentId },
data
})
@ -999,7 +975,7 @@ class SmartForm extends Component {
render() {
const fieldGroups = this.getFieldGroups();
const collectionName = this.getCollection()._name;
const collectionName = this.props.collectionName;
const FormComponents = mergeWithComponents(this.props.formComponents);
return (
@ -1062,6 +1038,7 @@ SmartForm.propTypes = {
collection: PropTypes.object.isRequired,
collectionName: PropTypes.string.isRequired,
typeName: PropTypes.string.isRequired,
document: PropTypes.object, // if a document is passed, this will be an edit form
schema: PropTypes.object, // usually not needed
@ -1086,13 +1063,7 @@ SmartForm.propTypes = {
formComponents: PropTypes.object,
// callbacks
changeCallback: PropTypes.func,
submitCallback: PropTypes.func,
successCallback: PropTypes.func,
removeSuccessCallback: PropTypes.func,
errorCallback: PropTypes.func,
cancelCallback: PropTypes.func,
revertCallback: PropTypes.func,
...callbackProps,
currentUser: PropTypes.object,
client: PropTypes.object

View file

@ -49,6 +49,7 @@ import {
} from '../modules/schema_utils';
import withCollectionProps from './withCollectionProps';
import { callbackProps } from './propTypes';
class FormWrapper extends PureComponent {
constructor(props) {
@ -302,13 +303,7 @@ FormWrapper.propTypes = {
warnUnsavedChanges: PropTypes.bool,
// callbacks
changeCallback: PropTypes.func,
submitCallback: PropTypes.func,
successCallback: PropTypes.func,
removeSuccessCallback: PropTypes.func,
errorCallback: PropTypes.func,
cancelCallback: PropTypes.func,
revertCallback: PropTypes.func,
...callbackProps,
currentUser: PropTypes.object,
client: PropTypes.object

View file

@ -1,5 +1,6 @@
/** PropTypes for documentation purpose (not tested yet) */
import PropTypes from 'prop-types';
const fieldProps = {
//
defaultValue: PropTypes.any,
@ -20,12 +21,12 @@ const fieldProps = {
// if it has an array field
// e.g addresses.$ : { type: .... }
arrayFieldSchema: PropTypes.object,
arrayField: fieldProps,
arrayField: PropTypes.object, //fieldProps,
// if it is a nested object itself
// eg address : { type : { ... }}
nestedSchema: PropTypes.object,
nestedInput: PropTypes.boolean, // flag
nestedFields: PropTypes.arrayOf(fieldProps)
nestedFields: PropTypes.array //arrayOf(fieldProps)
};
const groupProps = {
name: PropTypes.string.isRequired,
@ -34,4 +35,12 @@ const groupProps = {
fields: PropTypes.arrayOf(PropTypes.shape(fieldProps))
};
const callbacksProps = {};
export const callbackProps = {
changeCallback: PropTypes.func,
submitCallback: PropTypes.func,
successCallback: PropTypes.func,
removeSuccessCallback: PropTypes.func,
errorCallback: PropTypes.func,
cancelCallback: PropTypes.func,
revertCallback: PropTypes.func
};

View file

@ -1,26 +0,0 @@
import Users from 'meteor/vulcan:users';
/**
* @method Mongo.Collection.getInsertableFields
* Get an array of all fields editable by a specific user for a given collection
* @param {Object} user the user for which to check field permissions
*/
export const getInsertableFields = function(schema, user) {
const fields = _.filter(_.keys(schema), function(fieldName) {
var field = schema[fieldName];
return Users.canCreateField(user, field);
});
return fields;
};
/**
* @method Mongo.Collection.getEditableFields
* Get an array of all fields editable by a specific user for a given collection (and optionally document)
* @param {Object} user the user for which to check field permissions
*/
export const getEditableFields = function(schema, user, document) {
const fields = _.filter(_.keys(schema), function(fieldName) {
var field = schema[fieldName];
return Users.canUpdateField(user, field, document);
});
return fields;
};

View file

@ -1,8 +1,10 @@
/**
/*
* Schema converter/getters
* @param {*} schema
*/
import Users from 'meteor/vulcan:users';
import _ from 'lodash';
/* getters */
// filter out fields with "." or "$"
export const getValidFields = schema => {
return Object.keys(schema).filter(fieldName => !fieldName.includes('$') && !fieldName.includes('.'));
@ -23,6 +25,34 @@ export const getUpdateableFields = schema => {
return getValidFields(schema).filter(fieldName => schema[fieldName].canUpdate || schema[fieldName].editableBy);
};
/* permissions */
/**
* @method Mongo.Collection.getInsertableFields
* Get an array of all fields editable by a specific user for a given collection
* @param {Object} user the user for which to check field permissions
*/
export const getInsertableFields = function(schema, user) {
const fields = _.filter(_.keys(schema), function(fieldName) {
var field = schema[fieldName];
return Users.canCreateField(user, field);
});
return fields;
};
/**
* @method Mongo.Collection.getEditableFields
* Get an array of all fields editable by a specific user for a given collection (and optionally document)
* @param {Object} user the user for which to check field permissions
*/
export const getEditableFields = function(schema, user, document) {
const fields = _.filter(_.keys(schema), function(fieldName) {
var field = schema[fieldName];
return Users.canUpdateField(user, field, document);
});
return fields;
};
/*
Convert a nested SimpleSchema schema into a JSON object

View file

@ -172,24 +172,24 @@ describe('vulcan-forms/components', function() {
context
});
describe('Form (handle fields computation)', function() {
describe('Form collectionName="" (handle fields computation)', function() {
// getters
const getArrayFormGroup = wrapper => wrapper.find('FormGroup').find({ name: 'addresses' });
const getFields = arrayFormGroup => arrayFormGroup.prop('fields');
describe('basic collection - no nesting', function() {
it('shallow render', function() {
const wrapper = shallowWithContext(<Form collection={Addresses} />);
const wrapper = shallowWithContext(<Form collectionName="" collection={Addresses} />);
expect(wrapper).toBeDefined();
});
});
describe('nested object (not in array)', function() {
it('shallow render', () => {
const wrapper = shallowWithContext(<Form collection={Objects} />);
const wrapper = shallowWithContext(<Form collectionName="" collection={Objects} />);
expect(wrapper).toBeDefined();
});
it('define one field', () => {
const wrapper = shallowWithContext(<Form collection={Objects} />);
const wrapper = shallowWithContext(<Form collectionName="" collection={Objects} />);
const defaultGroup = wrapper.find('FormGroup').first();
const fields = defaultGroup.prop('fields');
expect(fields).toHaveLength(1); // addresses field
@ -201,7 +201,7 @@ describe('vulcan-forms/components', function() {
return fields;
};
const getFirstField = () => {
const wrapper = shallowWithContext(<Form collection={Objects} />);
const wrapper = shallowWithContext(<Form collectionName="" collection={Objects} />);
const fields = getFormFields(wrapper);
return fields[0];
};
@ -212,17 +212,17 @@ describe('vulcan-forms/components', function() {
});
describe('array of objects', function() {
it('shallow render', () => {
const wrapper = shallowWithContext(<Form collection={ArrayOfObjects} />);
const wrapper = shallowWithContext(<Form collectionName="" collection={ArrayOfObjects} />);
expect(wrapper).toBeDefined();
});
it('render a FormGroup for addresses', function() {
const wrapper = shallowWithContext(<Form collection={ArrayOfObjects} />);
const wrapper = shallowWithContext(<Form collectionName="" collection={ArrayOfObjects} />);
const formGroup = wrapper.find('FormGroup').find({ name: 'addresses' });
expect(formGroup).toBeDefined();
expect(formGroup).toHaveLength(1);
});
it('passes down the array child fields', function() {
const wrapper = shallowWithContext(<Form collection={ArrayOfObjects} />);
const wrapper = shallowWithContext(<Form collectionName="" collection={ArrayOfObjects} />);
const formGroup = getArrayFormGroup(wrapper);
const fields = getFields(formGroup);
const arrayField = fields[0];
@ -232,11 +232,11 @@ describe('vulcan-forms/components', function() {
});
describe('array with custom children inputs (e.g array of url)', function() {
it('shallow render', function() {
const wrapper = shallowWithContext(<Form collection={ArrayOfUrls} />);
const wrapper = shallowWithContext(<Form collectionName="" collection={ArrayOfUrls} />);
expect(wrapper).toBeDefined();
});
it('passes down the array item custom input', () => {
const wrapper = shallowWithContext(<Form collection={ArrayOfUrls} />);
const wrapper = shallowWithContext(<Form collectionName="" collection={ArrayOfUrls} />);
const formGroup = getArrayFormGroup(wrapper);
const fields = getFields(formGroup);
const arrayField = fields[0];
@ -245,12 +245,12 @@ describe('vulcan-forms/components', function() {
});
describe('array of objects with custom children inputs', function() {
it('shallow render', function() {
const wrapper = shallowWithContext(<Form collection={ArrayOfCustomObjects} />);
const wrapper = shallowWithContext(<Form collectionName="" collection={ArrayOfCustomObjects} />);
expect(wrapper).toBeDefined();
});
// TODO: does not work, schema_utils needs an update
it.skip('passes down the custom input', function() {
const wrapper = shallowWithContext(<Form collection={ArrayOfCustomObjects} />);
const wrapper = shallowWithContext(<Form collectionName="" collection={ArrayOfCustomObjects} />);
const formGroup = getArrayFormGroup(wrapper);
const fields = getFields(formGroup);
const arrayField = fields[0];
@ -259,11 +259,11 @@ describe('vulcan-forms/components', function() {
});
describe('array with a fully custom input (array itself and children)', function() {
it('shallow render', function() {
const wrapper = shallowWithContext(<Form collection={ArrayFullCustom} />);
const wrapper = shallowWithContext(<Form collectionName="" collection={ArrayFullCustom} />);
expect(wrapper).toBeDefined();
});
it('passes down the custom input', function() {
const wrapper = shallowWithContext(<Form collection={ArrayFullCustom} />);
const wrapper = shallowWithContext(<Form collectionName="" collection={ArrayFullCustom} />);
const formGroup = getArrayFormGroup(wrapper);
const fields = getFields(formGroup);
const arrayField = fields[0];
@ -390,7 +390,7 @@ describe('vulcan-forms/components', function() {
const wrapper = shallow(<Components.FormNestedObject {...defaultProps} currentValues={{}} />);
expect(wrapper).toBeDefined();
});
it.skip('render a form for the object', function() {
it.skip('render a Form collectionName="" for the object', function() {
// eslint-disable-next-line no-unused-vars
const wrapper = shallow(<Components.FormNestedObject {...defaultProps} currentValues={{}} />);
expect(false).toBe(true);

View file

@ -1,5 +1,3 @@
import './schema_utils.test.js';
import './components.test.js';
import './mergeWithComponents.test.js';
import './fieldUtils.test.js';