mirror of
https://github.com/zhigang1992/deployd.git
synced 2026-05-12 19:59:03 +08:00
Merge branch '0.7' of github.com:deployd/deployd into 0.7
This commit is contained in:
20
bin/createtemplate/events/helpers.js
Normal file
20
bin/createtemplate/events/helpers.js
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Add any helpers you need in other events.
|
||||
* This is useful to expose node modules to events
|
||||
* or to reuse code between events.
|
||||
*/
|
||||
|
||||
// var request = require('request');
|
||||
//
|
||||
// helpers.request = function (url, options, fn) {
|
||||
// request(url, options, function (err, res, body) {
|
||||
// if(err) throw err;
|
||||
//
|
||||
// if(res.statusCode >= 400) {
|
||||
// fn(null, body);
|
||||
// } else {
|
||||
// fn(body);
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
17
bin/createtemplate/events/request.js
Normal file
17
bin/createtemplate/events/request.js
Normal file
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Use the request event to define global business logic.
|
||||
* This will execute whenever a resource is requested.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Use prevent() and allow() to change your default permissions.
|
||||
* The following disables any unauthorized access to your app.
|
||||
*/
|
||||
|
||||
// only allow logged in users any permissions
|
||||
// if(!me) {
|
||||
// prevent('*');
|
||||
// }
|
||||
|
||||
// with the logging in being the only exception
|
||||
// allow('login');
|
||||
@@ -32,8 +32,21 @@ function Context(resource, req, res, server) {
|
||||
this.query = req.query || {};
|
||||
this.server = server;
|
||||
this.session = req.session;
|
||||
this.resource = resource;
|
||||
this.method = req && req.method;
|
||||
|
||||
if(resource && resource.getDefaultPermissions) {
|
||||
this.permissions = resource.getDefaultPermissions(this);
|
||||
} else {
|
||||
this.permissions = {};
|
||||
}
|
||||
|
||||
if(resource && resource.getRequiredPermissions) {
|
||||
this.requiredPermissions = resource.getRequiredPermissions(this);
|
||||
} else {
|
||||
this.requiredPermissions = {};
|
||||
}
|
||||
|
||||
// always bind done to this
|
||||
var done = this.done;
|
||||
this.done = function() {
|
||||
@@ -111,4 +124,75 @@ Context.prototype.done = function(err, res) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Permissions
|
||||
*/
|
||||
|
||||
Context.prototype.allow = function (permission) {
|
||||
var ctx = this;
|
||||
|
||||
if(permission === '*' || permission === 'all') {
|
||||
Object.keys(this.requiredPermissions).forEach(function (key) {
|
||||
ctx.permissions[key] = true;
|
||||
});
|
||||
} else {
|
||||
ctx.permissions[permission] = true;
|
||||
}
|
||||
}
|
||||
|
||||
Context.prototype.prevent = function (permission) {
|
||||
var ctx = this;
|
||||
|
||||
if(permission === '*' || permission === 'all') {
|
||||
ctx.permissions = {};
|
||||
} else {
|
||||
ctx.permissions[permission] = false;
|
||||
}
|
||||
}
|
||||
|
||||
Context.prototype.isAllowed = function (permission) {
|
||||
return !!this.permissions[permission];
|
||||
}
|
||||
|
||||
Context.prototype.allowByDefault = function (permission) {
|
||||
this.permissions[permission] = true;
|
||||
}
|
||||
|
||||
Context.prototype.requirePermission = function (permission) {
|
||||
this.requiredPermissions[permission] = true;
|
||||
}
|
||||
|
||||
Context.prototype.verifyPermissions = function (fn) {
|
||||
if(this.req.internal || this.req.isRoot) return fn();
|
||||
|
||||
var ctx = this;
|
||||
var requiredKeys = Object.keys(this.requiredPermissions);
|
||||
var requested = this.permissions;
|
||||
var failed;
|
||||
|
||||
if(requiredKeys.length) {
|
||||
requiredKeys.forEach(function (permission) {
|
||||
if(!requested[permission]) {
|
||||
if(ctx.server.options.env === 'development') {
|
||||
error('permission denied when ' + permission + ' - to allow this action, include `allow("'+ permission +'")` in an event script');
|
||||
} else {
|
||||
error('permission denied when ' + permission);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if(!failed) {
|
||||
fn();
|
||||
}
|
||||
} else {
|
||||
fn();
|
||||
}
|
||||
|
||||
function error(msg) {
|
||||
failed = true;
|
||||
ctx.res.statusCode = 401;
|
||||
ctx.done(new Error(msg));
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Context;
|
||||
@@ -61,13 +61,27 @@ Files.prototype.load = function(fn) {
|
||||
Files.prototype.handle = function (ctx, next) {
|
||||
if(ctx.req && ctx.req.method !== 'GET') return next();
|
||||
|
||||
send(ctx.req, url.parse(ctx.url).pathname)
|
||||
.root(path.resolve(this['public']))
|
||||
.on('error', function (err) {
|
||||
ctx.res.statusCode = 404;
|
||||
respond('Resource Not Found', ctx.req, ctx.res);
|
||||
})
|
||||
.pipe(ctx.res);
|
||||
ctx.verifyPermissions(function () {
|
||||
send(ctx.req, url.parse(ctx.url).pathname)
|
||||
.root(path.resolve(this['public']))
|
||||
.on('error', function (err) {
|
||||
ctx.res.statusCode = 404;
|
||||
respond('Resource Not Found', ctx.req, ctx.res);
|
||||
})
|
||||
.pipe(ctx.res);
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
|
||||
Files.prototype.getDefaultPermissions = function (ctx) {
|
||||
return {'reading a file': true};
|
||||
}
|
||||
|
||||
Files.prototype.getRequiredPermissions = function (ctx) {
|
||||
// a resource should return an object defining
|
||||
// required permissions for the given context
|
||||
return {'reading a file': true};
|
||||
}
|
||||
|
||||
|
||||
module.exports = Files;
|
||||
@@ -23,7 +23,8 @@ module.exports = Resource.extend("InternalModules", {
|
||||
exclude: {
|
||||
Collection: 1,
|
||||
UserCollection: 1,
|
||||
internal: 1
|
||||
internal: 1,
|
||||
'global-events': 1
|
||||
},
|
||||
|
||||
getModuleConfig: function(moduleId, fn) {
|
||||
|
||||
@@ -37,49 +37,13 @@ function Collection(name, options) {
|
||||
'creating an object': true,
|
||||
'deleting an object by id': true,
|
||||
'updating an object by id': true
|
||||
};
|
||||
|
||||
this.requiredPermissions = {
|
||||
'GET': {
|
||||
multi: {
|
||||
'querying multiple objects': true
|
||||
},
|
||||
single: {
|
||||
'querying an object by id': true
|
||||
}
|
||||
},
|
||||
'POST': {
|
||||
multi: {
|
||||
'creating multiple objects': true
|
||||
},
|
||||
single: {
|
||||
'creating an object': true
|
||||
}
|
||||
},
|
||||
'PUT': {
|
||||
multi: {
|
||||
'querying multiple objects': true,
|
||||
'updating multiple objects': true
|
||||
},
|
||||
single: {
|
||||
'updating an object by id': true,
|
||||
'querying an object by id': true
|
||||
}
|
||||
},
|
||||
'DELETE': {
|
||||
multi: {
|
||||
'deleting multiple objects': true
|
||||
},
|
||||
single: {
|
||||
'deleting an object by id': true
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
util.inherits(Collection, Resource);
|
||||
Collection.prototype.external = {};
|
||||
Collection.prototype.clientGeneration = true;
|
||||
Collection.events = ['Get', 'Validate', 'Post', 'Put', 'Delete', 'Query'];
|
||||
Collection.events = ['Get', 'Validate', 'Post', 'Put', 'Delete', 'Query', 'Request'];
|
||||
|
||||
Collection.prototype.eventNames = ['Get', 'Validate', 'Post', 'Put', 'Delete'];
|
||||
Collection.prototype.dashboard = {
|
||||
@@ -205,6 +169,64 @@ Collection.prototype.sanitizeQuery = function (query) {
|
||||
return sanitized;
|
||||
};
|
||||
|
||||
Collection.prototype.getRequiredPermissions = function (ctx) {
|
||||
var requiredPermissions = {}
|
||||
, hasId = !!(ctx.query.id || this.parseId(ctx) || (ctx.body && ctx.body.id));
|
||||
|
||||
if(hasId) {
|
||||
requiredPermissions['querying an object by id'] = true;
|
||||
}
|
||||
|
||||
switch(ctx.method) {
|
||||
case 'GET':
|
||||
if(hasId) {
|
||||
requiredPermissions['querying an object by id'] = true;
|
||||
} else {
|
||||
requiredPermissions['querying multiple objects'] = true;
|
||||
}
|
||||
break;
|
||||
case 'POST':
|
||||
// TODO ~ account for custom methods
|
||||
if(Array.isArray(ctx.body)) {
|
||||
requiredPermissions['creating multiple objects'] = true;
|
||||
} else if(hasId) {
|
||||
requiredPermissions['updating an object by id'] = true;
|
||||
} else {
|
||||
requiredPermissions['creating an object'] = true;
|
||||
}
|
||||
break;
|
||||
case 'PUT':
|
||||
if(hasId) {
|
||||
requiredPermissions['updating an object by id'] = true;
|
||||
requiredPermissions['querying an object by id'] = true;
|
||||
} else {
|
||||
requiredPermissions['querying multiple objects'] = true;
|
||||
requiredPermissions['updating multiple objects'] = true;
|
||||
}
|
||||
break;
|
||||
case 'DELETE':
|
||||
if(hasId) {
|
||||
requiredPermissions['deleting an object by id'] = true;
|
||||
} else {
|
||||
requiredPermissions['deleting multiple objects'] = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return requiredPermissions;
|
||||
}
|
||||
|
||||
|
||||
Collection.prototype.getDefaultPermissions = function (ctx) {
|
||||
return {
|
||||
'querying multiple objects': true,
|
||||
'querying an object by id': true,
|
||||
'creating an object': true,
|
||||
'deleting an object by id': true,
|
||||
'updating an object by id': true
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming http `req` and `res` and execute
|
||||
* the correct `Store` proxy function based on `req.method`.
|
||||
@@ -283,10 +305,10 @@ Collection.prototype.beforeQuery = function (ctx, fn) {
|
||||
queryScript.run(ctx, domain, function (err) {
|
||||
if(err) return ctx.done(err);
|
||||
|
||||
collection.verifyPermissions(ctx, fn);
|
||||
ctx.verifyPermissions(fn);
|
||||
});
|
||||
} else {
|
||||
collection.verifyPermissions(ctx, fn);
|
||||
ctx.verifyPermissions(fn);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -455,7 +477,7 @@ Collection.prototype.remove = function (ctx, fn) {
|
||||
|
||||
function done(err) {
|
||||
if(err) return fn(err);
|
||||
collection.verifyPermissions(ctx, function (err) {
|
||||
ctx.verifyPermissions(function (err) {
|
||||
if(err) return fn(err);
|
||||
|
||||
store.remove(sanitizedQuery, fn);
|
||||
@@ -593,7 +615,7 @@ Collection.prototype.save = function (ctx, fn) {
|
||||
return done(err || errors);
|
||||
}
|
||||
|
||||
collection.verifyPermissions(ctx, function (err) {
|
||||
ctx.verifyPermissions(function (err) {
|
||||
if(err) {
|
||||
return done(err);
|
||||
}
|
||||
@@ -637,14 +659,14 @@ Collection.prototype.save = function (ctx, fn) {
|
||||
}
|
||||
if(err || domain.hasErrors()) return done(err || errors);
|
||||
debug('inserting item', item);
|
||||
collection.verifyPermissions(ctx, function (err) {
|
||||
ctx.verifyPermissions(function (err) {
|
||||
if(err) return done(err);
|
||||
store.insert(item, done);
|
||||
if(session && session.emitToAll) session.emitToAll(collection.name + ':changed');
|
||||
});
|
||||
});
|
||||
} else {
|
||||
collection.verifyPermissions(ctx, function (err) {
|
||||
ctx.verifyPermissions(function (err) {
|
||||
if(err) return done(err);
|
||||
store.insert(item, done);
|
||||
if(session && session.emitToAll) session.emitToAll(collection.name + ':changed');
|
||||
@@ -746,7 +768,7 @@ Collection.prototype.saveAll = function (ctx, fn) {
|
||||
|
||||
function add(err) {
|
||||
if(err) return done(err);
|
||||
collection.verifyPermissions(ctx, function (err) {
|
||||
ctx.verifyPermissions(function (err) {
|
||||
if(err) return done(err);
|
||||
|
||||
updateBatch.push(updated);
|
||||
@@ -780,24 +802,8 @@ Collection.prototype.saveAll = function (ctx, fn) {
|
||||
function createDomain(collection, ctx, data, errors) {
|
||||
var hasErrors = false;
|
||||
var domain = {
|
||||
allow: function (permission) {
|
||||
if(permission === '*') {
|
||||
collection.forEachPermission('required', function (perm, event) {
|
||||
ctx.permissions[perm] = true;
|
||||
});
|
||||
} else {
|
||||
ctx.permissions[permission] = true;
|
||||
}
|
||||
},
|
||||
prevent: function (permission) {
|
||||
if(permission === '*') {
|
||||
collection.forEachPermission('required', function (perm, type, event) {
|
||||
ctx.permissions[perm] = false;
|
||||
});
|
||||
} else {
|
||||
delete ctx.permissions[permission];
|
||||
}
|
||||
},
|
||||
allow: ctx.allow.bind(ctx),
|
||||
prevent: ctx.prevent.bind(ctx),
|
||||
error: function(key, val) {
|
||||
debug('error %s %s', key, val);
|
||||
errors[key] = val || true;
|
||||
|
||||
13
lib/modules/global-events.js
Normal file
13
lib/modules/global-events.js
Normal file
@@ -0,0 +1,13 @@
|
||||
var Module = require('../module')
|
||||
, path = require('path')
|
||||
, Script = require('../script');
|
||||
|
||||
module.exports = Module.extend({
|
||||
|
||||
load: function(fn) {
|
||||
var events = this.server.events = this.events = {};
|
||||
|
||||
Script.loaddir(path.join(this.server.options.dir, 'events'), events, fn);
|
||||
}
|
||||
|
||||
});
|
||||
@@ -158,68 +158,6 @@ Resource.prototype.parseEvent = function (ctx) {
|
||||
if(ctx.url) return ctx.url.split('/')[1];
|
||||
}
|
||||
|
||||
Resource.prototype.verifyPermissions = function (ctx, fn) {
|
||||
if(ctx.req.internal || ctx.req.isRoot) return fn();
|
||||
|
||||
var required = this.requiredPermissions[ctx.method || ctx.req.method];
|
||||
var requested = ctx.permissions || this.defaultPermissions;
|
||||
var isSingle = !!ctx.query.id || ctx.method === 'POST';
|
||||
var failed = false;
|
||||
|
||||
if(required) {
|
||||
Object.keys(required[isSingle ? 'single' : 'multi']).forEach(function (permission) {
|
||||
if(!requested[permission]) {
|
||||
if(ctx.server.options.env === 'development') {
|
||||
error('permission denied when ' + permission + ' - to allow this action, include `allow("'+ permission +'")` in an event script');
|
||||
} else {
|
||||
error('permission denied when ' + permission);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if(!failed) {
|
||||
fn();
|
||||
}
|
||||
} else {
|
||||
error('an unkown error has occured');
|
||||
}
|
||||
|
||||
function error(msg) {
|
||||
failed = true;
|
||||
ctx.res.statusCode = 401;
|
||||
ctx.done(new Error(msg));
|
||||
}
|
||||
}
|
||||
|
||||
Resource.prototype.setDefaultPermissions = function (ctx) {
|
||||
if(ctx.permissions) return;
|
||||
ctx.permissions = {};
|
||||
if(!this.defaultPermissions) return;
|
||||
Object.keys(this.defaultPermissions).forEach(function (key) {
|
||||
ctx.permissions[key] = true;
|
||||
});
|
||||
}
|
||||
|
||||
Resource.prototype.forEachPermission = function (type, fn) {
|
||||
var resource = this;
|
||||
|
||||
if(type === 'default') {
|
||||
if(this.defaultPermissions) {
|
||||
Object.keys(this.defaultPermissions).forEach(fn);
|
||||
}
|
||||
} else {
|
||||
if(this.requiredPermissions) {
|
||||
Object.keys(resource.requiredPermissions).forEach(function (event) {
|
||||
Object.keys(resource.requiredPermissions[event]).forEach(function (type) {
|
||||
Object.keys(resource.requiredPermissions[event][type]).forEach(function (permission) {
|
||||
fn(permission, type, event);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming request. This gets called by the router.
|
||||
* Call `next()` if the resource cannot handle the request.
|
||||
@@ -264,8 +202,20 @@ Resource.prototype.handle = function (ctx, next) {
|
||||
}
|
||||
};
|
||||
|
||||
Resource.prototype.getDefaultPermissions = function (ctx) {
|
||||
// a resource should return an object defining
|
||||
// default permissions for the given context
|
||||
return {};
|
||||
}
|
||||
|
||||
Resource.prototype.getRequiredPermissions = function (ctx) {
|
||||
// a resource should return an object defining
|
||||
// required permissions for the given context
|
||||
return {};
|
||||
}
|
||||
|
||||
Resource.prototype.beforeHandle = function (ctx) {
|
||||
this.setDefaultPermissions(ctx);
|
||||
// hook
|
||||
}
|
||||
|
||||
Resource.prototype.afterHandle = function (ctx) {
|
||||
|
||||
@@ -73,16 +73,23 @@ Router.prototype.route = function (req, res) {
|
||||
|
||||
// default root to false
|
||||
if(ctx.session) ctx.session.isRoot = req.isRoot || false;
|
||||
|
||||
// external functions
|
||||
var furl = ctx.url.replace('/', '');
|
||||
if(resource.external && resource.external[furl]) {
|
||||
resource.external[furl](ctx.body, ctx, ctx.done);
|
||||
} else {
|
||||
resource.beforeHandle(ctx);
|
||||
resource.handle(ctx, nextResource);
|
||||
resource.afterHandle(ctx);
|
||||
}
|
||||
|
||||
router.runRequestEvent(ctx, function (err) {
|
||||
if(err) {
|
||||
ctx.done(err);
|
||||
return;
|
||||
}
|
||||
|
||||
// external functions
|
||||
var furl = ctx.url.replace('/', '');
|
||||
if(resource.external && resource.external[furl]) {
|
||||
resource.external[furl](ctx.body, ctx, ctx.done);
|
||||
} else {
|
||||
resource.beforeHandle(ctx);
|
||||
resource.handle(ctx, nextResource);
|
||||
resource.afterHandle(ctx);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
debug('404 %s', req.url);
|
||||
res.statusCode = 404;
|
||||
@@ -94,6 +101,34 @@ Router.prototype.route = function (req, res) {
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Run the global request event using the given context.
|
||||
*/
|
||||
|
||||
Router.prototype.runRequestEvent = function (ctx, fn) {
|
||||
var domain = {
|
||||
prevent: ctx.prevent.bind(ctx),
|
||||
allow: ctx.allow.bind(ctx),
|
||||
url: ctx.req.url
|
||||
};
|
||||
|
||||
if(this.server.events && this.server.events.request) {
|
||||
this.server.events.request.run(ctx, domain, resource);
|
||||
} else {
|
||||
resource();
|
||||
}
|
||||
|
||||
function resource(err) {
|
||||
if(err) return fn(err);
|
||||
|
||||
if(ctx.resource && ctx.resource.events && ctx.resource.events.request) {
|
||||
ctx.resource.events.request.run(ctx, domain, fn);
|
||||
} else {
|
||||
fn();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get resources whose base path matches the incoming URL, and order by specificness.
|
||||
|
||||
@@ -140,7 +140,7 @@ Script.loaddir = function (configPath, events, fn) {
|
||||
|
||||
fs.readdir(configPath, function (err, files) {
|
||||
if(err) {
|
||||
console.error(err);
|
||||
// console.error(err);
|
||||
return fn();
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,8 @@ function Server(options) {
|
||||
// defaults
|
||||
this.options = options = extend({
|
||||
port: 2403,
|
||||
db: {port: 27017, host: '127.0.0.1', name: 'deployd'}
|
||||
db: {port: 27017, host: '127.0.0.1', name: 'deployd'},
|
||||
dir: process.cwd()
|
||||
}, options);
|
||||
|
||||
debug('started with options %j', options);
|
||||
|
||||
@@ -3,6 +3,8 @@ var Server = require('./server')
|
||||
, Monitor = require('./monitor')
|
||||
, commands = {};
|
||||
|
||||
require('longjohn');
|
||||
|
||||
/**
|
||||
* Commands exposed to parent process.
|
||||
*/
|
||||
|
||||
0
test-app/events/request.js
Normal file
0
test-app/events/request.js
Normal file
@@ -1,5 +1,23 @@
|
||||
var Collection = require('../lib/modules/collection')
|
||||
, db = require('../lib/db');
|
||||
, db = require('../lib/db')
|
||||
, Context = require('../lib/context');
|
||||
|
||||
|
||||
function createMockContext(options) {
|
||||
options.query = options.query || {};
|
||||
options.path = options.path || '/';
|
||||
options.req.url = options.req.url || '/';
|
||||
var ctx = new Context({path: options.path}, options.req, options.res, {});
|
||||
ctx.session = options.session || {};
|
||||
ctx.done = function () {
|
||||
options.res.end();
|
||||
}
|
||||
|
||||
Object.keys(options).forEach(function (key) {
|
||||
ctx[key] = options[key];
|
||||
});
|
||||
return ctx;
|
||||
}
|
||||
|
||||
describe('collection', function(){
|
||||
function createCollection(properties) {
|
||||
@@ -97,7 +115,7 @@ describe('collection', function(){
|
||||
// faux body
|
||||
req.body = body;
|
||||
req.query = query;
|
||||
c.handle({req: req, res: res, query: query || {}, session: {}, done: function() {res.end();}});
|
||||
c.handle(createMockContext({path: path, req: req, res: res, query: query}));
|
||||
}, function (req, res) {
|
||||
test(req, res, method, path, properties, body, query);
|
||||
// cleanup
|
||||
@@ -171,7 +189,7 @@ describe('collection', function(){
|
||||
it('should save the provided data', function(done) {
|
||||
var c = new Collection('counts', {db: db.create(TEST_DB), config: { properties: {count: {type: 'number'}}}});
|
||||
|
||||
c.save({session: {}, body: {count: 1}, query: {}, dpd: {}, req: {}, res: {}, done: done, method: 'POST'}, function (err, item) {
|
||||
c.save(createMockContext({session: {}, body: {count: 1}, query: {}, dpd: {}, req: {}, res: {}, done: done, method: 'POST'}), function (err, item) {
|
||||
expect(item.id).to.exist;
|
||||
expect(err).to.not.exist;
|
||||
done();
|
||||
@@ -181,10 +199,10 @@ describe('collection', function(){
|
||||
it('should pass commands like $inc', function(done) {
|
||||
var c = new Collection('counts', {db: db.create(TEST_DB), config: { properties: {count: {type: 'number'}}}});
|
||||
|
||||
c.save({body: {count: 1}, req: {}, res: {}, method: 'POST', query: {}}, function (err, item) {
|
||||
c.save(createMockContext({body: {count: 1}, req: {}, res: {}, method: 'POST', query: {}}), function (err, item) {
|
||||
expect(item.id).to.exist;
|
||||
expect(err).to.not.exist;
|
||||
c.save({body: {count: {$inc: 100}}, query: {id: item.id}, req: {}, res: {}, done: done, method: 'PUT'}, function (err, updated) {
|
||||
c.save(createMockContext({body: {count: {$inc: 100}}, query: {id: item.id}, req: {}, res: {}, done: done, method: 'PUT'}), function (err, updated) {
|
||||
expect(err).to.not.exist;
|
||||
expect(updated).to.exist;
|
||||
expect(updated.count).to.equal(101);
|
||||
@@ -209,7 +227,7 @@ describe('collection', function(){
|
||||
it('should return the provided data', function(done) {
|
||||
var c = new Collection('foo', {db: db.create(TEST_DB), config: { properties: {count: {type: 'number'}}}});
|
||||
|
||||
c.save({body: {count: 1}, query: {}, req: {}, res: {}, done: done, method: 'POST'}, function (err, item) {
|
||||
c.save(createMockContext({body: {count: 1}, query: {}, req: {}, res: {}, done: done, method: 'POST'}), function (err, item) {
|
||||
c.find({query: {}, req: {}, res: {}, done: done, method: 'GET'}, function (err, items) {
|
||||
expect(items.length).to.equal(1);
|
||||
done(err);
|
||||
@@ -220,10 +238,10 @@ describe('collection', function(){
|
||||
it('should return the provided data in sorted order', function(done) {
|
||||
var c = new Collection('sort', { db: db.create(TEST_DB), config: { properties: {count: {type: 'number'}}}});
|
||||
|
||||
c.save({body: {count: 1}, query: {}, req: {}, res: {}, done: done, method: 'POST'}, function (err, item) {
|
||||
c.save({body: {count: 3}, query: {}, req: {}, res: {}, done: done, method: 'POST'}, function (err, item) {
|
||||
c.save({body: {count: 2}, query: {}, req: {}, res: {}, done: done, method: 'POST'}, function (err, item) {
|
||||
c.find({query: {$sort: {count: 1}}, req: {}, res: {}, done: done, method: 'GET'}, function (err, items) {
|
||||
c.save(createMockContext({body: {count: 1}, query: {}, req: {}, res: {}, done: done, method: 'POST'}), function (err, item) {
|
||||
c.save(createMockContext({body: {count: 3}, query: {}, req: {}, res: {}, done: done, method: 'POST'}), function (err, item) {
|
||||
c.save(createMockContext({body: {count: 2}, query: {}, req: {}, res: {}, done: done, method: 'POST'}), function (err, item) {
|
||||
c.find(createMockContext({query: {$sort: {count: 1}}, req: {}, res: {}, done: done, method: 'GET'}), function (err, items) {
|
||||
expect(items.length).to.equal(3);
|
||||
for(var i = 0; i < 3; i++) {
|
||||
delete items[i].id;
|
||||
|
||||
@@ -37,8 +37,8 @@ describe('config-loader', function() {
|
||||
if (err) return done(err);
|
||||
var resources = result.resources;
|
||||
expect(resources).to.have.length(7);
|
||||
expect(resources.filter(function(r) { return r.name == 'foo';})).to.have.length(1);
|
||||
expect(resources.filter(function(r) { return r.name == 'bar';})).to.have.length(1);
|
||||
expect(resources.filter(function(r) { return r.name == 'foo'; })).to.have.length(1);
|
||||
expect(resources.filter(function(r) { return r.name == 'bar'; })).to.have.length(1);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user