diff --git a/lib/application.js b/lib/application.js index 9943f0a9..16289bca 100644 --- a/lib/application.js +++ b/lib/application.js @@ -222,14 +222,15 @@ app.models = function () { * Define a DataSource. * * @param {String} name The data source name - * @param {Object} config The data source config + * @param {Object} config The data source config + * @param {DataSource} The registered data source */ - app.dataSource = function (name, config) { + var ds = dataSourcesFromConfig(config, this.connectors); this.dataSources[name] = this.dataSources[classify(name)] = - this.dataSources[camelize(name)] = - dataSourcesFromConfig(config, this.connectors); + this.dataSources[camelize(name)] = ds; + return ds; } /** diff --git a/lib/models/persisted-model.js b/lib/models/persisted-model.js index f8c71798..0d93fa9c 100644 --- a/lib/models/persisted-model.js +++ b/lib/models/persisted-model.js @@ -448,7 +448,25 @@ PersistedModel.setupRemoting = function() { description: 'Check whether a model instance exists in the data source', accepts: {arg: 'id', type: 'any', description: 'Model id', required: true}, returns: {arg: 'exists', type: 'boolean'}, - http: {verb: 'get', path: '/:id/exists'} + http: [ + {verb: 'get', path: '/:id/exists'}, + {verb: 'head', path: '/:id'} + ], + rest: { + // After hook to map exists to 200/404 for HEAD + after: function(ctx, cb) { + if(!ctx.result.exists) { + var modelName = ctx.method.sharedClass.name; + var id = ctx.getArgByName('id'); + var msg = 'Unknown "' + modelName + '" id "' + id + '".'; + var error = new Error(msg); + error.statusCode = error.status = 404; + cb(error); + } else { + cb(); + } + } + } }); setRemoting(PersistedModel, 'findById', { diff --git a/test/rest.middleware.test.js b/test/rest.middleware.test.js index 3c1e9886..027fed39 100644 --- a/test/rest.middleware.test.js +++ b/test/rest.middleware.test.js @@ -1,16 +1,54 @@ describe('loopback.rest', function() { + var MyModel; beforeEach(function() { - app.dataSource('db', { connector: loopback.Memory }); + var ds = app.dataSource('db', { connector: loopback.Memory }); + MyModel = ds.createModel('MyModel', {name: String}); }); it('works out-of-the-box', function(done) { - app.model('MyModel', { dataSource: 'db' }); + app.model(MyModel); app.use(loopback.rest()); request(app).get('/mymodels') .expect(200) .end(done); }); + it('should report 404 for GET /:id not found', function(done) { + app.model(MyModel); + app.use(loopback.rest()); + request(app).get('/mymodels/1') + .expect(404) + .end(done); + }); + + it('should report 404 for HEAD /:id not found', function(done) { + app.model(MyModel); + app.use(loopback.rest()); + request(app).head('/mymodels/1') + .expect(404) + .end(done); + }); + + it('should report 200 for GET /:id found', function(done) { + app.model(MyModel); + app.use(loopback.rest()); + MyModel.create({name: 'm1'}, function(err, inst) { + request(app).get('/mymodels/' + inst.id) + .expect(200) + .end(done); + }); + }); + + it('should report 200 for HEAD /:id found', function(done) { + app.model(MyModel); + app.use(loopback.rest()); + MyModel.create({name: 'm2'}, function(err, inst) { + request(app).head('/mymodels/' + inst.id) + .expect(200) + .end(done); + }); + }); + it('includes loopback.token when necessary', function(done) { givenUserModelWithAuth(); app.enableAuth();