@arrai-innovations/reactive-helpers 1.0.0

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.
Files changed (53) hide show
  1. package/.circleci/config.yml +91 -0
  2. package/.commitlintrc.json +3 -0
  3. package/.editorconfig +5 -0
  4. package/.eslintignore +2 -0
  5. package/.eslintrc.js +26 -0
  6. package/.husky/commit-msg +2 -0
  7. package/.husky/pre-commit +2 -0
  8. package/.idea/encodings.xml +6 -0
  9. package/.idea/inspectionProfiles/Project_Default.xml +6 -0
  10. package/.idea/modules.xml +8 -0
  11. package/.idea/prettier.xml +8 -0
  12. package/.idea/reactive-helpers.iml +15 -0
  13. package/.lintstagedrc +11 -0
  14. package/.prettierignore +4 -0
  15. package/.prettierrc.js +5 -0
  16. package/README.md +598 -0
  17. package/babel.config.js +15 -0
  18. package/index.js +2 -0
  19. package/jest.config.mjs +27 -0
  20. package/package.json +59 -0
  21. package/tests/unit/.eslintrc.js +10 -0
  22. package/tests/unit/expectHelpers.js +6 -0
  23. package/tests/unit/mockOnUnmounted.js +9 -0
  24. package/tests/unit/use/index.spec.js +18 -0
  25. package/tests/unit/use/listFilter.spec.js +332 -0
  26. package/tests/unit/use/listInstance.spec.js +424 -0
  27. package/tests/unit/use/listRelated.spec.js +73 -0
  28. package/tests/unit/use/listSort.spec.js +220 -0
  29. package/tests/unit/use/listSubscription.spec.js +540 -0
  30. package/tests/unit/use/objectInstance.spec.js +897 -0
  31. package/tests/unit/use/objectSubscription.spec.js +671 -0
  32. package/tests/unit/use/search.spec.js +67 -0
  33. package/tests/unit/use/watches.spec.js +252 -0
  34. package/tests/unit/utils/assignReactiveObject.spec.js +127 -0
  35. package/tests/unit/utils/index.spec.js +18 -0
  36. package/tests/unit/utils/keyDiff.spec.js +67 -0
  37. package/tests/unit/utils/set.spec.js +68 -0
  38. package/tests/unit/utils/unrefAndToRawDeep.spec.js +170 -0
  39. package/use/index.js +8 -0
  40. package/use/listFilter.js +157 -0
  41. package/use/listInstance.js +144 -0
  42. package/use/listRelated.js +135 -0
  43. package/use/listSort.js +190 -0
  44. package/use/listSubscription.js +143 -0
  45. package/use/objectInstance.js +222 -0
  46. package/use/objectSubscription.js +188 -0
  47. package/use/search.js +104 -0
  48. package/utils/assignReactiveObject.js +62 -0
  49. package/utils/index.js +5 -0
  50. package/utils/keyDiff.js +10 -0
  51. package/utils/set.js +48 -0
  52. package/utils/unrefAndToRawDeep.js +49 -0
  53. package/utils/watches.js +170 -0
