@stream-io/feeds-client 0.2.16 → 0.2.18

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 (82) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/cjs/index.js +1 -1
  3. package/dist/cjs/react-bindings.js +1 -1
  4. package/dist/es/index.mjs +2 -2
  5. package/dist/es/react-bindings.mjs +1 -1
  6. package/dist/{index-CaFrpjpl.js → index--koeDtxd.js} +310 -80
  7. package/dist/index--koeDtxd.js.map +1 -0
  8. package/dist/{index-J3MkoYPN.mjs → index-Zde8UE5f.mjs} +310 -80
  9. package/dist/index-Zde8UE5f.mjs.map +1 -0
  10. package/dist/tsconfig.tsbuildinfo +1 -1
  11. package/dist/types/common/real-time/StableWSConnection.d.ts +3 -3
  12. package/dist/types/feed/event-handlers/activity/handle-activity-added.d.ts +4 -3
  13. package/dist/types/feed/event-handlers/activity/handle-activity-added.d.ts.map +1 -1
  14. package/dist/types/feed/event-handlers/activity/handle-activity-reaction-updated.d.ts +14 -0
  15. package/dist/types/feed/event-handlers/activity/handle-activity-reaction-updated.d.ts.map +1 -0
  16. package/dist/types/feed/event-handlers/activity/handle-activity-updated.d.ts.map +1 -1
  17. package/dist/types/feed/event-handlers/activity/index.d.ts +1 -0
  18. package/dist/types/feed/event-handlers/activity/index.d.ts.map +1 -1
  19. package/dist/types/feed/event-handlers/activity-updater.d.ts +44 -0
  20. package/dist/types/feed/event-handlers/activity-updater.d.ts.map +1 -0
  21. package/dist/types/feed/event-handlers/add-aggregated-activities-to-state.d.ts +6 -0
  22. package/dist/types/feed/event-handlers/add-aggregated-activities-to-state.d.ts.map +1 -0
  23. package/dist/types/feed/event-handlers/comment/handle-comment-reaction-added.d.ts.map +1 -1
  24. package/dist/types/feed/event-handlers/comment/handle-comment-reaction-updated.d.ts +6 -0
  25. package/dist/types/feed/event-handlers/comment/handle-comment-reaction-updated.d.ts.map +1 -0
  26. package/dist/types/feed/event-handlers/comment/index.d.ts +1 -0
  27. package/dist/types/feed/event-handlers/comment/index.d.ts.map +1 -1
  28. package/dist/types/feed/event-handlers/index.d.ts +3 -1
  29. package/dist/types/feed/event-handlers/index.d.ts.map +1 -1
  30. package/dist/types/feed/event-handlers/{aggregated-feed/handle-aggregated-feed-updated.d.ts → notification-feed/handle-notification-feed-updated.d.ts} +2 -11
  31. package/dist/types/feed/event-handlers/notification-feed/handle-notification-feed-updated.d.ts.map +1 -0
  32. package/dist/types/feed/event-handlers/notification-feed/index.d.ts +2 -0
  33. package/dist/types/feed/event-handlers/notification-feed/index.d.ts.map +1 -0
  34. package/dist/types/feed/event-handlers/story-feeds/handle-story-feeds-updated.d.ts +15 -0
  35. package/dist/types/feed/event-handlers/story-feeds/handle-story-feeds-updated.d.ts.map +1 -0
  36. package/dist/types/feed/event-handlers/story-feeds/index.d.ts +2 -0
  37. package/dist/types/feed/event-handlers/story-feeds/index.d.ts.map +1 -0
  38. package/dist/types/feed/feed.d.ts +9 -3
  39. package/dist/types/feed/feed.d.ts.map +1 -1
  40. package/dist/types/feeds-client/feeds-client.d.ts +5 -3
  41. package/dist/types/feeds-client/feeds-client.d.ts.map +1 -1
  42. package/dist/types/gen/feeds/FeedsApi.d.ts.map +1 -1
  43. package/dist/types/gen/models/index.d.ts +43 -452
  44. package/dist/types/gen/models/index.d.ts.map +1 -1
  45. package/dist/types/utils/state-update-queue.d.ts +5 -1
  46. package/dist/types/utils/state-update-queue.d.ts.map +1 -1
  47. package/package.json +1 -1
  48. package/src/feed/event-handlers/activity/handle-activity-added.test.ts +16 -5
  49. package/src/feed/event-handlers/activity/handle-activity-added.ts +9 -11
  50. package/src/feed/event-handlers/activity/handle-activity-reaction-updated.test.ts +282 -0
  51. package/src/feed/event-handlers/activity/handle-activity-reaction-updated.ts +140 -0
  52. package/src/feed/event-handlers/activity/handle-activity-updated.ts +8 -16
  53. package/src/feed/event-handlers/activity/index.ts +1 -0
  54. package/src/feed/event-handlers/activity-updater.ts +15 -0
  55. package/src/feed/event-handlers/add-aggregated-activities-to-state.test.ts +510 -0
  56. package/src/feed/event-handlers/add-aggregated-activities-to-state.ts +72 -0
  57. package/src/feed/event-handlers/comment/handle-comment-reaction-added.ts +1 -2
  58. package/src/feed/event-handlers/comment/handle-comment-reaction-updated.test.ts +350 -0
  59. package/src/feed/event-handlers/comment/handle-comment-reaction-updated.ts +72 -0
  60. package/src/feed/event-handlers/comment/index.ts +1 -1
  61. package/src/feed/event-handlers/index.ts +3 -1
  62. package/src/feed/event-handlers/notification-feed/handle-notification-feed-updated.test.ts +182 -0
  63. package/src/feed/event-handlers/{aggregated-feed/handle-aggregated-feed-updated.ts → notification-feed/handle-notification-feed-updated.ts} +2 -94
  64. package/src/feed/event-handlers/notification-feed/index.ts +1 -0
  65. package/src/feed/event-handlers/story-feeds/handle-story-feeds-updated.test.ts +45 -0
  66. package/src/feed/event-handlers/story-feeds/handle-story-feeds-updated.ts +122 -0
  67. package/src/feed/event-handlers/story-feeds/index.ts +1 -0
  68. package/src/feed/feed.ts +16 -2
  69. package/src/feeds-client/feeds-client.ts +36 -6
  70. package/src/gen/feeds/FeedsApi.ts +5 -0
  71. package/src/gen/model-decoders/decoders.ts +10 -4
  72. package/src/gen/models/index.ts +76 -835
  73. package/src/test-utils/response-generators.ts +89 -1
  74. package/src/utils/state-update-queue.ts +14 -2
  75. package/dist/index-CaFrpjpl.js.map +0 -1
  76. package/dist/index-J3MkoYPN.mjs.map +0 -1
  77. package/dist/types/feed/event-handlers/aggregated-feed/handle-aggregated-feed-updated.d.ts.map +0 -1
  78. package/dist/types/feed/event-handlers/aggregated-feed/index.d.ts +0 -2
  79. package/dist/types/feed/event-handlers/aggregated-feed/index.d.ts.map +0 -1
  80. package/src/feed/event-handlers/activity/activity-utils.test.ts +0 -252
  81. package/src/feed/event-handlers/aggregated-feed/handle-aggregated-feed-updated.test.ts +0 -644
  82. package/src/feed/event-handlers/aggregated-feed/index.ts +0 -1
