Skip to content

Commit

Permalink
fixed transforms, added tests
Browse files Browse the repository at this point in the history
  • Loading branch information
juspears committed Mar 24, 2015
1 parent 46ba672 commit c4b0545
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 14 deletions.
26 changes: 13 additions & 13 deletions Readme.md
Expand Up @@ -7,8 +7,9 @@
Mers is a plugin for express to expose mongoose finders as simple crud/rest operations. The
basic idea being you should just define your model/finders and the rest should be be magic.

![build status](https://travis-ci.org/jspears/mers.svg)

## Usage [usage]
## Usage

Install mers, mongoose, express and body-parser

Expand All @@ -27,25 +28,24 @@ Install mers, mongoose, express and body-parser
Schema = mongoose.Schema,
bodyParser = require('body-parser')

app.use(bodyParser.json({ type: 'application/*+json' }))

app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }));
var SampleSchema = new Schema({
name:String,
age:Number
});

mongoose.model('sample', SampleSchema);

var mers = require('mers');
app.use('/rest', mers({uri:'mongodb://localhost/your_db'}).rest());

```
Configuration options include:
* `uri:uri://mongoose` (as shown above)
* `mongoose:mongoose` (your mongoose instance)
* `[error][error]:function` (your custom error handler)
* `responseStream:function` (your custom respost stream. See: lib/streams.js)
* `transformer:function` (your custom transformer factory)
* `mongoose:{mongoose}` (your mongoose instance)
* `error:{function}` (your custom Error Handler)
* `responseStream:{function}` (your custom respost stream. See: lib/streams.js)
* `transformer:{function}` (your custom transformer factory)
# `inject:{Nojector}` (custom nojector add resovlers, or whatever)

###If you had a schema such as
Expand Down Expand Up @@ -239,7 +239,7 @@ Occassionally you may want to do something like a double query within a finder.
```


### [Error Handling][error]
### Error Handling ###
To create a custom error handler

```javascript
Expand All @@ -266,7 +266,7 @@ that can't just be filtered. Of course you can return nested nestings too...
###Returning an Object
This one just returns an object, from /department/<id>/hello/name
This one just returns an object, from /department/$id/hello/name
```javascript
DepartmentSchema.methods.hello = function DepartmentSchema$hello(){
Expand All @@ -275,7 +275,7 @@ DepartmentSchema.methods.hello = function DepartmentSchema$hello(){
```
###Returning a Promise.
This is returns a promise from /department/<id>/promises. Really you just
This is returns a promise from /department/$id/promises. Really you just
need to return an object with an then function. So any promise library should work.
```javascript
Expand All @@ -287,7 +287,7 @@ DepartmentSchema.methods.promises = function (data){
```
### Returning a Query object.
This is returns a query from /department/<id>/superDo
This is returns a query from /department/$id/superDo
```javascript
DepartmentSchema.methods.superDo = function DepartmentSchema$hello(data){
Expand Down Expand Up @@ -332,7 +332,7 @@ DepartmentSchema.static.byName = function DepartmentSchema$hello(query$name){
works on instances to...
```
url: http://localhost/rest/department/<id>/hello/?name=STuff
url: http://localhost/rest/department/$id/hello/?name=STuff
```
Expand Down
1 change: 1 addition & 0 deletions example/models/blogpost.js
Expand Up @@ -12,6 +12,7 @@ module.exports = function (m) {
});

var BlogPostSchema = new Schema({
owner:String,
title: {
type: String,
match: new RegExp('^.{3,}$')
Expand Down
4 changes: 3 additions & 1 deletion lib/streams/transformer.js
Expand Up @@ -15,7 +15,9 @@ function ObjTransformer(options) {
inherits(ObjTransformer, Transform);

ObjTransformer.prototype._transform = function ObjTransformer$_transform(chunk, enc, cb) {
chainCB(cb, chunk, this.transformers);
chainCB(cb, this.transformers.map(function(v){
return v(chunk);
}));
}

module.exports = ObjTransformer;
150 changes: 150 additions & 0 deletions test/routes-transform-mocha.js
@@ -0,0 +1,150 @@
process.env.NODE_ENV = 'test';
require('should');
var request = require('./support/http'),
mers = require('../index'),
assert = require('assert'),
json = JSON.stringify, express = require('express'),
bodyParser = require('body-parser');
var app;
var d = 0;
var pids = [];

var data = [
{title: 'Post A', body: 'A', owner:'abc'},
{title: 'Post B', body: 'B'},
{title: 'Post C', body: 'C', date: new Date(140000000000)},
{title: 'Post CD', body: 'CD', date: new Date(150000000000)},
{title: 'Post E', body: 'E', date: new Date(156000000000)},

{
title: 'Post F',
body: 'Should be deep',
comments: [
{
title: 'hello', body: 'world', comment: 'im here', posts: [
{
title: 'hello2', body: 'world2', comment: 'im here',
posts: [
{
title: 'hello2-3', body: 'world2-3', comment: 'im here'
}
]
},
{
title: 'hello3', body: 'world3', comment: 'im here',
posts: [
{
title: 'hello3-3', body: 'world3-3', comment: 'im here'
}
]
}
]
},
{title: 'comment 2', body: 'comment2'}
]

}


]

describe('transformers routes', function () {
var connection;
this.timeout(50000);
before(function onBefore(done) {
var mongoose = connection = require('mongoose').createConnection();
require('../example/models/blogpost')(mongoose);
app = express();
app.use(bodyParser.json());
//fake login session.
app.use(function (req, res, next) {
var session = req.session || (req.session = {});
session.user = {_id: 'abc'};
next();
})
app.use('/rest', mers({
mongoose: connection,
transformers: {
renameId: function (obj) {
obj = obj.toJSON();
obj.id = obj._id + '';
delete obj._id;
//don't forget to return the object. Null will filter it from the results.
return obj;
},

/**
* Injects the user into the function, and checks if the
* owner is the same as the current user. Works with passport.
*/

checkOwner: function (obj, session$user) {
if (obj.owner === session$user._id) {
//returning null, short circuits the other transformers. And will
//not be included in the response.
return obj;
} else {
return null;
}

}
}
}).rest());

mongoose.on('connected', function () {
var db = mongoose.db;
db.dropDatabase(function () {
var count = 0;

var BlogPost = mongoose.model('BlogPost');
data.forEach(function (d, i) {
new BlogPost(d).save(function (e, o) {
if (e) return done();
pids[i] = o._id;
d._id = o._id + "";
if (data.length === ++count) {

done();

}
});
});
});
})
if (mongoose.readyState === 1) mongoose.close();
mongoose.open('mongodb://localhost/routes-mocha-transform');
});
after(function onAfter(done) {
connection.on('disconnected', function () {
done();
});
connection.close();

});
it('should rename id', function (done) {
request(app).get('/rest/blogpost?transform=renameId')
.end(function (e, o) {
if (e)return done(e);
var payload = o.body.should.have.property('payload').obj;
payload.should.have.property('length', 6);
payload[0].should.have.property('id');
payload[0].should.not.have.property('_id');
done();
});

});
it('should reject non-owners id', function (done) {
request(app).get('/rest/blogpost?transform=checkOwner')
.end(function (e, o) {
if (e)return done(e);
var payload = o.body.should.have.property('payload').obj;
payload.should.have.property('length', 1);

payload[0].should.have.property('owner', 'abc');
done();
});

});


});

0 comments on commit c4b0545

Please sign in to comment.