UNPKG

merest

Version:

Express based REST-full API for Mongoose models

407 lines (365 loc) 12.3 kB
var async = require('async'); var mongoose = require('mongoose'); var request = require("request"); var util = require("util"); var assert = require('assert'); var app = require('../setup/app'); var db = require('../setup/db'); var models = require('../models'); var api = require("../../lib"); var testPort = 30023; var testUrl = 'http://127.0.0.1:' + testPort; var people = require('../fixtures/people'); describe("Population -- simplest", function (done) { before(function (done) { async.waterfall([ app.init, db.init, db.fixtures.bind(null, { Person: people, Book: '../fixtures/books' }), function (next) { var modelAPI = new api.ModelAPIExpress(); modelAPI.expose(models.Book, {populate: 'author'}); app.use('/api/v1/', modelAPI); app.listen(testPort, next); } ], done); }); after(function (done) { async.waterfall([db.close, app.close], done) }); it("OPTIONS /api/v1/books 200 -- get options for Books API", function (done) { request.post({ url: util.format('%s/api/v1/books', testUrl), headers: { "X-HTTP-Method-Override": "OPTIONS" } }, function (err, res, body) { assert.ok(!err); assert.equal(res.statusCode, 200); if (typeof(body) == "string") { body = JSON.parse(body); } assert.equal(body.length, 6); done(); }); }); it("GET /api/v1/people/:id 200 -- get a specific Book (with populated author)", function(done) { models.Book.findOne({}, function (err, b) { assert.ok(!err); assert.ok(b); assert.ok(b._id); request.get({ url: util.format('%s/api/v1/books/%s', testUrl, b._id) }, function (err, res, body) { assert.ok(!err); assert.equal(res.statusCode, 200); if (typeof(body) == "string") { body = JSON.parse(body); } assert.equal(body.title, b.title); assert.equal(body.year, b.year); assert.ok(body.author); assert.ok(body.author instanceof Array); assert.ok(body.author.length); assert.ok(body.author[0]._id); assert.ok(body.author[0].firstName); assert.ok(body.author[0].lastName); assert.equal(body.author[0]._id, b.author[0]); done(); }); }); }); it("GET /api/v1/people/:id 200 -- get all Books (with populated author)", function(done) { request.get({ url: util.format('%s/api/v1/books', testUrl) }, function (err, res, body) { assert.ok(!err); assert.equal(res.statusCode, 200); if (typeof(body) == "string") { body = JSON.parse(body); } assert.equal(body.length, 16); body.forEach(function(book) { assert.ok(book.author instanceof Array); assert.ok(book.author.length); assert.ok(book.author[0]._id); assert.ok(book.author[0].firstName); assert.ok(book.author[0].lastName); }); done(); }); }); it("POST /api/v1/people/:id 200 -- create a new Book (with populated author)", function(done) { request.post({ url: util.format('%s/api/v1/books', testUrl), json: { title: 'New book', year: 2000, description: 'The description', author: people[0]._id } }, function (err, res, body) { assert.ok(!err); assert.equal(res.statusCode, 201); if (typeof(body) == "string") { body = JSON.parse(body); } assert.equal(body.title, 'New book'); assert.equal(body.year, 2000); assert.equal(body.description, 'The description'); assert.ok(body.author); assert.ok(body.author instanceof Array); assert.ok(body.author.length); assert.ok(body.author[0]._id); assert.ok(body.author[0].firstName); assert.ok(body.author[0].lastName); assert.equal(body.author[0]._id, people[0]._id); done(); }); }); it("POST /api/v1/people/:id 200 -- update a specific Book (with populated author)", function(done) { models.Book.findOne({}, function (err, b) { assert.ok(!err); assert.ok(b); assert.ok(b._id); request.post({ url: util.format('%s/api/v1/books/%s', testUrl, b._id), json: { description: "Updated description" } }, function (err, res, body) { assert.ok(!err); assert.equal(res.statusCode, 200); if (typeof(body) == "string") { body = JSON.parse(body); } assert.equal(body.title, b.title); assert.equal(body.year, b.year); assert.equal(body.description, 'Updated description'); assert.ok(body.description != b.description) assert.ok(body.author); assert.ok(body.author instanceof Array); assert.ok(body.author.length); assert.ok(body.author[0]._id); assert.ok(body.author[0].firstName); assert.ok(body.author[0].lastName); assert.equal(body.author[0]._id, b.author[0]); done(); }); }); }); }); describe("Population -- only for details", function (done) { before(function (done) { async.waterfall([ app.init, db.init, db.fixtures.bind(null, { Person: '../fixtures/people', Book: '../fixtures/books' }), function (next) { var modelAPI = new api.ModelAPIExpress(); modelAPI.expose(models.Book, { details: { populate: 'author' } }); app.use('/api/v1/', modelAPI); app.listen(testPort, next); } ], done); }); after(function (done) { async.waterfall([db.close, app.close], done) }); it("GET /api/v1/people/:id 200 -- get a specific Book (with populated author)", function(done) { models.Book.findOne({}, function (err, b) { assert.ok(!err); assert.ok(b); assert.ok(b._id); request.get({ url: util.format('%s/api/v1/books/%s', testUrl, b._id) }, function (err, res, body) { assert.ok(!err); assert.equal(res.statusCode, 200); if (typeof(body) == "string") { body = JSON.parse(body); } assert.equal(body.title, b.title); assert.equal(body.year, b.year); assert.ok(body.author); assert.ok(body.author instanceof Array); assert.ok(body.author.length); assert.ok(body.author[0]._id); assert.ok(body.author[0].firstName); assert.ok(body.author[0].lastName); assert.equal(body.author[0]._id, b.author[0]); done(); }); }); }); it("GET /api/v1/people/:id 200 -- get all Books (with non-populated author)", function(done) { request.get({ url: util.format('%s/api/v1/books', testUrl) }, function (err, res, body) { assert.ok(!err); assert.equal(res.statusCode, 200); if (typeof(body) == "string") { body = JSON.parse(body); } assert.equal(body.length, 16); body.forEach(function(book) { assert.ok(book.author instanceof Array); assert.ok(book.author.length); assert.ok(mongoose.Types.ObjectId.isValid(book.author[0])) assert.ok(!book.author[0]._id); assert.ok(!book.author[0].firstName); assert.ok(!book.author[0].lastName); }); done(); }); }); }); describe("Population -- only for list", function (done) { before(function (done) { async.waterfall([ app.init, db.init, db.fixtures.bind(null, { Person: '../fixtures/people', Book: '../fixtures/books' }), function (next) { var modelAPI = new api.ModelAPIExpress(); modelAPI.expose(models.Book, { search: { populate: 'author' } }); app.use('/api/v1/', modelAPI); app.listen(testPort, next); } ], done); }); after(function (done) { async.waterfall([db.close, app.close], done) }); it("GET /api/v1/books/:id 200 -- get a specific Book (with non-populated author)", function(done) { models.Book.findOne({}, function (err, b) { assert.ok(!err); assert.ok(b); assert.ok(b._id); request.get({ url: util.format('%s/api/v1/books/%s', testUrl, b._id) }, function (err, res, body) { assert.ok(!err); assert.equal(res.statusCode, 200); if (typeof(body) == "string") { body = JSON.parse(body); } assert.equal(body.title, b.title); assert.equal(body.year, b.year); assert.ok(body.author); assert.ok(body.author instanceof Array); assert.ok(body.author.length); assert.ok(mongoose.Types.ObjectId.isValid(body.author[0])) assert.ok(!body.author[0]._id); assert.ok(!body.author[0].firstName); assert.ok(!body.author[0].lastName); assert.equal(body.author[0], b.author[0]); done(); }); }); }); it("GET /api/v1/books/ 200 -- get all Books (with populated author)", function(done) { request.get({ url: util.format('%s/api/v1/books', testUrl) }, function (err, res, body) { assert.ok(!err); assert.equal(res.statusCode, 200); if (typeof(body) == "string") { body = JSON.parse(body); } assert.equal(body.length, 16); body.forEach(function(book) { assert.ok(book.author instanceof Array); assert.ok(book.author.length); assert.ok(book.author[0]._id); assert.ok(book.author[0].firstName); assert.ok(book.author[0].lastName); }); done(); }); }); }); describe("Population -- with mongoose population options", function (done) { before(function (done) { async.waterfall([ app.init, db.init, db.fixtures.bind(null, { Person: '../fixtures/people', Book: '../fixtures/books' }), function (next) { var modelAPI = new api.ModelAPIExpress(); modelAPI.expose(models.Book, {populate: { path: 'author', select: 'isPoet -_id' }}); app.use('/api/v1/', modelAPI); app.listen(testPort, next); } ], done); }); after(function (done) { async.waterfall([db.close, app.close], done) }); it("GET /api/v1/people/:id 200 -- get a specific Book (with populated author)", function(done) { models.Book.findOne({}, function (err, b) { assert.ok(!err); assert.ok(b); assert.ok(b._id); request.get({ url: util.format('%s/api/v1/books/%s', testUrl, b._id) }, function (err, res, body) { assert.ok(!err); assert.equal(res.statusCode, 200); if (typeof(body) == "string") { body = JSON.parse(body); } assert.equal(body.title, b.title); assert.equal(body.year, b.year); assert.ok(body.author); assert.ok(body.author instanceof Array); assert.ok(body.author.length); assert.ok(!body.author[0]._id); assert.ok(!body.author[0].firstName); assert.ok(!body.author[0].lastName); assert.ok(typeof body.author[0].isPoet === 'boolean'); done(); }); }); }); it("GET /api/v1/people/:id 200 -- get all Books (with populated author)", function(done) { request.get({ url: util.format('%s/api/v1/books', testUrl) }, function (err, res, body) { assert.ok(!err); assert.equal(res.statusCode, 200); if (typeof(body) == "string") { body = JSON.parse(body); } assert.equal(body.length, 16); body.forEach(function(book) { assert.ok(book.author instanceof Array); assert.ok(book.author.length); assert.ok(!book.author[0]._id); assert.ok(!book.author[0].firstName); assert.ok(!book.author[0].lastName); assert.ok(typeof book.author[0].isPoet === 'boolean'); }); done(); }); }); });