2014-07-10 16:32:58 +00:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
var modelHelper = require('../lib/model-helper');
|
2014-08-05 06:22:41 +00:00
|
|
|
var loopback = require('loopback');
|
2014-07-10 16:32:58 +00:00
|
|
|
var expect = require('chai').expect;
|
|
|
|
|
|
|
|
describe('model-helper', function() {
|
|
|
|
describe('properly converts LDL definitions to swagger types', function() {
|
|
|
|
it('converts constructor types', function() {
|
2014-07-24 20:35:02 +00:00
|
|
|
var def = buildSwaggerModels({
|
2014-07-10 16:32:58 +00:00
|
|
|
str: String, // 'string'
|
|
|
|
num: Number, // {type: 'number', format: 'double'}
|
|
|
|
date: Date, // {type: 'string', format: 'date'}
|
|
|
|
bool: Boolean, // 'boolean'
|
|
|
|
buf: Buffer // {type: 'string', format: 'byte'}
|
|
|
|
});
|
|
|
|
var props = def.properties;
|
2014-07-11 13:55:19 +00:00
|
|
|
expect(props.str).to.eql({ type: 'string' });
|
|
|
|
expect(props.num).to.eql({ type: 'number', format: 'double' });
|
|
|
|
expect(props.date).eql({ type: 'string', format: 'date' });
|
|
|
|
expect(props.bool).to.eql({ type: 'boolean' });
|
|
|
|
expect(props.buf).to.eql({ type: 'string', format: 'byte' });
|
2014-07-10 16:32:58 +00:00
|
|
|
});
|
|
|
|
it('converts string types', function() {
|
2014-07-24 20:35:02 +00:00
|
|
|
var def = buildSwaggerModels({
|
2014-07-10 16:32:58 +00:00
|
|
|
str: 'string', // 'string'
|
|
|
|
num: 'number', // {type: 'number', format: 'double'}
|
|
|
|
date: 'date', // {type: 'string', format: 'date'}
|
|
|
|
bool: 'boolean', // 'boolean'
|
|
|
|
buf: 'buffer' // {type: 'string', format: 'byte'}
|
|
|
|
});
|
|
|
|
var props = def.properties;
|
2014-07-11 13:55:19 +00:00
|
|
|
expect(props.str).to.eql({ type: 'string' });
|
|
|
|
expect(props.num).to.eql({ type: 'number', format: 'double' });
|
|
|
|
expect(props.date).eql({ type: 'string', format: 'date' });
|
|
|
|
expect(props.bool).to.eql({ type: 'boolean' });
|
|
|
|
expect(props.buf).to.eql({ type: 'string', format: 'byte' });
|
2014-07-10 16:32:58 +00:00
|
|
|
});
|
|
|
|
describe('array definitions', function() {
|
|
|
|
// There are three types we want to checK:
|
|
|
|
// [String]
|
|
|
|
// ["string"],
|
|
|
|
// [{type: String, ...}]
|
|
|
|
it('converts [Constructor] type', function() {
|
2014-07-24 20:35:02 +00:00
|
|
|
var def = buildSwaggerModels({
|
2014-07-10 16:32:58 +00:00
|
|
|
array: [String]
|
|
|
|
});
|
|
|
|
var props = def.properties;
|
2014-07-11 13:55:19 +00:00
|
|
|
expect(props.array).to.eql({ type: 'array', items: {
|
|
|
|
type: 'string'
|
|
|
|
}});
|
2014-07-10 16:32:58 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
it('converts ["string"] type', function() {
|
2014-07-24 20:35:02 +00:00
|
|
|
var def = buildSwaggerModels({
|
2014-07-10 16:32:58 +00:00
|
|
|
array: ['string']
|
|
|
|
});
|
|
|
|
var props = def.properties;
|
2014-07-11 13:55:19 +00:00
|
|
|
expect(props.array).to.eql({ type: 'array', items: {
|
|
|
|
type: 'string'
|
|
|
|
}});
|
2014-07-10 16:32:58 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
it('converts [{type: "string", length: 64}] type', function() {
|
2014-07-24 20:35:02 +00:00
|
|
|
var def = buildSwaggerModels({
|
2014-07-10 16:32:58 +00:00
|
|
|
array: [{type: 'string', length: 64}]
|
|
|
|
});
|
|
|
|
var props = def.properties;
|
2014-07-11 13:55:19 +00:00
|
|
|
expect(props.array).to.eql({ type: 'array', items: {
|
|
|
|
type: 'string',
|
|
|
|
length: 64
|
|
|
|
}});
|
2014-07-10 16:32:58 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
it('converts [{type: "date"}] type (with `format`)', function() {
|
2014-07-24 20:35:02 +00:00
|
|
|
var def = buildSwaggerModels({
|
2014-07-10 16:32:58 +00:00
|
|
|
array: [{type: 'date'}]
|
|
|
|
});
|
|
|
|
var props = def.properties;
|
2014-07-11 13:55:19 +00:00
|
|
|
expect(props.array).to.eql({ type: 'array', items: {
|
|
|
|
type: 'string', format: 'date'
|
|
|
|
}});
|
2014-07-10 16:32:58 +00:00
|
|
|
});
|
2014-07-22 19:34:42 +00:00
|
|
|
|
|
|
|
it('converts [] type', function() {
|
2014-07-24 20:35:02 +00:00
|
|
|
var def = buildSwaggerModels({
|
2014-07-22 19:34:42 +00:00
|
|
|
array: []
|
|
|
|
});
|
|
|
|
var prop = def.properties.array;
|
2014-07-31 22:52:52 +00:00
|
|
|
expect(prop).to.eql({
|
|
|
|
type: 'array',
|
|
|
|
items: { type: 'any' }
|
|
|
|
});
|
2014-07-22 19:34:42 +00:00
|
|
|
});
|
|
|
|
|
2014-07-22 19:52:25 +00:00
|
|
|
it('converts [undefined] type', function() {
|
2014-07-24 20:35:02 +00:00
|
|
|
var def = buildSwaggerModels({
|
2014-07-22 19:52:25 +00:00
|
|
|
// This value is somehow provided by loopback-boot called from
|
|
|
|
// loopback-workspace.
|
|
|
|
array: [undefined]
|
|
|
|
});
|
|
|
|
var prop = def.properties.array;
|
2014-07-31 22:52:52 +00:00
|
|
|
expect(prop).to.eql({ type: 'array', items: { type: 'any' } });
|
2014-07-22 19:52:25 +00:00
|
|
|
});
|
|
|
|
|
2014-07-22 19:34:42 +00:00
|
|
|
it('converts "array" type', function() {
|
2014-07-24 20:35:02 +00:00
|
|
|
var def = buildSwaggerModels({
|
2014-07-22 19:34:42 +00:00
|
|
|
array: 'array'
|
|
|
|
});
|
|
|
|
var prop = def.properties.array;
|
2014-07-31 22:52:52 +00:00
|
|
|
expect(prop).to.eql({ type: 'array', items: { type: 'any' } });
|
2014-07-22 19:34:42 +00:00
|
|
|
});
|
2014-08-05 06:22:41 +00:00
|
|
|
|
|
|
|
it('converts Model type', function() {
|
|
|
|
var Address = loopback.createModel('Address', {street: String});
|
|
|
|
var def = buildSwaggerModels({
|
|
|
|
str: String,
|
|
|
|
address: Address
|
|
|
|
});
|
|
|
|
var prop = def.properties.address;
|
|
|
|
expect(prop).to.eql({ type: 'Address' });
|
|
|
|
});
|
|
|
|
|
2014-07-10 16:32:58 +00:00
|
|
|
});
|
|
|
|
});
|
2014-08-28 22:20:03 +00:00
|
|
|
|
2014-07-24 20:35:02 +00:00
|
|
|
describe('related models', function() {
|
2014-08-28 22:20:03 +00:00
|
|
|
it('should include related models', function () {
|
2014-07-24 20:35:02 +00:00
|
|
|
var defs = buildSwaggerModelsWithRelations({
|
|
|
|
str: String // 'string'
|
|
|
|
});
|
|
|
|
expect(defs).has.property('testModel');
|
|
|
|
expect(defs).has.property('relatedModel');
|
|
|
|
});
|
2014-08-28 22:20:03 +00:00
|
|
|
|
|
|
|
it('should include nesting models', function() {
|
|
|
|
var Model2 = loopback.createModel('Model2', {street: String});
|
|
|
|
var Model1 = loopback.createModel('Model1', {
|
|
|
|
str: String, // 'string'
|
|
|
|
address: Model2
|
|
|
|
});
|
|
|
|
var defs = modelHelper.generateModelDefinition(Model1, {});
|
|
|
|
expect(defs).has.property('Model1');
|
|
|
|
expect(defs).has.property('Model2');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should include used models', function() {
|
|
|
|
var Model4 = loopback.createModel('Model4', {street: String});
|
|
|
|
var Model3 = loopback.createModel('Model3', {
|
|
|
|
str: String, // 'string'
|
|
|
|
}, {models: {model4: 'Model4'}});
|
|
|
|
var defs = modelHelper.generateModelDefinition(Model3, {});
|
|
|
|
expect(defs).has.property('Model3');
|
|
|
|
expect(defs).has.property('Model4');
|
|
|
|
});
|
2014-08-29 08:06:05 +00:00
|
|
|
|
|
|
|
it('should include nesting models in array', function() {
|
|
|
|
var Model6 = loopback.createModel('Model6', {street: String});
|
|
|
|
var Model5 = loopback.createModel('Model5', {
|
|
|
|
str: String, // 'string'
|
|
|
|
addresses: [Model6]
|
|
|
|
});
|
|
|
|
var defs = modelHelper.generateModelDefinition(Model5, {});
|
|
|
|
expect(defs).has.property('Model5');
|
|
|
|
expect(defs).has.property('Model6');
|
|
|
|
});
|
2014-07-24 20:35:02 +00:00
|
|
|
});
|
2014-08-28 22:20:03 +00:00
|
|
|
|
2014-07-26 17:12:05 +00:00
|
|
|
describe('hidden properties', function() {
|
|
|
|
it('should hide properties marked as "hidden"', function() {
|
|
|
|
var aClass = createModelCtor({
|
|
|
|
visibleProperty: 'string',
|
|
|
|
hiddenProperty: 'string'
|
|
|
|
});
|
|
|
|
aClass.ctor.definition.settings = {
|
|
|
|
hidden: ['hiddenProperty']
|
|
|
|
};
|
|
|
|
var def = modelHelper.generateModelDefinition(aClass.ctor, {}).testModel;
|
|
|
|
expect(def.properties).to.not.have.property('hiddenProperty');
|
|
|
|
expect(def.properties).to.have.property('visibleProperty');
|
|
|
|
});
|
|
|
|
});
|
2014-07-10 16:32:58 +00:00
|
|
|
});
|
|
|
|
|
2014-07-11 13:55:19 +00:00
|
|
|
// Simulates the format of a remoting class.
|
2014-07-24 20:35:02 +00:00
|
|
|
function buildSwaggerModels(model) {
|
2014-07-26 17:12:05 +00:00
|
|
|
var aClass = createModelCtor(model);
|
|
|
|
return modelHelper.generateModelDefinition(aClass.ctor, {}).testModel;
|
|
|
|
}
|
|
|
|
|
|
|
|
function createModelCtor(model) {
|
2014-07-24 20:35:02 +00:00
|
|
|
Object.keys(model).forEach(function(name) {
|
|
|
|
model[name] = {type: model[name]};
|
|
|
|
});
|
|
|
|
var aClass = {
|
|
|
|
ctor: {
|
|
|
|
definition: {
|
|
|
|
name: 'testModel',
|
|
|
|
properties: model
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2014-07-26 17:12:05 +00:00
|
|
|
return aClass;
|
2014-07-24 20:35:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function buildSwaggerModelsWithRelations(model) {
|
2014-07-10 16:32:58 +00:00
|
|
|
Object.keys(model).forEach(function(name) {
|
|
|
|
model[name] = {type: model[name]};
|
|
|
|
});
|
2014-07-24 20:35:02 +00:00
|
|
|
// Mock up the related model
|
|
|
|
var relatedModel = {
|
|
|
|
definition: {
|
|
|
|
name: 'relatedModel',
|
|
|
|
properties: {
|
|
|
|
fk: String
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2014-07-10 16:32:58 +00:00
|
|
|
var aClass = {
|
|
|
|
ctor: {
|
|
|
|
definition: {
|
|
|
|
name: 'testModel',
|
|
|
|
properties: model
|
2014-07-24 20:35:02 +00:00
|
|
|
},
|
|
|
|
// Mock up relations
|
|
|
|
relations: {
|
|
|
|
other: {
|
|
|
|
modelTo: relatedModel
|
|
|
|
}
|
2014-07-10 16:32:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2014-07-24 20:35:02 +00:00
|
|
|
return modelHelper.generateModelDefinition(aClass.ctor, {});
|
2014-07-10 16:32:58 +00:00
|
|
|
}
|
2014-07-24 20:35:02 +00:00
|
|
|
|