@@ -0,0 +1,671 @@
1
+ import flushPromises from "flush-promises";
2
+ import { inspect } from "util";
3
+ import { nextTick } from "vue";
4
+ import { expectErrorToBeNull } from "../expectHelpers";
5
+ import { getMockOnUnmounted } from "../mockOnUnmounted";
6
+ import { assignReactiveObject } from "../../../utils/assignReactiveObject";
7
+
8
+ getMockOnUnmounted();
9
+
10
+ afterAll(() => {
11
+ jest.restoreAllMocks();
12
+ });
13
+
14
+ describe("use/objectSubscription.js", function () {
15
+ let useObjectSubscription, ObjectSubscriptionError, useObjectSubscriptions, globalSubscribe, globalRetrieve;
16
+ beforeEach(async () => {
17
+ const objectInstanceModule = await import("../../../use/objectInstance");
18
+ objectInstanceModule.setObjectInstanceCrud({
19
+ retrieve: jest.fn(),
20
+ create: jest.fn(),
21
+ update: jest.fn(),
22
+ patch: jest.fn(),
23
+ delete: jest.fn(),
24
+ });
25
+ globalRetrieve = jest.fn();
26
+ objectInstanceModule.setObjectInstanceCrud({
27
+ retrieve: globalRetrieve,
28
+ args: { stream: "test_stream" },
29
+ });
30
+ const objectSubscriptionModule = await import("../../../use/objectSubscription");
31
+ useObjectSubscription = objectSubscriptionModule.useObjectSubscription;
32
+ ObjectSubscriptionError = objectSubscriptionModule.ObjectSubscriptionError;
33
+ globalSubscribe = jest.fn();
34
+ objectSubscriptionModule.setObjectSubscriptionCrud({
35
+ subscribe: globalSubscribe,
36
+ args: { stream: "test_stream" },
37
+ });
38
+ useObjectSubscriptions = objectSubscriptionModule.useObjectSubscriptions;
39
+ });
40
+ afterEach(function () {
41
+ jest.resetAllMocks();
42
+ });
43
+ const crudRetrieveResolved = {
44
+ id: 1,
45
+ __str__: "asdf",
46
+ name: "zxcv",
47
+ };
48
+ const crudSubscribeResolved = null;
49
+ const crudRetrieveRejected = {
50
+ errors: ["Not found"],
51
+ data: null,
52
+ action: "retrieve",
53
+ response_status: 404,
54
+ request_id: "60799141-959a-4ff7-80bc-1ad6b805a8fd",
55
+ };
56
+ const crudSubscribeRejected = {
57
+ errors: ["Not found"],
58
+ data: null,
59
+ action: "subscribe",
60
+ response_status: 404,
61
+ request_id: "60799141-959a-4ff7-80bc-1ad6b805a8fd",
62
+ };
63
+ const fields = ["id", "__str__", "name"];
64
+ let objectSubscription;
65
+ beforeEach(() => {
66
+ objectSubscription = useObjectSubscription({
67
+ id: 1,
68
+ retrieveArgs: {
69
+ fields,
70
+ },
71
+ });
72
+ });
73
+ describe("subscribe", function () {
74
+ let crudRetrieveResolve, crudRetrieveReject, crudSubscribeResolve, crudSubscribeReject, crudSubscribePromise;
75
+ beforeEach(() => {
76
+ const crudRetrievePromise = new Promise((resolve, reject) => {
77
+ crudRetrieveResolve = resolve;
78
+ crudRetrieveReject = reject;
79
+ });
80
+ globalRetrieve.mockReturnValueOnce(crudRetrievePromise);
81
+ crudSubscribePromise = new Promise((resolve, reject) => {
82
+ crudSubscribeResolve = resolve;
83
+ crudSubscribeReject = reject;
84
+ });
85
+ crudSubscribePromise.cancel = jest.fn();
86
+ crudSubscribePromise.cancel.mockReturnValueOnce(true).mockReturnValue(false);
87
+ globalSubscribe.mockReturnValueOnce(crudSubscribePromise);
88
+ });
89
+ it("success", async function () {
90
+ expect(objectSubscription.state.loading).toBeUndefined();
91
+ expect(objectSubscription.state.errored).toBe(false);
92
+ expectErrorToBeNull(objectSubscription.state.error);
93
+ expect(objectSubscription.objectInstance.state.deleted).toBe(false);
94
+ expect(objectSubscription.state.subscribed).toBe(false);
95
+ expect(objectSubscription.state.intendToSubscribe).toBe(false);
96
+ expect(objectSubscription.state.intendToRetrieve).toBe(false);
97
+ expect(objectSubscription.objectInstance.state.object).toEqual({});
98
+
99
+ const subscribePromise = objectSubscription.subscribe();
100
+
101
+ expect(objectSubscription.state.loading).toBe(true);
102
+ expect(objectSubscription.state.errored).toBe(false);
103
+ expectErrorToBeNull(objectSubscription.state.error);
104
+ expect(objectSubscription.objectInstance.state.deleted).toBe(false);
105
+ expect(objectSubscription.state.subscribed).toBe(false);
106
+ expect(objectSubscription.state.intendToSubscribe).toBe(true);
107
+ expect(objectSubscription.state.intendToRetrieve).toBe(true);
108
+ expect(objectSubscription.objectInstance.state.object).toEqual({});
109
+ await nextTick();
110
+
111
+ crudRetrieveResolve(crudRetrieveResolved);
112
+ crudSubscribeResolve(crudSubscribeResolved);
113
+ await flushPromises();
114
+
115
+ expect(objectSubscription.state.loading).toBe(false);
116
+ expect(objectSubscription.state.errored).toBe(false);
117
+ expectErrorToBeNull(objectSubscription.state.error);
118
+ expect(objectSubscription.objectInstance.state.deleted).toBe(false);
119
+ expect(objectSubscription.state.subscribed).toBe(true);
120
+ expect(objectSubscription.state.intendToSubscribe).toBe(true);
121
+ expect(objectSubscription.state.intendToRetrieve).toBe(true);
122
+ expect(objectSubscription.objectInstance.state.object).toEqual(crudRetrieveResolved);
123
+ await nextTick();
124
+ await expect(subscribePromise).resolves.toBe(true);
125
+
126
+ expect(globalRetrieve).toHaveBeenCalledWith({
127
+ crudArgs: { stream: "test_stream" },
128
+ id: 1,
129
+ retrieveArgs: {
130
+ fields,
131
+ },
132
+ });
133
+ expect(globalRetrieve).toHaveBeenCalledTimes(1);
134
+ expect(globalSubscribe).toHaveBeenCalledWith({
135
+ crudArgs: { stream: "test_stream" },
136
+ id: 1,
137
+ retrieveArgs: {
138
+ fields,
139
+ },
140
+ callback: expect.any(Function),
141
+ });
142
+ expect(globalSubscribe).toHaveBeenCalledTimes(1);
143
+ });
144
+ it("subscribe callback", async function () {
145
+ globalSubscribe.mockReset();
146
+
147
+ let subscribeCallback;
148
+
149
+ globalSubscribe.mockImplementation(({ callback }) => {
150
+ subscribeCallback = callback;
151
+ return crudSubscribePromise;
152
+ });
153
+
154
+ objectSubscription.objectInstance.updateFromSubscription = jest.fn();
155
+ objectSubscription.objectInstance.deleteFromSubscription = jest.fn();
156
+
157
+ const subscribePromise = objectSubscription.subscribe();
158
+ crudRetrieveResolve(crudRetrieveResolved);
159
+ crudSubscribeResolve(crudSubscribeResolved);
160
+ await expect(subscribePromise).resolves.toBe(true);
161
+
162
+ subscribeCallback({ id: 1, __str__: "!asdf", name: "!zxcv" }, "update");
163
+ subscribeCallback({ id: 1, __str__: "asdf!", name: "zxcv!" }, "create");
164
+ subscribeCallback({ pk: 1 }, "delete");
165
+ expect(objectSubscription.objectInstance.updateFromSubscription).toHaveBeenNthCalledWith(1, {
166
+ id: 1,
167
+ __str__: "!asdf",
168
+ name: "!zxcv",
169
+ });
170
+ expect(objectSubscription.objectInstance.updateFromSubscription).toHaveBeenNthCalledWith(2, {
171
+ id: 1,
172
+ __str__: "asdf!",
173
+ name: "zxcv!",
174
+ });
175
+ expect(objectSubscription.objectInstance.updateFromSubscription).toHaveBeenCalledTimes(2);
176
+ expect(objectSubscription.objectInstance.deleteFromSubscription).toHaveBeenNthCalledWith(1);
177
+ expect(objectSubscription.objectInstance.deleteFromSubscription).toHaveBeenCalledTimes(1);
178
+ });
179
+ it("intendToSubscribe but dont intendToRetrieve", async function () {
180
+ const subscribePromise = objectSubscription.subscribe({ retrieve: false });
181
+ crudSubscribeResolve(crudSubscribeResolved);
182
+ await expect(subscribePromise).resolves.toBe(true);
183
+
184
+ expect(objectSubscription.state.loading).toBe(false);
185
+ expect(objectSubscription.state.errored).toBe(false);
186
+ expectErrorToBeNull(objectSubscription.state.error);
187
+ expect(objectSubscription.objectInstance.state.deleted).toBe(false);
188
+ expect(objectSubscription.state.subscribed).toBe(true);
189
+ expect(objectSubscription.state.intendToSubscribe).toBe(true);
190
+ expect(objectSubscription.state.intendToRetrieve).toBe(false);
191
+ expect(objectSubscription.objectInstance.state.object).toEqual({});
192
+
193
+ expect(globalRetrieve).toHaveBeenCalledTimes(0);
194
+ expect(globalSubscribe).toHaveBeenNthCalledWith(1, {
195
+ crudArgs: { stream: "test_stream" },
196
+ id: 1,
197
+ retrieveArgs: {
198
+ fields,
199
+ },
200
+ callback: expect.any(Function),
201
+ });
202
+ expect(globalSubscribe).toHaveBeenCalledTimes(1);
203
+ });
204
+ it("success (delayed)", async function () {
205
+ objectSubscription.state.retrieveArgs = false;
206
+ objectSubscription.objectInstance.state.retrieveArgs = false;
207
+
208
+ expect(objectSubscription.state.loading).toBeUndefined();
209
+ expect(objectSubscription.state.errored).toBe(false);
210
+ expectErrorToBeNull(objectSubscription.state.error);
211
+ expect(objectSubscription.objectInstance.state.deleted).toBe(false);
212
+ expect(objectSubscription.state.subscribed).toBe(false);
213
+ expect(objectSubscription.state.intendToSubscribe).toBe(false);
214
+ expect(objectSubscription.state.intendToRetrieve).toBe(false);
215
+ expect(objectSubscription.objectInstance.state.object).toEqual({});
216
+
217
+ const subscribePromise = objectSubscription.subscribe();
218
+ await expect(subscribePromise).resolves.toBe(false);
219
+
220
+ expect(objectSubscription.state.loading).toBeUndefined();
221
+ expect(objectSubscription.state.errored).toBe(false);
222
+ expectErrorToBeNull(objectSubscription.state.error);
223
+ expect(objectSubscription.objectInstance.state.deleted).toBe(false);
224
+ expect(objectSubscription.state.subscribed).toBe(false);
225
+ expect(objectSubscription.state.intendToSubscribe).toBe(true);
226
+ expect(objectSubscription.state.intendToRetrieve).toBe(true);
227
+ expect(objectSubscription.objectInstance.state.object).toEqual({});
228
+
229
+ objectSubscription.state.retrieveArgs = { fields };
230
+ objectSubscription.objectInstance.state.retrieveArgs = { fields };
231
+ await nextTick();
232
+
233
+ expect(objectSubscription.state.loading).toBe(true);
234
+ expect(objectSubscription.state.errored).toBe(false);
235
+ expectErrorToBeNull(objectSubscription.state.error);
236
+ expect(objectSubscription.objectInstance.state.deleted).toBe(false);
237
+ expect(objectSubscription.state.subscribed).toBe(false);
238
+ expect(objectSubscription.state.intendToSubscribe).toBe(true);
239
+ expect(objectSubscription.state.intendToRetrieve).toBe(true);
240
+ expect(objectSubscription.objectInstance.state.object).toEqual({});
241
+
242
+ crudRetrieveResolve(crudRetrieveResolved);
243
+ crudSubscribeResolve(crudSubscribeResolved);
244
+ await flushPromises();
245
+
246
+ expect(objectSubscription.state.loading).toBe(false);
247
+ expect(objectSubscription.state.errored).toBe(false);
248
+ expectErrorToBeNull(objectSubscription.state.error);
249
+ expect(objectSubscription.objectInstance.state.deleted).toBe(false);
250
+ expect(objectSubscription.state.subscribed).toBe(true);
251
+ expect(objectSubscription.state.intendToSubscribe).toBe(true);
252
+ expect(objectSubscription.state.intendToRetrieve).toBe(true);
253
+ expect(objectSubscription.objectInstance.state.object).toEqual(crudRetrieveResolved);
254
+ await nextTick();
255
+
256
+ expect(globalRetrieve).toHaveBeenNthCalledWith(1, {
257
+ crudArgs: { stream: "test_stream" },
258
+ id: 1,
259
+ retrieveArgs: {
260
+ fields,
261
+ },
262
+ });
263
+ expect(globalRetrieve).toHaveBeenCalledTimes(1);
264
+ expect(globalSubscribe).toHaveBeenNthCalledWith(1, {
265
+ crudArgs: { stream: "test_stream" },
266
+ id: 1,
267
+ retrieveArgs: {
268
+ fields,
269
+ },
270
+ callback: expect.any(Function),
271
+ });
272
+ expect(globalSubscribe).toHaveBeenCalledTimes(1);
273
+ });
274
+ it("errored (retrieve)", async function () {
275
+ expect(objectSubscription.state.loading).toBeUndefined();
276
+ expect(objectSubscription.state.errored).toBe(false);
277
+ expectErrorToBeNull(objectSubscription.state.error);
278
+ expect(objectSubscription.objectInstance.state.deleted).toBe(false);
279
+ expect(objectSubscription.state.subscribed).toBe(false);
280
+ expect(objectSubscription.state.intendToSubscribe).toBe(false);
281
+ expect(objectSubscription.state.intendToRetrieve).toBe(false);
282
+ expect(objectSubscription.objectInstance.state.object).toEqual({});
283
+
284
+ const subscribePromise = objectSubscription.subscribe();
285
+
286
+ expect(objectSubscription.state.loading).toBe(true);
287
+ expect(objectSubscription.state.errored).toBe(false);
288
+ expectErrorToBeNull(objectSubscription.state.error);
289
+ expect(objectSubscription.objectInstance.state.deleted).toBe(false);
290
+ expect(objectSubscription.state.subscribed).toBe(false);
291
+ expect(objectSubscription.state.intendToSubscribe).toBe(true);
292
+ expect(objectSubscription.state.intendToRetrieve).toBe(true);
293
+ expect(objectSubscription.objectInstance.state.object).toEqual({});
294
+ await nextTick();
295
+
296
+ crudRetrieveReject(crudRetrieveRejected);
297
+ crudSubscribeResolve(crudSubscribeResolved);
298
+ await flushPromises();
299
+
300
+ expect(objectSubscription.state.loading).toBe(false);
301
+ expect(objectSubscription.state.errored).toBe(true);
302
+ expect(objectSubscription.state.error).toEqual(crudRetrieveRejected);
303
+ expect(objectSubscription.objectInstance.state.deleted).toBe(false);
304
+ expect(objectSubscription.state.subscribed).toBe(true);
305
+ expect(objectSubscription.state.intendToSubscribe).toBe(true);
306
+ expect(objectSubscription.state.intendToRetrieve).toBe(true);
307
+ expect(objectSubscription.objectInstance.state.object).toEqual({});
308
+ await expect(subscribePromise).resolves.toBe(true);
309
+ await nextTick();
310
+
311
+ expect(globalRetrieve).toHaveBeenCalledWith({
312
+ crudArgs: { stream: "test_stream" },
313
+ id: 1,
314
+ retrieveArgs: {
315
+ fields,
316
+ },
317
+ });
318
+ expect(globalRetrieve).toHaveBeenCalledTimes(1);
319
+ expect(globalSubscribe).toHaveBeenCalledWith({
320
+ crudArgs: { stream: "test_stream" },
321
+ id: 1,
322
+ retrieveArgs: {
323
+ fields,
324
+ },
325
+ callback: expect.any(Function),
326
+ });
327
+ expect(globalSubscribe).toHaveBeenCalledTimes(1);
328
+ });
329
+ it("errored (subscribe)", async function () {
330
+ expect(objectSubscription.state.loading).toBeUndefined();
331
+ expect(objectSubscription.state.errored).toBe(false);
332
+ expectErrorToBeNull(objectSubscription.state.error);
333
+ expect(objectSubscription.objectInstance.state.deleted).toBe(false);
334
+ expect(objectSubscription.state.subscribed).toBe(false);
335
+ expect(objectSubscription.state.intendToSubscribe).toBe(false);
336
+ expect(objectSubscription.state.intendToRetrieve).toBe(false);
337
+ expect(objectSubscription.objectInstance.state.object).toEqual({});
338
+
339
+ const subscribePromise = objectSubscription.subscribe();
340
+
341
+ expect(objectSubscription.state.loading).toBe(true);
342
+ expect(objectSubscription.state.errored).toBe(false);
343
+ expectErrorToBeNull(objectSubscription.state.error);
344
+ expect(objectSubscription.objectInstance.state.deleted).toBe(false);
345
+ expect(objectSubscription.state.subscribed).toBe(false);
346
+ expect(objectSubscription.state.intendToSubscribe).toBe(true);
347
+ expect(objectSubscription.state.intendToRetrieve).toBe(true);
348
+ expect(objectSubscription.objectInstance.state.object).toEqual({});
349
+ await nextTick();
350
+
351
+ crudRetrieveResolve(crudRetrieveResolved);
352
+ crudSubscribeReject(crudSubscribeRejected);
353
+ await flushPromises();
354
+
355
+ expect(objectSubscription.state.loading).toBe(false);
356
+ expect(objectSubscription.state.errored).toBe(true);
357
+ expect(objectSubscription.state.error).toEqual(crudSubscribeRejected);
358
+ expect(objectSubscription.objectInstance.state.deleted).toBe(false);
359
+ expect(objectSubscription.state.subscribed).toBe(false);
360
+ expect(objectSubscription.state.intendToSubscribe).toBe(true);
361
+ expect(objectSubscription.state.intendToRetrieve).toBe(true);
362
+ expect(objectSubscription.objectInstance.state.object).toEqual(crudRetrieveResolved);
363
+ await expect(subscribePromise).resolves.toBe(false);
364
+ await nextTick();
365
+
366
+ expect(globalRetrieve).toHaveBeenCalledWith({
367
+ crudArgs: { stream: "test_stream" },
368
+ id: 1,
369
+ retrieveArgs: {
370
+ fields,
371
+ },
372
+ });
373
+ expect(globalRetrieve).toHaveBeenCalledTimes(1);
374
+ expect(globalSubscribe).toHaveBeenCalledWith({
375
+ crudArgs: { stream: "test_stream" },
376
+ id: 1,
377
+ retrieveArgs: {
378
+ fields,
379
+ },
380
+ callback: expect.any(Function),
381
+ });
382
+ expect(globalSubscribe).toHaveBeenCalledTimes(1);
383
+ });
384
+ it("already subscribed", async function () {
385
+ expect(objectSubscription.state.loading).toBeUndefined();
386
+ expect(objectSubscription.state.errored).toBe(false);
387
+ expectErrorToBeNull(objectSubscription.state.error);
388
+ expect(objectSubscription.objectInstance.state.deleted).toBe(false);
389
+ expect(objectSubscription.state.subscribed).toBe(false);
390
+ expect(objectSubscription.state.intendToSubscribe).toBe(false);
391
+ expect(objectSubscription.state.intendToRetrieve).toBe(false);
392
+ expect(objectSubscription.objectInstance.state.object).toEqual({});
393
+
394
+ objectSubscription.subscribe();
395
+ const subscribePromise = objectSubscription.subscribe();
396
+ await expect(subscribePromise).rejects.toThrow(ObjectSubscriptionError);
397
+ });
398
+ });
399
+ describe("unsubscribe", function () {
400
+ let crudRetrieveResolve, crudSubscribePromise, crudSubscribeResolve, crudCancelResolve;
401
+ beforeEach(() => {
402
+ const crudRetrievePromise = new Promise((resolve) => {
403
+ crudRetrieveResolve = resolve;
404
+ });
405
+ globalRetrieve.mockReturnValueOnce(crudRetrievePromise);
406
+ crudSubscribePromise = new Promise((resolve) => {
407
+ crudSubscribeResolve = resolve;
408
+ });
409
+ const crudCancelPromise = new Promise((resolve) => {
410
+ crudCancelResolve = resolve;
411
+ });
412
+ crudSubscribePromise.cancel = jest.fn();
413
+ crudSubscribePromise.cancel.mockReturnValueOnce(crudCancelPromise).mockResolvedValue(false);
414
+ globalSubscribe.mockReturnValueOnce(crudSubscribePromise);
415
+ });
416
+ it("success", async function () {
417
+ const subscribePromise = objectSubscription.subscribe();
418
+ crudSubscribeResolve(crudSubscribeResolved);
419
+ crudRetrieveResolve(crudRetrieveResolved);
420
+ await expect(subscribePromise).resolves.toBe(true);
421
+
422
+ expect(objectSubscription.state.loading).toBe(false);
423
+ expect(objectSubscription.state.errored).toBe(false);
424
+ expectErrorToBeNull(objectSubscription.state.error);
425
+ expect(objectSubscription.objectInstance.state.deleted).toBe(false);
426
+ expect(objectSubscription.state.subscribed).toBe(true);
427
+ expect(objectSubscription.state.intendToSubscribe).toBe(true);
428
+ expect(objectSubscription.state.intendToRetrieve).toBe(true);
429
+ expect(objectSubscription.objectInstance.state.object).toEqual(crudRetrieveResolved);
430
+
431
+ const unsubscribePromise = objectSubscription.unsubscribe();
432
+
433
+ expect(objectSubscription.state.loading).toBe(false);
434
+ expect(objectSubscription.state.errored).toBe(false);
435
+ expectErrorToBeNull(objectSubscription.state.error);
436
+ expect(objectSubscription.objectInstance.state.deleted).toBe(false);
437
+ expect(objectSubscription.state.subscribed).toBe(false);
438
+ expect(objectSubscription.state.intendToSubscribe).toBe(false);
439
+ expect(objectSubscription.state.intendToRetrieve).toBe(false);
440
+ expect(objectSubscription.objectInstance.state.object).toEqual(crudRetrieveResolved);
441
+
442
+ crudCancelResolve(true);
443
+
444
+ expect(objectSubscription.state.loading).toBe(false);
445
+ expect(objectSubscription.state.errored).toBe(false);
446
+ expectErrorToBeNull(objectSubscription.state.error);
447
+ expect(objectSubscription.objectInstance.state.deleted).toBe(false);
448
+ expect(objectSubscription.state.subscribed).toBe(false);
449
+ expect(objectSubscription.state.intendToSubscribe).toBe(false);
450
+ expect(objectSubscription.state.intendToRetrieve).toBe(false);
451
+ expect(objectSubscription.objectInstance.state.object).toEqual(crudRetrieveResolved);
452
+
453
+ await expect(unsubscribePromise).resolves.toBe(true);
454
+ });
455
+ it("errored", async function () {
456
+ const subscribePromise = objectSubscription.subscribe();
457
+ crudSubscribeResolve(crudSubscribeResolved);
458
+ crudRetrieveResolve(crudRetrieveResolved);
459
+ await expect(subscribePromise).resolves.toBe(true);
460
+
461
+ expect(objectSubscription.state.loading).toBe(false);
462
+ expect(objectSubscription.state.errored).toBe(false);
463
+ expectErrorToBeNull(objectSubscription.state.error);
464
+ expect(objectSubscription.objectInstance.state.deleted).toBe(false);
465
+ expect(objectSubscription.state.subscribed).toBe(true);
466
+ expect(objectSubscription.state.intendToSubscribe).toBe(true);
467
+ expect(objectSubscription.state.intendToRetrieve).toBe(true);
468
+ expect(objectSubscription.objectInstance.state.object).toEqual(crudRetrieveResolved);
469
+
470
+ const unsubscribePromise = objectSubscription.unsubscribe();
471
+
472
+ expect(objectSubscription.state.loading).toBe(false);
473
+ expect(objectSubscription.state.errored).toBe(false);
474
+ expectErrorToBeNull(objectSubscription.state.error);
475
+ expect(objectSubscription.objectInstance.state.deleted).toBe(false);
476
+ expect(objectSubscription.state.subscribed).toBe(false);
477
+ expect(objectSubscription.state.intendToSubscribe).toBe(false);
478
+ expect(objectSubscription.state.intendToRetrieve).toBe(false);
479
+ expect(objectSubscription.objectInstance.state.object).toEqual(crudRetrieveResolved);
480
+
481
+ crudCancelResolve(false);
482
+
483
+ expect(objectSubscription.state.loading).toBe(false);
484
+ expect(objectSubscription.state.errored).toBe(false);
485
+ expectErrorToBeNull(objectSubscription.state.error);
486
+ expect(objectSubscription.objectInstance.state.deleted).toBe(false);
487
+ expect(objectSubscription.state.subscribed).toBe(false);
488
+ expect(objectSubscription.state.intendToSubscribe).toBe(false);
489
+ expect(objectSubscription.state.intendToRetrieve).toBe(false);
490
+ expect(objectSubscription.objectInstance.state.object).toEqual(crudRetrieveResolved);
491
+
492
+ await expect(unsubscribePromise).resolves.toBe(false);
493
+ });
494
+ it("already unsubscribed", async function () {
495
+ const subscribePromise = objectSubscription.subscribe();
496
+ crudSubscribeResolve(crudSubscribeResolved);
497
+ crudRetrieveResolve(crudRetrieveResolved);
498
+ await expect(subscribePromise).resolves.toBe(true);
499
+
500
+ objectSubscription.unsubscribe();
501
+ const unsubscribePromise = objectSubscription.unsubscribe();
502
+ await expect(unsubscribePromise).resolves.toBe(false);
503
+ });
504
+
505
+ it("not subscribed", async function () {
506
+ const unsubscribePromise = objectSubscription.unsubscribe();
507
+ await expect(unsubscribePromise).resolves.toBe(false);
508
+ });
509
+ });
510
+ describe("custom crud", function () {
511
+ it("custom crud args", async function () {
512
+ let crudRetrieveResolve, crudSubscribeResolve;
513
+ const crudRetrievePromise = new Promise((resolve) => {
514
+ crudRetrieveResolve = resolve;
515
+ });
516
+ globalRetrieve.mockReturnValueOnce(crudRetrievePromise);
517
+ const crudSubscribePromise = new Promise((resolve) => {
518
+ crudSubscribeResolve = resolve;
519
+ });
520
+ crudSubscribePromise.cancel = jest.fn();
521
+ crudSubscribePromise.cancel.mockReturnValueOnce(true).mockReturnValue(false);
522
+ globalSubscribe.mockReturnValueOnce(crudSubscribePromise);
523
+
524
+ const objectSubscription = useObjectSubscription({
525
+ crudArgs: { stream: "test_stream2" },
526
+ id: 1,
527
+ retrieveArgs: {
528
+ fields,
529
+ },
530
+ });
531
+
532
+ const subscribePromise = objectSubscription.subscribe();
533
+ crudRetrieveResolve(crudRetrieveResolved);
534
+ crudSubscribeResolve(crudSubscribeResolved);
535
+ await flushPromises();
536
+ await expect(subscribePromise).resolves.toBe(true);
537
+
538
+ expect(globalRetrieve).toHaveBeenCalledWith({
539
+ crudArgs: { stream: "test_stream2" },
540
+ id: 1,
541
+ retrieveArgs: {
542
+ fields,
543
+ },
544
+ });
545
+ expect(globalRetrieve).toHaveBeenCalledTimes(1);
546
+ expect(globalSubscribe).toHaveBeenCalledWith({
547
+ crudArgs: { stream: "test_stream2" },
548
+ id: 1,
549
+ retrieveArgs: {
550
+ fields,
551
+ },
552
+ callback: expect.any(Function),
553
+ });
554
+ expect(globalSubscribe).toHaveBeenCalledTimes(1);
555
+ });
556
+ it("override subscribe", async function () {
557
+ let crudRetrieveResolve, crudSubscribeResolve;
558
+
559
+ const customCrudRetrieve = jest.fn();
560
+ const customCrudSubscribe = jest.fn();
561
+
562
+ const crudRetrievePromise = new Promise((resolve) => {
563
+ crudRetrieveResolve = resolve;
564
+ });
565
+ customCrudRetrieve.mockReturnValueOnce(crudRetrievePromise);
566
+ const crudSubscribePromise = new Promise((resolve) => {
567
+ crudSubscribeResolve = resolve;
568
+ });
569
+ crudSubscribePromise.cancel = jest.fn();
570
+ crudSubscribePromise.cancel.mockReturnValueOnce(true).mockReturnValue(false);
571
+ customCrudSubscribe.mockReturnValueOnce(crudSubscribePromise);
572
+
573
+ const objectSubscription = useObjectSubscription({
574
+ id: 1,
575
+ retrieveArgs: {
576
+ fields,
577
+ },
578
+ });
579
+ objectSubscription.objectInstance.state.objectInstanceCrud.retrieve = customCrudRetrieve;
580
+ objectSubscription.state.objectSubscriptionCrud.subscribe = customCrudSubscribe;
581
+
582
+ const subscribePromise = objectSubscription.subscribe();
583
+ crudRetrieveResolve(crudRetrieveResolved);
584
+ crudSubscribeResolve(crudSubscribeResolved);
585
+ await flushPromises();
586
+ await expect(subscribePromise).resolves.toBe(true);
587
+
588
+ expect(globalRetrieve).toHaveBeenCalledTimes(0);
589
+ expect(globalSubscribe).toHaveBeenCalledTimes(0);
590
+ expect(customCrudRetrieve).toHaveBeenCalledWith({
591
+ crudArgs: { stream: "test_stream" },
592
+ id: 1,
593
+ retrieveArgs: {
594
+ fields,
595
+ },
596
+ });
597
+ expect(customCrudRetrieve).toHaveBeenCalledTimes(1);
598
+ expect(customCrudSubscribe).toHaveBeenCalledWith({
599
+ crudArgs: { stream: "test_stream" },
600
+ id: 1,
601
+ retrieveArgs: {
602
+ fields,
603
+ },
604
+ callback: expect.any(Function),
605
+ });
606
+ expect(customCrudSubscribe).toHaveBeenCalledTimes(1);
607
+ });
608
+ });
609
+ it("useObjectSubscriptions", async function () {
610
+ const objectSubscriptionA = useObjectSubscription({
611
+ crudArgs: { stream: "test_streamA" },
612
+ id: 1,
613
+ retrieveArgs: {
614
+ fields,
615
+ },
616
+ });
617
+ const objectSubscriptionB = useObjectSubscription({
618
+ crudArgs: { stream: "test_streamB" },
619
+ id: 2,
620
+ retrieveArgs: {
621
+ fields,
622
+ },
623
+ });
624
+ const objSubs = useObjectSubscriptions({
625
+ A: {
626
+ crudArgs: { stream: "test_streamA" },
627
+ id: 1,
628
+ retrieveArgs: {
629
+ fields,
630
+ },
631
+ },
632
+ B: {
633
+ crudArgs: { stream: "test_streamB" },
634
+ id: 2,
635
+ retrieveArgs: {
636
+ fields,
637
+ },
638
+ },
639
+ });
640
+ expect(inspect(objSubs.A)).toEqual(inspect(objectSubscriptionA));
641
+ expect(inspect(objSubs.B)).toEqual(inspect(objectSubscriptionB));
642
+ });
643
+ it("updateFromSubscription", function () {
644
+ const objectSubscription = useObjectSubscription({
645
+ stream: "test_stream",
646
+ });
647
+ assignReactiveObject(objectSubscription.objectInstance.state.object, {
648
+ id: 1,
649
+ __str__: "asdf",
650
+ name: "zxcv",
651
+ });
652
+ objectSubscription.updateFromSubscription({ id: 1, name: "asdf" });
653
+ expect({ ...objectSubscription.objectInstance.state.object }).toEqual({ id: 1, name: "asdf" });
654
+ objectSubscription.updateFromSubscription({ id: 1, __str__: "zxcv" });
655
+ expect({ ...objectSubscription.objectInstance.state.object }).toEqual({ id: 1, __str__: "zxcv" });
656
+ });
657
+ it("deleteFromSubscription", function () {
658
+ const objectSubscription = useObjectSubscription({
659
+ stream: "test_stream",
660
+ });
661
+ assignReactiveObject(objectSubscription.objectInstance.state.object, {
662
+ id: 1,
663
+ __str__: "asdf",
664
+ name: "zxcv",
665
+ });
666
+ expect(objectSubscription.objectInstance.state.deleted).toBe(false);
667
+ objectSubscription.deleteFromSubscription();
668
+ expect(objectSubscription.objectInstance.state.object).toEqual({});
669
+ expect(objectSubscription.objectInstance.state.deleted).toBe(true);
670
+ });
671
+ });