Skip to content

Instantly share code, notes, and snippets.

@bendrucker
Last active August 29, 2015 13:57
Show Gist options
  • Save bendrucker/9418385 to your computer and use it in GitHub Desktop.
Save bendrucker/9418385 to your computer and use it in GitHub Desktop.
The current base model that i'm using
'use strict';
var DB = require('./db');
var Joi = require('joi');
var Promise = require('bluebird');
var _ = require('lodash');
var Model = DB.Model.extend({
constructor: function () {
DB.Model.apply(this, arguments);
this.on('saving', function (model, attrs, options) {
options = options || {};
if (options.validate === false) return;
return this.validate();
}, this);
},
hasTimestamps: true,
validate: Promise.method(function () {
if (!this.schema) return;
if (this.hasTimestamps && !this.schema.created_at) {
_.extend(this.schema, {
'created_at': Joi.date(),
'updated_at': Joi.date()
});
}
var err = Joi.validate(this.toJSON(), this.schema);
return err ? Promise.reject(err) : err;
})
});
var base = {
Model: Model
};
require('bookshelf-authorization')(DB, {
base: base
});
module.exports = base;
var expect = require('chai').expect;
var sinon = require('sinon');
var _ = require('lodash');
var Joi = require('joi');
var Promise = require('bluebird');
var Model = require('../../../src/lib/model').Model;
describe('Model', function () {
var model;
beforeEach(function () {
model = new Model();
});
it('uses the authorization plugin', function () {
expect(Model).to.have.a.property('authorize');
});
it('has timestamps', function () {
expect(model.hasTimestamps).to.be.ok;
});
describe('events', function () {
describe('saving', function () {
it('validates the model', function () {
sinon.spy(model, 'validate');
return model.triggerThen('saving').finally(function () {
expect(model.validate).to.have.been.called;
});
});
it('permits saving if validation returns no errors', function () {
return model.triggerThen('saving');
});
it('halt saving when validation is rejected', function () {
var err = new Error();
sinon.stub(model, 'validate').returns(Promise.reject(err));
return expect(model.triggerThen('saving'))
.to.be.rejectedWith(err);
});
it('can disable validation', function () {
sinon.spy(model, 'validate');
return model.triggerThen('saving', null, null, {
validate: false
})
.finally(function () {
expect(model.validate).to.not.have.been.called;
});
});
});
});
describe('#validate', function () {
beforeEach(function () {
sinon.stub(Joi, 'validate');
model.schema = {};
});
afterEach(function () {
Joi.validate.restore();
});
it('validates the schema using Joi', function () {
Joi.validate.returns(null);
return model.validate().then(function (response) {
expect(response).to.be.null;
expect(Joi.validate).to.have.been.calledWith(model.toJSON(), model.schema);
});
});
it('rejects when Joi.validate returns an error', function () {
var err = new Error();
Joi.validate.returns(err);
return expect(model.validate())
.to.be.rejectedWith(err);
});
it('appends timestamps to the schema if used', function () {
return model.validate().finally(function () {
expect(model.schema).to.have.keys('created_at', 'updated_at');
});
});
it('does not overwrite the timestamp fields', function () {
sinon.spy(_, 'extend');
model.schema['created_at'] = Joi.date();
return model.validate().finally(function () {
expect(_.extend).to.not.have.been.called;
_.extend.restore();
});
});
it('is a noop if there is no schema', function () {
model.schema = null;
return model.validate();
});
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment