@stream-io/feeds-client 0.2.17 → 0.2.19

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 (117) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/cjs/index.js +94 -25
  3. package/dist/cjs/index.js.map +1 -1
  4. package/dist/cjs/react-bindings.js +26 -55
  5. package/dist/cjs/react-bindings.js.map +1 -1
  6. package/dist/es/index.mjs +86 -17
  7. package/dist/es/index.mjs.map +1 -1
  8. package/dist/es/react-bindings.mjs +19 -48
  9. package/dist/es/react-bindings.mjs.map +1 -1
  10. package/dist/{index-nq6SDtbt.js → feeds-client-C09giTf1.js} +322 -133
  11. package/dist/feeds-client-C09giTf1.js.map +1 -0
  12. package/dist/{index-BZL77zNq.mjs → feeds-client-CFadXO-B.mjs} +335 -146
  13. package/dist/feeds-client-CFadXO-B.mjs.map +1 -0
  14. package/dist/tsconfig.tsbuildinfo +1 -1
  15. package/dist/types/bindings/react/hooks/feed-state-hooks/useOwnCapabilities.d.ts +2 -32
  16. package/dist/types/bindings/react/hooks/feed-state-hooks/useOwnCapabilities.d.ts.map +1 -1
  17. package/dist/types/common/real-time/StableWSConnection.d.ts +3 -3
  18. package/dist/types/common/real-time/event-models.d.ts +7 -2
  19. package/dist/types/common/real-time/event-models.d.ts.map +1 -1
  20. package/dist/types/common/types.d.ts +1 -0
  21. package/dist/types/common/types.d.ts.map +1 -1
  22. package/dist/types/feed/event-handlers/activity/handle-activity-added.d.ts +4 -3
  23. package/dist/types/feed/event-handlers/activity/handle-activity-added.d.ts.map +1 -1
  24. package/dist/types/feed/event-handlers/activity/handle-activity-updated.d.ts.map +1 -1
  25. package/dist/types/feed/event-handlers/activity-updater.d.ts +44 -0
  26. package/dist/types/feed/event-handlers/activity-updater.d.ts.map +1 -0
  27. package/dist/types/feed/event-handlers/add-aggregated-activities-to-state.d.ts +6 -0
  28. package/dist/types/feed/event-handlers/add-aggregated-activities-to-state.d.ts.map +1 -0
  29. package/dist/types/feed/event-handlers/index.d.ts +3 -1
  30. package/dist/types/feed/event-handlers/index.d.ts.map +1 -1
  31. package/dist/types/feed/event-handlers/{aggregated-feed/handle-aggregated-feed-updated.d.ts → notification-feed/handle-notification-feed-updated.d.ts} +2 -11
  32. package/dist/types/feed/event-handlers/notification-feed/handle-notification-feed-updated.d.ts.map +1 -0
  33. package/dist/types/feed/event-handlers/notification-feed/index.d.ts +2 -0
  34. package/dist/types/feed/event-handlers/notification-feed/index.d.ts.map +1 -0
  35. package/dist/types/feed/event-handlers/story-feeds/handle-story-feeds-updated.d.ts +15 -0
  36. package/dist/types/feed/event-handlers/story-feeds/handle-story-feeds-updated.d.ts.map +1 -0
  37. package/dist/types/feed/event-handlers/story-feeds/index.d.ts +2 -0
  38. package/dist/types/feed/event-handlers/story-feeds/index.d.ts.map +1 -0
  39. package/dist/types/feed/feed.d.ts +10 -4
  40. package/dist/types/feed/feed.d.ts.map +1 -1
  41. package/dist/types/feeds-client/feeds-client.d.ts +14 -4
  42. package/dist/types/feeds-client/feeds-client.d.ts.map +1 -1
  43. package/dist/types/gen/feeds/FeedsApi.d.ts.map +1 -1
  44. package/dist/types/gen/models/index.d.ts +42 -451
  45. package/dist/types/gen/models/index.d.ts.map +1 -1
  46. package/dist/types/utils/throttling/index.d.ts +3 -0
  47. package/dist/types/utils/throttling/index.d.ts.map +1 -0
  48. package/dist/types/utils/throttling/throttle.d.ts +34 -0
  49. package/dist/types/utils/throttling/throttle.d.ts.map +1 -0
  50. package/dist/types/utils/throttling/throttled-get-batched-own-capabilities.d.ts +14 -0
  51. package/dist/types/utils/throttling/throttled-get-batched-own-capabilities.d.ts.map +1 -0
  52. package/package.json +7 -3
  53. package/react-bindings.d.ts +11 -0
  54. package/react-bindings.js +7 -0
  55. package/react-bindings.mjs +11 -0
  56. package/src/bindings/react/hooks/feed-state-hooks/useOwnCapabilities.ts +21 -73
  57. package/src/common/real-time/event-models.ts +8 -2
  58. package/src/common/types.ts +1 -0
  59. package/src/feed/event-handlers/activity/handle-activity-added.ts +18 -12
  60. package/src/feed/event-handlers/activity/handle-activity-updated.ts +12 -16
  61. package/src/feed/event-handlers/activity-updater.ts +15 -0
  62. package/src/feed/event-handlers/add-aggregated-activities-to-state.ts +72 -0
  63. package/src/feed/event-handlers/index.ts +3 -1
  64. package/src/feed/event-handlers/{aggregated-feed/handle-aggregated-feed-updated.ts → notification-feed/handle-notification-feed-updated.ts} +2 -94
  65. package/src/feed/event-handlers/notification-feed/index.ts +1 -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 +30 -3
  69. package/src/feeds-client/feeds-client.ts +127 -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 +75 -834
  73. package/src/test-utils/response-generators.ts +37 -1
  74. package/src/utils/throttling/index.ts +2 -0
  75. package/src/utils/throttling/throttle.ts +123 -0
  76. package/src/utils/throttling/throttled-get-batched-own-capabilities.ts +42 -0
  77. package/dist/index-BZL77zNq.mjs.map +0 -1
  78. package/dist/index-nq6SDtbt.js.map +0 -1
  79. package/dist/types/feed/event-handlers/aggregated-feed/handle-aggregated-feed-updated.d.ts.map +0 -1
  80. package/dist/types/feed/event-handlers/aggregated-feed/index.d.ts +0 -2
  81. package/dist/types/feed/event-handlers/aggregated-feed/index.d.ts.map +0 -1
  82. package/src/feed/event-handlers/activity/activity-marked-utils.test.ts +0 -208
  83. package/src/feed/event-handlers/activity/activity-reaction-utils.test.ts +0 -371
  84. package/src/feed/event-handlers/activity/activity-utils.test.ts +0 -252
  85. package/src/feed/event-handlers/activity/handle-activity-added.test.ts +0 -86
  86. package/src/feed/event-handlers/activity/handle-activity-deleted.test.ts +0 -117
  87. package/src/feed/event-handlers/activity/handle-activity-pinned.test.ts +0 -60
  88. package/src/feed/event-handlers/activity/handle-activity-reaction-added.test.ts +0 -257
  89. package/src/feed/event-handlers/activity/handle-activity-reaction-deleted.test.ts +0 -317
  90. package/src/feed/event-handlers/activity/handle-activity-reaction-updated.test.ts +0 -282
  91. package/src/feed/event-handlers/activity/handle-activity-unpinned.test.ts +0 -95
  92. package/src/feed/event-handlers/activity/handle-activity-updated.test.ts +0 -245
  93. package/src/feed/event-handlers/aggregated-feed/handle-aggregated-feed-updated.test.ts +0 -644
  94. package/src/feed/event-handlers/aggregated-feed/index.ts +0 -1
  95. package/src/feed/event-handlers/bookmark/bookmark-utils.test.ts +0 -521
  96. package/src/feed/event-handlers/bookmark/handle-bookmark-added.test.ts +0 -178
  97. package/src/feed/event-handlers/bookmark/handle-bookmark-deleted.test.ts +0 -188
  98. package/src/feed/event-handlers/bookmark/handle-bookmark-updated.test.ts +0 -196
  99. package/src/feed/event-handlers/comment/handle-comment-added.test.ts +0 -271
  100. package/src/feed/event-handlers/comment/handle-comment-deleted.test.ts +0 -255
  101. package/src/feed/event-handlers/comment/handle-comment-reaction-added.test.ts +0 -329
  102. package/src/feed/event-handlers/comment/handle-comment-reaction-deleted.test.ts +0 -343
  103. package/src/feed/event-handlers/comment/handle-comment-reaction-updated.test.ts +0 -350
  104. package/src/feed/event-handlers/comment/handle-comment-updated.test.ts +0 -267
  105. package/src/feed/event-handlers/comment/utils/update-comment-count.test.ts +0 -322
  106. package/src/feed/event-handlers/feed-member/handle-feed-member-added.test.ts +0 -75
  107. package/src/feed/event-handlers/feed-member/handle-feed-member-removed.test.ts +0 -82
  108. package/src/feed/event-handlers/feed-member/handle-feed-member-updated.test.ts +0 -84
  109. package/src/feed/event-handlers/follow/follow-state-update-queue.test.ts +0 -219
  110. package/src/feed/event-handlers/follow/handle-follow-created.test.ts +0 -250
  111. package/src/feed/event-handlers/follow/handle-follow-deleted.test.ts +0 -268
  112. package/src/feed/event-handlers/follow/handle-follow-updated.test.ts +0 -131
  113. package/src/feed/feed.test.ts +0 -90
  114. package/src/feeds-client/event-handlers/user/handle-user-updated.test.ts +0 -53
  115. package/src/utils/event-triggered-by-connected-user.test.ts +0 -73
  116. package/src/utils/state-update-queue.test.ts +0 -129
  117. package/src/utils/unique-array-merge.test.ts +0 -179
@@ -1,268 +0,0 @@
1
- import type {
2
- FollowResponse,
3
- FeedResponse,
4
- UserResponse,
5
- } from '../../../gen/models';
6
- import { generateFollowResponse } from '../../../test-utils';
7
- import { updateStateFollowDeleted } from './handle-follow-deleted';
8
-
9
- import { describe, it, expect, beforeEach } from 'vitest';
10
-
11
- describe('handle-follow-deleted', () => {
12
- describe(updateStateFollowDeleted.name, () => {
13
- let mockFollow: FollowResponse;
14
- let mockFeed: FeedResponse;
15
- let mockUser: UserResponse;
16
-
17
- beforeEach(() => {
18
- mockFollow = generateFollowResponse();
19
- mockFeed = mockFollow.source_feed;
20
- mockUser = mockFeed.created_by;
21
- });
22
-
23
- it('should handle when this feed unfollows someone', () => {
24
- const existingFollow: FollowResponse = {
25
- ...mockFollow,
26
- source_feed: {
27
- ...mockFeed,
28
- id: 'feed-1',
29
- feed: 'user:feed-1',
30
- created_by: mockUser,
31
- },
32
- target_feed: {
33
- ...mockFeed,
34
- id: 'other-feed',
35
- feed: 'user:other-feed',
36
- created_by: mockUser,
37
- },
38
- };
39
-
40
- const follow: FollowResponse = existingFollow;
41
-
42
- // @ts-expect-error - we're not testing the full state here
43
- const currentState: FeedState = {
44
- following: [existingFollow],
45
- following_count: 1,
46
- };
47
-
48
- const result = updateStateFollowDeleted(
49
- follow,
50
- currentState,
51
- 'user:feed-1',
52
- 'user-1',
53
- );
54
-
55
- expect(result.changed).toBe(true);
56
- expect(result.data.following).toHaveLength(0);
57
- expect(result.data).toMatchObject(follow.source_feed);
58
- });
59
-
60
- it('should handle when someone unfollows this feed', () => {
61
- const existingFollow: FollowResponse = {
62
- ...mockFollow,
63
- source_feed: {
64
- ...mockFeed,
65
- id: 'other-feed',
66
- feed: 'user:other-feed',
67
- created_by: {
68
- ...mockUser,
69
- id: 'other-user',
70
- },
71
- },
72
- target_feed: {
73
- ...mockFeed,
74
- id: 'feed-1',
75
- feed: 'user:feed-1',
76
- created_by: mockUser,
77
- },
78
- };
79
-
80
- const follow: FollowResponse = existingFollow;
81
-
82
- // @ts-expect-error - we're not testing the full state here
83
- const currentState: FeedState = {
84
- followers: [existingFollow],
85
- own_follows: [existingFollow],
86
- following_count: 1,
87
- };
88
-
89
- const result = updateStateFollowDeleted(
90
- follow,
91
- currentState,
92
- 'user:feed-1',
93
- 'user-1',
94
- );
95
-
96
- expect(result.changed).toBe(true);
97
- expect(result.data.followers).toHaveLength(0);
98
- expect(result.data.own_follows).toBe(currentState.own_follows);
99
- expect(result.data).toMatchObject(follow.target_feed);
100
- });
101
-
102
- it('should only remove own_follows when connected user is the source', () => {
103
- const existingFollow: FollowResponse = {
104
- ...mockFollow,
105
- source_feed: {
106
- ...mockFeed,
107
- id: 'other-feed',
108
- feed: 'user:other-feed',
109
- created_by: { ...mockUser, id: 'user-1' },
110
- },
111
- target_feed: {
112
- ...mockFeed,
113
- id: 'feed-1',
114
- feed: 'user:feed-1',
115
- created_by: mockUser,
116
- },
117
- };
118
-
119
- const follow: FollowResponse = existingFollow;
120
-
121
- // @ts-expect-error - we're not testing the full state here
122
- const currentState: FeedState = {
123
- followers: [existingFollow],
124
- own_follows: [existingFollow],
125
- following_count: 1,
126
- };
127
-
128
- const result = updateStateFollowDeleted(
129
- follow,
130
- currentState,
131
- 'user:feed-1',
132
- 'user-1',
133
- );
134
-
135
- expect(result.changed).toBe(true);
136
- expect(result.data.followers).toHaveLength(0);
137
- expect(result.data.own_follows).toHaveLength(0);
138
- });
139
-
140
- it('should not remove own_follows when connected user is not the source', () => {
141
- const existingFollow: FollowResponse = {
142
- ...mockFollow,
143
- source_feed: {
144
- ...mockFeed,
145
- id: 'other-feed',
146
- feed: 'user:other-feed',
147
- created_by: { ...mockUser, id: 'other-user' },
148
- },
149
- target_feed: {
150
- ...mockFeed,
151
- id: 'feed-1',
152
- feed: 'user:feed-1',
153
- created_by: mockUser,
154
- },
155
- };
156
-
157
- const follow: FollowResponse = existingFollow;
158
-
159
- // @ts-expect-error - we're not testing the full state here
160
- const currentState: FeedState = {
161
- followers: [existingFollow],
162
- own_follows: [existingFollow],
163
- };
164
-
165
- const result = updateStateFollowDeleted(
166
- follow,
167
- currentState,
168
- 'user:feed-1',
169
- 'user-1',
170
- );
171
-
172
- expect(result.changed).toBe(true);
173
- expect(result.data.followers).toHaveLength(0);
174
- expect(result.data.own_follows).toHaveLength(1); // Should remain unchanged
175
- });
176
-
177
- it('should not update followers/following when they are undefined in delete', () => {
178
- const existingFollow: FollowResponse = {
179
- ...mockFollow,
180
- source_feed: {
181
- ...mockFeed,
182
- id: 'other-feed',
183
- feed: 'user:other-feed',
184
- created_by: mockUser,
185
- },
186
- target_feed: {
187
- ...mockFeed,
188
- id: 'feed-1',
189
- feed: 'user:feed-1',
190
- created_by: mockUser,
191
- },
192
- };
193
-
194
- const follow: FollowResponse = existingFollow;
195
-
196
- // @ts-expect-error - we're not testing the full state here
197
- const currentState: FeedState = {
198
- followers: undefined,
199
- own_follows: undefined,
200
- };
201
-
202
- const result = updateStateFollowDeleted(
203
- follow,
204
- currentState,
205
- 'user:feed-1',
206
- 'user-1',
207
- );
208
-
209
- expect(result.changed).toBe(true);
210
- expect(result.data.followers).toBeUndefined();
211
- expect(result.data.own_follows).toBeUndefined();
212
- expect(result.data).toMatchObject(follow.target_feed);
213
- });
214
-
215
- it('should filter out the correct follow by target feed id', () => {
216
- const followToRemove: FollowResponse = {
217
- ...mockFollow,
218
- source_feed: {
219
- ...mockFeed,
220
- id: 'feed-1',
221
- feed: 'user:feed-1',
222
- created_by: mockUser,
223
- },
224
- target_feed: {
225
- ...mockFeed,
226
- id: 'target-to-remove',
227
- feed: 'user:target-to-remove',
228
- created_by: mockUser,
229
- },
230
- };
231
-
232
- const followToKeep: FollowResponse = {
233
- ...mockFollow,
234
- source_feed: {
235
- ...mockFeed,
236
- id: 'feed-1',
237
- feed: 'user:feed-1',
238
- created_by: mockUser,
239
- },
240
- target_feed: {
241
- ...mockFeed,
242
- id: 'target-to-keep',
243
- feed: 'user:target-to-keep',
244
- created_by: mockUser,
245
- },
246
- };
247
-
248
- const follow: FollowResponse = followToRemove;
249
-
250
- // @ts-expect-error - we're not testing the full state here
251
- const currentState: FeedState = {
252
- following: [followToRemove, followToKeep],
253
- following_count: 2,
254
- };
255
-
256
- const result = updateStateFollowDeleted(
257
- follow,
258
- currentState,
259
- 'user:feed-1',
260
- 'user-1',
261
- );
262
-
263
- expect(result.changed).toBe(true);
264
- expect(result.data.following).toHaveLength(1);
265
- expect(result.data.following?.[0]).toBe(followToKeep);
266
- });
267
- });
268
- });
@@ -1,131 +0,0 @@
1
- import { describe, it, expect, beforeEach } from 'vitest';
2
- import { Feed } from '../../../feed';
3
- import { FeedsClient } from '../../../feeds-client';
4
- import { handleFollowUpdated } from './handle-follow-updated';
5
- import {
6
- generateFollowResponse,
7
- generateFeedResponse,
8
- getHumanId,
9
- generateOwnUser,
10
- } from '../../../test-utils/response-generators';
11
- import type { FollowResponse } from '../../../gen/models';
12
-
13
- describe(handleFollowUpdated.name, () => {
14
- let feed: Feed;
15
- let client: FeedsClient;
16
- let follow: FollowResponse;
17
- let otherFollow: FollowResponse;
18
- let ownFollow: FollowResponse;
19
- let userId: string;
20
-
21
- beforeEach(() => {
22
- userId = getHumanId();
23
- client = new FeedsClient('mock-api-key');
24
-
25
- client.state.partialNext({
26
- connected_user: generateOwnUser({ id: userId }),
27
- });
28
-
29
- const feedResponse = generateFeedResponse({
30
- id: 'main',
31
- group_id: 'user',
32
- created_by: { id: userId },
33
- });
34
- feed = new Feed(client, 'user', 'main', feedResponse);
35
- // Setup follows
36
- follow = generateFollowResponse({
37
- source_feed: generateFeedResponse({
38
- id: 'main',
39
- group_id: 'user',
40
- created_by: { id: userId },
41
- }),
42
- target_feed: generateFeedResponse({
43
- id: 'target',
44
- group_id: 'user',
45
- }),
46
- });
47
-
48
- otherFollow = generateFollowResponse({
49
- source_feed: generateFeedResponse({
50
- id: 'other',
51
- group_id: 'user',
52
- created_by: { id: getHumanId() },
53
- }),
54
- target_feed: generateFeedResponse({
55
- id: 'main',
56
- group_id: 'user',
57
- }),
58
- });
59
-
60
- ownFollow = generateFollowResponse({
61
- source_feed: generateFeedResponse({
62
- id: 'other',
63
- group_id: 'user',
64
- created_by: { id: userId },
65
- }),
66
- target_feed: generateFeedResponse({
67
- id: 'main',
68
- group_id: 'user',
69
- }),
70
- });
71
- // Set up initial state
72
- feed.state.next((currentState) => ({
73
- ...currentState,
74
- following: [follow],
75
- followers: [otherFollow],
76
- own_follows: [ownFollow],
77
- }));
78
- });
79
-
80
- it('updates a follow in following when this feed is the source', () => {
81
- const updatedFollow: FollowResponse = { ...follow, status: 'pending' };
82
-
83
- handleFollowUpdated.call(feed, { follow: updatedFollow });
84
-
85
- const [updatedFollowAfter] = feed.currentState.following!;
86
-
87
- expect(updatedFollowAfter).toBe(updatedFollow);
88
- });
89
-
90
- it('updates a follow in followers when this feed is the target', () => {
91
- const updatedOtherFollow: FollowResponse = {
92
- ...otherFollow,
93
- status: 'rejected',
94
- };
95
-
96
- handleFollowUpdated.call(feed, { follow: updatedOtherFollow });
97
-
98
- const [updatedOtherFollowAfter] = feed.currentState.followers!;
99
-
100
- expect(updatedOtherFollowAfter).toBe(updatedOtherFollow);
101
- });
102
-
103
- it('updates a follow in own_follows when connected user is the creator', () => {
104
- const updatedOwnFollow: FollowResponse = {
105
- ...ownFollow,
106
- status: 'pending',
107
- };
108
-
109
- handleFollowUpdated.call(feed, { follow: updatedOwnFollow });
110
-
111
- const [ownFollowAfter] = feed.currentState.own_follows!;
112
-
113
- expect(ownFollowAfter).toBe(updatedOwnFollow);
114
- });
115
-
116
- it('does not update if follow is not found', () => {
117
- const unrelatedFollow = generateFollowResponse();
118
-
119
- const stateBefore = feed.currentState;
120
-
121
- handleFollowUpdated.call(feed, { follow: unrelatedFollow });
122
-
123
- const stateAfter = feed.currentState;
124
-
125
- expect(stateAfter.own_follows).toBe(stateBefore.own_follows);
126
- expect(stateAfter.followers).toBe(stateBefore.followers);
127
- expect(stateAfter.follower_count).toBe(stateBefore.follower_count);
128
- expect(stateAfter.following).toBe(stateBefore.following);
129
- expect(stateAfter.following_count).toBe(stateBefore.following_count);
130
- });
131
- });
@@ -1,90 +0,0 @@
1
- import { beforeEach, describe, expect, it } from 'vitest';
2
- import { FeedsClient } from '../feeds-client';
3
- import { Feed } from './feed';
4
- import type { ActivityResponse } from '../gen/models';
5
- import { generateActivityResponse, generateFeedResponse } from '../test-utils';
6
-
7
- describe('Feed derived state updates', () => {
8
- let feed: Feed;
9
- let client: FeedsClient;
10
- let activities: ActivityResponse[];
11
-
12
- beforeEach(() => {
13
- client = new FeedsClient('mock-api-key');
14
- const feedResponse = generateFeedResponse({ id: 'main', group_id: 'user' });
15
- feed = new Feed(
16
- client,
17
- feedResponse.group_id,
18
- feedResponse.id,
19
- feedResponse,
20
- );
21
- activities = [
22
- generateActivityResponse(),
23
- generateActivityResponse(),
24
- generateActivityResponse(),
25
- ];
26
- });
27
-
28
- it('should update the cache if activities change in feed.state', () => {
29
- let indexedActivityIds = (feed as any).indexedActivityIds;
30
- expect(indexedActivityIds.size).toEqual(0);
31
-
32
- feed.state.partialNext({ activities });
33
-
34
- indexedActivityIds = (feed as any).indexedActivityIds;
35
- expect(indexedActivityIds.size).toEqual(3);
36
- for (const activity of activities) {
37
- expect(indexedActivityIds.has(activity.id)).toBe(true);
38
- }
39
- });
40
-
41
- it('should update the cache if activities are further updated', () => {
42
- // Include all of them
43
- feed.state.partialNext({ activities });
44
-
45
- let indexedActivityIds = (feed as any).indexedActivityIds;
46
- expect(indexedActivityIds.size).toEqual(3);
47
- for (const activity of activities) {
48
- expect(indexedActivityIds.has(activity.id)).toBe(true);
49
- }
50
-
51
- // Take only the last 2
52
- const newActivities = activities.slice(1);
53
- feed.state.partialNext({ activities: newActivities });
54
-
55
- indexedActivityIds = (feed as any).indexedActivityIds;
56
- expect((feed as any).indexedActivityIds.size).toEqual(2);
57
- for (const activity of newActivities) {
58
- expect(indexedActivityIds.has(activity.id)).toBe(true);
59
- }
60
-
61
- // Include all of them again
62
- feed.state.partialNext({ activities });
63
-
64
- indexedActivityIds = (feed as any).indexedActivityIds;
65
- expect(indexedActivityIds.size).toEqual(3);
66
- for (const activity of activities) {
67
- expect(indexedActivityIds.has(activity.id)).toBe(true);
68
- }
69
- });
70
-
71
- it('should not update the cache if the length of activities has not changed', () => {
72
- feed.state.partialNext({ activities });
73
-
74
- const indexedActivityIdsBefore = (feed as any).indexedActivityIds;
75
- expect(indexedActivityIdsBefore.size).toEqual(3);
76
- for (const activity of activities) {
77
- expect(indexedActivityIdsBefore.has(activity.id)).toBe(true);
78
- }
79
-
80
- const reversedActivities = activities.toReversed();
81
- feed.state.partialNext({ activities: reversedActivities });
82
-
83
- const indexedActivityIdsAfter = (feed as any).indexedActivityIds;
84
- expect(indexedActivityIdsAfter.size).toEqual(3);
85
- for (const activity of activities) {
86
- expect(indexedActivityIdsAfter.has(activity.id)).toBe(true);
87
- }
88
- expect(indexedActivityIdsBefore).toBe(indexedActivityIdsAfter);
89
- });
90
- });
@@ -1,53 +0,0 @@
1
- import { describe, it, beforeEach, expect } from 'vitest';
2
-
3
- import { FeedsClient, handleUserUpdated } from '../..';
4
- import { generateOwnUser, generateUserResponse } from '../../../test-utils';
5
- import type { EventPayload } from '../../../types-internal';
6
-
7
- describe('handleUserUpdated', () => {
8
- let feedsClient: FeedsClient;
9
-
10
- beforeEach(() => {
11
- feedsClient = new FeedsClient('mock-api-key');
12
- const connectedUser = generateOwnUser();
13
-
14
- feedsClient.state.partialNext({ connected_user: connectedUser });
15
- });
16
-
17
- it('should update the connected user in the state', () => {
18
- const stateBefore = feedsClient.state.getLatestValue();
19
-
20
- const event: EventPayload<'user.updated'> = {
21
- type: 'user.updated',
22
- created_at: new Date(),
23
- custom: {},
24
- user: {
25
- ...generateUserResponse(),
26
- ...stateBefore.connected_user!,
27
- },
28
- };
29
-
30
- handleUserUpdated.call(feedsClient, event);
31
-
32
- const stateAfter = feedsClient.state.getLatestValue();
33
-
34
- expect(stateAfter.connected_user).toMatchObject({ name: event.user.name });
35
- });
36
-
37
- it('should not update the connected user if the incoming event contains other user', () => {
38
- const event: EventPayload<'user.updated'> = {
39
- type: 'user.updated',
40
- created_at: new Date(),
41
- custom: {},
42
- user: generateUserResponse(),
43
- };
44
-
45
- const stateBefore = feedsClient.state.getLatestValue();
46
-
47
- handleUserUpdated.call(feedsClient, event);
48
-
49
- const stateAfter = feedsClient.state.getLatestValue();
50
-
51
- expect(stateAfter.connected_user).toBe(stateBefore.connected_user);
52
- });
53
- });
@@ -1,73 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
-
3
- import { eventTriggeredByConnectedUser as eventTriggeredByConnectedUserInternal } from './event-triggered-by-connected-user';
4
- import { FeedsClient } from '../feeds-client';
5
- import { Feed } from '../feed';
6
- import {
7
- generateFeedResponse,
8
- generateOwnUser, generateUserResponse,
9
- getHumanId,
10
- } from '../test-utils';
11
-
12
- describe('eventTriggeredByConnectedUser', () => {
13
- let feed: Feed;
14
- let client: FeedsClient;
15
- let currentUserId: string;
16
-
17
- let eventTriggeredByConnectedUser: OmitThisParameter<typeof eventTriggeredByConnectedUserInternal>
18
-
19
- beforeEach(() => {
20
- client = new FeedsClient('mock-api-key');
21
- currentUserId = getHumanId();
22
-
23
- client.state.partialNext({
24
- connected_user: generateOwnUser({ id: currentUserId }),
25
- });
26
-
27
- const feedResponse = generateFeedResponse({
28
- id: 'main',
29
- group_id: 'user',
30
- created_by: { id: currentUserId },
31
- });
32
-
33
- feed = new Feed(
34
- client,
35
- feedResponse.group_id,
36
- feedResponse.id,
37
- feedResponse,
38
- );
39
-
40
- eventTriggeredByConnectedUser = eventTriggeredByConnectedUserInternal.bind(feed);
41
- });
42
-
43
- afterEach(() => {
44
- vi.resetAllMocks();
45
- })
46
-
47
- it('returns true when payload.user.id matches connected_user.id', () => {
48
- const user = generateUserResponse({ id: currentUserId });
49
- const result = eventTriggeredByConnectedUser({ user });
50
- expect(result).toBe(true);
51
- });
52
-
53
- it('returns true when payload.user is undefined and connected_user exists', () => {
54
- const result = eventTriggeredByConnectedUser({});
55
- expect(result).toBe(true);
56
- });
57
-
58
- it('returns false when payload.user.id differs from connected_user.id', () => {
59
- const user = generateUserResponse({ id: getHumanId() });
60
- const result = eventTriggeredByConnectedUser({ user });
61
- expect(result).toBe(false);
62
- });
63
-
64
- it('returns false when connected_user is undefined (even if payload.user present)', () => {
65
- // @ts-expect-error using protected value only in tests
66
- feed.client.state.partialNext({ connected_user: undefined });
67
- const user = generateUserResponse({ id: currentUserId });
68
- const result1 = eventTriggeredByConnectedUser({ user });
69
- const result2 = eventTriggeredByConnectedUser({});
70
- expect(result1).toBe(false);
71
- expect(result2).toBe(false);
72
- });
73
- });