|
| 1 | +var |
| 2 | + should = require('should'), |
| 3 | + rewire = require('rewire'), |
| 4 | + EventEmitter = require('events').EventEmitter, |
| 5 | + Kuzzle = rewire('../../src/kuzzle'); |
| 6 | + |
| 7 | +describe('Query management', function () { |
| 8 | + describe('#emitRequest', function () { |
| 9 | + var |
| 10 | + emitRequest = Kuzzle.__get__('emitRequest'), |
| 11 | + kuzzle; |
| 12 | + |
| 13 | + before(function () { |
| 14 | + Kuzzle.__set__('io', function () { return new EventEmitter; }); |
| 15 | + }); |
| 16 | + |
| 17 | + beforeEach(function () { |
| 18 | + kuzzle = new Kuzzle('foo'); |
| 19 | + }); |
| 20 | + |
| 21 | + it('should emit the request when asked to', function (done) { |
| 22 | + var start = Date.now(); |
| 23 | + |
| 24 | + this.timeout(50); |
| 25 | + |
| 26 | + kuzzle.socket.on('kuzzle', function () { |
| 27 | + // the event is emitted before the historization, so we need to delay our check a bit |
| 28 | + process.nextTick(() => { |
| 29 | + var end = Date.now(); |
| 30 | + |
| 31 | + try { |
| 32 | + should(kuzzle.requestHistory['bar']).be.within(start, end); |
| 33 | + done(); |
| 34 | + } |
| 35 | + catch (e) { |
| 36 | + done(e); |
| 37 | + } |
| 38 | + }); |
| 39 | + }); |
| 40 | + |
| 41 | + emitRequest.call(kuzzle, {requestId: 'bar'}); |
| 42 | + }); |
| 43 | + |
| 44 | + it('should launch the callback once a response has been received', function (done) { |
| 45 | + var response = {result: 'foo', error: 'bar'}, |
| 46 | + cb = function (err, res) { |
| 47 | + should(err).be.exactly(response.error); |
| 48 | + should(res).be.exactly(response.result); |
| 49 | + done(); |
| 50 | + }; |
| 51 | + |
| 52 | + this.timeout(50); |
| 53 | + |
| 54 | + kuzzle.socket.on('kuzzle', request => { |
| 55 | + kuzzle.socket.emit(request.requestId, response); |
| 56 | + }); |
| 57 | + |
| 58 | + emitRequest.call(kuzzle, {requestId: 'someEvent'}, cb); |
| 59 | + }); |
| 60 | + |
| 61 | + it('should delete older history entries when necessary', function () { |
| 62 | + var now = Date.now(); |
| 63 | + |
| 64 | + kuzzle.requestHistory['foo'] = now - 30000; |
| 65 | + kuzzle.requestHistory['bar'] = now - 20000; |
| 66 | + kuzzle.requestHistory['baz'] = now - 11000; |
| 67 | + kuzzle.requestHistory['qux'] = now - 1000; |
| 68 | + |
| 69 | + emitRequest.call(kuzzle, {requestId: 'xyz'}); |
| 70 | + |
| 71 | + should(Object.keys(kuzzle.requestHistory).length).be.exactly(2); |
| 72 | + should(Object.keys(kuzzle.requestHistory)).match(['qux', 'xyz']); |
| 73 | + }); |
| 74 | + }); |
| 75 | + |
| 76 | + describe('#query', function () { |
| 77 | + var |
| 78 | + requestObject, |
| 79 | + emitted, |
| 80 | + callback, |
| 81 | + kuzzle; |
| 82 | + |
| 83 | + before(function () { |
| 84 | + Kuzzle.__set__('emitRequest', function (object, cb) { |
| 85 | + emitted = true; |
| 86 | + requestObject = object; |
| 87 | + callback = cb; |
| 88 | + }); |
| 89 | + }); |
| 90 | + |
| 91 | + beforeEach(function () { |
| 92 | + kuzzle = new Kuzzle('foo'); |
| 93 | + kuzzle.state = 'connected'; |
| 94 | + requestObject = {}; |
| 95 | + callback = null; |
| 96 | + emitted = false; |
| 97 | + }); |
| 98 | + |
| 99 | + it('should generate a valid request object', function () { |
| 100 | + kuzzle.query('collection', 'controller', 'action', { body: { some: 'query'}}); |
| 101 | + should(requestObject.controller).be.exactly('controller'); |
| 102 | + should(requestObject.collection).be.exactly('collection'); |
| 103 | + should(requestObject.action).be.exactly('action'); |
| 104 | + should(requestObject.body).match({some: 'query'}); |
| 105 | + should(requestObject.requestId).not.be.undefined().and.match(/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i); |
| 106 | + }); |
| 107 | + |
| 108 | + it('should manage arguments properly if no options are provided', function () { |
| 109 | + var cb = function () {}; |
| 110 | + |
| 111 | + kuzzle.query('collection', 'controller', 'action', { body: { some: 'query'}}, cb); |
| 112 | + |
| 113 | + should(callback).be.exactly(cb); |
| 114 | + }); |
| 115 | + |
| 116 | + it('should handle options metadata properly', function () { |
| 117 | + var |
| 118 | + metadata = { |
| 119 | + foo: 'bar', |
| 120 | + baz: ['foo', 'bar', 'qux'] |
| 121 | + }; |
| 122 | + |
| 123 | + kuzzle.query('collection', 'controller', 'action', { body: { some: 'query'}}, {metadata: metadata}); |
| 124 | + should(requestObject.metadata).match(metadata); |
| 125 | + }); |
| 126 | + |
| 127 | + it('should exit early if the query is not queuable and the SDK is offline', function () { |
| 128 | + kuzzle.state = 'offline'; |
| 129 | + kuzzle.query('collection', 'controller', 'action', { body: { some: 'query'}}, {queuable: false}); |
| 130 | + should(emitted).be.false(); |
| 131 | + }); |
| 132 | + |
| 133 | + it('should copy query local metadata over optional ones', function () { |
| 134 | + var |
| 135 | + metadata = { |
| 136 | + foo: 'bar', |
| 137 | + baz: ['foo', 'bar', 'qux'] |
| 138 | + }; |
| 139 | + |
| 140 | + kuzzle.query('collection', 'controller', 'action', { body: { some: 'query'}, metadata: {foo: 'foo'}}, {metadata: metadata}); |
| 141 | + should(requestObject.metadata.foo).be.exactly('foo'); |
| 142 | + should(requestObject.metadata.baz).match(metadata.baz); |
| 143 | + }); |
| 144 | + |
| 145 | + it('should not define a "collection" member if none was provided', function () { |
| 146 | + kuzzle.query(null, 'controller', 'action', { body: { some: 'query'}}); |
| 147 | + should(requestObject.collection).be.undefined(); |
| 148 | + }); |
| 149 | + |
| 150 | + it('should not generate a new request ID if one is already defined', function () { |
| 151 | + kuzzle.query('collection', 'controller', 'action', { body: { some: 'query'}, requestId: 'foobar'}); |
| 152 | + should(requestObject.requestId).be.exactly('foobar'); |
| 153 | + }); |
| 154 | + |
| 155 | + it('should emit the request directly without waiting the end of dequeuing if queuable is false', function () { |
| 156 | + kuzzle.state = 'reconnecting'; |
| 157 | + kuzzle.query('collection', 'controller', 'action', { body: { some: 'query'}}, {queuable: false}); |
| 158 | + should(emitted).be.true(); |
| 159 | + |
| 160 | + emitted = false; |
| 161 | + kuzzle.queuing = true; |
| 162 | + kuzzle.query('collection', 'controller', 'action', { body: { some: 'query'}}, {queuable: false}); |
| 163 | + should(emitted).be.true(); |
| 164 | + }); |
| 165 | + |
| 166 | + it('should queue the request during offline mode, if queuing has been activated', function () { |
| 167 | + var |
| 168 | + query = { body: { some: 'query'}}, |
| 169 | + cb = function () {}, |
| 170 | + now = Date.now(); |
| 171 | + |
| 172 | + kuzzle.state = 'offline'; |
| 173 | + kuzzle.queuing = true; |
| 174 | + kuzzle.query('collection', 'controller', 'action', query, cb); |
| 175 | + |
| 176 | + should(emitted).be.false(); |
| 177 | + should(kuzzle.offlineQueue.length).be.exactly(1); |
| 178 | + should(kuzzle.offlineQueue[0].ts).not.be.undefined().and.be.approximately(now, 10); |
| 179 | + should(kuzzle.offlineQueue[0].query).match(query); |
| 180 | + should(kuzzle.offlineQueue[0].cb).be.exactly(cb); |
| 181 | + }); |
| 182 | + |
| 183 | + it('should queue the request if a queue filter has been defined and if it allows queuing', function () { |
| 184 | + var |
| 185 | + query = { body: { some: 'query'}}, |
| 186 | + cb = function () {}, |
| 187 | + now = Date.now(); |
| 188 | + |
| 189 | + kuzzle.state = 'offline'; |
| 190 | + kuzzle.queueFilter = function () { return true; }; |
| 191 | + kuzzle.queuing = true; |
| 192 | + kuzzle.query('collection', 'controller', 'action', query, cb); |
| 193 | + |
| 194 | + should(emitted).be.false(); |
| 195 | + should(kuzzle.offlineQueue.length).be.exactly(1); |
| 196 | + should(kuzzle.offlineQueue[0].ts).not.be.undefined().and.be.approximately(now, 10); |
| 197 | + should(kuzzle.offlineQueue[0].query).match(query); |
| 198 | + should(kuzzle.offlineQueue[0].cb).be.exactly(cb); |
| 199 | + }); |
| 200 | + |
| 201 | + it('should discard the request if a queue filter has been defined and if it does not allows queuing', function () { |
| 202 | + var |
| 203 | + query = { body: { some: 'query'}}, |
| 204 | + cb = function () {}; |
| 205 | + |
| 206 | + kuzzle.state = 'offline'; |
| 207 | + kuzzle.queueFilter = function () { return false; }; |
| 208 | + kuzzle.queuing = true; |
| 209 | + kuzzle.query('collection', 'controller', 'action', query, cb); |
| 210 | + |
| 211 | + should(emitted).be.false(); |
| 212 | + should(kuzzle.offlineQueue.length).be.exactly(0); |
| 213 | + }); |
| 214 | + |
| 215 | + it('should discard the request if in offline mode but queuing has not yet been activated', function () { |
| 216 | + var |
| 217 | + query = { body: { some: 'query'}}, |
| 218 | + cb = function () {}; |
| 219 | + |
| 220 | + kuzzle.state = 'offline'; |
| 221 | + kuzzle.queuing = false; |
| 222 | + kuzzle.query('collection', 'controller', 'action', query, cb); |
| 223 | + |
| 224 | + should(emitted).be.false(); |
| 225 | + should(kuzzle.offlineQueue.length).be.exactly(0); |
| 226 | + }); |
| 227 | + }); |
| 228 | +}); |
0 commit comments