@sockethub/data-layer 1.0.0-alpha.4 → 1.0.0-alpha.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,252 +1,280 @@
1
- import proxyquire from 'proxyquire';
2
- import { expect } from 'chai';
3
- import * as sinon from 'sinon';
4
-
5
- proxyquire.noPreserveCache();
6
- proxyquire.noCallThru();
7
-
8
- describe('JobQueue', () => {
9
- let jobQueue, MockBull, bullMocks, cryptoMocks, sandbox;
10
-
11
- beforeEach(() => {
12
- sandbox = sinon.createSandbox();
13
- cryptoMocks = {
14
- objectHash: sandbox.stub(),
15
- decrypt: sandbox.stub(),
16
- encrypt: sandbox.stub(),
17
- hash: sandbox.stub(),
18
- };
19
- bullMocks = {
20
- add: sandbox.stub(),
21
- getJob: sandbox.stub(),
22
- process: sandbox.stub(),
23
- removeAllListeners: sandbox.stub(),
24
- pause: sandbox.stub(),
25
- resume: sandbox.stub(),
26
- isPaused: sandbox.stub(),
27
- obliterate: sandbox.stub(),
28
- emit: sandbox.stub(),
29
- on: sandbox.stub().callsArgWith(1, 'a job id', 'a result string')
30
- };
31
- MockBull = sandbox.stub().returns(bullMocks);
32
- const JobQueueMod = proxyquire('./job-queue', {
33
- 'bull': MockBull,
34
- '@sockethub/crypto': cryptoMocks
35
- });
36
- const JobQueue = JobQueueMod.default;
37
- jobQueue = new JobQueue('a parent id', 'a session id', 'a secret', 'redis config');
38
- jobQueue.emit = sandbox.stub();
39
- });
40
-
41
- afterEach(() => {
42
- sinon.restore();
43
- sandbox.reset();
44
- });
45
-
46
- it('returns a valid JobQueue object', () => {
47
- sinon.assert.calledOnce(MockBull);
48
- sinon.assert.calledWith(MockBull,
49
- 'a parent ida session id', { redis: 'redis config' }
50
- );
51
- expect(typeof jobQueue).to.equal('object');
52
- expect(jobQueue.uid).to.equal(`sockethub:data-layer:job-queue:a parent id:a session id`);
53
- expect(typeof jobQueue.add).to.equal('function');
54
- expect(typeof jobQueue.getJob).to.equal('function');
55
- expect(typeof jobQueue.onJob).to.equal('function');
56
- expect(typeof jobQueue.shutdown).to.equal('function');
57
- });
58
-
59
- describe('initResultEvents', () => {
60
- it('registers handlers when called', () => {
61
- bullMocks.on.reset();
62
- jobQueue.initResultEvents();
63
- expect(bullMocks.on.callCount).to.eql(4);
64
- sinon.assert.calledWith(bullMocks.on, 'global:completed');
65
- sinon.assert.calledWith(bullMocks.on, 'global:error');
66
- sinon.assert.calledWith(bullMocks.on, 'global:failed');
67
- sinon.assert.calledWith(bullMocks.on, 'failed');
68
- });
69
- });
70
-
71
- describe('createJob', () => {
72
- it('returns expected job format', () => {
73
- cryptoMocks.encrypt.returns('an encrypted message');
74
- const job = jobQueue.createJob('a socket id', {
75
- context: 'some context',
76
- id: 'an identifier'
77
- });
78
- expect(job).to.eql({
79
- title: 'some context-an identifier',
80
- msg: 'an encrypted message',
81
- sessionId: 'a socket id'
82
- })
83
- });
1
+ import { expect } from "chai";
2
+ import * as sinon from "sinon";
3
+
4
+ import { JobQueue } from "./index";
5
+
6
+ describe("JobQueue", () => {
7
+ let MockBull, jobQueue, cryptoMocks, sandbox;
8
+
9
+ beforeEach(() => {
10
+ sandbox = sinon.createSandbox();
11
+ cryptoMocks = {
12
+ objectHash: sandbox.stub(),
13
+ decrypt: sandbox.stub(),
14
+ encrypt: sandbox.stub(),
15
+ hash: sandbox.stub(),
16
+ };
17
+ MockBull = sandbox.stub().returns({
18
+ add: sandbox.stub(),
19
+ getJob: sandbox.stub(),
20
+ removeAllListeners: sandbox.stub(),
21
+ pause: sandbox.stub(),
22
+ resume: sandbox.stub(),
23
+ isPaused: sandbox.stub(),
24
+ obliterate: sandbox.stub(),
25
+ isRunning: sandbox.stub(),
26
+ close: sandbox.stub(),
27
+ emit: sandbox.stub(),
28
+ disconnect: sandbox.stub(),
29
+ on: sandbox.stub().callsArgWith(1, "a job id", "a result string"),
30
+ });
84
31
 
85
- it('uses counter when no id provided', () => {
86
- cryptoMocks.encrypt.returns('an encrypted message');
87
- let job = jobQueue.createJob('a socket id', {
88
- context: 'some context'
89
- });
90
- expect(job).to.eql({
91
- title: 'some context-0',
92
- msg: 'an encrypted message',
93
- sessionId: 'a socket id'
94
- });
95
- job = jobQueue.createJob('a socket id', {
96
- context: 'some context'
97
- });
98
- expect(job).to.eql({
99
- title: 'some context-1',
100
- msg: 'an encrypted message',
101
- sessionId: 'a socket id'
102
- });
103
- })
104
- });
105
-
106
- describe('add', () => {
107
- it('stores encrypted job', async () => {
108
- cryptoMocks.encrypt.returns('encrypted foo')
109
- bullMocks.isPaused.returns(false);
110
- const resultJob = {title: 'a platform-an identifier', sessionId: 'a socket id', msg: 'encrypted foo'}
111
- const res = await jobQueue.add(
112
- 'a socket id', {context: 'a platform', id: 'an identifier'}
113
- );
114
- sinon.assert.calledOnce(bullMocks.isPaused);
115
- sinon.assert.notCalled(bullMocks.emit);
116
- sinon.assert.calledOnceWithExactly(bullMocks.add,
117
- resultJob);
118
- expect(res).to.eql(resultJob);
32
+ class TestJobQueue extends JobQueue {
33
+ init() {
34
+ this.redisConnection = MockBull();
35
+ this.queue = MockBull(this.uid, {
36
+ connection: this.redisConnection,
37
+ });
38
+ this.events = MockBull(this.uid, {
39
+ connection: this.redisConnection,
40
+ });
41
+ }
42
+ initCrypto() {
43
+ this.crypto = cryptoMocks;
44
+ }
45
+ }
46
+ jobQueue = new TestJobQueue(
47
+ "a parent id",
48
+ "a session id",
49
+ "secret is 32 char long like this",
50
+ {
51
+ url: "redis config",
52
+ },
53
+ );
54
+ jobQueue.emit = sandbox.stub();
119
55
  });
120
- it('fails job if queue paused', async () => {
121
- cryptoMocks.encrypt.returns('encrypted foo')
122
- bullMocks.isPaused.returns(true);
123
- const resultJob = {title: 'a platform-an identifier', sessionId: 'a socket id', msg: 'encrypted foo'}
124
- const res = await jobQueue.add(
125
- 'a socket id', {context: 'a platform', id: 'an identifier'}
126
- );
127
- sinon.assert.calledOnce(bullMocks.isPaused);
128
- sinon.assert.calledOnceWithExactly(bullMocks.emit, 'failed', resultJob, 'queue closed');
129
- sinon.assert.notCalled(bullMocks.add);
130
- expect(res).to.be.undefined;
56
+
57
+ afterEach(() => {
58
+ sinon.restore();
59
+ sandbox.reset();
131
60
  });
132
- });
133
-
134
- describe('getJob', () => {
135
- const encryptedJob = {
136
- data: {
137
- title: 'a title',
138
- msg: 'an encrypted msg',
139
- sessionId: 'a socket id'
140
- }
141
- };
142
-
143
- it('handles fetching a valid job', async () => {
144
- bullMocks.getJob.returns(encryptedJob);
145
- cryptoMocks.decrypt.returns('an unencrypted message')
146
- const job = await jobQueue.getJob('a valid job');
147
- sinon.assert.calledOnceWithExactly(bullMocks.getJob, 'a valid job');
148
- encryptedJob.data.msg = 'an unencrypted message';
149
- expect(job).to.eql(encryptedJob);
61
+
62
+ it("returns a valid JobQueue object", () => {
63
+ sinon.assert.calledThrice(MockBull);
64
+ sinon.assert.calledWith(
65
+ MockBull,
66
+ "sockethub:data-layer:queue:a parent id:a session id",
67
+ {
68
+ connection: MockBull(),
69
+ },
70
+ );
71
+ expect(typeof jobQueue).to.equal("object");
72
+ expect(jobQueue.uid).to.equal(
73
+ `sockethub:data-layer:queue:a parent id:a session id`,
74
+ );
75
+ expect(typeof jobQueue.add).to.equal("function");
76
+ expect(typeof jobQueue.getJob).to.equal("function");
77
+ expect(typeof jobQueue.shutdown).to.equal("function");
150
78
  });
151
79
 
152
- it('handles fetching an invalid job', async () => {
153
- bullMocks.getJob.returns(undefined);
154
- const job = await jobQueue.getJob('an invalid job');
155
- expect(job).to.eql(undefined);
156
- sinon.assert.calledOnceWithExactly(bullMocks.getJob, 'an invalid job');
157
- sinon.assert.notCalled(cryptoMocks.decrypt)
80
+ // describe("initResultEvents", () => {
81
+ // it("registers handlers when called", () => {
82
+ // bullMocks.on.reset();
83
+ // // jobQueue.initResultEvents();
84
+ // expect(bullMocks.on.callCount).to.eql(4);
85
+ // sinon.assert.calledWith(bullMocks.on, "global:completed");
86
+ // sinon.assert.calledWith(bullMocks.on, "global:error");
87
+ // sinon.assert.calledWith(bullMocks.on, "global:failed");
88
+ // sinon.assert.calledWith(bullMocks.on, "failed");
89
+ // });
90
+ // });
91
+
92
+ describe("createJob", () => {
93
+ it("returns expected job format", () => {
94
+ cryptoMocks.encrypt.returns("an encrypted message");
95
+ const job = jobQueue.createJob("a socket id", {
96
+ context: "some context",
97
+ id: "an identifier",
98
+ });
99
+ expect(job).to.eql({
100
+ title: "some context-an identifier",
101
+ msg: "an encrypted message",
102
+ sessionId: "a socket id",
103
+ });
104
+ });
105
+
106
+ it("uses counter when no id provided", () => {
107
+ cryptoMocks.encrypt.returns("an encrypted message");
108
+ let job = jobQueue.createJob("a socket id", {
109
+ context: "some context",
110
+ });
111
+ expect(job).to.eql({
112
+ title: "some context-0",
113
+ msg: "an encrypted message",
114
+ sessionId: "a socket id",
115
+ });
116
+ job = jobQueue.createJob("a socket id", {
117
+ context: "some context",
118
+ });
119
+ expect(job).to.eql({
120
+ title: "some context-1",
121
+ msg: "an encrypted message",
122
+ sessionId: "a socket id",
123
+ });
124
+ });
158
125
  });
159
126
 
160
- it('removes sessionSecret', async () => {
161
- bullMocks.getJob.returns(encryptedJob);
162
- cryptoMocks.decrypt.returns({
163
- foo:'bar',
164
- sessionSecret: 'yarg'
165
- })
166
- const job = await jobQueue.getJob('a valid job');
167
- sinon.assert.calledOnceWithExactly(bullMocks.getJob, 'a valid job');
168
- // @ts-ignore
169
- encryptedJob.data.msg = {
170
- foo:'bar'
171
- }
172
- expect(job).to.eql(encryptedJob);
127
+ describe("getJob", () => {
128
+ const encryptedJob = {
129
+ data: {
130
+ title: "a title",
131
+ msg: "an encrypted msg",
132
+ sessionId: "a socket id",
133
+ },
134
+ };
135
+
136
+ it("handles fetching a valid job", async () => {
137
+ jobQueue.queue.getJob.returns(encryptedJob);
138
+ cryptoMocks.decrypt.returns("an unencrypted message");
139
+ const job = await jobQueue.getJob("a valid job");
140
+ sinon.assert.calledOnceWithExactly(
141
+ jobQueue.queue.getJob,
142
+ "a valid job",
143
+ );
144
+ encryptedJob.data.msg = "an unencrypted message";
145
+ expect(job).to.eql(encryptedJob);
146
+ });
147
+
148
+ it("handles fetching an invalid job", async () => {
149
+ jobQueue.queue.getJob.returns(undefined);
150
+ const job = await jobQueue.getJob("an invalid job");
151
+ expect(job).to.eql(undefined);
152
+ sinon.assert.calledOnceWithExactly(
153
+ jobQueue.queue.getJob,
154
+ "an invalid job",
155
+ );
156
+ sinon.assert.notCalled(cryptoMocks.decrypt);
157
+ });
158
+
159
+ it("removes sessionSecret", async () => {
160
+ jobQueue.queue.getJob.returns(encryptedJob);
161
+ cryptoMocks.decrypt.returns({
162
+ foo: "bar",
163
+ sessionSecret: "yarg",
164
+ });
165
+ const job = await jobQueue.getJob("a valid job");
166
+ sinon.assert.calledOnceWithExactly(
167
+ jobQueue.queue.getJob,
168
+ "a valid job",
169
+ );
170
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
171
+ // @ts-ignore
172
+ encryptedJob.data.msg = {
173
+ foo: "bar",
174
+ };
175
+ expect(job).to.eql(encryptedJob);
176
+ });
173
177
  });
174
- });
175
-
176
- describe('onJob', () => {
177
- it('queues the handler', () => {
178
- jobQueue.onJob((job, done) => {
179
- throw new Error('This handler should never be called');
180
- });
181
- sinon.assert.calledOnce(bullMocks.process);
178
+
179
+ describe("add", () => {
180
+ it("stores encrypted job", async () => {
181
+ cryptoMocks.encrypt.returns("encrypted foo");
182
+ jobQueue.queue.isPaused.returns(false);
183
+ const resultJob = {
184
+ title: "a platform-an identifier",
185
+ sessionId: "a socket id",
186
+ msg: "encrypted foo",
187
+ };
188
+ const res = await jobQueue.add("a socket id", {
189
+ context: "a platform",
190
+ id: "an identifier",
191
+ });
192
+ sinon.assert.calledOnce(jobQueue.queue.isPaused);
193
+ sinon.assert.notCalled(jobQueue.queue.emit);
194
+ sinon.assert.calledOnceWithExactly(
195
+ jobQueue.queue.add,
196
+ "a platform-an identifier",
197
+ resultJob,
198
+ {
199
+ removeOnComplete: { age: 300 },
200
+ removeOnFail: { age: 300 },
201
+ },
202
+ );
203
+ expect(res).to.eql(resultJob);
204
+ });
205
+ it("fails job if queue paused", async () => {
206
+ cryptoMocks.encrypt.returns("encrypted foo");
207
+ jobQueue.queue.isPaused.returns(true);
208
+ try {
209
+ await jobQueue.add("a socket id", {
210
+ context: "a platform",
211
+ id: "an identifier",
212
+ });
213
+ } catch (err) {
214
+ expect(err.toString()).to.eql("Error: queue closed");
215
+ }
216
+ sinon.assert.calledOnce(jobQueue.queue.isPaused);
217
+ sinon.assert.notCalled(jobQueue.queue.add);
218
+ });
182
219
  });
183
- });
184
-
185
- it('pause', async () => {
186
- await jobQueue.pause();
187
- sinon.assert.calledOnce(bullMocks.pause)
188
- });
189
-
190
- it('resume', async () => {
191
- await jobQueue.resume();
192
- sinon.assert.calledOnce(bullMocks.resume)
193
- });
194
-
195
- describe('shutdown', () => {
196
- it('is sure to pause when not already paused', async () => {
197
- bullMocks.isPaused.returns(false)
198
- await jobQueue.shutdown()
199
- sinon.assert.calledOnce(bullMocks.isPaused);
200
- sinon.assert.calledOnce(bullMocks.pause);
201
- sinon.assert.calledOnce(bullMocks.removeAllListeners);
202
- sinon.assert.calledOnce(bullMocks.obliterate);
220
+
221
+ it("pause", async () => {
222
+ await jobQueue.pause();
223
+ sinon.assert.calledOnce(jobQueue.queue.pause);
203
224
  });
204
- it('skips pausing when already paused', async () => {
205
- bullMocks.isPaused.returns(true)
206
- await jobQueue.shutdown()
207
- sinon.assert.calledOnce(bullMocks.isPaused);
208
- sinon.assert.notCalled(bullMocks.pause);
209
- sinon.assert.calledOnce(bullMocks.removeAllListeners);
210
- sinon.assert.calledOnce(bullMocks.obliterate);
225
+
226
+ it("resume", async () => {
227
+ await jobQueue.resume();
228
+ sinon.assert.calledOnce(jobQueue.queue.resume);
211
229
  });
212
- });
213
-
214
- describe('jobHandler', () => {
215
- it('calls handler as expected', (done) => {
216
- cryptoMocks.decrypt.returns('an unencrypted message');
217
- const encryptedJob = {
218
- data: {
219
- title: 'a title',
220
- msg: 'an encrypted message',
221
- sessionId: 'a socket id'
222
- }
223
- };
224
- jobQueue.onJob((job, cb) => {
225
- const decryptedData = encryptedJob.data;
226
- decryptedData.msg = 'an unencrypted message'
227
- expect(job).to.eql(decryptedData);
228
- cb();
229
- });
230
- sinon.assert.calledOnce(bullMocks.process);
231
- jobQueue.jobHandler(encryptedJob, done);
230
+
231
+ describe("shutdown", () => {
232
+ // it("is sure to pause when not already paused", async () => {
233
+ // sinon.assert.notCalled(jobQueue.queue.pause);
234
+ // jobQueue.initWorker();
235
+ // sinon.assert.notCalled(jobQueue.queue.pause);
236
+ // jobQueue.queue.isPaused.returns(false);
237
+ // sinon.assert.notCalled(jobQueue.queue.pause);
238
+ // await jobQueue.shutdown();
239
+ // sinon.assert.calledOnce(jobQueue.queue.pause);
240
+ // sinon.assert.calledOnce(jobQueue.queue.removeAllListeners);
241
+ // sinon.assert.calledOnce(jobQueue.queue.obliterate);
242
+ // });
243
+ it("skips pausing when already paused", async () => {
244
+ jobQueue.queue.isPaused.returns(true);
245
+ sinon.assert.notCalled(jobQueue.queue.pause);
246
+ await jobQueue.shutdown();
247
+ sinon.assert.notCalled(jobQueue.queue.pause);
248
+ sinon.assert.calledOnce(jobQueue.queue.removeAllListeners);
249
+ sinon.assert.calledOnce(jobQueue.queue.obliterate);
250
+ });
232
251
  });
233
- });
234
-
235
- describe("decryptJobData", () => {
236
- it("decrypts and returns expected object", () => {
237
- cryptoMocks.decrypt.returnsArg(0);
238
- const jobData = {data:{title:"foo", msg:'encryptedjobdata', sessionId:'foobar'}};
239
- const secret = 'secretstring';
240
- expect(jobQueue.decryptJobData(jobData, secret)).to.be.eql(jobData.data);
252
+
253
+ describe("decryptJobData", () => {
254
+ it("decrypts and returns expected object", () => {
255
+ cryptoMocks.decrypt.returnsArg(0);
256
+ const jobData = {
257
+ data: {
258
+ title: "foo",
259
+ msg: "encryptedjobdata",
260
+ sessionId: "foobar",
261
+ },
262
+ };
263
+ const secret = "secretstring";
264
+ expect(jobQueue.decryptJobData(jobData, secret)).to.be.eql(
265
+ jobData.data,
266
+ );
267
+ });
241
268
  });
242
- });
243
-
244
- describe("decryptActivityStream", () => {
245
- it("decrypts and returns expected object", () => {
246
- cryptoMocks.decrypt.returnsArg(0);
247
- const jobData = 'encryptedjobdata';
248
- const secret = 'secretstring';
249
- expect(jobQueue.decryptActivityStream(jobData, secret)).to.be.eql(jobData);
269
+
270
+ describe("decryptActivityStream", () => {
271
+ it("decrypts and returns expected object", () => {
272
+ cryptoMocks.decrypt.returnsArg(0);
273
+ const jobData = "encryptedjobdata";
274
+ const secret = "secretstring";
275
+ expect(jobQueue.decryptActivityStream(jobData, secret)).to.be.eql(
276
+ jobData,
277
+ );
278
+ });
250
279
  });
251
- });
252
280
  });