Merge branch 'master' of github.com:deployd/deployd

This commit is contained in:
Dallon Feldner
2012-03-27 09:44:13 -07:00
7 changed files with 139 additions and 63 deletions

View File

@@ -20,6 +20,15 @@ module.exports =
, errs = []
;
end(function (req, res, next) {
if(!collectionPath) return next();
collection.use(collectionPath).rename(collectionPath.replace('/', ''), function (err) {
next(err);
});
})
properties && Object.keys(properties).forEach(function (key) {
prop = properties[key];
rename = prop.$renameFrom;

View File

@@ -81,61 +81,3 @@ var router = module.exports = function (req, res, next) {
}
})
}
// module.exports = function (req, res, next) {
// var parsed = url.parse(req.url).path.split('?')[0].replace('/', '').split('/')
// , collections = req.collections = []
// , references = req.references = []
// , method = req.method
// , path = '/'
// ;
//
// // parse url into references and collections
// parsed.forEach(function (part, i) {
// (i % 2 ? references : collections).push(part);
// });
//
// // cat collection reference
// path += collections[0];
//
// // route to the first collection
// resources.get({path: path}).first(function (err, resource) {
//
// if(internals[path]) {
// if(req.isRemote && !req.isRoot) {
// // remote requests must have a registered key
// return next({status: 401});
// } else {
// req.resource = {
// require: internals[path],
// path: path
// };
//
// next();
// }
// } else {
// // for future reference
// req.resource = resource;
//
// if(!resource) {
// err = {status: 404};
// }
//
// // continue
// next(err);
// }
// });
// }

View File

@@ -44,6 +44,12 @@ middleware.listen = function (callback) {
// by default pause the request
req.pause();
// query sugar for JSON based query strings
// eg ?q={"foo": {"bar": true}}
if(req.query && req.query.q && req.query.q[0] === '{') {
req.query = JSON.parse(req.query.q);
}
if(req.method === 'GET' || req.method === 'DELETE') return next();
// check for json content type

View File

@@ -15,6 +15,7 @@ module.exports = function (req, res, next) {
, resource = req.resource
, validation
, err
, sanitized = {}
;
// rewrite queries from references
@@ -37,15 +38,58 @@ module.exports = function (req, res, next) {
}
// if trying to write data
if((method === 'POST' || method === 'PUT') && resource && resource.properties) {
if((method === 'POST' || method === 'PUT') && req.body && resource && resource.properties) {
// sanitize data
Object.keys(resource.properties).forEach(function (key) {
sanitized[key] = req.body[key];
})
// replace input with sanitized data
req.body = req.data = sanitized;
// validate JSON
validation = revalidator.validate(req.body, resource);
err = validation.valid ? err : validation;
err = validation.valid ? err : transform(validation);
next(err);
} else {
// continue
next(err);
}
}
}
/**
* Transform revalidator errors into human redable errors.
*/
function transform(validation) {
var err = {}
, errors = validation.errors
, e
, prop
;
for(var i = 0, len = errors.length; i < len; i++) {
e = errors[i];
prop = e.property;
switch(e.attribute) {
case 'type':
err[prop] = 'must be a ' + e.expected;
break;
case 'required':
err[prop] = 'is required';
break;
default:
err[prop] = 'is not valid'
break;
}
}
// rename and add human readable errors
validation.validation = validation.errors;
validation.errors = err;
return validation;
}

43
test/query.test.js Normal file
View File

@@ -0,0 +1,43 @@
describe('Queries', function(){
describe('GET /todos?title=testing title', function(){
it('should return the documents that match the query', function(done) {
todos.post({title: 'testing title'}, function (err) {
todos.use('?title=testing%20title').get(function (err, todos) {
expect(todos).to.exist;
expect(todos).to.have.length(1);
done(err);
})
})
})
})
describe('GET /todos?q={"title": "testing title"}', function(){
it('should parse the JSON and return the documents that match the query', function(done) {
todos.post({title: 'testing title'}, function (err) {
todos.use('?q=' + encodeURI(JSON.stringify({title: 'testing title'}))).get(function (err, todos) {
expect(todos).to.exist;
expect(todos).to.have.length(1);
done(err);
})
})
})
})
})
describe('Advanced Queries', function(){
describe('GET /todos?q={"title": {$regex: "^title"}', function(){
it('should parse the JSON and return the documents that match the query', function(done) {
todos.post({title: 'title one'}, function (err) {
todos.post({title: 'title two'}, function (err) {
todos.post({title: 'another title'}, function (err) {
todos.use('?q=' + encodeURI(JSON.stringify({title: {$regex: "^title"}}))).get(function (err, todos) {
expect(todos).to.exist;
expect(todos).to.have.length(2);
done(err);
})
})
})
})
})
})
})

View File

@@ -62,6 +62,26 @@ describe('Application Resource Types', function(){
})
})
describe('PUT /resources/<ObjectID>', function(){
it('should rename the resource collection', function(done) {
resources.get(function (e, all) {
var res = all[0];
res.path = '/tasks';
todos.post({title: 'foo'}, function () {
resources.use('/' + res._id).put(res, function (err, upd) {
unauthed.use('/tasks').get(function (ee, r) {
expect(r).to.exist;
client.use('/tasks').del(function () {
done(ee || e || err);
})
})
})
})
})
})
})
describe('PUT /resources/<ObjectID>', function(){
it('should rename change properties on any existing data', function(done) {
var exTodo = {title: 'feed fido', completed: true};

View File

@@ -12,15 +12,27 @@ describe('Resource Actions', function(){
describe('POST /todos', function(){
it('should return an error when provided invalid data', function(done) {
todos.post({foo: 'bar', bat: 'baz'}, function (err, todo, req, res) {
todos.post({foo: 123, completed: 'flarg'}, function (err, todo, req, res) {
expect(err).to.exist;
expect(err.valid).to.equal(false);
expect(err.errors).to.have.length(1);
expect(err.validation).to.have.length(2);
expect(err.errors).to.be.a('object');
expect(todo).to.not.exist;
done();
})
})
it('should ignore properties outside the schema', function(done) {
todos.post({title: 'foo', bat: 'baz'}, function (err, todo, req, res) {
todos.get(function (err, todos) {
var todo = todos[0];
expect(todo.title).to.equal('foo');
expect(todo.bat).to.not.exist;
done(err);
})
})
})
it('should save the todo when valid', function(done) {
todos.post({title: 'feed the cat'}, function (err, todo) {
expect(todo._id).to.exist;