@loudsrl/loopback-cascade-delete-mixin
Version:
Loopback cascade delete mixin
433 lines (399 loc) • 16.2 kB
JavaScript
;
describe('Cascade Delete Mixin', () => {
let Product;
let Category;
let CategoryMapping;
let Purchase;
let User;
let CascadeDelete = require('../cascade-delete');
let ModelBuilder = require('loopback-datasource-juggler').ModelBuilder;
let modelBuilder = new ModelBuilder();
let mixins = modelBuilder.mixins;
let sandbox;
let db;
before(() => {
db = new loopback.DataSource('memory', {
connector: loopback.Memory
}, modelBuilder);
mixins.define('CascadeDelete', CascadeDelete);
});
beforeEach(() => {
sandbox = sinon.sandbox.create();
});
afterEach(() => {
sandbox.restore();
});
describe('belongsTo', () => {
before(done => {
User = db.createModel('User', {name: String}, {
mixins: {
CascadeDelete: {
relations: ['product']
}
}
});
Product = db.createModel('Product', {name: 'string'});
User.belongsTo('product', {model: Product});
db.automigrate(['User', 'Product'], done);
});
it('should delete related model -- Product', done => {
let user;
sandbox.spy(Product, 'destroyAll');
User.create({name: 'John User'})
.then(_user => {
user = _user;
sandbox.spy(user, 'destroy');
return user.product.create({name: 'phone'});
}).then(() => {
return user.destroy();
}).then(() => {
expect(user.destroy).to.have.been.called;
expect(Product.destroyAll).to.have.been.called;
done();
}).catch(err => {
done(err);
});
});
it('should delete related model -- Product (deep delete)', done => {
User.settings.mixins.CascadeDelete.deepDelete = true;
let user;
User.create({name: 'John User'})
.then(_user => {
user = _user;
sandbox.spy(user, 'destroy');
return user.product.create({name: 'phone'});
}).then(() => {
return user.destroy();
})
.then(() => {
expect(user.destroy).to.have.been.called;
return Product.find()
})
.then(products => {
expect(products).to.be.an('array').that.is.empty;
done()
})
.catch(err => {
done(err);
});
});
it ('should delete related model -- Product (object)', done => {
User.settings.mixins.CascadeDelete.relations = [{name: 'product'}];
let user;
sandbox.spy(Product, 'destroyAll');
User.create({name: 'John User'})
.then(_user => {
user = _user;
sandbox.spy(user, 'destroy');
return user.product.create({name: 'phone'});
}).then(() => {
return user.destroy();
}).then(() => {
expect(user.destroy).to.have.been.called;
expect(Product.destroyAll).to.have.been.called;
done();
}).catch(err => {
done(err);
});
});
it ('should delete related model -- Product (object, deep delete)', done => {
User.settings.mixins.CascadeDelete.relations = [{name: 'product', deepDelete: true}];
let user;
User.create({name: 'John User'})
.then(_user => {
user = _user;
sandbox.spy(user, 'destroy');
sandbox.spy(Product, 'destroyAll');
return user.product.create({name: 'phone'});
}).then(() => {
return user.destroy();
})
.then(() => {
expect(user.destroy).to.have.been.called;
return Product.find()
})
.then(products => {
expect(products).to.be.an('array').that.is.empty;
expect(Product.destroyAll).not.to.have.been.called;
done()
})
.catch(err => {
done(err);
});
})
});
describe('hasOne', () => {
before(done => {
User = db.createModel('User', {name: String}, {
mixins: {
CascadeDelete: {
relations: ['product']
}
}
});
Product = db.createModel('Product', {name: 'string'});
User.hasOne('product', {model: Product});
db.automigrate(['User', 'Product'], done);
});
it('should delete related model -- Product', done => {
let user;
sandbox.spy(Product, 'destroyAll');
User.create({name: 'John User'})
.then(_user => {
user = _user;
sandbox.spy(user, 'destroy');
return user.product.create({name: 'phone'});
}).then(() => {
return user.destroy();
}).then(() => {
expect(user.destroy).to.have.been.called;
expect(Product.destroyAll).to.have.been.called;
done();
}).catch(err => {
done(err);
});
});
it('should delete related model -- Product (deep delete)', done => {
User.settings.mixins.CascadeDelete.deepDelete = true;
let user;
User.create({name: 'John User'})
.then(_user => {
user = _user;
sandbox.spy(user, 'destroy');
return user.product.create({name: 'phone'});
}).then(() => {
return user.destroy();
})
.then(() => {
expect(user.destroy).to.have.been.called;
return Product.find()
})
.then(products => {
expect(products).to.be.an('array').that.is.empty;
done();
})
.catch(err => {
done(err);
});
});
it('should delete related model -- Product (object)', done => {
User.settings.mixins.CascadeDelete.relations = [{name: 'product'}];
let user;
sandbox.spy(Product, 'destroyAll');
User.create({name: 'John User'})
.then(_user => {
user = _user;
sandbox.spy(user, 'destroy');
return user.product.create({name: 'phone'});
}).then(() => {
return user.destroy();
}).then(() => {
expect(user.destroy).to.have.been.called;
expect(Product.destroyAll).to.have.been.called;
done();
}).catch(err => {
done(err);
});
});
it('should delete related model -- Product (object, deep delete)', done => {
User.settings.mixins.CascadeDelete.deepDelete = true;
User.settings.mixins.CascadeDelete.relations = [{name: 'product', deepDelete: true}];
let user;
User.create({name: 'John User'})
.then(_user => {
user = _user;
sandbox.spy(user, 'destroy');
return user.product.create({name: 'phone'});
}).then(() => {
return user.destroy();
})
.then(() => {
expect(user.destroy).to.have.been.called;
return Product.find()
})
.then(products => {
expect(products).to.be.an('array').that.is.empty;
done();
})
.catch(err => {
done(err);
});
});
});
describe('hasMany', () => {
before(done => {
User = db.createModel('User', {name: String}, {
mixins: {
CascadeDelete: {
relations: ['products', 'purchases']
}
}
});
Product = db.createModel('Product', {name: 'string'});
Purchase = db.createModel('Purchase', {name: 'string'});
User.hasMany('products', {model: Product});
User.hasMany('purchases', {model: Purchase});
db.automigrate(['User', 'Product', 'Purchase'], done);
});
it('should delete related models -- Product, Purchase', done => {
let user;
sandbox.spy(Product, 'destroyAll');
sandbox.spy(Purchase, 'destroyAll');
User.create({name: 'John User'})
.then(_user => {
user = _user;
sandbox.spy(user, 'destroy');
return Promise.all([user.products.create({name: 'phone'}), user.products.create({name: 'phone1'})]);
}).then(() => {
return user.purchases.create({name: 'purchase 1'})
}).then(() => {
return user.destroy();
}).then(() => {
expect(user.destroy).to.have.been.called;
expect(Product.destroyAll).to.have.been.called;
expect(Purchase.destroyAll).to.have.been.called;
done();
}).catch(err => {
done(err);
});
});
it('should delete related models -- Product, Purchase (deep delete)', done => {
User.settings.mixins.CascadeDelete.deepDelete = true;
let user;
User.create({name: 'John User'})
.then(_user => {
user = _user;
sandbox.spy(user, 'destroy');
return Promise.all([user.products.create({name: 'phone'}), user.products.create({name: 'phone1'})]);
}).then(() => {
return user.purchases.create({name: 'purchase 1'})
}).then(() => {
return user.destroy();
})
.then(() => {
expect(user.destroy).to.have.been.called;
return Promise.all([Product.find(), Purchase.find()]);
})
.then(([products, purchases]) => {
expect(products).to.be.an('array').that.is.empty;
expect(purchases).to.be.an('array').that.is.empty;
done();
})
.catch(err => {
done(err);
});
});
it('should delete related models -- Product, Purchase (object)', done => {
User.settings.mixins.CascadeDelete.relations = [{'name': 'products'}, 'purchases'];
let user;
sandbox.spy(Product, 'destroyAll');
sandbox.spy(Purchase, 'destroyAll');
User.create({name: 'John User'})
.then(_user => {
user = _user;
sandbox.spy(user, 'destroy');
return Promise.all([user.products.create({name: 'phone'}), user.products.create({name: 'phone1'})]);
}).then(() => {
return user.purchases.create({name: 'purchase 1'})
}).then(() => {
return user.destroy();
}).then(() => {
expect(user.destroy).to.have.been.called;
expect(Product.destroyAll).to.have.been.called;
expect(Purchase.destroyAll).to.have.been.called;
done();
}).catch(err => {
done(err);
});
});
it('should delete related models -- Product, Purchase (object, deep delete)', done => {
User.settings.mixins.CascadeDelete.relations = [{'name': 'products', deepDelete: false}, 'purchases'];
User.settings.mixins.CascadeDelete.deepDelete = true;
let user;
User.create({name: 'John User'})
.then(_user => {
user = _user;
sandbox.spy(user, 'destroy');
sandbox.spy(Product, 'destroyAll');
return Promise.all([user.products.create({name: 'phone'}), user.products.create({name: 'phone1'})]);
}).then(() => {
return user.purchases.create({name: 'purchase 1'})
}).then(() => {
return user.destroy();
})
.then(() => {
expect(user.destroy).to.have.been.called;
return Promise.all([Product.find(), Purchase.find()]);
})
.then(([products, purchases]) => {
expect(Product.destroyAll).to.have.been.called;
expect(products).to.be.an('array').that.is.empty;
expect(purchases).to.be.an('array').that.is.empty;
done();
})
.catch(err => {
done(err);
});
});
});
describe('hasMany through', () => {
before(done => {
Product = db.define('Product', {name: String}, {
mixins: {
CascadeDelete: {
relations: ['categories']
}
}
});
Category = db.define('Category', {name: String});
CategoryMapping = db.define('CategoryMapping', {name: String});
Product.hasMany('categories', {model: Category, through: CategoryMapping});
Category.hasMany('products', {model: Product, through: CategoryMapping});
CategoryMapping.belongsTo(Product);
CategoryMapping.belongsTo(Category);
db.automigrate(['Category', 'CategoryMapping', 'Product'], done);
});
it('should delete through models -- CategoryMapping', done => {
let product;
sandbox.spy(CategoryMapping, 'destroyAll');
Product.create({name: 'product1'})
.then(_product => {
product = _product;
return Category.create({name: 'category1'});
}).then(category => {
return category.products.add(product);
}).then(() => {
sandbox.spy(product, 'destroy');
return product.destroy();
})
.then(() => {
expect(CategoryMapping.destroyAll).to.have.been.called;
expect(product.destroy).to.have.been.called;
done();
})
.catch(err => done(err));
});
it('should delete through models -- CategoryMapping (deep delete)', done => {
let product;
Product.create({name: 'product1'})
.then(_product => {
product = _product;
return Category.create({name: 'category1'});
}).then(category => {
return category.products.add(product);
}).then(() => {
sandbox.spy(product, 'destroy');
return product.destroy();
})
.then(() => {
expect(product.destroy).to.have.been.called;
return CategoryMapping.find()
})
.then(cm => {
expect(cm).to.be.an('array').that.is.empty;
done();
})
.catch(err => done(err));
});
});
});