add baseModel plugin with some tests

This commit is contained in:
Matteo Pagliazzi
2015-11-24 18:51:48 +01:00
parent 1826cf2784
commit 3f1faf113e
3 changed files with 119 additions and 7 deletions

View File

@@ -0,0 +1,59 @@
import baseModel from '../../../../../website/src/libs/api-v3/baseModel';
describe('Base model plugin', () => {
let schema = {
add () {
return true;
},
statics: {},
options: {},
pre () {
return true;
},
};
beforeEach(() => {
sandbox.stub(schema, 'add');
});
it('adds a _id field to the schema', () => {
baseModel(schema);
expect(schema.add).to.be.calledWith(sinon.match({
_id: sinon.match.object,
}));
});
it('can add timestamps fields', () => {
baseModel(schema, {timestamps: true});
expect(schema.add).to.be.calledTwice;
});
it('can sanitize input objects', () => {
baseModel(schema, {
noSet: ['noUpdateForMe']
});
expect(schema.statics.sanitize).to.exist;
let sanitized = schema.statics.sanitize({ok: true, noUpdateForMe: true});
expect(sanitized).to.have.property('ok');
expect(sanitized).to.have.property('noUpdateForMe');
expect(sanitized.noUpdateForMe).to.equal(undefined);
});
it('can make fields private', () => {
baseModel(schema, {
private: ['amPrivate']
});
expect(schema.options.toObject.transform).to.exist;
let objToTransform = {ok: true, amPrivate: true};
let privatized = schema.options.toObject.transform({}, objToTransform);
expect(objToTransform).to.have.property('ok');
expect(objToTransform).to.have.property('amPrivate');
expect(objToTransform.amPrivate).to.equal(undefined);
});
});

View File

@@ -0,0 +1,53 @@
import _ from 'lodash';
import { uuid } from '../../../../common';
import validator from 'validator';
export default function baseModel (schema, options = {}) {
schema.add({
_id: {
type: String,
default: uuid.v4,
validate: [validator.isUUID, 'Invalid uuid.'], // TODO check for UUID version
},
});
if (options.timestamps) {
schema.add({
createdAt: {
type: Date,
default: Date.now,
},
updatedAt: {
type: Date,
default: Date.now,
},
});
}
if (options.timestamps) {
schema.pre('save', function updateUpdatedAt (next) {
if (!this.isNew) this.updatedAt = Date.now();
next();
});
}
let noSetFields = ['createdAt', 'updatedAt'];
let privateFields = ['__v'];
if (Array.isArray(options.noSet)) noSetFields.push(...options.noSet);
schema.statics.sanitize = function sanitize (objToSanitize = {}) {
noSetFields.forEach((fieldPath) => {
_.set(objToSanitize, fieldPath, undefined); // TODO decide wheter to use delete here
});
return objToSanitize;
};
if (Array.isArray(options.private)) privateFields.push(...options.private);
if (!schema.options.toObject) schema.options.toObject = {};
schema.options.toObject.transform = function transformToObject (doc, plainObj) {
privateFields.forEach((fieldPath) => {
_.set(plainObj, fieldPath, undefined); // TODO decide wheter to use delete here
});
};
}

View File

@@ -5,19 +5,13 @@ import _ from 'lodash';
import validator from 'validator'; import validator from 'validator';
import moment from 'moment'; import moment from 'moment';
import TaskSchemas from './task'; import TaskSchemas from './task';
import baseModel from '../libs/api-v3/baseModel';
// import {model as Challenge} from './challenge'; // import {model as Challenge} from './challenge';
let Schema = mongoose.Schema; let Schema = mongoose.Schema;
// User schema definition // User schema definition
export let schema = new Schema({ export let schema = new Schema({
// The user _id, stored as a string
// TODO validation
_id: {
type: String,
default: shared.uuid,
},
// TODO validation
apiToken: { apiToken: {
type: String, type: String,
default: shared.uuid, default: shared.uuid,
@@ -480,6 +474,12 @@ export let schema = new Schema({
minimize: false, // So empty objects are returned minimize: false, // So empty objects are returned
}); });
schema.plugin(baseModel, {
noSet: ['_id', 'apikey', 'auth.blocked', 'auth.timestamps', 'lastCron', 'auth.local.hashed_password', 'auth.local.salt'],
private: ['auth.local.hashed_password', 'auth.local.salt'],
});
schema.methods.deleteTask = function deleteTask (tid) { schema.methods.deleteTask = function deleteTask (tid) {
this.ops.deleteTask({params: {id: tid}}, () => {}); // TODO remove this whole method, since it just proxies, and change all references to this method this.ops.deleteTask({params: {id: tid}}, () => {}); // TODO remove this whole method, since it just proxies, and change all references to this method
}; };