@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.
- package/CHANGELOG.md +24 -0
- package/dist/cjs/index.js +94 -25
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/react-bindings.js +26 -55
- package/dist/cjs/react-bindings.js.map +1 -1
- package/dist/es/index.mjs +86 -17
- package/dist/es/index.mjs.map +1 -1
- package/dist/es/react-bindings.mjs +19 -48
- package/dist/es/react-bindings.mjs.map +1 -1
- package/dist/{index-nq6SDtbt.js → feeds-client-C09giTf1.js} +322 -133
- package/dist/feeds-client-C09giTf1.js.map +1 -0
- package/dist/{index-BZL77zNq.mjs → feeds-client-CFadXO-B.mjs} +335 -146
- package/dist/feeds-client-CFadXO-B.mjs.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/bindings/react/hooks/feed-state-hooks/useOwnCapabilities.d.ts +2 -32
- package/dist/types/bindings/react/hooks/feed-state-hooks/useOwnCapabilities.d.ts.map +1 -1
- package/dist/types/common/real-time/StableWSConnection.d.ts +3 -3
- package/dist/types/common/real-time/event-models.d.ts +7 -2
- package/dist/types/common/real-time/event-models.d.ts.map +1 -1
- package/dist/types/common/types.d.ts +1 -0
- package/dist/types/common/types.d.ts.map +1 -1
- package/dist/types/feed/event-handlers/activity/handle-activity-added.d.ts +4 -3
- package/dist/types/feed/event-handlers/activity/handle-activity-added.d.ts.map +1 -1
- package/dist/types/feed/event-handlers/activity/handle-activity-updated.d.ts.map +1 -1
- package/dist/types/feed/event-handlers/activity-updater.d.ts +44 -0
- package/dist/types/feed/event-handlers/activity-updater.d.ts.map +1 -0
- package/dist/types/feed/event-handlers/add-aggregated-activities-to-state.d.ts +6 -0
- package/dist/types/feed/event-handlers/add-aggregated-activities-to-state.d.ts.map +1 -0
- package/dist/types/feed/event-handlers/index.d.ts +3 -1
- package/dist/types/feed/event-handlers/index.d.ts.map +1 -1
- package/dist/types/feed/event-handlers/{aggregated-feed/handle-aggregated-feed-updated.d.ts → notification-feed/handle-notification-feed-updated.d.ts} +2 -11
- package/dist/types/feed/event-handlers/notification-feed/handle-notification-feed-updated.d.ts.map +1 -0
- package/dist/types/feed/event-handlers/notification-feed/index.d.ts +2 -0
- package/dist/types/feed/event-handlers/notification-feed/index.d.ts.map +1 -0
- package/dist/types/feed/event-handlers/story-feeds/handle-story-feeds-updated.d.ts +15 -0
- package/dist/types/feed/event-handlers/story-feeds/handle-story-feeds-updated.d.ts.map +1 -0
- package/dist/types/feed/event-handlers/story-feeds/index.d.ts +2 -0
- package/dist/types/feed/event-handlers/story-feeds/index.d.ts.map +1 -0
- package/dist/types/feed/feed.d.ts +10 -4
- package/dist/types/feed/feed.d.ts.map +1 -1
- package/dist/types/feeds-client/feeds-client.d.ts +14 -4
- package/dist/types/feeds-client/feeds-client.d.ts.map +1 -1
- package/dist/types/gen/feeds/FeedsApi.d.ts.map +1 -1
- package/dist/types/gen/models/index.d.ts +42 -451
- package/dist/types/gen/models/index.d.ts.map +1 -1
- package/dist/types/utils/throttling/index.d.ts +3 -0
- package/dist/types/utils/throttling/index.d.ts.map +1 -0
- package/dist/types/utils/throttling/throttle.d.ts +34 -0
- package/dist/types/utils/throttling/throttle.d.ts.map +1 -0
- package/dist/types/utils/throttling/throttled-get-batched-own-capabilities.d.ts +14 -0
- package/dist/types/utils/throttling/throttled-get-batched-own-capabilities.d.ts.map +1 -0
- package/package.json +7 -3
- package/react-bindings.d.ts +11 -0
- package/react-bindings.js +7 -0
- package/react-bindings.mjs +11 -0
- package/src/bindings/react/hooks/feed-state-hooks/useOwnCapabilities.ts +21 -73
- package/src/common/real-time/event-models.ts +8 -2
- package/src/common/types.ts +1 -0
- package/src/feed/event-handlers/activity/handle-activity-added.ts +18 -12
- package/src/feed/event-handlers/activity/handle-activity-updated.ts +12 -16
- package/src/feed/event-handlers/activity-updater.ts +15 -0
- package/src/feed/event-handlers/add-aggregated-activities-to-state.ts +72 -0
- package/src/feed/event-handlers/index.ts +3 -1
- package/src/feed/event-handlers/{aggregated-feed/handle-aggregated-feed-updated.ts → notification-feed/handle-notification-feed-updated.ts} +2 -94
- package/src/feed/event-handlers/notification-feed/index.ts +1 -0
- package/src/feed/event-handlers/story-feeds/handle-story-feeds-updated.ts +122 -0
- package/src/feed/event-handlers/story-feeds/index.ts +1 -0
- package/src/feed/feed.ts +30 -3
- package/src/feeds-client/feeds-client.ts +127 -6
- package/src/gen/feeds/FeedsApi.ts +5 -0
- package/src/gen/model-decoders/decoders.ts +10 -4
- package/src/gen/models/index.ts +75 -834
- package/src/test-utils/response-generators.ts +37 -1
- package/src/utils/throttling/index.ts +2 -0
- package/src/utils/throttling/throttle.ts +123 -0
- package/src/utils/throttling/throttled-get-batched-own-capabilities.ts +42 -0
- package/dist/index-BZL77zNq.mjs.map +0 -1
- package/dist/index-nq6SDtbt.js.map +0 -1
- package/dist/types/feed/event-handlers/aggregated-feed/handle-aggregated-feed-updated.d.ts.map +0 -1
- package/dist/types/feed/event-handlers/aggregated-feed/index.d.ts +0 -2
- package/dist/types/feed/event-handlers/aggregated-feed/index.d.ts.map +0 -1
- package/src/feed/event-handlers/activity/activity-marked-utils.test.ts +0 -208
- package/src/feed/event-handlers/activity/activity-reaction-utils.test.ts +0 -371
- package/src/feed/event-handlers/activity/activity-utils.test.ts +0 -252
- package/src/feed/event-handlers/activity/handle-activity-added.test.ts +0 -86
- package/src/feed/event-handlers/activity/handle-activity-deleted.test.ts +0 -117
- package/src/feed/event-handlers/activity/handle-activity-pinned.test.ts +0 -60
- package/src/feed/event-handlers/activity/handle-activity-reaction-added.test.ts +0 -257
- package/src/feed/event-handlers/activity/handle-activity-reaction-deleted.test.ts +0 -317
- package/src/feed/event-handlers/activity/handle-activity-reaction-updated.test.ts +0 -282
- package/src/feed/event-handlers/activity/handle-activity-unpinned.test.ts +0 -95
- package/src/feed/event-handlers/activity/handle-activity-updated.test.ts +0 -245
- package/src/feed/event-handlers/aggregated-feed/handle-aggregated-feed-updated.test.ts +0 -644
- package/src/feed/event-handlers/aggregated-feed/index.ts +0 -1
- package/src/feed/event-handlers/bookmark/bookmark-utils.test.ts +0 -521
- package/src/feed/event-handlers/bookmark/handle-bookmark-added.test.ts +0 -178
- package/src/feed/event-handlers/bookmark/handle-bookmark-deleted.test.ts +0 -188
- package/src/feed/event-handlers/bookmark/handle-bookmark-updated.test.ts +0 -196
- package/src/feed/event-handlers/comment/handle-comment-added.test.ts +0 -271
- package/src/feed/event-handlers/comment/handle-comment-deleted.test.ts +0 -255
- package/src/feed/event-handlers/comment/handle-comment-reaction-added.test.ts +0 -329
- package/src/feed/event-handlers/comment/handle-comment-reaction-deleted.test.ts +0 -343
- package/src/feed/event-handlers/comment/handle-comment-reaction-updated.test.ts +0 -350
- package/src/feed/event-handlers/comment/handle-comment-updated.test.ts +0 -267
- package/src/feed/event-handlers/comment/utils/update-comment-count.test.ts +0 -322
- package/src/feed/event-handlers/feed-member/handle-feed-member-added.test.ts +0 -75
- package/src/feed/event-handlers/feed-member/handle-feed-member-removed.test.ts +0 -82
- package/src/feed/event-handlers/feed-member/handle-feed-member-updated.test.ts +0 -84
- package/src/feed/event-handlers/follow/follow-state-update-queue.test.ts +0 -219
- package/src/feed/event-handlers/follow/handle-follow-created.test.ts +0 -250
- package/src/feed/event-handlers/follow/handle-follow-deleted.test.ts +0 -268
- package/src/feed/event-handlers/follow/handle-follow-updated.test.ts +0 -131
- package/src/feed/feed.test.ts +0 -90
- package/src/feeds-client/event-handlers/user/handle-user-updated.test.ts +0 -53
- package/src/utils/event-triggered-by-connected-user.test.ts +0 -73
- package/src/utils/state-update-queue.test.ts +0 -129
- 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
|
-
});
|
package/src/feed/feed.test.ts
DELETED
|
@@ -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
|
-
});
|