baqend
Version:
Baqend JavaScript SDK
1,060 lines (895 loc) • 39.8 kB
JavaScript
if (typeof module !== 'undefined') {
require('./node');
}
describe('Test metamodel classes', function () {
var metamodel;
beforeEach(function () {
metamodel = new DB.metamodel.Metamodel(null);
});
describe('ModelBuilder', function () {
it('should create basic and object type', function () {
metamodel.init([]);
expect(metamodel.baseType(DB.metamodel.BasicType.Date.ref)).equals(DB.metamodel.BasicType.Date);
expect(metamodel.baseType(DB.metamodel.BasicType.DateTime.ref)).equals(DB.metamodel.BasicType.DateTime);
expect(metamodel.baseType(DB.metamodel.BasicType.Boolean.ref)).equals(DB.metamodel.BasicType.Boolean);
expect(metamodel.baseType(DB.metamodel.BasicType.Double.ref)).equals(DB.metamodel.BasicType.Double);
expect(metamodel.baseType(DB.metamodel.BasicType.Integer.ref)).equals(DB.metamodel.BasicType.Integer);
expect(metamodel.baseType(DB.metamodel.BasicType.String.ref)).equals(DB.metamodel.BasicType.String);
expect(metamodel.baseType(DB.metamodel.BasicType.Time.ref)).equals(DB.metamodel.BasicType.Time);
expect(metamodel.baseType(DB.metamodel.BasicType.File.ref)).equals(DB.metamodel.BasicType.File);
expect(metamodel.baseType(DB.metamodel.BasicType.GeoPoint.ref)).equals(DB.metamodel.BasicType.GeoPoint);
expect(metamodel.baseType(DB.metamodel.BasicType.JsonArray.ref)).equals(DB.metamodel.BasicType.JsonArray);
expect(metamodel.baseType(DB.metamodel.BasicType.JsonObject.ref)).equals(DB.metamodel.BasicType.JsonObject);
expect(metamodel.entity(DB.metamodel.EntityType.Object.ref)).instanceof(DB.metamodel.EntityType.Object);
});
it('should build type with attributes', function () {
var model = {
class: '/db/test.OtherPersClass',
fields: {
value: {
name: 'value',
type: '/db/Integer',
order: 0,
},
},
};
metamodel.fromJSON([model]);
var entity = metamodel.entity('/db/test.OtherPersClass');
expect(entity).instanceof(DB.metamodel.EntityType);
expect(entity.ref).equals('/db/test.OtherPersClass');
expect(entity.superType).equals(metamodel.entity(DB.metamodel.EntityType.Object.ref));
expect(entity.typeConstructor).be.ok;
expect(entity.declaredAttributes).length(1);
expect(entity.declaredAttributes[0]).instanceof(DB.metamodel.SingularAttribute);
expect(entity.declaredAttributes[0].declaringType).equals(entity);
expect(entity.declaredAttributes[0].name).equals('value');
expect(entity.declaredAttributes[0].type).equals(DB.metamodel.BasicType.Integer);
expect(entity.declaredAttributes[0].typeConstructor).equals(Number);
expect(entity.declaredAttributes[0].order).equals(0);
});
it('should build type with inheritance', function () {
var model = [
{
class: '/db/test.PersClass',
fields: {
name: {
name: 'name',
type: '/db/String',
},
ref: {
name: 'ref',
type: '/db/test.ChildPersClass',
},
},
},
{
class: '/db/test.ChildPersClass',
superClass: '/db/test.PersClass',
fields: {
value: {
name: 'value',
type: '/db/Integer',
},
},
},
];
metamodel.fromJSON(model);
var entity = metamodel.entity('/db/test.PersClass');
expect(entity).instanceof(DB.metamodel.EntityType);
expect(entity.ref).equals('/db/test.PersClass');
expect(entity.superType).equals(metamodel.entity(DB.metamodel.EntityType.Object.ref));
expect(entity.typeConstructor).be.ok;
expect(entity.declaredAttributes).length(2);
var name = entity.getDeclaredAttribute('name');
expect(entity.getAttribute('name')).equals(name);
expect(name).instanceof(DB.metamodel.SingularAttribute);
expect(name.declaringType).equals(entity);
expect(name.name).equals('name');
expect(name.type).equals(DB.metamodel.BasicType.String);
expect(name.typeConstructor).equals(String);
var ref = entity.getDeclaredAttribute('ref');
expect(entity.getAttribute('ref')).equals(ref);
expect(ref).instanceof(DB.metamodel.SingularAttribute);
expect(ref.declaringType).equals(entity);
expect(ref.name).equals('ref');
expect(ref.type).equals(metamodel.entity('/db/test.ChildPersClass'));
expect(ref.typeConstructor).be.ok;
expect(entity.getDeclaredAttribute('value')).be.null;
expect(entity.getAttribute('value')).be.null;
entity = metamodel.entity('/db/test.ChildPersClass');
expect(entity).instanceof(DB.metamodel.EntityType);
expect(entity.ref).equals('/db/test.ChildPersClass');
expect(entity.superType).equals(metamodel.entity('/db/test.PersClass'));
expect(entity.typeConstructor).be.ok;
expect(entity.declaredAttributes).length(1);
var value = entity.getDeclaredAttribute('value');
expect(entity.getAttribute('value')).equals(value);
expect(value).instanceof(DB.metamodel.SingularAttribute);
expect(value.declaringType).equals(entity);
expect(value.name).equals('value');
expect(value.type).equals(DB.metamodel.BasicType.Integer);
expect(value.typeConstructor).equals(Number);
expect(entity.getDeclaredAttribute('name')).be.null;
expect(entity.getAttribute('name')).equals(name);
expect(entity.getDeclaredAttribute('ref')).be.null;
expect(entity.getAttribute('ref')).equals(ref);
});
it('should build embedded type', function () {
var model = {
class: '/db/test.EmbeddedPersClass',
embedded: true,
fields: {
name: {
name: 'name',
type: '/db/String',
},
},
};
metamodel.fromJSON([model]);
var entity = metamodel.embeddable('/db/test.EmbeddedPersClass');
expect(entity).instanceof(DB.metamodel.EmbeddableType);
expect(entity.ref).equals('/db/test.EmbeddedPersClass');
expect(entity.typeConstructor).be.ok;
expect(entity.declaredAttributes).length(1);
expect(entity.declaredAttributes[0]).instanceof(DB.metamodel.SingularAttribute);
expect(entity.declaredAttributes[0].declaringType).equals(entity);
expect(entity.declaredAttributes[0].name).equals('name');
expect(entity.declaredAttributes[0].type).equals(DB.metamodel.BasicType.String);
expect(entity.declaredAttributes[0].typeConstructor).equals(String);
});
it('should build model with basic attribute', function () {
var model = {
class: '/db/test.TestClass',
fields: {
name: {
name: 'name',
type: '/db/String',
},
},
};
metamodel.fromJSON([model]);
var type = metamodel.entity('/db/test.TestClass');
var attr = type.declaredAttributes[0];
expect(attr).instanceof(DB.metamodel.SingularAttribute);
expect(attr.declaringType).equals(type);
expect(attr.name).equals('name');
expect(attr.type).equals(DB.metamodel.BasicType.String);
expect(attr.typeConstructor).equals(String);
expect(attr.persistentAttributeType).equals(DB.metamodel.Attribute.PersistentAttributeType.BASIC);
expect(attr.isAssociation).be.false;
expect(attr.isCollection).be.false;
});
it('should build model with reference attribute', function () {
var model = {
class: '/db/test.TestClass',
fields: {
name: {
name: 'name',
type: '/db/test.TestClass',
},
},
};
metamodel.fromJSON([model]);
var type = metamodel.entity('/db/test.TestClass');
var attr = type.declaredAttributes[0];
expect(attr).instanceof(DB.metamodel.SingularAttribute);
expect(attr.declaringType).equals(type);
expect(attr.name).equals('name');
expect(attr.type).equals(type);
expect(attr.typeConstructor).be.ok;
expect(attr.persistentAttributeType).equals(DB.metamodel.Attribute.PersistentAttributeType.ONE_TO_MANY);
expect(attr.isAssociation).be.true;
expect(attr.isCollection).be.false;
});
it('should build model with embedded attribute', function () {
var model = {
class: '/db/test.TestClass',
embedded: true,
fields: {
name: {
name: 'name',
type: '/db/test.TestClass',
},
},
};
metamodel.fromJSON([model]);
var type = metamodel.embeddable('/db/test.TestClass');
var attr = type.declaredAttributes[0];
expect(attr).instanceof(DB.metamodel.SingularAttribute);
expect(attr.declaringType).equals(type);
expect(attr.name).equals('name');
expect(attr.type).equals(type);
expect(attr.typeConstructor).be.ok;
expect(attr.persistentAttributeType).equals(DB.metamodel.Attribute.PersistentAttributeType.EMBEDDED);
expect(attr.isAssociation).be.false;
expect(attr.isCollection).be.false;
});
it('should build model with list attribute', function () {
var model = {
class: '/db/test.TestClass',
fields: {
name: {
name: 'name',
type: '/db/collection.List[/db/String]',
},
},
};
metamodel.fromJSON([model]);
var type = metamodel.entity('/db/test.TestClass');
var attr = type.declaredAttributes[0];
expect(attr).instanceof(DB.metamodel.ListAttribute);
expect(attr.declaringType).equals(type);
expect(attr.name).equals('name');
expect(attr.elementType).equals(DB.metamodel.BasicType.String);
expect(attr.typeConstructor).equals(DB.List);
expect(attr.persistentAttributeType).equals(DB.metamodel.Attribute.PersistentAttributeType.ELEMENT_COLLECTION);
expect(attr.isAssociation).be.false;
expect(attr.isCollection).be.true;
expect(attr.collectionType).equals(DB.metamodel.PluralAttribute.CollectionType.LIST);
});
it('should build model with set attribute', function () {
var model = {
class: '/db/test.TestClass',
fields: {
name: {
name: 'name',
type: '/db/collection.Set[/db/String]',
},
},
};
metamodel.fromJSON([model]);
var type = metamodel.entity('/db/test.TestClass');
var attr = type.declaredAttributes[0];
expect(attr).instanceof(DB.metamodel.SetAttribute);
expect(attr.declaringType).equals(type);
expect(attr.name).equals('name');
expect(attr.elementType).equals(DB.metamodel.BasicType.String);
expect(attr.typeConstructor).equals(DB.Set);
expect(attr.persistentAttributeType).equals(DB.metamodel.Attribute.PersistentAttributeType.ELEMENT_COLLECTION);
expect(attr.isAssociation).be.false;
expect(attr.isCollection).be.true;
expect(attr.collectionType).equals(DB.metamodel.PluralAttribute.CollectionType.SET);
});
it('should build model with map attribute', function () {
var model = {
class: '/db/test.TestClass',
fields: {
name: {
name: 'name',
type: '/db/collection.Map[/db/String,/db/Integer]',
},
},
};
metamodel.fromJSON([model]);
var type = metamodel.entity('/db/test.TestClass');
var attr = type.declaredAttributes[0];
expect(attr).instanceof(DB.metamodel.MapAttribute);
expect(attr.declaringType).equals(type);
expect(attr.name).equals('name');
expect(attr.elementType).equals(DB.metamodel.BasicType.Integer);
expect(attr.keyType).equals(DB.metamodel.BasicType.String);
expect(attr.typeConstructor).equals(DB.Map);
expect(attr.persistentAttributeType).equals(DB.metamodel.Attribute.PersistentAttributeType.ELEMENT_COLLECTION);
expect(attr.isAssociation).be.false;
expect(attr.isCollection).be.true;
expect(attr.collectionType).equals(DB.metamodel.PluralAttribute.CollectionType.MAP);
});
});
describe('BasicType', function () {
it('should be accessible by native constructors', function () {
metamodel.init([]);
expect(metamodel.baseType(Boolean)).equals(DB.metamodel.BasicType.Boolean);
expect(metamodel.baseType(Number)).equals(DB.metamodel.BasicType.Double);
expect(metamodel.baseType(String)).equals(DB.metamodel.BasicType.String);
expect(metamodel.baseType(Date)).equals(DB.metamodel.BasicType.DateTime);
expect(metamodel.baseType(Object)).equals(DB.metamodel.BasicType.JsonObject);
expect(metamodel.baseType(Array)).equals(DB.metamodel.BasicType.JsonArray);
expect(metamodel.baseType(DB.GeoPoint)).equals(DB.metamodel.BasicType.GeoPoint);
expect(metamodel.entity(Object)).instanceof(DB.metamodel.EntityType.Object);
});
it('should be accessible by simple name', function () {
metamodel.init([]);
expect(metamodel.baseType('Date')).equals(DB.metamodel.BasicType.Date);
expect(metamodel.baseType('DateTime')).equals(DB.metamodel.BasicType.DateTime);
expect(metamodel.baseType('Boolean')).equals(DB.metamodel.BasicType.Boolean);
expect(metamodel.baseType('Double')).equals(DB.metamodel.BasicType.Double);
expect(metamodel.baseType('Integer')).equals(DB.metamodel.BasicType.Integer);
expect(metamodel.baseType('String')).equals(DB.metamodel.BasicType.String);
expect(metamodel.baseType('Time')).equals(DB.metamodel.BasicType.Time);
expect(metamodel.baseType('File')).equals(DB.metamodel.BasicType.File);
expect(metamodel.baseType('GeoPoint')).equals(DB.metamodel.BasicType.GeoPoint);
expect(metamodel.baseType('JsonArray')).equals(DB.metamodel.BasicType.JsonArray);
expect(metamodel.baseType('JsonObject')).equals(DB.metamodel.BasicType.JsonObject);
});
});
describe('EntityType', function () {
it('Object should have metadata fields', function () {
metamodel.init([]);
var entity = metamodel.entity(DB.metamodel.EntityType.Object.ref);
expect(entity.declaredId).instanceof(DB.metamodel.SingularAttribute);
expect(entity.declaredId.name).equals('id');
expect(entity.declaredVersion).instanceof(DB.metamodel.SingularAttribute);
expect(entity.declaredVersion.name).equals('version');
expect(entity.declaredAcl).instanceof(DB.metamodel.SingularAttribute);
expect(entity.declaredAcl.name).equals('acl');
expect(entity.id).equals(entity.declaredId);
expect(entity.version).equals(entity.declaredVersion);
expect(entity.acl).equals(entity.declaredAcl);
});
it('Object metadata fields should be iterable', function () {
metamodel.init([]);
var entity = metamodel.entity(DB.metamodel.EntityType.Object.ref);
var names = ['id', 'version', 'acl'];
var count = 0;
for (var iter = entity.attributes(), item = iter.next(); !item.done; item = iter.next()) {
var attr = item.value;
var index = names.indexOf(attr.name);
expect(index).equals(attr.order);
expect(attr).equals(entity.getAttribute(attr.name));
count += 1;
}
expect(count).equals(3);
});
it('attributes should be iterable', function () {
var model = [
{
class: '/db/test.PersClass',
fields: {
name: {
name: 'name',
type: '/db/String',
},
ref: {
name: 'ref',
type: '/db/test.ChildPersClass',
},
},
},
{
class: '/db/test.ChildPersClass',
superClass: '/db/test.PersClass',
fields: {
value: {
name: 'value',
type: '/db/Integer',
},
},
},
];
metamodel.fromJSON(model);
var entity = metamodel.entity('/db/test.ChildPersClass');
var names = ['id', 'version', 'acl', 'name', 'ref', 'value'];
for (var iter = entity.attributes(), item = iter.next(); !item.done; item = iter.next()) {
var attr = item.value;
var index = names.indexOf(attr.name);
expect(index).not.equals(-1);
expect(attr).equals(entity.getAttribute(attr.name));
names.splice(index, 1);
}
expect(names).length(0);
});
});
});
describe('Test Metamodel', function () {
var metamodel;
beforeEach(async function () {
var emf = new DB.EntityManagerFactory({
host: env.TEST_SERVER,
tokenStorage: await helper.rootTokenStorage,
});
metamodel = emf.createMetamodel();
});
it('not init twice', function () {
metamodel.init([]);
expect(metamodel.init.bind(metamodel, {})).throw(Error);
});
it('should only be allowed once to load the metamodel', function () {
return metamodel.load().then(function () {
expect(function () { metamodel.load(); }).throw(Error);
});
});
it('should not be allowed to load after save metamodel', function () {
metamodel.init([]);
return metamodel.save().then(function () {
expect(function () { metamodel.load(); }).throw(Error);
});
});
it('should block the entityManager when isn\'t ready', function () {
var emf = new DB.EntityManagerFactory(env.TEST_SERVER);
expect(emf.createEntityManager().isReady).be.false;
});
it('should not block the entityManager when is ready', function () {
var emf = new DB.EntityManagerFactory({
host: env.TEST_SERVER,
schema: [],
tokenStorage: new DB.util.TokenStorage(),
});
expect(emf.createEntityManager().isReady).be.true;
});
it('should not be allowed to save without initialization', function () {
var emf = new DB.EntityManagerFactory(env.TEST_SERVER);
return expect(function () {
emf.metamodel.save();
}).throw('Metamodel is not initialized.');
});
it('should allow modification when used by an EntityManager', async function () {
var emf = new DB.EntityManagerFactory({
host: env.TEST_SERVER,
tokenStorage: await helper.rootTokenStorage,
});
var em = emf.createEntityManager();
return emf.ready()
.then(function () {
return emf.metamodel.save();
});
});
it('should update schema', function () {
var emf = new DB.EntityManagerFactory({ host: env.TEST_SERVER, tokenStorage: new DB.util.TokenStorage() });
var db = emf.createEntityManager(true);
var { metamodel } = db;
var SchemaUpdatePerson = helper.randomize('SchemaUpdatePerson');
var initialType;
return db.ready().then(function () {
return db.login('root', 'root');
}).then(function () {
var type = new DB.metamodel.EntityType(SchemaUpdatePerson, metamodel.entity(Object));
metamodel.addType(type);
type.addAttribute(new DB.metamodel.SingularAttribute('name', metamodel.baseType(String)));
type.addAttribute(new DB.metamodel.SingularAttribute('street', metamodel.baseType(String)));
type.addAttribute(new DB.metamodel.SingularAttribute('age', metamodel.baseType('Integer')));
initialType = type.toJSON();
return metamodel.update(initialType);
}).then(function () {
var UpdatePerson = metamodel.entity(SchemaUpdatePerson);
var renameField = {
operation: 'renameField',
bucket: UpdatePerson.ref,
from: 'name',
to: 'lastName',
};
var addField = {
operation: 'addField',
bucket: UpdatePerson.ref,
field: {
name: 'firstName',
type: '/db/String',
order: 2,
},
};
return metamodel.update(renameField).then(function () {
}).then(function () {
return metamodel.update(addField);
});
})
.then(function () {
var newPerson = metamodel.entity(SchemaUpdatePerson);
expect(newPerson.getDeclaredAttribute('firstName')).be.ok;
expect(newPerson.getDeclaredAttribute('firstName').type).equals(metamodel.baseType(String));
expect(newPerson.getDeclaredAttribute('lastName')).be.ok;
expect(newPerson.getDeclaredAttribute('lastName').type).equals(metamodel.baseType(String));
});
});
it('should handle metadata on classes', function () {
var model = {
class: '/db/test.OtherPersClass',
metadata: {
hello: 'world',
},
fields: {
value: {
name: 'value',
type: '/db/Integer',
order: 0,
},
},
};
metamodel.fromJSON([model]);
var entity = metamodel.entity('/db/test.OtherPersClass');
expect(entity).instanceof(DB.metamodel.EntityType);
expect(entity.metadata).deep.equals({
hello: 'world',
});
expect(entity.hasMetadata('hello')).be.true;
expect(entity.getMetadata('hello')).equals('world');
expect(entity.hasMetadata('notexisting')).be.false;
expect(entity.getMetadata('notexisting')).be.null;
});
it('should handle metadata on fields', function () {
var model = {
class: '/db/test.OtherPersClass',
fields: {
value: {
name: 'value',
type: '/db/Integer',
order: 0,
metadata: {
hello: 'world',
},
},
},
};
metamodel.fromJSON([model]);
var entity = metamodel.entity('/db/test.OtherPersClass');
expect(entity).instanceof(DB.metamodel.EntityType);
expect(entity.getDeclaredAttribute('value').metadata).deep.equals({
hello: 'world',
});
expect(entity.getDeclaredAttribute('value').hasMetadata('hello')).be.true;
expect(entity.getDeclaredAttribute('value').getMetadata('hello')).equals('world');
expect(entity.getDeclaredAttribute('value').hasMetadata('notexisting')).be.false;
expect(entity.getDeclaredAttribute('value').getMetadata('notexisting')).be.null;
});
describe('Testmodel', function () {
var type, childType, embeddedType, metamodel;
before(async function () {
var emf = new DB.EntityManagerFactory({
host: env.TEST_SERVER,
tokenStorage: await helper.rootTokenStorage,
});
metamodel = emf.metamodel;
metamodel.init([]);
metamodel.addType(type = new DB.metamodel.EntityType('jstest.Person', metamodel.entity(Object)));
metamodel.addType(childType = new DB.metamodel.EntityType('jstest.ChildPerson', type));
metamodel.addType(embeddedType = new DB.metamodel.EmbeddableType('jstest.EmbeddedPerson'));
type.addAttribute(new DB.metamodel.SingularAttribute('name', metamodel.baseType(String)));
type.addAttribute(new DB.metamodel.SingularAttribute('ref', type));
type.addAttribute(new DB.metamodel.SingularAttribute('date', metamodel.baseType(Date)));
type.addAttribute(new DB.metamodel.ListAttribute('list', metamodel.baseType('String')));
type.addAttribute(new DB.metamodel.SetAttribute('set', metamodel.baseType('Integer')));
type.addAttribute(new DB.metamodel.MapAttribute('map', metamodel.baseType('String'), type));
type.addAttribute(new DB.metamodel.SingularAttribute('removeMe', metamodel.baseType('String')));
childType.addAttribute(new DB.metamodel.SingularAttribute('age', metamodel.baseType('Integer')));
embeddedType.addAttribute(new DB.metamodel.SingularAttribute('age', metamodel.baseType(Number)));
embeddedType.addAttribute(new DB.metamodel.SingularAttribute('ref', type));
return metamodel.save();
});
it('should be available', function () {
var loadType = metamodel.entity('jstest.Person');
var loadChildType = metamodel.entity('jstest.ChildPerson');
var loadEmbeddedType = metamodel.embeddable('jstest.EmbeddedPerson');
expect(loadType).equals(type);
expect(loadChildType).equals(childType);
expect(loadEmbeddedType).equals(embeddedType);
testLoadedTypes(loadType, loadChildType, loadEmbeddedType, metamodel);
});
it('should be loadable', function () {
var emf = new DB.EntityManagerFactory({ host: env.TEST_SERVER });
var model = emf.createMetamodel();
return model.load().then(function () {
var loadType = model.entity('jstest.Person');
var loadChildType = model.entity('jstest.ChildPerson');
var loadEmbeddedType = model.embeddable('jstest.EmbeddedPerson');
expect(loadType).not.equals(type);
expect(loadChildType).not.equals(childType);
expect(loadEmbeddedType).not.equals(embeddedType);
testLoadedTypes(loadType, loadChildType, loadEmbeddedType, model);
});
});
it('should be accessible via db', function () {
var emf = new DB.EntityManagerFactory({ host: env.TEST_SERVER, staleness: 0 });
return emf.createEntityManager().ready().then(function (db) {
var loadType = db.metamodel.entity('jstest.Person');
var loadChildType = db.metamodel.entity('jstest.ChildPerson');
var loadEmbeddedType = db.metamodel.embeddable('jstest.EmbeddedPerson');
expect(loadType).not.equals(type);
expect(loadChildType).not.equals(childType);
expect(loadEmbeddedType).not.equals(embeddedType);
testLoadedTypes(loadType, loadChildType, loadEmbeddedType, db.metamodel);
});
});
it('should be allowed to remove attributes', function () {
expect(function () { type.removeAttribute('removeMeNot'); }).to.throw(Error);
expect(type.getAttribute('removeMe')).to.be.ok;
type.removeAttribute('removeMe');
expect(type.getAttribute('removeMe')).to.be.null;
type.addAttribute(new DB.metamodel.SingularAttribute('removeMe', metamodel.baseType('String')));
});
});
function testLoadedTypes(loadType, loadChildType, loadEmbeddedType, metamodel) {
expect(loadType).be.ok;
expect(loadType).instanceof(DB.metamodel.EntityType);
expect(loadType.ref).equals('/db/jstest.Person');
expect(loadType.superType).equals(metamodel.entity(Object));
expect(loadType.declaredAttributes).length(7);
expect(loadChildType).be.ok;
expect(loadChildType).instanceof(DB.metamodel.EntityType);
expect(loadChildType.ref).equals('/db/jstest.ChildPerson');
expect(loadChildType.superType).equals(loadType);
expect(loadChildType.declaredAttributes).length(1);
expect(loadEmbeddedType).be.ok;
expect(loadEmbeddedType).instanceof(DB.metamodel.EmbeddableType);
expect(loadEmbeddedType.ref).equals('/db/jstest.EmbeddedPerson');
expect(loadEmbeddedType.declaredAttributes).length(2);
expect(loadType.getDeclaredAttribute('name')).instanceof(DB.metamodel.SingularAttribute);
expect(loadType.getDeclaredAttribute('name').declaringType).equals(loadType);
expect(loadType.getDeclaredAttribute('name').name).equals('name');
expect(loadType.getDeclaredAttribute('name').type).equals(metamodel.baseType(String));
expect(loadType.getDeclaredAttribute('ref')).instanceof(DB.metamodel.SingularAttribute);
expect(loadType.getDeclaredAttribute('ref').declaringType).equals(loadType);
expect(loadType.getDeclaredAttribute('ref').name).equals('ref');
expect(loadType.getDeclaredAttribute('ref').type).equals(loadType);
expect(loadType.getDeclaredAttribute('date')).instanceof(DB.metamodel.SingularAttribute);
expect(loadType.getDeclaredAttribute('date').declaringType).equals(loadType);
expect(loadType.getDeclaredAttribute('date').name).equals('date');
expect(loadType.getDeclaredAttribute('date').type).equals(metamodel.baseType(Date));
expect(loadType.getDeclaredAttribute('list')).instanceof(DB.metamodel.ListAttribute);
expect(loadType.getDeclaredAttribute('list').declaringType).equals(loadType);
expect(loadType.getDeclaredAttribute('list').name).equals('list');
expect(loadType.getDeclaredAttribute('list').elementType).equals(metamodel.baseType('String'));
expect(loadType.getDeclaredAttribute('set')).instanceof(DB.metamodel.SetAttribute);
expect(loadType.getDeclaredAttribute('set').declaringType).equals(loadType);
expect(loadType.getDeclaredAttribute('set').name).equals('set');
expect(loadType.getDeclaredAttribute('set').elementType).equals(metamodel.baseType('Integer'));
expect(loadType.getDeclaredAttribute('map')).instanceof(DB.metamodel.MapAttribute);
expect(loadType.getDeclaredAttribute('map').declaringType).equals(loadType);
expect(loadType.getDeclaredAttribute('map').name).equals('map');
expect(loadType.getDeclaredAttribute('map').keyType).equals(metamodel.baseType('String'));
expect(loadType.getDeclaredAttribute('map').elementType).equals(loadType);
expect(loadChildType.getDeclaredAttribute('age')).instanceof(DB.metamodel.SingularAttribute);
expect(loadChildType.getDeclaredAttribute('age').declaringType).equals(loadChildType);
expect(loadChildType.getDeclaredAttribute('age').name).equals('age');
expect(loadChildType.getDeclaredAttribute('age').type).equals(metamodel.baseType('Integer'));
expect(loadEmbeddedType.getDeclaredAttribute('age')).instanceof(DB.metamodel.SingularAttribute);
expect(loadEmbeddedType.getDeclaredAttribute('age').declaringType).equals(loadEmbeddedType);
expect(loadEmbeddedType.getDeclaredAttribute('age').name).equals('age');
expect(loadEmbeddedType.getDeclaredAttribute('age').type).equals(metamodel.baseType('Double'));
expect(loadEmbeddedType.getDeclaredAttribute('ref')).instanceof(DB.metamodel.SingularAttribute);
expect(loadEmbeddedType.getDeclaredAttribute('ref').declaringType).equals(loadEmbeddedType);
expect(loadEmbeddedType.getDeclaredAttribute('ref').name).equals('ref');
expect(loadEmbeddedType.getDeclaredAttribute('ref').type).equals(loadType);
}
describe('Acl', function () {
var db, emf, obj, user1, user2, user3, initialType, initialEmbeddedType;
var SchemaAclPersonName = helper.randomize('SchemaAclPerson');
var SchemaAclEmbeddedPersonName = helper.randomize('SchemaAclEmbeddedPerson');
function createUser(emf, username) {
return emf.createEntityManager().ready().then(function (db) {
return db.User.register(username, 'secret', db.User.LoginOption.NO_LOGIN);
});
}
before(async function () {
var staticEmf = new DB.EntityManagerFactory({
host: env.TEST_SERVER,
tokenStorage: await helper.rootTokenStorage,
});
return Promise.all([
createUser(staticEmf, helper.makeLogin()),
createUser(staticEmf, helper.makeLogin()),
createUser(staticEmf, helper.makeLogin()),
])
.then(function (users) {
user1 = users[0];
user2 = users[1];
user3 = users[2];
var metamodel = staticEmf.createMetamodel();
metamodel.init([]);
var type,
embeddedType;
metamodel.addType(type = new DB.metamodel.EntityType(SchemaAclPersonName, metamodel.entity(Object)));
metamodel.addType(embeddedType = new DB.metamodel.EmbeddableType(SchemaAclEmbeddedPersonName));
type.addAttribute(new DB.metamodel.SingularAttribute('name', metamodel.baseType(String)));
embeddedType.addAttribute(new DB.metamodel.SingularAttribute('name', metamodel.baseType(String)));
type.insertPermission.denyAccess(user2);
type.updatePermission.denyAccess(user2)
.denyAccess(user3);
type.deletePermission.denyAccess(user2)
.denyAccess(user3)
.allowAccess(user1);
type.queryPermission.allowAccess(user2);
type.schemaSubclassPermission.allowAccess(user1)
.allowAccess(user3);
type.schemaAddPermission.allowAccess(user1);
type.schemaReplacePermission.allowAccess(user1);
embeddedType.schemaAddPermission.allowAccess(user1);
embeddedType.schemaReplacePermission.allowAccess(user1);
return metamodel.save();
})
.then(function () {
emf = new DB.EntityManagerFactory({
host: env.TEST_SERVER,
staleness: 0,
});
// db and emf shares the same login credentials
db = emf.createEntityManager(true);
return db.ready()
.then(function () {
obj = new db[SchemaAclPersonName]();
return obj.insert();
});
})
.then(function () {
return db.User.logout();
});
});
it('should convert acls', function () {
var metamodel = emf.createMetamodel();
return metamodel.load().then(function () {
var AclPerson = metamodel.entity(SchemaAclPersonName);
expect(AclPerson.insertPermission.isDenied(user2)).be.true;
expect(AclPerson.updatePermission.isDenied(user2)).be.true;
expect(AclPerson.deletePermission.isDenied(user2)).be.true;
expect(AclPerson.queryPermission.isAllowed(user2)).be.true;
expect(AclPerson.schemaSubclassPermission.isAllowed(user1)).be.true;
expect(AclPerson.schemaAddPermission.isAllowed(user1)).be.true;
expect(AclPerson.schemaReplacePermission.isAllowed(user1)).be.true;
var EmbeddableType = metamodel.embeddable(SchemaAclEmbeddedPersonName);
expect(EmbeddableType.schemaAddPermission.isAllowed(user1)).be.true;
expect(EmbeddableType.schemaReplacePermission.isAllowed(user1)).be.true;
});
});
describe('for user1', function () {
var metamodel;
before(function () {
return db.User.login(user1.username, 'secret');
});
after(function () {
return db.User.logout();
});
beforeEach(function () {
metamodel = emf.createMetamodel();
});
it('should allow schema load', function () {
return metamodel.load().then(function () {
expect(metamodel.entity(SchemaAclPersonName)).be.ok;
expect(metamodel.embeddable(SchemaAclEmbeddedPersonName)).be.ok;
});
});
it('should deny schema add', async function () {
await metamodel.load();
try {
await metamodel.save();
expect.fail();
} catch {}
});
it('should allow schema subclassing', async function () {
await metamodel.load();
var AclPerson = metamodel.entity(SchemaAclPersonName);
var child = new DB.metamodel.EntityType(helper.randomize('SchemaAclChildPerson'), AclPerson);
child.schemaReplacePermission.allowAccess(db.User.me);
metamodel.addType(child);
await metamodel.save(child);
});
it('should allow object load', async function () {
expect(await db[SchemaAclPersonName].load(obj.id)).be.ok;
});
it('should allow object creation', async function () {
expect(await new db[SchemaAclPersonName]().insert()).be.ok;
});
it('should allow object update', async function () {
const o = await new db[SchemaAclPersonName]().insert();
expect(await o.save()).be.ok;
});
it('should allow object removal', async function () {
const o = await new db[SchemaAclPersonName]().insert();
expect(await o.delete()).be.ok;
});
});
describe('for user2', function () {
var metamodel;
before(function () {
return db.User.login(user2.username, 'secret');
});
after(function () {
return db.User.logout();
});
beforeEach(function () {
metamodel = emf.createMetamodel();
});
it('should allow schema load', function () {
return metamodel.load().then(function () {
expect(metamodel.entity(SchemaAclPersonName)).be.ok;
expect(metamodel.embeddable(SchemaAclEmbeddedPersonName)).be.ok;
});
});
it('should deny schema add', async function () {
await metamodel.load();
try {
await metamodel.save();
expect.fail();
} catch {}
});
it('should deny schema subclassing', async function () {
await metamodel.load();
var AclPerson = metamodel.entity(SchemaAclPersonName);
var rnd = Math.floor(Math.random() * 1000000);
var child = new DB.metamodel.EntityType(`SchemaAclChildPerson${rnd}`, AclPerson);
child.schemaReplacePermission.allowAccess(db.User.me);
metamodel.addType(child);
try {
await metamodel.save(child);
expect.fail();
} catch {}
});
it('should allow object load', async function () {
expect(await db[SchemaAclPersonName].load(obj.id)).be.ok;
});
it('should deny object creation', async function () {
try {
await new db[SchemaAclPersonName]().insert();
expect.fail();
} catch {}
});
it('should deny object update', async function () {
const o = await db[SchemaAclPersonName].load(obj.id);
o.name = 'New Name';
try {
await o.save();
expect.fail();
} catch {}
});
it('should deny object removal', async function () {
const o = await db[SchemaAclPersonName].load(obj.id);
try {
await o.delete();
expect.fail();
} catch {}
});
});
describe('for user3', function () {
var metamodel;
before(function () {
return db.User.login(user3.username, 'secret');
});
after(function () {
return db.User.logout();
});
beforeEach(function () {
metamodel = emf.createMetamodel();
});
it('should allow schema load', function () {
return metamodel.load().then(function () {
expect(metamodel.entity(SchemaAclPersonName)).be.ok;
expect(metamodel.embeddable(SchemaAclEmbeddedPersonName)).be.ok;
});
});
it('should deny schema add', async function () {
await metamodel.load();
var AclPerson = metamodel.entity(SchemaAclPersonName);
try {
await metamodel.save(AclPerson);
expect.fail();
} catch {}
});
it('should deny schema replace', async function () {
await metamodel.load();
var AclPerson = metamodel.entity(SchemaAclPersonName);
var json = AclPerson.toJSON();
json.operation = 'replaceClass';
try {
await metamodel.update(json);
expect.fail();
} catch {}
});
it('should allow schema subclassing', async function () {
await metamodel.load();
var AclPerson = metamodel.entity(SchemaAclPersonName);
var rnd = Math.floor(Math.random() * 1000000);
var child = new DB.metamodel.EntityType(`SchemaAclChildPerson${rnd}`, AclPerson);
child.schemaReplacePermission.allowAccess(db.User.me);
metamodel.addType(child);
expect(await metamodel.save(child)).be.ok;
});
it('should allow object load', async function () {
expect(await db[SchemaAclPersonName].load(obj.id)).be.ok;
});
it('should allow object creation', async function () {
expect(await new db[SchemaAclPersonName]().insert()).be.ok;
});
it('should deny object update', async function () {
const o = await db[SchemaAclPersonName].load(obj.id);
o.name = 'New Name';
try {
await o.save();
expect.fail();
} catch {}
});
it('should deny object removal', async function () {
const o = await db[SchemaAclPersonName].load(obj.id);
try {
await o.delete();
expect.fail();
} catch {}
});
});
});
});