apostrophe
Version:
The Apostrophe Content Management System.
1,978 lines (1,898 loc) • 53.7 kB
JavaScript
var t = require('../test-lib/test.js');
var assert = require('assert');
var _ = require('@sailshq/lodash');
var apos;
var simpleFields = [
{
name: 'name',
label: 'Name',
type: 'string'
},
{
name: 'address',
label: 'Address',
type: 'string',
textarea: true
},
{
name: 'variety',
label: 'Variety',
type: 'select',
choices: [
{
value: 'candy',
label: 'Candy'
},
{
value: 'cheese',
label: 'Cheese'
}
],
def: 'candy'
},
{
name: 'tags',
label: 'Tags',
type: 'tags'
},
{
name: 'slug',
label: 'Slug',
type: 'slug'
}
];
var realWorldCase = {
"addFields": [
{
"type": "string",
"name": "title",
"label": "Title",
"required": true,
"sortify": true
},
{
"type": "slug",
"name": "slug",
"label": "Slug",
"required": true
},
{
"type": "tags",
"name": "tags",
"label": "Tags"
},
{
"type": "boolean",
"name": "published",
"label": "Published",
"def": true
},
{
"type": "boolean",
"name": "trash",
"label": "Trash",
"contextual": true,
"def": false
},
{
"type": "slug",
"name": "slug",
"label": "Old URL",
"required": true,
"page": true
},
{
"name": "title",
"label": "Description",
"type": "string",
"required": true
},
{
"type": "boolean",
"name": "published",
"label": "Published",
"required": true,
"def": true,
"contextual": true
},
{
"name": "urlType",
"label": "Link To",
"type": "select",
"choices": [
{
"label": "Internal Page",
"value": "internal",
"showFields": [
"_newPage"
]
},
{
"label": "External URL",
"value": "external",
"showFields": [
"externalUrl"
]
}
]
},
{
"name": "externalUrl",
"label": "URL",
"type": "url"
},
{
"name": "_newPage",
"type": "joinByOne",
"withType": "apostrophe-page",
"label": "Page Title",
"idField": "pageId"
}
],
"removeFields": [
"tags"
],
"arrangeFields": [
{
"name": "basics",
"label": "Basics",
"fields": [
"title",
"slug",
"published",
"tags"
]
},
{
"name": "permissions",
"label": "Permissions",
"fields": [
"loginRequired",
"_viewUsers",
"_viewGroups",
"_editUsers",
"_editGroups"
],
"last": true
},
{
"name": "info",
"label": "Info",
"fields": [
"slug",
"urlType",
"_newPage",
"title",
"externalUrl"
]
}
]
};
var pageSlug = [
{
type: 'slug',
name: 'slug',
page: true
}
];
var regularSlug = [
{
type: 'slug',
name: 'slug'
}
];
var hasArea = {
addFields: [
{
type: 'area',
name: 'body',
label: 'Body',
widgets: {
'apostrophe-rich-text': {}
}
}
]
};
describe('Schemas', function() {
this.timeout(t.timeout);
after(function(done) {
return t.destroy(apos, done);
});
/// ///
// EXISTENCE
/// ///
it('should be a property of the apos object', function(done) {
apos = require('../index.js')({
root: module,
shortName: 'test',
modules: {
'apostrophe-express': {
secret: 'xxx',
port: 7900
}
},
afterInit: function(callback) {
assert(apos.schemas);
apos.argv._ = [];
return callback(null);
},
afterListen: function(err) {
assert(!err);
done();
}
});
});
it('should compose schemas correctly', function() {
var options = {
addFields: [
{
name: 'name',
type: 'string',
label: 'Name'
},
{
name: 'address',
type: 'string',
label: 'Address',
textarea: true
},
{
name: 'variety',
type: 'select',
label: 'Variety',
choices: [
{
value: 'candy',
label: 'Candy'
},
{
value: 'cheese',
label: 'Cheese'
}
]
}
],
removeFields: [ 'address' ],
alterFields: function(schema) {
var variety = _.find(schema, { name: 'variety' });
assert(variety);
variety.choices.push({
value: 'record',
label: 'Record'
});
}
};
var schema = apos.schemas.compose(options);
assert(schema.length === 2);
assert(schema[0].name === 'name');
assert(schema[1].name === 'variety');
assert(_.keys(schema[1].choices).length === 3);
});
it('should compose a schema for a complex real world case correctly', function() {
var schema = apos.schemas.compose(realWorldCase);
assert(schema);
var externalUrl = _.find(schema, { name: 'externalUrl' });
assert(externalUrl);
assert(externalUrl.group.name === 'info');
var _newPage = _.find(schema, { name: '_newPage' });
assert(_newPage);
assert(_newPage.group.name === 'info');
});
it('should error if a field is required and an empty value is submitted for a string field type', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'string',
name: 'name',
label: 'Name',
required: true
}
]
});
assert(schema.length === 1);
var input = {
name: ''
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(err === 'name.required');
done();
});
});
it('should error if the value submitted is less than min length for a string field type', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'string',
name: 'name',
label: 'Name',
min: 5
}
]
});
assert(schema.length === 1);
var input = {
name: 'Cow'
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(err === 'name.min');
done();
});
});
it('should convert and keep the correct value for a field which is required for a string field type', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'string',
name: 'name',
label: 'Name',
required: true
}
]
});
assert(schema.length === 1);
var input = {
name: 'Apostrophe^CMS'
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
assert(result.name === 'Apostrophe^CMS');
done();
});
});
it('should error if an email address is improperly formed', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'email',
name: 'email',
label: 'Email'
}
]
});
assert(schema.length === 1);
var input = {
email: 'testguy1%oopsbad'
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(err === 'email.invalid');
done();
});
});
it('should tolerate no email value if field not required', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'email',
name: 'email',
label: 'Email'
}
]
});
assert(schema.length === 1);
var input = {
email: ''
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
done();
});
});
it('should reject no email value if field required', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'email',
name: 'email',
label: 'Email',
required: true
}
]
});
assert(schema.length === 1);
var input = {
email: ''
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(err);
assert(err === 'email.required');
done();
});
});
it('should accept a well formed email address with a + sign', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'email',
name: 'email',
label: 'Email'
}
]
});
assert(schema.length === 1);
var input = {
email: 'testguy1+cool@yaygreat.com'
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
done();
});
});
it('should keep an empty submitted field value null when there is a min / max configuration for an integer field type', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'integer',
name: 'price',
label: 'Price',
min: 1,
max: 10
}
]
});
assert(schema.length === 1);
var input = {
price: ''
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
assert(_.keys(result).length === 1);
assert(result.price === null);
done();
});
});
it('should keep an empty submitted field value null when there is a min / max configuration for a float field type', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'float',
name: 'price',
label: 'Price',
min: 1,
max: 10
}
]
});
assert(schema.length === 1);
var input = {
price: ''
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
assert(_.keys(result).length === 1);
assert(result.price === null);
done();
});
});
it('should keep an empty submitted field value null for a time field type', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'time',
name: 'time',
label: 'time'
}
]
});
assert(schema.length === 1);
var input = {
time: ''
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
assert(_.keys(result).length === 1);
assert(result.time === null);
done();
});
});
it('should keep an empty submitted field value null for a date field type', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'date',
name: 'date',
label: 'date'
}
]
});
assert(schema.length === 1);
var input = {
date: ''
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
assert(_.keys(result).length === 1);
assert(result.date === null);
done();
});
});
it('should ensure a max value is being trimmed to the max length for a string field type', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'string',
name: 'name',
label: 'Name',
max: 5
}
]
});
assert(schema.length === 1);
var input = {
name: 'Apostrophe'
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
assert(_.keys(result).length === 1);
assert(result.name === 'Apost');
done();
});
});
it('should allow saving a 0 value provided as a number if a field is required for an integer field type', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'integer',
name: 'price',
label: 'Price',
required: true
}
]
});
assert(schema.length === 1);
var input = {
price: 0
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
assert(_.keys(result).length === 1);
assert(result.price === 0);
done();
});
});
it('should gracefully reject null provided as a number if a field is required for an integer field type', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'integer',
name: 'price',
label: 'Price',
required: true
}
]
});
assert(schema.length === 1);
var input = {
price: null
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(err);
assert.equal(err, 'price.required');
done();
});
});
it('should gracefully reject undefined provided as a number if a field is required for an integer field type', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'integer',
name: 'price',
label: 'Price',
required: true
}
]
});
assert(schema.length === 1);
var input = {
price: undefined
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(err);
assert.equal(err, 'price.required');
done();
});
});
it('should allow saving a 0 value provided as a float if a field is required for an float field type', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'float',
name: 'price',
label: 'Price',
required: true
}
]
});
assert(schema.length === 1);
var input = {
price: 0.00
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
assert(_.keys(result).length === 1);
assert(result.price === 0.00);
done();
});
});
it('should allow saving a 0 value provided as a number if a field is required for an float field type', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'float',
name: 'price',
label: 'Price',
required: true
}
]
});
assert(schema.length === 1);
var input = {
price: 0
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
assert(_.keys(result).length === 1);
assert(result.price === 0);
done();
});
});
it('should allow saving a 0 value provided as a number if a field is required for an string field type', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'string',
name: 'price',
label: 'Price',
required: true
}
]
});
assert(schema.length === 1);
var input = {
price: 0
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
assert(_.keys(result).length === 1);
assert(result.price === '0');
done();
});
});
it('should allow saving a 0 value provided as a string if a field is required for an integer field type', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'integer',
name: 'price',
label: 'Price',
required: true
}
]
});
assert(schema.length === 1);
var input = {
price: '0'
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
assert(_.keys(result).length === 1);
assert(result.price === 0);
done();
});
});
it('should allow saving a 0 value provided as a string if a field is required for an string field type', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'string',
name: 'price',
label: 'Price',
required: true
}
]
});
assert(schema.length === 1);
var input = {
price: '0'
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
assert(_.keys(result).length === 1);
assert(result.price === '0');
done();
});
});
it('should allow saving a 0 value provided as a string if a field is required for an float field type', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'float',
name: 'price',
label: 'Price',
required: true
}
]
});
assert(schema.length === 1);
var input = {
price: '0'
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
assert(_.keys(result).length === 1);
assert(result.price === 0);
done();
});
});
it('should allow saving a 0 value provided as a string if there is no min value set for an integer field type', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'integer',
name: 'price',
label: 'Price'
}
]
});
assert(schema.length === 1);
var input = {
price: '0'
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
assert(_.keys(result).length === 1);
assert(result.price === 0);
done();
});
});
it('should allow saving a 0 value provided as a string if there is no min value set for a float field type', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'float',
name: 'price',
label: 'Price'
}
]
});
assert(schema.length === 1);
var input = {
price: '0'
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
assert(_.keys(result).length === 1);
assert(result.price === 0);
done();
});
});
it('should allow saving a negative value provided as a number for an integer field type', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'integer',
name: 'price',
label: 'Price'
}
]
});
assert(schema.length === 1);
var input = {
price: -1
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
assert(_.keys(result).length === 1);
assert(result.price === -1);
done();
});
});
it('should allow saving a negative value provided as a float for an float field type', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'float',
name: 'price',
label: 'Price'
}
]
});
assert(schema.length === 1);
var input = {
price: -1.3
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
assert(_.keys(result).length === 1);
assert(result.price === -1.3);
done();
});
});
it('should allow saving a negative value provided as a float for an string field type', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'string',
name: 'price',
label: 'Price'
}
]
});
assert(schema.length === 1);
var input = {
price: -1.3
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
assert(_.keys(result).length === 1);
assert(result.price === '-1.3');
done();
});
});
it('should allow saving a negative value provided as a number if a field is required for an integer field type', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'integer',
name: 'price',
label: 'Price',
required: true
}
]
});
assert(schema.length === 1);
var input = {
price: -1
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
assert(_.keys(result).length === 1);
assert(result.price === -1);
done();
});
});
it('should allow saving a negative value provided as a number if a field is required for an float field type', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'float',
name: 'price',
label: 'Price',
required: true
}
]
});
assert(schema.length === 1);
var input = {
price: -1.3
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
assert(_.keys(result).length === 1);
assert(result.price === -1.3);
done();
});
});
it('should allow saving a negative value provided as a string if a field is required for an float field type', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'float',
name: 'price',
label: 'Price',
required: true
}
]
});
assert(schema.length === 1);
var input = {
price: '-1.3'
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
assert(_.keys(result).length === 1);
assert(result.price === -1.3);
done();
});
});
it('should override the saved value if min and max value has been set and the submitted value is out of range for an integer field type', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'integer',
name: 'price',
label: 'Price',
min: 5,
max: 6
}
]
});
assert(schema.length === 1);
var input = {
price: '3'
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
assert(_.keys(result).length === 1);
assert(result.price === 5);
done();
});
});
it('should override the saved value if min and max value has been set and the submitted value is out of range for a float field type', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'float',
name: 'price',
label: 'Price',
min: 5.1,
max: 6
}
]
});
assert(schema.length === 1);
var input = {
price: '3.2'
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
assert(_.keys(result).length === 1);
assert(result.price === 5.1);
done();
});
});
it('should ensure a min value is being set to the configured min value if a lower value is submitted for an integer field type', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'integer',
name: 'price',
label: 'Price',
min: 5
}
]
});
assert(schema.length === 1);
var input = {
price: '1'
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
assert(_.keys(result).length === 1);
assert(result.price === 5);
done();
});
});
it('should ensure a min value is being set to the configured min value if a lower value is submitted for a float field type', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'float',
name: 'price',
label: 'Price',
min: 5.3
}
]
});
assert(schema.length === 1);
var input = {
price: '1.2'
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
assert(_.keys(result).length === 1);
assert(result.price === 5.3);
done();
});
});
it('should ensure a max value is being set to the max if a higher value is submitted for an integer field type', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'integer',
name: 'price',
label: 'Price',
max: 5
}
]
});
assert(schema.length === 1);
var input = {
price: '8'
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
assert(_.keys(result).length === 1);
assert(result.price === 5);
done();
});
});
it('should ensure a max value is being set to the max if a higher value is submitted for a float field type', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'float',
name: 'price',
label: 'Price',
max: 5.9
}
]
});
assert(schema.length === 1);
var input = {
price: '8'
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
assert(_.keys(result).length === 1);
assert(result.price === 5.9);
done();
});
});
it('should not modify a value if the submitted value is within min and max for an integer field type', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'integer',
name: 'price',
label: 'Price',
min: 4,
max: 6
}
]
});
assert(schema.length === 1);
var input = {
price: '5'
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
assert(_.keys(result).length === 1);
assert(result.price === 5);
done();
});
});
it('should not modify a value if the submitted value is within min and max for a float field type', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'float',
name: 'price',
label: 'Price',
min: 4,
max: 5
}
]
});
assert(schema.length === 1);
var input = {
price: '4.3'
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
assert(_.keys(result).length === 1);
assert(result.price === 4.3);
done();
});
});
it('should not allow a text value to be submitted for a required integer field', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'integer',
name: 'price',
label: 'Price',
required: true
}
]
});
assert(schema.length === 1);
var input = {
price: 'A'
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(err);
done();
});
});
it('should not allow a text value to be submitted for a required float field', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'float',
name: 'price',
label: 'Price',
required: true
}
]
});
assert(schema.length === 1);
var input = {
price: 'A'
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(err);
done();
});
});
it('should not allow a text value to be submitted for a non required integer field with min and max', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'integer',
name: 'price',
label: 'Price',
min: 1,
max: 10
}
]
});
assert(schema.length === 1);
var input = {
price: 'A'
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(err);
done();
});
});
it('should not allow a text value to be submitted for a non required float field with min and max', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'float',
name: 'price',
label: 'Price',
min: 1,
max: 10
}
]
});
assert(schema.length === 1);
var input = {
price: 'A'
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(err);
done();
});
});
it('should not allow a text value to be submitted for a non required integer field with a default value set', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'integer',
name: 'price',
label: 'Price',
def: 2
}
]
});
assert(schema.length === 1);
var input = {
price: 'A'
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(err);
done();
});
});
it('should not allow a text value to be submitted for a non required float field with a default value set', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'float',
name: 'price',
label: 'Price',
def: 2.10
}
]
});
assert(schema.length === 1);
var input = {
price: 'A'
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(err);
done();
});
});
it('should not allow a text value to be submitted for a non required integer field', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'integer',
name: 'price',
label: 'Price'
}
]
});
assert(schema.length === 1);
var input = {
price: 'A'
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(err);
done();
});
});
it('should not allow a text value to be submitted for a non required float field', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'float',
name: 'price',
label: 'Price'
}
]
});
assert(schema.length === 1);
var input = {
price: 'A'
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(err);
done();
});
});
it('should allow a parsable string/integer value to be submitted for a non required integer field', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'integer',
name: 'price',
label: 'Price'
}
]
});
assert(schema.length === 1);
var input = {
price: '22a'
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
assert(result.price === 22);
done();
});
});
it('should allow a parsable string/float value to be submitted for a non required float field', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'float',
name: 'price',
label: 'Price'
}
]
});
assert(schema.length === 1);
var input = {
price: '11.4b'
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
assert(result.price === 11.4);
done();
});
});
it('should convert simple data correctly', function(done) {
var schema = apos.schemas.compose({
addFields: simpleFields
});
assert(schema.length === 5);
var input = apos.schemas.newInstance(schema);
Object.assign(input, {
name: 'Bob Smith',
address: '5017 Awesome Street\nPhiladelphia, PA 19147',
irrelevant: 'Irrelevant',
slug: 'This Is Cool'
});
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
// no irrelevant or missing fields
assert(_.keys(result).length === 5);
// expected fields came through
assert(result.name === input.name);
assert(result.address === input.address);
// default
assert(result.variety === simpleFields[2].choices[0].value);
assert(Array.isArray(result.tags) && (result.tags.length === 0));
assert(result.slug === 'this-is-cool');
done();
});
});
it('should convert tags correctly', function(done) {
var schema = apos.schemas.compose({
addFields: simpleFields
});
assert(schema.length === 5);
var input = {
tags: [ 4, 5, 'Seven' ]
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
// without def, the default is undefined, so this is right
assert(_.keys(result.tags).length === 3);
assert(Array.isArray(result.tags));
assert(result.tags[0] === '4');
assert(result.tags[1] === '5');
// case conversion
assert(result.tags[2] === 'seven');
assert(result.slug === 'none');
done();
});
});
it('should update a password if provided', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'password',
name: 'password',
label: 'Password'
}
]
});
assert(schema.length === 1);
var input = {
password: 'silly'
};
var req = apos.tasks.getReq();
var result = { password: 'serious' };
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
assert(_.keys(result).length === 1);
// hashing is not the business of schemas, see the
// apostrophe-users module
assert(result.password === 'silly');
done();
});
});
it('should leave a password alone if not provided', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'password',
name: 'password',
label: 'Password'
}
]
});
assert(schema.length === 1);
var input = {
password: ''
};
var req = apos.tasks.getReq();
var result = { password: 'serious' };
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
assert(_.keys(result).length === 1);
// hashing is not the business of schemas, see the
// apostrophe-users module
assert(result.password === 'serious');
done();
});
});
it('should handle array schemas', function(done) {
var schema = apos.schemas.compose({
addFields: [
{
type: 'array',
name: 'addresses',
label: 'Addresses',
schema: [
{
name: 'address',
type: 'string',
label: 'Address'
}
]
}
]
});
assert(schema.length === 1);
var input = {
addresses: [
{
address: '500 test lane'
},
{
address: '602 test ave'
}
]
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
assert(!err);
assert(_.keys(result).length === 1);
assert(Array.isArray(result.addresses));
assert(result.addresses.length === 2);
assert(result.addresses[0].id);
assert(result.addresses[1].id);
assert(result.addresses[0].address === '500 test lane');
assert(result.addresses[1].address === '602 test ave');
done();
});
});
it('should convert string areas correctly', function(done) {
var schema = apos.schemas.compose(hasArea);
assert(schema.length === 1);
var input = {
irrelevant: 'Irrelevant',
// Should get escaped, not be treated as HTML
body: 'This is the greatest <h1>thing</h1>'
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'string', input, result, function(err) {
assert(!err);
// no irrelevant or missing fields
assert(_.keys(result).length === 1);
// expected fields came through
assert(result.body);
assert(result.body.type === 'area');
assert(result.body.items);
assert(result.body.items[0]);
assert(result.body.items[0].type === 'apostrophe-rich-text');
assert(result.body.items[0].content === apos.utils.escapeHtml(input.body));
done();
});
});
it('should convert string areas gracefully when they are undefined', function(done) {
var schema = apos.schemas.compose(hasArea);
assert(schema.length === 1);
var input = {
irrelevant: 'Irrelevant',
// Should get escaped, not be treated as HTML
body: undefined
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'string', input, result, function(err) {
assert(!err);
// no irrelevant or missing fields
assert(_.keys(result).length === 1);
// expected fields came through
assert(result.body);
assert(result.body.type === 'area');
assert(result.body.items);
assert(!result.body.items[0]);
done();
});
});
it('should accept csv as a bc equivalent for string in convert', function(done) {
var schema = apos.schemas.compose(hasArea);
assert(schema.length === 1);
var input = {
irrelevant: 'Irrelevant',
// Should get escaped, not be treated as HTML
body: 'This is the greatest <h1>thing</h1>'
};
var req = apos.tasks.getReq();
var result = {};
return apos.schemas.convert(req, schema, 'string', input, result, function(err) {
assert(!err);
// no irrelevant or missing fields
assert(_.keys(result).length === 1);
// expected fields came through
assert(result.body);
assert(result.body.type === 'area');
assert(result.body.items);
assert(result.body.items[0]);
assert(result.body.items[0].type === 'apostrophe-rich-text');
assert(result.body.items[0].content === apos.utils.escapeHtml(input.body));
done();
});
});
it('should clean up extra slashes in page slugs', function(done) {
var req = apos.tasks.getReq();
var schema = apos.schemas.compose({ addFields: pageSlug });
assert(schema.length === 1);
var input = {
slug: '/wiggy//wacky///wobbly////whizzle/////'
};
var result = {};
return apos.schemas.convert(req, schema, 'string', input, result, function(err) {
assert(!err);
assert(result.slug === '/wiggy/wacky/wobbly/whizzle');
done();
});
});
it('retains trailing / on the home page', function(done) {
var req = apos.tasks.getReq();
var schema = apos.schemas.compose({ addFields: pageSlug });
assert(schema.length === 1);
var input = {
slug: '/'
};
var result = {};
return apos.schemas.convert(req, schema, 'string', input, result, function(err) {
assert(!err);
assert(result.slug === '/');
done();
});
});
it('does not keep slashes when page: true not present for slug', function(done) {
var req = apos.tasks.getReq();
var schema = apos.schemas.compose({ addFields: regularSlug });
assert(schema.length === 1);
var input = {
slug: '/wiggy//wacky///wobbly////whizzle/////'
};
var result = {};
return apos.schemas.convert(req, schema, 'string', input, result, function(err) {
assert(!err);
assert(result.slug === 'wiggy-wacky-wobbly-whizzle');
done();
});
});
it('enforces required property for ordinary field', function(done) {
var req = apos.tasks.getReq();
var schema = apos.schemas.compose({
addFields: [
{
name: 'age',
label: 'Age',
type: 'integer',
required: true
}
]
});
var output = {};
apos.schemas.convert(req, schema, 'form', { age: '' }, output, function(err) {
assert(err);
assert(err === 'age.required');
done();
});
});
it('ignores required property for hidden field', function(done) {
var req = apos.tasks.getReq();
var schema = apos.schemas.compose({
addFields: [
{
name: 'age',
type: 'integer',
required: true
},
{
name: 'shoeSize',
type: 'integer',
required: false
},
{
name: 'ageOrShoeSize',
type: 'select',
choices: [
{
label: 'age',
value: 'age',
showFields: [ 'age' ]
},
{
label: 'shoeSize',
value: 'shoeSize',
showFields: [ 'shoeSize' ]
}
]
}
]
});
var output = {};
apos.schemas.convert(req, schema, 'form', { ageOrShoeSize: 'shoeSize', age: '' }, output, function(err) {
assert(!err);
assert(output.ageOrShoeSize === 'shoeSize');
done();
});
});
it('enforces required property for shown field', function(done) {
var req = apos.tasks.getReq();
var schema = apos.schemas.compose({
addFields: [
{
name: 'age',
type: 'integer',
required: true
},
{
name: 'shoeSize',
type: 'integer',
required: false
},
{
name: 'ageOrShoeSize',
type: 'select',
choices: [
{
label: 'age',
value: 'age',
showFields: [ 'age' ]
},
{
label: 'shoeSize',
value: 'shoeSize',
showFields: [ 'shoeSize' ]
}
]
}
]
});
var output = {};
apos.schemas.convert(req, schema, 'form', { ageOrShoeSize: 'age', age: '' }, output, function(err) {
assert(err);
assert(err === 'age.required');
done();
});
});
it('ignores required property for recursively hidden field', function(done) {
var req = apos.tasks.getReq();
var schema = apos.schemas.compose({
addFields: [
{
name: 'age',
type: 'integer',
required: true
},
{
name: 'shoeSize',
type: 'integer',
required: false
},
{
name: 'ageOrShoeSize',
type: 'select',
choices: [
{
label: 'age',
value: 'age',
showFields: [ 'age' ]
},
{
label: 'shoeSize',
value: 'shoeSize',
showFields: [ 'shoeSize' ]
}
]
},
{
name: 'doWeCare',
type: 'select',
choices: [
{
label: 'Yes',
value: '1',
showFields: [ 'ageOrShoeSize' ]
},
{
label: 'No',
value: '0',
showFields: []
}
]
}
]
});
var output = {};
apos.schemas.convert(req, schema, 'form', { ageOrShoeSize: 'age', doWeCare: '0', age: '' }, output, function(err) {
assert(!err);
assert(output.ageOrShoeSize === 'age');
done();
});
});
it('enforces required property for recursively shown field', function(done) {
var req = apos.tasks.getReq();
var schema = apos.schemas.compose({
addFields: [
{
name: 'age',
type: 'integer',
required: true
},
{
name: 'shoeSize',
type: 'integer',
required: false
},
{
name: 'ageOrShoeSize',
type: 'select',
choices: [
{
label: 'age',
value: 'age',
showFields: [ 'age' ]
},
{
label: 'shoeSize',
value: 'shoeSize',
showFields: [ 'shoeSize' ]
}
]
},
{
name: 'doWeCare',
type: 'select',
choices: [
{
label: 'Yes',
value: '1',
showFields: [ 'ageOrShoeSize' ]
},
{
label: 'No',
value: '0',
showFields: []
}
]
}
]
});
var output = {};
apos.schemas.convert(req, schema, 'form', { ageOrShoeSize: 'age', doWeCare: '1', age: '' }, output, function(err) {
assert(err);
assert(err === 'age.required');
done();
});
});
it('ignores required property for recursively hidden field with checkboxes', function(done) {
var req = apos.tasks.getReq();
var schema = apos.schemas.compose({
addFields: [
{
name: 'age',
type: 'integer',
required: true
},
{
name: 'shoeSize',
type: 'integer',
required: false
},
{
name: 'ageOrShoeSize',
type: 'checkboxes',
choices: [
{
label: 'age',
value: 'age',
showFields: [ 'age' ]
},
{
label: 'shoeSize',
value: 'shoeSize',
showFields: [ 'shoeSize' ]
}
]
},
{
name: 'doWeCare',
type: 'checkboxes',
choices: [
{
label: 'Yes',
value: '1',
showFields: [ 'ageOrShoeSize' ]
},
{
label: 'No',
value: '0',
showFields: []
}
]
}
]
});
var output = {};
apos.schemas.convert(req, schema, 'form', { ageOrShoeSize: ['age'], doWeCare: ['0'], age: '' }, output, function(err) {
assert(!err);
assert.deepEqual(output.ageOrShoeSize, ['age']);
done();
});
});
it('enforces required property for recursively shown field with checkboxes', function(done) {
var req = apos.tasks.getReq();
var schema = apos.schemas.compose({
addFields: [
{
name: 'age',
type: 'integer',
required: true
},
{
name: 'shoeSize',