baucis-vivify
Version:
A module for adding child controller paths
422 lines (371 loc) • 13.1 kB
JavaScript
var mongoose = require('mongoose');
var express = require('express');
var baucis = require('baucis');
var request = require('request');
var expect = require('expect.js');
var plugin = require('.');
var config = require('./config');
var app;
var server;
var Schema = mongoose.Schema;
var User = new Schema({
name: String,
tasks: [{ type: Schema.ObjectId, ref: 'task' }]
});
var Task = new Schema({
name: String,
user: {
type: Schema.Types.ObjectId,
ref: 'User'
}
});
var Stores = new Schema({
name: { type: String, required: true, unique: true },
tools: [{ type: mongoose.Schema.ObjectId, ref: 'tool' }],
mercoledi: Boolean,
voltaic: { type: Boolean, default: true },
'hyphenated-field-name': { type: Boolean, default: true }
});
var Tools = new Schema({
name: { type: String, required: true },
store: { type: String, required: true },
bogus: { type: Boolean, default: false, required: true }
});
mongoose.model('user', User);
mongoose.model('task', Task);
mongoose.model('tool', Tools);
mongoose.model('store', Stores);
var fixture = {
init: function (done) {
mongoose.connect(config.mongo.url);
// Stores controller
var stores = baucis.rest('store').findBy('name').select('-hyphenated-field-name -voltaic');
// Tools embedded controller
var storeTools = stores.vivify('tools');
storeTools.query(function (request, response, next) {
request.baucis.query.where('bogus', false);
next();
});
var users = baucis.rest('user');
var tasks = users.vivify('tasks');
tasks.request(function (request, response, next) {
request.baucis.outgoing(function (context, callback) {
context.doc.name = 'Changed by Middleware';
callback(null, context);
});
next();
});
tasks.query(function (request, response, next) {
request.baucis.query.where('user', request.params._id);
next();
});
app = express();
app.use('/api', baucis());
server = app.listen(8012);
done();
},
deinit: function (done) {
server.close();
mongoose.disconnect();
done();
},
create: function (done) {
// clear all first
mongoose.model('store').remove({}, function (error) {
if (error) return done(error);
mongoose.model('tool').remove({}, function (error) {
if (error) return done(error);
mongoose.model('user').remove({}, function (error) {
if (error) return done(error);
mongoose.model('task').remove({}, function (error) {
if (error) return done(error);
mongoose.model('user').create(
['Alice', 'Bob'].map(function (name) { return { name: name } }),
function (error, alice) {
if (error) return done(error);
mongoose.model('task').create(
['Mow the Lawn', 'Make the Bed', 'Darn the Socks'].map(function (name) { return { name: name } }),
function (error,task) {
if (error) return done(error);
if (Array.isArray(task)) {
task = task[0];
}
task.user = alice._id;
task.save();
// create stores and tools
mongoose.model('store').create(
['Westlake', 'Corner'].map(function (name) { return { name: name } }),
function (error, store) {
if (error) return done(error);
if (Array.isArray(store)) {
store = store[0];
}
var cheeses = [
{ name: 'Cheddar', color: 'Yellow' },
{ name: 'Huntsman', color: 'Yellow, Blue, White' },
{ name: 'Camembert', color: 'White',
arbitrary: [
{ goat: true, llama: [ 3, 4 ] },
{ goat: false, llama: [ 1, 2 ] }
]
}
];
mongoose.model('tool').create(
['Hammer', 'Saw', 'Axe'].map(function (name) { return { store: store.name, name: name } }),
done
);
}
);
}
);
}
);
});
});
});
});
}
};
describe('vivify', function () {
// __Test Hooks__
before(fixture.init);
beforeEach(fixture.create);
after(fixture.deinit);
it('should 404 when parent ID is not found', function (done) {
var options = {
url: 'http://localhost:8012/api/stores/Lolo/tools?sort=name',
json: true
};
request.get(options, function (error, response, body) {
if (error) return done(error);
expect(response.statusCode).to.be(404);
expect(body).to.match(/Not Found/);
done();
});
});
it('should 200 when restricted query has no results', function (done) {
var options = {
url: 'http://localhost:8012/api/stores/Corner/tools?sort=name',
json: true
};
request.get(options, function (error, response, body) {
if (error) return done(error);
expect(response.statusCode).to.be(200);
expect(body).to.eql([]);
done();
});
});
it('should 400 when restricted query parent ID is invalid');
it('should allow mounting of subcontrollers (GET plural)', function (done) {
var options = {
url: 'http://localhost:8012/api/stores/Westlake/tools?sort=name',
json: true
};
request.get(options, function (error, response, body) {
if (error) return done(error);
expect(response.statusCode).to.be(200);
expect(body).to.have.property('length', 3);
done();
});
});
it('should allow mounting of subcontrollers (POST plural)', function (done) {
var options = {
url: 'http://localhost:8012/api/stores/Westlake/tools',
json: { name: 'Reticulating Saw' }
};
request.post(options, function (error, response, body) {
if (error) return done(error);
expect(response.statusCode).to.be(201);
expect(body).to.have.property('bogus', false);
expect(body).to.have.property('store', 'Westlake');
done();
});
});
it('should allow mounting of subcontrollers (DEL plural)', function (done) {
var options = {
url: 'http://localhost:8012/api/stores/Westlake/tools',
json: true
};
request.del(options, function (error, response, body) {
if (error) return done(error);
expect(response.statusCode).to.be(200);
expect(body).to.be(3);
done();
});
});
it('should allow mounting of subcontrollers (GET singular)', function (done) {
var options = {
url: 'http://localhost:8012/api/stores/Westlake/tools?sort=name',
json: true
};
request.get(options, function (error, response, body) {
if (error) return done(error);
expect(response.statusCode).to.be(200);
expect(body).to.have.property('length', 3);
expect(body[0]).to.have.property('name', 'Axe');
var id = body[0]._id;
var options = {
url: 'http://localhost:8012/api/stores/Westlake/tools/' + id,
json: true
};
request.get(options, function (error, response, body) {
if (error) return done(error);
expect(response.statusCode).to.be(200);
expect(body).to.have.property('name', 'Axe');
done();
});
});
});
it('should allow mounting of subcontrollers (PUT singular)', function (done) {
var options = {
url: 'http://localhost:8012/api/stores/Westlake/tools',
json: true
};
request.get(options, function (error, response, body) {
if (error) return done(error);
expect(response.statusCode).to.be(200);
var id = body[0]._id;
var options = {
url: 'http://localhost:8012/api/stores/Westlake/tools/' + id,
json: { name: 'Screwdriver' }
};
request.put(options, function (error, response, body) {
if (error) return done(error);
expect(response.statusCode).to.be(200);
expect(body).to.have.property('name', 'Screwdriver');
expect(body).to.have.property('bogus', false);
done();
});
});
});
it('should allow mounting of subcontrollers (DEL singular)', function (done) {
var options = {
url: 'http://localhost:8012/api/stores/Westlake/tools?sort=name',
json: true
};
request.get(options, function (error, response, body) {
if (error) return done(error);
expect(response.statusCode).to.be(200);
expect(body).to.have.property('length', 3);
expect(body[0]).to.have.property('name', 'Axe');
var id = body[0]._id;
var options = {
url: 'http://localhost:8012/api/stores/Westlake/tools/' + id,
json: true
};
request.del(options, function (error, response, body) {
if (error) return done(error);
expect(response.statusCode).to.be(200);
expect(body).to.be(1);
done();
});
});
});
it('should allow parent to function when mounting subcontrollers (GET plural)', function (done) {
var options = {
url: 'http://localhost:8012/api/stores/?sort=name',
json: true
};
request.get(options, function (error, response, body) {
if (error) return done(error);
expect(response.statusCode).to.be(200);
expect(body).to.have.length(2);
done();
});
});
it('should allow parent to function when mounting subcontrollers (POST plural)', function (done) {
var options = {
url: 'http://localhost:8012/api/stores/',
json: { name: 'Arena' }
};
request.post(options, function (error, response, body) {
if (error) return done(error);
expect(response.statusCode).to.be(201);
expect(body).not.to.have.property('bogus');
done();
});
});
it('should allow parent to function when mounting subcontrollers (DELETE plural)', function (done) {
var options = {
url: 'http://localhost:8012/api/stores/',
json: true
};
request.del(options, function (error, response, body) {
if (error) return done(error);
expect(response.statusCode).to.be(200);
expect(body).to.be(2);
done();
});
});
it('should allow parent to function when mounting subcontrollers (GET singular)', function (done) {
var options = {
url: 'http://localhost:8012/api/stores/Westlake',
json: true
};
request.get(options, function (error, response, body) {
if (error) return done(error);
expect(response.statusCode).to.be(200);
expect(body).to.have.property('name', 'Westlake');
done();
});
});
it('should allow parent to function when mounting subcontrollers (PUT singular)', function (done) {
var options = {
url: 'http://localhost:8012/api/stores/Westlake',
json: { mercoledi: false, __v: 0 }
};
request.put(options, function (error, response, body) {
if (error) return done(error);
expect(response.statusCode).to.be(200);
expect(body).to.have.property('mercoledi', false);
done();
});
});
it('should allow parent to function when mounting subcontrollers (DELETE singular)', function (done) {
var options = {
url: 'http://localhost:8012/api/stores/Westlake',
json: true
};
request.del(options, function (error, response, body) {
if (error) return done(error);
expect(response.statusCode).to.be(200);
expect(body).to.be(1);
done();
});
});
it("should not overwrite parent controller's request property", function (done) {
var options = {
url: 'http://localhost:8012/api/users?sort=name',
json: true
};
request.get(options, function (error, response, body) {
if (error) return done(error);
expect(response.statusCode).to.be(200);
expect(body).to.have.property('length', 2);
expect(body[0]).to.have.property('name', 'Alice');
done();
});
});
it("should use subcontroller middleware", function (done) {
var options = {
url: 'http://localhost:8012/api/users',
json: true
};
request.get(options, function (error, response, body) {
if (error) return done(error);
expect(response.statusCode).to.be(200);
expect(body).to.have.property('length', 2);
expect(body[0]).to.have.property('name', 'Alice');
var options = {
url: 'http://localhost:8012/api/users/' + body[0]._id + "/tasks",
json: true
};
request.get(options, function (error, response, body) {
if (error) return done(error);
expect(response.statusCode).to.be(200);
expect(body[0]).to.have.property('name', 'Changed by Middleware');
done();
});
});
});
});