2018-01-03 04:05:53 +00:00
|
|
|
// Copyright IBM Corp. 2016,2018. All Rights Reserved.
|
|
|
|
// Node module: loopback
|
|
|
|
// This file is licensed under the MIT License.
|
|
|
|
// License text available at https://opensource.org/licenses/MIT
|
|
|
|
|
2016-11-15 21:46:23 +00:00
|
|
|
'use strict';
|
2016-11-22 14:30:04 +00:00
|
|
|
var expect = require('./helpers/expect');
|
2016-08-08 15:24:17 +00:00
|
|
|
var http = require('http');
|
|
|
|
var loopback = require('..');
|
|
|
|
var supertest = require('supertest');
|
|
|
|
|
2016-11-15 21:46:23 +00:00
|
|
|
var AN_OBJECT_VALUE = {name: 'an-object'};
|
2016-08-08 15:24:17 +00:00
|
|
|
|
|
|
|
describe('KeyValueModel', function() {
|
|
|
|
var request, app, CacheItem;
|
|
|
|
beforeEach(setupAppAndCacheItem);
|
|
|
|
|
|
|
|
describe('REST API', function() {
|
|
|
|
before(setupSharedHttpServer);
|
|
|
|
|
|
|
|
it('provides "get(key)" at "GET /key"', function(done) {
|
|
|
|
CacheItem.set('get-key', AN_OBJECT_VALUE);
|
|
|
|
request.get('/CacheItems/get-key')
|
|
|
|
.end(function(err, res) {
|
|
|
|
if (err) return done(err);
|
|
|
|
expect(res.body).to.eql(AN_OBJECT_VALUE);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('returns 404 when getting a key that does not exist', function(done) {
|
|
|
|
request.get('/CacheItems/key-does-not-exist')
|
|
|
|
.expect(404, done);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('provides "set(key)" at "PUT /key"', function(done) {
|
|
|
|
request.put('/CacheItems/set-key')
|
|
|
|
.send(AN_OBJECT_VALUE)
|
|
|
|
.expect(204)
|
|
|
|
.end(function(err, res) {
|
|
|
|
if (err) return done(err);
|
|
|
|
CacheItem.get('set-key', function(err, value) {
|
|
|
|
if (err) return done(err);
|
|
|
|
expect(value).to.eql(AN_OBJECT_VALUE);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('provides "set(key, ttl)" at "PUT /key?ttl={num}"', function(done) {
|
|
|
|
request.put('/CacheItems/set-key-ttl?ttl=10')
|
|
|
|
.send(AN_OBJECT_VALUE)
|
|
|
|
.end(function(err, res) {
|
|
|
|
if (err) return done(err);
|
|
|
|
setTimeout(function() {
|
|
|
|
CacheItem.get('set-key-ttl', function(err, value) {
|
|
|
|
if (err) return done(err);
|
|
|
|
expect(value).to.equal(null);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
}, 20);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('provides "expire(key, ttl)" at "PUT /key/expire"',
|
2017-12-12 08:33:15 +00:00
|
|
|
function(done) {
|
|
|
|
CacheItem.set('expire-key', AN_OBJECT_VALUE, function(err) {
|
|
|
|
if (err) return done(err);
|
|
|
|
request.put('/CacheItems/expire-key/expire')
|
|
|
|
.send({ttl: 10})
|
|
|
|
.end(function(err, res) {
|
|
|
|
if (err) return done(err);
|
|
|
|
setTimeout(function() {
|
|
|
|
CacheItem.get('set-key-ttl', function(err, value) {
|
|
|
|
if (err) return done(err);
|
|
|
|
expect(value).to.equal(null);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
}, 20);
|
|
|
|
});
|
|
|
|
});
|
2016-08-08 15:24:17 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
it('returns 404 when expiring a key that does not exist', function(done) {
|
|
|
|
request.put('/CacheItems/key-does-not-exist/expire')
|
2016-11-15 21:46:23 +00:00
|
|
|
.send({ttl: 10})
|
2016-08-08 15:24:17 +00:00
|
|
|
.expect(404, done);
|
|
|
|
});
|
2016-08-16 12:56:15 +00:00
|
|
|
|
2016-08-29 21:41:21 +00:00
|
|
|
it('provides "ttl(key)" at "GET /key/ttl"', function(done) {
|
|
|
|
request.put('/CacheItems/ttl-key?ttl=2000')
|
|
|
|
.end(function(err, res) {
|
|
|
|
if (err) return done(err);
|
|
|
|
request.get('/CacheItems/ttl-key/ttl')
|
|
|
|
.end(function(err, res) {
|
|
|
|
if (err) return done(err);
|
2016-11-22 14:30:04 +00:00
|
|
|
expect(res.body).to.be.a('number');
|
2016-08-29 21:41:21 +00:00
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('returns 204 when getting TTL for a key that does not have TTL set',
|
2017-12-12 08:33:15 +00:00
|
|
|
function(done) {
|
|
|
|
request.put('/CacheItems/ttl-key')
|
|
|
|
.end(function(err, res) {
|
2016-08-29 21:41:21 +00:00
|
|
|
if (err) return done(err);
|
|
|
|
request.get('/CacheItems/ttl-key/ttl')
|
2017-12-12 08:33:15 +00:00
|
|
|
.expect(204, done);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('returns 404 when getting TTL for a key when TTL has expired',
|
|
|
|
function(done) {
|
|
|
|
request.put('/CacheItems/ttl-key?ttl=10')
|
|
|
|
.end(function(err, res) {
|
|
|
|
setTimeout(function() {
|
|
|
|
if (err) return done(err);
|
|
|
|
request.get('/CacheItems/ttl-key/ttl')
|
|
|
|
.expect(404, done);
|
|
|
|
}, 20);
|
|
|
|
});
|
|
|
|
});
|
2016-08-29 21:41:21 +00:00
|
|
|
|
|
|
|
it('returns 404 when getting TTL for a key that does not exist',
|
2017-12-12 08:33:15 +00:00
|
|
|
function(done) {
|
|
|
|
request.get('/CacheItems/key-does-not-exist/ttl')
|
|
|
|
.expect(404, done);
|
|
|
|
});
|
2016-08-29 21:41:21 +00:00
|
|
|
|
2016-08-16 12:56:15 +00:00
|
|
|
it('provides "keys(filter)" at "GET /keys"', function(done) {
|
|
|
|
CacheItem.set('list-key', AN_OBJECT_VALUE, function(err) {
|
|
|
|
if (err) return done(err);
|
|
|
|
request.get('/CacheItems/keys')
|
|
|
|
.send(AN_OBJECT_VALUE)
|
|
|
|
.end(function(err, res) {
|
|
|
|
if (err) return done(err);
|
|
|
|
if (res.body.error) return done(res.body.error);
|
|
|
|
expect(res.body).to.eql(['list-key']);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
2016-08-08 15:24:17 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
function setupAppAndCacheItem() {
|
2016-11-15 21:46:23 +00:00
|
|
|
app = loopback({localRegistry: true, loadBuiltinModels: true});
|
2016-08-08 15:24:17 +00:00
|
|
|
app.use(loopback.rest());
|
|
|
|
|
|
|
|
CacheItem = app.registry.createModel({
|
|
|
|
name: 'CacheItem',
|
|
|
|
base: 'KeyValueModel',
|
|
|
|
});
|
|
|
|
|
2016-11-15 21:46:23 +00:00
|
|
|
app.dataSource('kv', {connector: 'kv-memory'});
|
|
|
|
app.model(CacheItem, {dataSource: 'kv'});
|
2016-08-08 15:24:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var _server, _requestHandler; // eslint-disable-line one-var
|
|
|
|
function setupSharedHttpServer(done) {
|
|
|
|
_server = http.createServer(function(req, res) {
|
|
|
|
app(req, res);
|
|
|
|
});
|
|
|
|
_server.listen(0, '127.0.0.1')
|
|
|
|
.once('listening', function() {
|
|
|
|
request = supertest('http://127.0.0.1:' + this.address().port);
|
|
|
|
done();
|
|
|
|
})
|
|
|
|
.once('error', function(err) { done(err); });
|
|
|
|
}
|
|
|
|
});
|