diff --git a/lib/mixins/event.js b/lib/mixins/event.js index cb7b2ec05f..cff12346d2 100644 --- a/lib/mixins/event.js +++ b/lib/mixins/event.js @@ -43,7 +43,11 @@ module.exports = function (service) { emitter.on(eventName, function (results, args) { if (!results[0]) { // callback without error var hook = hookObject(method, 'after', args); - service.emit(event, results[1], hook); + var data = Array.isArray(results[1]) ? results[1] : [ results[1] ]; + + data.forEach(function(current) { + service.emit(event, current, hook); + }); } else { service.emit('serviceError', results[0]); } diff --git a/lib/providers/rest/index.js b/lib/providers/rest/index.js index cb12fa1901..08208402ef 100644 --- a/lib/providers/rest/index.js +++ b/lib/providers/rest/index.js @@ -50,8 +50,14 @@ module.exports = function (config) { // GET / -> service.find(cb, params) baseRoute.get.apply(baseRoute, before.concat(app.rest.find(service), after, handler)); - // POST -> service.create(data, params, cb) + // POST / -> service.create(data, params, cb) baseRoute.post.apply(baseRoute, before.concat(app.rest.create(service), after, handler)); + // PATCH / -> service.patch(null, data, params) + baseRoute.patch.apply(baseRoute, before.concat(app.rest.patch(service), after, handler)); + // PUT / -> service.update(null, data, params) + baseRoute.put.apply(baseRoute, before.concat(app.rest.update(service), after, handler)); + // DELETE / -> service.remove(null, data, params) + baseRoute.delete.apply(baseRoute, before.concat(app.rest.remove(service), after, handler)); // GET /:id -> service.get(id, params, cb) idRoute.get.apply(idRoute, before.concat(app.rest.get(service), after, handler)); diff --git a/lib/providers/rest/wrappers.js b/lib/providers/rest/wrappers.js index 236cb35156..ed788f724c 100644 --- a/lib/providers/rest/wrappers.js +++ b/lib/providers/rest/wrappers.js @@ -55,12 +55,12 @@ function reqNone () { // Returns the leading parameters for a `get` or `remove` request (the id) function reqId (req) { - return [ req.params.id ]; + return [ req.params.id || null ]; } // Returns the leading parameters for an `update` or `patch` request (id, data) function reqUpdate (req) { - return [ req.params.id, req.body ]; + return [ req.params.id || null, req.body ]; } // Returns the leading parameters for a `create` request (data) diff --git a/test/mixins/event.test.js b/test/mixins/event.test.js index 353bdd68eb..636f787991 100644 --- a/test/mixins/event.test.js +++ b/test/mixins/event.test.js @@ -160,6 +160,36 @@ describe('Event mixin', function () { }); }); + it('array event data emits multiple event', function (done) { + var fixture = [ + { id: 0 }, + { id: 1 }, + { id: 2 }, + ]; + var FixtureService = Proto.extend({ + create: function (data, params, cb) { + _.defer(function () { + cb(null, fixture); + }); + } + }); + + var instance = create.call(FixtureService); + var counter = 0; + + mixinEvent(instance); + + instance.on('created', function (data) { + assert.equal(data.id, counter); + counter++; + if(counter === fixture.length) { + done(); + } + }); + + instance.create({}, {}, function () {}); + }); + it('does not punch when service has an events list (#118)', function(done) { var FixtureService = Proto.extend({ events: [ 'created' ], diff --git a/test/providers/primus.test.js b/test/providers/primus.test.js index d93b121a96..0e5a2d20e2 100644 --- a/test/providers/primus.test.js +++ b/test/providers/primus.test.js @@ -181,6 +181,19 @@ describe('Primus provider', function () { }); }); + it('::update many', function (done) { + var original = { + name: 'updating', + many: true + }; + + socket.send('todo::update', null, original, {}, function (error, data) { + verify.update(null, original, data); + + done(error); + }); + }); + it('::patch', function (done) { var original = { name: 'patching' @@ -193,6 +206,19 @@ describe('Primus provider', function () { }); }); + it('::patch many', function (done) { + var original = { + name: 'patching', + many: true + }; + + socket.send('todo::patch', null, original, {}, function (error, data) { + verify.patch(null, original, data); + + done(error); + }); + }); + it('::remove', function (done) { socket.send('todo::remove', 11, {}, function (error, data) { verify.remove(11, data); @@ -200,6 +226,14 @@ describe('Primus provider', function () { done(error); }); }); + + it('::remove many', function (done) { + socket.send('todo::remove', null, {}, function (error, data) { + verify.remove(null, data); + + done(error); + }); + }); }); describe('Events', function () { diff --git a/test/providers/rest.test.js b/test/providers/rest.test.js index 6f78286acf..3343beb321 100644 --- a/test/providers/rest.test.js +++ b/test/providers/rest.test.js @@ -94,6 +94,28 @@ describe('REST provider', function () { }); }); + it('PUT .update many', function (done) { + var original = { + description: 'PUT .update', + many: true + }; + + request({ + url: 'http://localhost:4777/todo', + method: 'put', + body: JSON.stringify(original), + headers: { + 'Content-Type': 'application/json' + } + }, function (error, response, body) { + var data = JSON.parse(body); + assert.ok(response.statusCode === 200, 'Got OK status code'); + verify.update(null, original, data); + + done(error); + }); + }); + it('PATCH .patch', function (done) { var original = { description: 'PATCH .patch' @@ -113,12 +135,31 @@ describe('REST provider', function () { done(error); }); }); - }); - describe('Dynamic Services', function() { - it('.remove', function (done) { + it('PATCH .patch many', function (done) { + var original = { + description: 'PATCH .patch', + many: true + }; + request({ - url: 'http://localhost:4777/todo/233', + url: 'http://localhost:4777/todo', + method: 'patch', + body: JSON.stringify(original), + headers: { + 'Content-Type': 'application/json' + } + }, function (error, response, body) { + assert.ok(response.statusCode === 200, 'Got OK status code'); + verify.patch(null, original, JSON.parse(body)); + + done(error); + }); + }); + + it('DELETE .remove', function (done) { + request({ + url: 'http://localhost:4777/tasks/233', method: 'delete' }, function (error, response, body) { assert.ok(response.statusCode === 200, 'Got OK status code'); @@ -128,6 +169,20 @@ describe('REST provider', function () { }); }); + it('DELETE .remove many', function (done) { + request({ + url: 'http://localhost:4777/tasks', + method: 'delete' + }, function (error, response, body) { + assert.ok(response.statusCode === 200, 'Got OK status code'); + verify.remove(null, JSON.parse(body)); + + done(error); + }); + }); + }); + + describe('Dynamic Services', function() { it('GET .find', function (done) { request('http://localhost:4777/tasks', function (error, response, body) { assert.ok(response.statusCode === 200, 'Got OK status code'); @@ -270,7 +325,7 @@ describe('REST provider', function () { done(error); }); }); - + it('empty response sets 204 status codes', function(done) { request('http://localhost:4780/todo', function (error, response) { assert.ok(response.statusCode === 204, 'Got empty status code'); diff --git a/test/providers/service-fixture.js b/test/providers/service-fixture.js index 1e828fba1f..bfe5a5d3a6 100644 --- a/test/providers/service-fixture.js +++ b/test/providers/service-fixture.js @@ -29,6 +29,11 @@ exports.Service = { var result = _.clone(data); result.id = 42; result.status = 'created'; + + if(Array.isArray(data)) { + result.many = true; + } + callback(null, result); }, @@ -36,6 +41,11 @@ exports.Service = { var result = _.clone(data); result.id = id; result.status = 'updated'; + + if(id === null) { + result.many = true; + } + callback(null, result); }, @@ -43,13 +53,20 @@ exports.Service = { var result = _.clone(data); result.id = id; result.status = 'patched'; + + if(id === null) { + result.many = true; + } + callback(null, result); }, remove: function (id, params, callback) { - callback(null, { + var result = { id: id - }); + }; + + callback(null, result); } }; diff --git a/test/providers/socketio.test.js b/test/providers/socketio.test.js index 85d5a685a1..5ed5fd1fac 100644 --- a/test/providers/socketio.test.js +++ b/test/providers/socketio.test.js @@ -177,6 +177,19 @@ describe('SocketIO provider', function () { }); }); + it('::update many', function (done) { + var original = { + name: 'updating', + many: true + }; + + socket.emit('todo::update', null, original, {}, function (error, data) { + verify.update(null, original, data); + + done(error); + }); + }); + it('::patch', function (done) { var original = { name: 'patching' @@ -189,6 +202,19 @@ describe('SocketIO provider', function () { }); }); + it('::patch many', function (done) { + var original = { + name: 'patching', + many: true + }; + + socket.emit('todo::patch', null, original, {}, function (error, data) { + verify.patch(null, original, data); + + done(error); + }); + }); + it('::remove', function (done) { socket.emit('todo::remove', 11, {}, function (error, data) { verify.remove(11, data); @@ -196,6 +222,14 @@ describe('SocketIO provider', function () { done(error); }); }); + + it('::remove many', function (done) { + socket.emit('todo::remove', null, {}, function (error, data) { + verify.remove(null, data); + + done(error); + }); + }); }); describe('Events', function () {