@@ -1,644 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import type {
3
- NotificationFeedUpdatedEvent,
4
- NotificationStatusResponse,
5
- AggregatedActivityResponse,
6
- } from '../../../gen/models';
7
- import {
8
- updateNotificationFeedFromEvent,
9
- addAggregatedActivitiesToState,
10
- updateNotificationStatus,
11
- } from './handle-aggregated-feed-updated';
12
-
13
- const createMockNotificationFeedUpdatedEvent = (
14
- overrides: Partial<NotificationFeedUpdatedEvent> = {},
15
- ): NotificationFeedUpdatedEvent => ({
16
- created_at: new Date(),
17
- fid: 'user:notification',
18
- custom: {},
19
- type: 'feeds.notification_feed.updated',
20
- ...overrides,
21
- });
22
-
23
- const createMockNotificationStatus = (
24
- overrides: Partial<NotificationStatusResponse> = {},
25
- ): NotificationStatusResponse => ({
26
- unread: 0,
27
- unseen: 0,
28
- ...overrides,
29
- });
30
-
31
- const createMockAggregatedActivity = (
32
- overrides: Partial<AggregatedActivityResponse> = {},
33
- ): AggregatedActivityResponse => ({
34
- activity_count: 1,
35
- created_at: new Date(),
36
- group: 'test-group',
37
- user_count_truncated: false,
38
- score: 1,
39
- updated_at: new Date(),
40
- user_count: 1,
41
- activities: [],
42
- ...overrides,
43
- });
44
-
45
- describe('notification-feed-utils', () => {
46
- describe('updateNotificationFeedFromEvent', () => {
47
- it('should return unchanged if event has no notification_status or aggregated_activities', () => {
48
- const event = createMockNotificationFeedUpdatedEvent();
49
-
50
- const result = updateNotificationFeedFromEvent(event, [], {
51
- unread: 0,
52
- unseen: 0,
53
- read_activities: [],
54
- seen_activities: [],
55
- });
56
-
57
- expect(result.changed).toBe(false);
58
- });
59
-
60
- it(`shouldn't update notification_status when event has notification_status but currentNotificationStatus is undefined`, () => {
61
- const event = createMockNotificationFeedUpdatedEvent({
62
- notification_status: createMockNotificationStatus(),
63
- });
64
- const result = updateNotificationFeedFromEvent(event, [], undefined);
65
-
66
- expect(result.changed).toBe(false);
67
- });
68
-
69
- it(`shouldn't update aggregated_activities when event has aggregated_activities but currentAggregatedActivities is undefined`, () => {
70
- const event = createMockNotificationFeedUpdatedEvent({
71
- aggregated_activities: [createMockAggregatedActivity()],
72
- });
73
- const result = updateNotificationFeedFromEvent(
74
- event,
75
- undefined,
76
- createMockNotificationStatus(),
77
- );
78
-
79
- expect(result.changed).toBe(false);
80
- });
81
-
82
- it('should update notification_status when event has notification_status', () => {
83
- const notificationStatus = createMockNotificationStatus({
84
- unread: 5,
85
- unseen: 3,
86
- read_activities: ['activity1', 'activity2'],
87
- seen_activities: [],
88
- });
89
- const event = createMockNotificationFeedUpdatedEvent({
90
- notification_status: notificationStatus,
91
- });
92
-
93
- const result = updateNotificationFeedFromEvent(event, [], {
94
- unread: 0,
95
- unseen: 0,
96
- read_activities: [],
97
- seen_activities: [],
98
- });
99
-
100
- expect(result.changed).toBe(true);
101
- expect(result.data?.notification_status).toStrictEqual(
102
- notificationStatus,
103
- );
104
- expect(result.data?.aggregated_activities).toBeUndefined();
105
- });
106
-
107
- it('should update aggregated_activities when event has aggregated_activities', () => {
108
- const aggregatedActivities = [
109
- createMockAggregatedActivity({ group: 'group1' }),
110
- createMockAggregatedActivity({ group: 'group2' }),
111
- ];
112
- const event = createMockNotificationFeedUpdatedEvent({
113
- aggregated_activities: aggregatedActivities,
114
- });
115
-
116
- const result = updateNotificationFeedFromEvent(event, [], {
117
- unread: 0,
118
- unseen: 0,
119
- read_activities: [],
120
- seen_activities: [],
121
- });
122
-
123
- expect(result.changed).toBe(true);
124
- expect(result.data?.aggregated_activities).toStrictEqual(
125
- aggregatedActivities,
126
- );
127
- expect(result.data?.notification_status).toBeUndefined();
128
- });
129
-
130
- it('should update both notification_status and aggregated_activities when event has both', () => {
131
- const notificationStatus = createMockNotificationStatus({
132
- unread: 2,
133
- unseen: 1,
134
- });
135
- const aggregatedActivities = [
136
- createMockAggregatedActivity({ group: 'group1' }),
137
- ];
138
- const event = createMockNotificationFeedUpdatedEvent({
139
- notification_status: notificationStatus,
140
- aggregated_activities: aggregatedActivities,
141
- });
142
-
143
- const result = updateNotificationFeedFromEvent(event, [], {
144
- unread: 0,
145
- unseen: 0,
146
- read_activities: [],
147
- seen_activities: [],
148
- });
149
-
150
- expect(result.changed).toBe(true);
151
- expect(result.data?.notification_status?.unread).toBe(
152
- notificationStatus.unread,
153
- );
154
- expect(result.data?.notification_status?.unseen).toBe(
155
- notificationStatus.unseen,
156
- );
157
- expect(result.data?.aggregated_activities).toStrictEqual(
158
- aggregatedActivities,
159
- );
160
- });
161
-
162
- it('should handle notification_status with all fields', () => {
163
- const notificationStatus = createMockNotificationStatus({
164
- unread: 10,
165
- unseen: 5,
166
- last_seen_at: new Date('2023-01-01'),
167
- seen_activities: [],
168
- read_activities: ['activity1', 'activity2', 'activity3'],
169
- });
170
- const event = createMockNotificationFeedUpdatedEvent({
171
- notification_status: notificationStatus,
172
- });
173
-
174
- const result = updateNotificationFeedFromEvent(event, [], {
175
- unread: 0,
176
- unseen: 0,
177
- read_activities: [],
178
- seen_activities: [],
179
- });
180
-
181
- expect(result.changed).toBe(true);
182
- expect(result.data?.notification_status).toStrictEqual(
183
- notificationStatus,
184
- );
185
- });
186
- });
187
-
188
- describe('addAggregatedActivitiesToState', () => {
189
- it('should add new activities when none exist', () => {
190
- const newActivities = [
191
- createMockAggregatedActivity({ group: 'group1' }),
192
- createMockAggregatedActivity({ group: 'group2' }),
193
- ];
194
-
195
- const result = addAggregatedActivitiesToState(
196
- newActivities,
197
- undefined,
198
- 'start',
199
- );
200
-
201
- expect(result.changed).toBe(true);
202
- expect(result.aggregated_activities).toStrictEqual(newActivities);
203
- });
204
-
205
- it('should add new activities to existing ones', () => {
206
- const existingActivities = [
207
- createMockAggregatedActivity({ group: 'existing1' }),
208
- ];
209
- const newActivities = [
210
- createMockAggregatedActivity({ group: 'new1' }),
211
- createMockAggregatedActivity({ group: 'new2' }),
212
- ];
213
-
214
- const result = addAggregatedActivitiesToState(
215
- newActivities,
216
- existingActivities,
217
- 'start',
218
- );
219
-
220
- expect(result.changed).toBe(true);
221
- expect(result.aggregated_activities).toStrictEqual([
222
- ...newActivities,
223
- ...existingActivities,
224
- ]);
225
- });
226
-
227
- it('should add new activities at the end when position is end', () => {
228
- const existingActivities = [
229
- createMockAggregatedActivity({ group: 'existing1' }),
230
- ];
231
- const newActivities = [createMockAggregatedActivity({ group: 'new1' })];
232
-
233
- const result = addAggregatedActivitiesToState(
234
- newActivities,
235
- existingActivities,
236
- 'end',
237
- );
238
-
239
- expect(result.changed).toBe(true);
240
- expect(result.aggregated_activities).toStrictEqual([
241
- ...existingActivities,
242
- ...newActivities,
243
- ]);
244
- });
245
-
246
- it('should update existing activities with same group (upsert)', () => {
247
- const baseDate = new Date('2023-01-01');
248
- const existingActivities = [
249
- createMockAggregatedActivity({
250
- group: 'group1',
251
- activity_count: 1,
252
- score: 10,
253
- updated_at: baseDate,
254
- }),
255
- createMockAggregatedActivity({
256
- group: 'group2',
257
- activity_count: 2,
258
- score: 20,
259
- }),
260
- ];
261
- const newActivities = [
262
- createMockAggregatedActivity({
263
- group: 'group1',
264
- activity_count: 3,
265
- score: 30,
266
- updated_at: new Date('2023-01-02'),
267
- }),
268
- createMockAggregatedActivity({
269
- group: 'group3',
270
- activity_count: 4,
271
- score: 40,
272
- }),
273
- ];
274
-
275
- const result = addAggregatedActivitiesToState(
276
- newActivities,
277
- existingActivities,
278
- 'start',
279
- );
280
-
281
- expect(result.changed).toBe(true);
282
- expect(result.aggregated_activities).toHaveLength(3);
283
-
284
- // Check that group1 was updated
285
- const updatedGroup1 = result.aggregated_activities.find(
286
- (a) => a.group === 'group1',
287
- );
288
- expect(updatedGroup1?.activity_count).toBe(3);
289
- expect(updatedGroup1?.score).toBe(30);
290
- expect(updatedGroup1?.updated_at).toEqual(new Date('2023-01-02'));
291
-
292
- // Check that group2 remains unchanged
293
- const unchangedGroup2 = result.aggregated_activities.find(
294
- (a) => a.group === 'group2',
295
- );
296
- expect(unchangedGroup2?.activity_count).toBe(2);
297
- expect(unchangedGroup2?.score).toBe(20);
298
-
299
- // Check that group3 was added
300
- const newGroup3 = result.aggregated_activities.find(
301
- (a) => a.group === 'group3',
302
- );
303
- expect(newGroup3?.activity_count).toBe(4);
304
- expect(newGroup3?.score).toBe(40);
305
- });
306
-
307
- it('should handle mixed new and existing activities', () => {
308
- const existingActivities = [
309
- createMockAggregatedActivity({ group: 'existing1' }),
310
- createMockAggregatedActivity({ group: 'existing2' }),
311
- ];
312
- const newActivities = [
313
- createMockAggregatedActivity({ group: 'existing1', activity_count: 5 }), // Update existing
314
- createMockAggregatedActivity({ group: 'new1' }), // Add new
315
- createMockAggregatedActivity({ group: 'existing2', score: 100 }), // Update existing
316
- createMockAggregatedActivity({ group: 'new2' }), // Add new
317
- ];
318
-
319
- const result = addAggregatedActivitiesToState(
320
- newActivities,
321
- existingActivities,
322
- 'start',
323
- );
324
-
325
- expect(result.changed).toBe(true);
326
- expect(result.aggregated_activities).toHaveLength(4);
327
-
328
- // Check that existing1 was updated
329
- const updatedExisting1 = result.aggregated_activities.find(
330
- (a) => a.group === 'existing1',
331
- );
332
- expect(updatedExisting1?.activity_count).toBe(5);
333
-
334
- // Check that existing2 was updated
335
- const updatedExisting2 = result.aggregated_activities.find(
336
- (a) => a.group === 'existing2',
337
- );
338
- expect(updatedExisting2?.score).toBe(100);
339
-
340
- // Check that new activities were added
341
- expect(
342
- result.aggregated_activities.find((a) => a.group === 'new1'),
343
- ).toBeDefined();
344
- expect(
345
- result.aggregated_activities.find((a) => a.group === 'new2'),
346
- ).toBeDefined();
347
- });
348
-
349
- it('should preserve order when adding at start', () => {
350
- const existingActivities = [
351
- createMockAggregatedActivity({ group: 'existing1' }),
352
- createMockAggregatedActivity({ group: 'existing2' }),
353
- ];
354
- const newActivities = [
355
- createMockAggregatedActivity({ group: 'new1' }),
356
- createMockAggregatedActivity({ group: 'new2' }),
357
- ];
358
-
359
- const result = addAggregatedActivitiesToState(
360
- newActivities,
361
- existingActivities,
362
- 'start',
363
- );
364
-
365
- expect(result.aggregated_activities).toStrictEqual([
366
- ...newActivities,
367
- ...existingActivities,
368
- ]);
369
- });
370
-
371
- it('should preserve order when adding at end', () => {
372
- const existingActivities = [
373
- createMockAggregatedActivity({ group: 'existing1' }),
374
- createMockAggregatedActivity({ group: 'existing2' }),
375
- ];
376
- const newActivities = [
377
- createMockAggregatedActivity({ group: 'new1' }),
378
- createMockAggregatedActivity({ group: 'new2' }),
379
- ];
380
-
381
- const result = addAggregatedActivitiesToState(
382
- newActivities,
383
- existingActivities,
384
- 'end',
385
- );
386
-
387
- expect(result.aggregated_activities).toStrictEqual([
388
- ...existingActivities,
389
- ...newActivities,
390
- ]);
391
- });
392
-
393
- describe('replace position', () => {
394
- it('should replace existing activities with same group', () => {
395
- const baseDate = new Date('2023-01-01');
396
- const existingActivities = [
397
- createMockAggregatedActivity({
398
- group: 'group1',
399
- activity_count: 1,
400
- score: 10,
401
- updated_at: baseDate,
402
- }),
403
- createMockAggregatedActivity({
404
- group: 'group2',
405
- activity_count: 2,
406
- score: 20,
407
- updated_at: baseDate,
408
- }),
409
- ];
410
- const newActivities = [
411
- createMockAggregatedActivity({
412
- group: 'group1',
413
- activity_count: 3,
414
- score: 30,
415
- updated_at: new Date('2023-01-02'),
416
- }),
417
- createMockAggregatedActivity({
418
- group: 'group3',
419
- activity_count: 4,
420
- score: 40,
421
- updated_at: new Date('2023-01-02'),
422
- }),
423
- ];
424
-
425
- const result = addAggregatedActivitiesToState(
426
- newActivities,
427
- existingActivities,
428
- 'replace',
429
- );
430
-
431
- expect(result.changed).toBe(true);
432
- expect(result.aggregated_activities).toHaveLength(3);
433
-
434
- // Check that group1 was replaced
435
- const replacedGroup1 = result.aggregated_activities.find(
436
- (a) => a.group === 'group1',
437
- );
438
- expect(replacedGroup1?.activity_count).toBe(3);
439
- expect(replacedGroup1?.score).toBe(30);
440
- expect(replacedGroup1?.updated_at).toEqual(new Date('2023-01-02'));
441
-
442
- // Check that group2 remains unchanged
443
- const unchangedGroup2 = result.aggregated_activities.find(
444
- (a) => a.group === 'group2',
445
- );
446
- expect(unchangedGroup2?.activity_count).toBe(2);
447
- expect(unchangedGroup2?.score).toBe(20);
448
- expect(unchangedGroup2?.updated_at).toEqual(baseDate);
449
-
450
- // Check that group3 was added
451
- const newGroup3 = result.aggregated_activities.find(
452
- (a) => a.group === 'group3',
453
- );
454
- expect(newGroup3?.activity_count).toBe(4);
455
- expect(newGroup3?.score).toBe(40);
456
- expect(newGroup3?.updated_at).toEqual(new Date('2023-01-02'));
457
- });
458
-
459
- it('should preserve order of existing activities when replacing', () => {
460
- const existingActivities = [
461
- createMockAggregatedActivity({ group: 'group1', activity_count: 1 }),
462
- createMockAggregatedActivity({ group: 'group2', activity_count: 2 }),
463
- createMockAggregatedActivity({ group: 'group3', activity_count: 3 }),
464
- ];
465
- const newActivities = [
466
- createMockAggregatedActivity({ group: 'group2', activity_count: 20 }),
467
- createMockAggregatedActivity({ group: 'group1', activity_count: 10 }),
468
- ];
469
-
470
- const result = addAggregatedActivitiesToState(
471
- newActivities,
472
- existingActivities,
473
- 'replace',
474
- );
475
-
476
- expect(result.changed).toBe(true);
477
- expect(result.aggregated_activities).toHaveLength(3);
478
-
479
- // Check that order is preserved
480
- expect(result.aggregated_activities[0].group).toBe('group1');
481
- expect(result.aggregated_activities[0].activity_count).toBe(10);
482
- expect(result.aggregated_activities[1].group).toBe('group2');
483
- expect(result.aggregated_activities[1].activity_count).toBe(20);
484
- expect(result.aggregated_activities[2].group).toBe('group3');
485
- expect(result.aggregated_activities[2].activity_count).toBe(3);
486
- });
487
-
488
- it('should add new activities at the end when replacing', () => {
489
- const existingActivities = [
490
- createMockAggregatedActivity({ group: 'group1', activity_count: 1 }),
491
- createMockAggregatedActivity({ group: 'group2', activity_count: 2 }),
492
- ];
493
- const newActivities = [
494
- createMockAggregatedActivity({ group: 'group1', activity_count: 10 }),
495
- createMockAggregatedActivity({ group: 'group3', activity_count: 3 }),
496
- createMockAggregatedActivity({ group: 'group4', activity_count: 4 }),
497
- ];
498
-
499
- const result = addAggregatedActivitiesToState(
500
- newActivities,
501
- existingActivities,
502
- 'replace',
503
- );
504
-
505
- expect(result.changed).toBe(true);
506
- expect(result.aggregated_activities).toHaveLength(4);
507
-
508
- // Check that existing activities are in their original positions
509
- expect(result.aggregated_activities[0].group).toBe('group1');
510
- expect(result.aggregated_activities[0].activity_count).toBe(10);
511
- expect(result.aggregated_activities[1].group).toBe('group2');
512
- expect(result.aggregated_activities[1].activity_count).toBe(2);
513
-
514
- // Check that new activities are added at the end
515
- expect(result.aggregated_activities[2].group).toBe('group3');
516
- expect(result.aggregated_activities[2].activity_count).toBe(3);
517
- expect(result.aggregated_activities[3].group).toBe('group4');
518
- expect(result.aggregated_activities[3].activity_count).toBe(4);
519
- });
520
-
521
- it('should handle empty new activities', () => {
522
- const existingActivities = [
523
- createMockAggregatedActivity({ group: 'group1', activity_count: 1 }),
524
- createMockAggregatedActivity({ group: 'group2', activity_count: 2 }),
525
- ];
526
-
527
- const result = addAggregatedActivitiesToState(
528
- [],
529
- existingActivities,
530
- 'replace',
531
- );
532
-
533
- expect(result.changed).toBe(false);
534
- expect(result.aggregated_activities).toStrictEqual(existingActivities);
535
- });
536
-
537
- it('should handle both arrays being empty', () => {
538
- const result = addAggregatedActivitiesToState([], [], 'replace');
539
-
540
- expect(result.changed).toBe(false);
541
- expect(result.aggregated_activities).toStrictEqual([]);
542
- });
543
-
544
- it('should replace multiple activities with same groups', () => {
545
- const existingActivities = [
546
- createMockAggregatedActivity({
547
- group: 'group1',
548
- activity_count: 1,
549
- score: 10,
550
- }),
551
- createMockAggregatedActivity({
552
- group: 'group2',
553
- activity_count: 2,
554
- score: 20,
555
- }),
556
- createMockAggregatedActivity({
557
- group: 'group3',
558
- activity_count: 3,
559
- score: 30,
560
- }),
561
- ];
562
- const newActivities = [
563
- createMockAggregatedActivity({
564
- group: 'group1',
565
- activity_count: 10,
566
- score: 100,
567
- }),
568
- createMockAggregatedActivity({
569
- group: 'group3',
570
- activity_count: 30,
571
- score: 300,
572
- }),
573
- createMockAggregatedActivity({
574
- group: 'group4',
575
- activity_count: 4,
576
- score: 40,
577
- }),
578
- ];
579
-
580
- const result = addAggregatedActivitiesToState(
581
- newActivities,
582
- existingActivities,
583
- 'replace',
584
- );
585
-
586
- expect(result.changed).toBe(true);
587
- expect(result.aggregated_activities).toHaveLength(4);
588
-
589
- // Check that group1 was replaced
590
- const replacedGroup1 = result.aggregated_activities.find(
591
- (a) => a.group === 'group1',
592
- );
593
- expect(replacedGroup1?.activity_count).toBe(10);
594
- expect(replacedGroup1?.score).toBe(100);
595
-
596
- // Check that group2 remains unchanged
597
- const unchangedGroup2 = result.aggregated_activities.find(
598
- (a) => a.group === 'group2',
599
- );
600
- expect(unchangedGroup2?.activity_count).toBe(2);
601
- expect(unchangedGroup2?.score).toBe(20);
602
-
603
- // Check that group3 was replaced
604
- const replacedGroup3 = result.aggregated_activities.find(
605
- (a) => a.group === 'group3',
606
- );
607
- expect(replacedGroup3?.activity_count).toBe(30);
608
- expect(replacedGroup3?.score).toBe(300);
609
-
610
- // Check that group4 was added
611
- const newGroup4 = result.aggregated_activities.find(
612
- (a) => a.group === 'group4',
613
- );
614
- expect(newGroup4?.activity_count).toBe(4);
615
- expect(newGroup4?.score).toBe(40);
616
- });
617
- });
618
- });
619
-
620
- describe('updateNotificationStatus', () => {
621
- it('should replace old state with new one', () => {
622
- const newNotificationStatus = createMockNotificationStatus({
623
- unread: 5,
624
- unseen: 3,
625
- read_activities: ['activity1', 'activity2'],
626
- seen_activities: ['activity3', 'activity4'],
627
- });
628
-
629
- const currentNotificationStatus = createMockNotificationStatus({
630
- unread: 2,
631
- unseen: 1,
632
- read_activities: ['activity5', 'activity6'],
633
- seen_activities: ['activity7', 'activity8'],
634
- });
635
-
636
- const result = updateNotificationStatus(
637
- newNotificationStatus,
638
- currentNotificationStatus,
639
- );
640
-
641
- expect(result.notification_status).toStrictEqual(newNotificationStatus);
642
- });
643
- });
644
- });
@@ -1 +0,0 @@
1
- export * from './handle-aggregated-feed-updated';