@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,252 +0,0 @@
|
|
|
1
|
-
import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
-
import type { ActivityResponse } from '../../../gen/models';
|
|
3
|
-
import { FeedsClient } from '../../../feeds-client';
|
|
4
|
-
import {
|
|
5
|
-
addActivitiesToState as addActivitiesToStateOriginal,
|
|
6
|
-
updateActivityInState,
|
|
7
|
-
removeActivityFromState as removeActivityFromStateOriginal,
|
|
8
|
-
} from './';
|
|
9
|
-
import {
|
|
10
|
-
generateActivityResponse,
|
|
11
|
-
generateFeedReactionResponse,
|
|
12
|
-
} from '../../../test-utils';
|
|
13
|
-
|
|
14
|
-
describe('activity-utils', () => {
|
|
15
|
-
let addActivitiesToState: OmitThisParameter<
|
|
16
|
-
typeof addActivitiesToStateOriginal
|
|
17
|
-
>;
|
|
18
|
-
let removeActivityFromState: OmitThisParameter<
|
|
19
|
-
typeof removeActivityFromStateOriginal
|
|
20
|
-
>;
|
|
21
|
-
let prehydrateActivities: (
|
|
22
|
-
newActivities: ActivityResponse[],
|
|
23
|
-
) => ActivityResponse[];
|
|
24
|
-
|
|
25
|
-
beforeEach(() => {
|
|
26
|
-
const client = new FeedsClient('mock-api-key');
|
|
27
|
-
const feed = client.feed('some', 'feed');
|
|
28
|
-
|
|
29
|
-
addActivitiesToState = addActivitiesToStateOriginal.bind(feed);
|
|
30
|
-
removeActivityFromState = removeActivityFromStateOriginal.bind(feed);
|
|
31
|
-
|
|
32
|
-
prehydrateActivities = (newActivities: ActivityResponse[]) => {
|
|
33
|
-
const existingActivities = [...newActivities];
|
|
34
|
-
|
|
35
|
-
feed.state.partialNext({ activities: existingActivities });
|
|
36
|
-
|
|
37
|
-
return existingActivities;
|
|
38
|
-
};
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
afterEach(() => {
|
|
42
|
-
vi.resetAllMocks();
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
describe('addActivitiesToState', () => {
|
|
46
|
-
const activity1 = generateActivityResponse({ id: 'activity1' });
|
|
47
|
-
const activity2 = generateActivityResponse({ id: 'activity2' });
|
|
48
|
-
|
|
49
|
-
it('should add activities to empty state', () => {
|
|
50
|
-
const result = addActivitiesToState([activity1], undefined, 'start');
|
|
51
|
-
|
|
52
|
-
expect(result.changed).toBe(true);
|
|
53
|
-
expect(result.activities).toHaveLength(1);
|
|
54
|
-
expect(result.activities[0].id).toBe('activity1');
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
it('should add activities to the start of existing activities', () => {
|
|
58
|
-
const existingActivities = prehydrateActivities([activity2]);
|
|
59
|
-
const result = addActivitiesToState(
|
|
60
|
-
[activity1],
|
|
61
|
-
existingActivities,
|
|
62
|
-
'start',
|
|
63
|
-
);
|
|
64
|
-
|
|
65
|
-
expect(result.changed).toBe(true);
|
|
66
|
-
expect(result.activities).toHaveLength(2);
|
|
67
|
-
expect(result.activities[0].id).toBe('activity1');
|
|
68
|
-
expect(result.activities[1].id).toBe('activity2');
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
it('should add activities to the end of existing activities', () => {
|
|
72
|
-
const existingActivities = prehydrateActivities([activity1]);
|
|
73
|
-
const result = addActivitiesToState(
|
|
74
|
-
[activity2],
|
|
75
|
-
existingActivities,
|
|
76
|
-
'end',
|
|
77
|
-
);
|
|
78
|
-
|
|
79
|
-
expect(result.changed).toBe(true);
|
|
80
|
-
expect(result.activities).toHaveLength(2);
|
|
81
|
-
expect(result.activities[0].id).toBe('activity1');
|
|
82
|
-
expect(result.activities[1].id).toBe('activity2');
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
it('should not add duplicate activities', () => {
|
|
86
|
-
const existingActivities = prehydrateActivities([activity1]);
|
|
87
|
-
const result = addActivitiesToState(
|
|
88
|
-
[activity1],
|
|
89
|
-
existingActivities,
|
|
90
|
-
'start',
|
|
91
|
-
);
|
|
92
|
-
|
|
93
|
-
expect(result.changed).toBe(false);
|
|
94
|
-
expect(result.activities).toHaveLength(1);
|
|
95
|
-
expect(result.activities[0].id).toBe('activity1');
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
it('should handle multiple new activities correctly', () => {
|
|
99
|
-
const activity3 = generateActivityResponse({ id: 'activity3' });
|
|
100
|
-
|
|
101
|
-
const existingActivities = prehydrateActivities([activity1]);
|
|
102
|
-
const result = addActivitiesToState(
|
|
103
|
-
[activity2, activity3],
|
|
104
|
-
existingActivities,
|
|
105
|
-
'start',
|
|
106
|
-
);
|
|
107
|
-
|
|
108
|
-
expect(result.changed).toBe(true);
|
|
109
|
-
expect(result.activities).toHaveLength(3);
|
|
110
|
-
expect(result.activities[0].id).toBe('activity2');
|
|
111
|
-
expect(result.activities[1].id).toBe('activity3');
|
|
112
|
-
expect(result.activities[2].id).toBe('activity1');
|
|
113
|
-
});
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
describe('updateActivityInState', () => {
|
|
117
|
-
it('should update an activity in the state', () => {
|
|
118
|
-
const originalActivity = generateActivityResponse({
|
|
119
|
-
id: 'activity1',
|
|
120
|
-
text: 'original text',
|
|
121
|
-
});
|
|
122
|
-
const updatedActivity = { ...originalActivity, text: 'updated text' };
|
|
123
|
-
const originalActivities = [originalActivity];
|
|
124
|
-
|
|
125
|
-
const result = updateActivityInState(
|
|
126
|
-
{
|
|
127
|
-
activity: updatedActivity,
|
|
128
|
-
created_at: new Date(),
|
|
129
|
-
fid: '',
|
|
130
|
-
type: '',
|
|
131
|
-
custom: {},
|
|
132
|
-
},
|
|
133
|
-
originalActivities,
|
|
134
|
-
);
|
|
135
|
-
|
|
136
|
-
expect(result.changed).toBe(true);
|
|
137
|
-
expect(result.entities).toHaveLength(1);
|
|
138
|
-
expect(result.entities![0].id).toBe('activity1');
|
|
139
|
-
expect(result.entities![0].text).toBe('updated text');
|
|
140
|
-
|
|
141
|
-
// Make sure we create a new array
|
|
142
|
-
expect(originalActivities === result.entities).toBe(false);
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
it('should preserve reaction data (own_reaction) when updating an activity', () => {
|
|
146
|
-
const r = generateFeedReactionResponse({
|
|
147
|
-
activity_id: 'activity1',
|
|
148
|
-
user: {
|
|
149
|
-
id: 'user1',
|
|
150
|
-
},
|
|
151
|
-
});
|
|
152
|
-
const originalActivity = generateActivityResponse({
|
|
153
|
-
id: 'activity1',
|
|
154
|
-
text: 'original text',
|
|
155
|
-
own_reactions: [r],
|
|
156
|
-
latest_reactions: [r],
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
const updatedActivity = generateActivityResponse({
|
|
160
|
-
id: 'activity1',
|
|
161
|
-
text: 'updated text',
|
|
162
|
-
own_reactions: [],
|
|
163
|
-
latest_reactions: [
|
|
164
|
-
r,
|
|
165
|
-
generateFeedReactionResponse({
|
|
166
|
-
activity_id: 'activity1',
|
|
167
|
-
user: { id: 'user2' },
|
|
168
|
-
}),
|
|
169
|
-
],
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
const result = updateActivityInState(
|
|
173
|
-
{
|
|
174
|
-
activity: updatedActivity,
|
|
175
|
-
created_at: new Date(),
|
|
176
|
-
fid: '',
|
|
177
|
-
type: '',
|
|
178
|
-
custom: {},
|
|
179
|
-
},
|
|
180
|
-
[originalActivity],
|
|
181
|
-
);
|
|
182
|
-
|
|
183
|
-
expect(result.changed).toBe(true);
|
|
184
|
-
expect(result.entities![0].text).toBe('updated text');
|
|
185
|
-
// Check that reactions were preserved
|
|
186
|
-
expect(result.entities![0].own_reactions).toEqual(
|
|
187
|
-
originalActivity.own_reactions,
|
|
188
|
-
);
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
it('should return unchanged state if activity not found', () => {
|
|
192
|
-
const existingActivity = generateActivityResponse({ id: 'activity1' });
|
|
193
|
-
const updatedActivity = generateActivityResponse({
|
|
194
|
-
id: 'activity2',
|
|
195
|
-
text: 'some text',
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
const result = updateActivityInState(
|
|
199
|
-
{
|
|
200
|
-
activity: updatedActivity,
|
|
201
|
-
created_at: new Date(),
|
|
202
|
-
fid: '',
|
|
203
|
-
type: '',
|
|
204
|
-
custom: {},
|
|
205
|
-
},
|
|
206
|
-
[existingActivity],
|
|
207
|
-
);
|
|
208
|
-
|
|
209
|
-
expect(result.changed).toBe(false);
|
|
210
|
-
expect(result.entities).toHaveLength(1);
|
|
211
|
-
expect(result.entities![0].id).toBe('activity1');
|
|
212
|
-
});
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
describe('removeActivityFromState', () => {
|
|
216
|
-
it('should remove an activity from the state', () => {
|
|
217
|
-
const activity1 = generateActivityResponse({ id: 'activity1' });
|
|
218
|
-
const activity2 = generateActivityResponse({ id: 'activity2' });
|
|
219
|
-
const activities = prehydrateActivities([activity1, activity2]);
|
|
220
|
-
|
|
221
|
-
const result = removeActivityFromState(activity1, activities);
|
|
222
|
-
|
|
223
|
-
expect(result.changed).toBe(true);
|
|
224
|
-
expect(result.activities).toHaveLength(1);
|
|
225
|
-
expect(result.activities![0].id).toBe('activity2');
|
|
226
|
-
// Make sure we create a new array
|
|
227
|
-
expect(activities === result.activities).toBe(false);
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
it('should return unchanged state if activity not found', () => {
|
|
231
|
-
const activity1 = generateActivityResponse({ id: 'activity1' });
|
|
232
|
-
const activity2 = generateActivityResponse({ id: 'activity2' });
|
|
233
|
-
const activities = prehydrateActivities([activity1]);
|
|
234
|
-
|
|
235
|
-
const result = removeActivityFromState(activity2, activities);
|
|
236
|
-
|
|
237
|
-
expect(result.changed).toBe(false);
|
|
238
|
-
expect(result.activities).toHaveLength(1);
|
|
239
|
-
expect(result.activities![0].id).toBe('activity1');
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
it('should handle empty activities array', () => {
|
|
243
|
-
const activity = generateActivityResponse({ id: 'activity1' });
|
|
244
|
-
const activities: ActivityResponse[] = [];
|
|
245
|
-
|
|
246
|
-
const result = removeActivityFromState(activity, activities);
|
|
247
|
-
|
|
248
|
-
expect(result.changed).toBe(false);
|
|
249
|
-
expect(result.activities).toHaveLength(0);
|
|
250
|
-
});
|
|
251
|
-
});
|
|
252
|
-
});
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|
2
|
-
import { Feed } from '../../../feed';
|
|
3
|
-
import { FeedsClient } from '../../../feeds-client';
|
|
4
|
-
import { handleActivityAdded } from './handle-activity-added';
|
|
5
|
-
import {
|
|
6
|
-
generateActivityAddedEvent,
|
|
7
|
-
generateActivityResponse,
|
|
8
|
-
generateFeedResponse,
|
|
9
|
-
generateOwnUser,
|
|
10
|
-
getHumanId,
|
|
11
|
-
} from '../../../test-utils';
|
|
12
|
-
|
|
13
|
-
describe(handleActivityAdded.name, () => {
|
|
14
|
-
let feed: Feed;
|
|
15
|
-
let client: FeedsClient;
|
|
16
|
-
let currentUserId: string;
|
|
17
|
-
|
|
18
|
-
beforeEach(() => {
|
|
19
|
-
client = new FeedsClient('mock-api-key');
|
|
20
|
-
currentUserId = getHumanId();
|
|
21
|
-
client.state.partialNext({
|
|
22
|
-
connected_user: generateOwnUser({ id: currentUserId }),
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
const feedResponse = generateFeedResponse({
|
|
26
|
-
id: 'main',
|
|
27
|
-
group_id: 'user',
|
|
28
|
-
created_by: { id: currentUserId },
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
feed = new Feed(
|
|
32
|
-
client,
|
|
33
|
-
feedResponse.group_id,
|
|
34
|
-
feedResponse.id,
|
|
35
|
-
feedResponse,
|
|
36
|
-
);
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
it('initializes activities when state is empty and adds new activity to the start', () => {
|
|
40
|
-
const event = generateActivityAddedEvent();
|
|
41
|
-
|
|
42
|
-
const stateBefore = feed.currentState;
|
|
43
|
-
expect(stateBefore.activities).toBeUndefined();
|
|
44
|
-
|
|
45
|
-
const hydrateSpy = vi.spyOn(client, 'hydratePollCache');
|
|
46
|
-
|
|
47
|
-
handleActivityAdded.call(feed, event);
|
|
48
|
-
|
|
49
|
-
const stateAfter = feed.currentState;
|
|
50
|
-
expect(stateAfter.activities).toBeDefined();
|
|
51
|
-
expect(stateAfter.activities).toHaveLength(1);
|
|
52
|
-
expect(stateAfter.activities?.[0]).toBe(event.activity);
|
|
53
|
-
expect(hydrateSpy).toHaveBeenCalledWith([event.activity]);
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
it('prepends new activity when activities already exist', () => {
|
|
57
|
-
const existing = generateActivityResponse();
|
|
58
|
-
feed.state.partialNext({ activities: [existing] });
|
|
59
|
-
|
|
60
|
-
const event = generateActivityAddedEvent();
|
|
61
|
-
|
|
62
|
-
handleActivityAdded.call(feed, event);
|
|
63
|
-
|
|
64
|
-
const stateAfter = feed.currentState;
|
|
65
|
-
expect(stateAfter.activities).toHaveLength(2);
|
|
66
|
-
expect(stateAfter.activities?.[0]).toBe(event.activity);
|
|
67
|
-
expect(stateAfter.activities?.[1]).toBe(existing);
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it('does not duplicate if activity already exists', () => {
|
|
71
|
-
const existing = generateActivityResponse();
|
|
72
|
-
feed.state.partialNext({ activities: [existing] });
|
|
73
|
-
|
|
74
|
-
const event = generateActivityAddedEvent({
|
|
75
|
-
activity: { id: existing.id },
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
const stateBefore = feed.currentState;
|
|
79
|
-
handleActivityAdded.call(feed, event);
|
|
80
|
-
const stateAfter = feed.currentState;
|
|
81
|
-
|
|
82
|
-
expect(stateAfter).toBe(stateBefore);
|
|
83
|
-
expect(stateAfter.activities).toHaveLength(1);
|
|
84
|
-
expect(stateAfter.activities?.[0]).toBe(existing);
|
|
85
|
-
});
|
|
86
|
-
});
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach } from 'vitest';
|
|
2
|
-
import { Feed } from '../../../feed';
|
|
3
|
-
import { FeedsClient } from '../../../feeds-client';
|
|
4
|
-
import { handleActivityDeleted } from './handle-activity-deleted';
|
|
5
|
-
import {
|
|
6
|
-
generateActivityDeletedEvent,
|
|
7
|
-
generateActivityPinResponse,
|
|
8
|
-
generateActivityResponse,
|
|
9
|
-
generateFeedResponse,
|
|
10
|
-
generateOwnUser,
|
|
11
|
-
getHumanId,
|
|
12
|
-
} from '../../../test-utils/response-generators';
|
|
13
|
-
|
|
14
|
-
describe(handleActivityDeleted.name, () => {
|
|
15
|
-
let feed: Feed;
|
|
16
|
-
let client: FeedsClient;
|
|
17
|
-
let currentUserId: string;
|
|
18
|
-
|
|
19
|
-
beforeEach(() => {
|
|
20
|
-
client = new FeedsClient('mock-api-key');
|
|
21
|
-
currentUserId = getHumanId();
|
|
22
|
-
client.state.partialNext({
|
|
23
|
-
connected_user: generateOwnUser({ id: currentUserId }),
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
const feedResponse = generateFeedResponse({
|
|
27
|
-
id: 'main',
|
|
28
|
-
group_id: 'user',
|
|
29
|
-
created_by: { id: currentUserId },
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
feed = new Feed(
|
|
33
|
-
client,
|
|
34
|
-
feedResponse.group_id,
|
|
35
|
-
feedResponse.id,
|
|
36
|
-
feedResponse,
|
|
37
|
-
);
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it('removes the activity from activities array when present', () => {
|
|
41
|
-
const activity1 = generateActivityResponse();
|
|
42
|
-
const activity2 = generateActivityResponse();
|
|
43
|
-
feed.state.partialNext({ activities: [activity1, activity2] });
|
|
44
|
-
|
|
45
|
-
const event = generateActivityDeletedEvent({
|
|
46
|
-
activity: { id: activity1.id },
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
const stateBefore = feed.currentState;
|
|
50
|
-
expect(stateBefore.activities).toHaveLength(2);
|
|
51
|
-
|
|
52
|
-
handleActivityDeleted.call(feed, event);
|
|
53
|
-
|
|
54
|
-
const stateAfter = feed.currentState;
|
|
55
|
-
expect(stateAfter.activities).toHaveLength(1);
|
|
56
|
-
expect(stateAfter.activities?.[0].id).toBe(activity2.id);
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it('removes the activity from pinned_activities when present', () => {
|
|
60
|
-
const pin1 = generateActivityPinResponse();
|
|
61
|
-
const pin2 = generateActivityPinResponse();
|
|
62
|
-
feed.state.partialNext({ pinned_activities: [pin1, pin2] });
|
|
63
|
-
|
|
64
|
-
const event = generateActivityDeletedEvent({
|
|
65
|
-
activity: { id: pin1.activity.id },
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
const stateBefore = feed.currentState;
|
|
69
|
-
expect(stateBefore.pinned_activities).toHaveLength(2);
|
|
70
|
-
|
|
71
|
-
handleActivityDeleted.call(feed, event);
|
|
72
|
-
|
|
73
|
-
const stateAfter = feed.currentState;
|
|
74
|
-
|
|
75
|
-
expect(stateAfter.pinned_activities).toHaveLength(1);
|
|
76
|
-
expect(stateAfter.pinned_activities?.[0]).toBe(pin2);
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
it('updates both arrays when the activity exists in both activities and pinned_activities', () => {
|
|
80
|
-
const sharedId = getHumanId();
|
|
81
|
-
const activity = generateActivityResponse({ id: sharedId });
|
|
82
|
-
const pinnedActivity = generateActivityPinResponse({
|
|
83
|
-
activity: { id: sharedId },
|
|
84
|
-
});
|
|
85
|
-
feed.state.partialNext({
|
|
86
|
-
activities: [activity],
|
|
87
|
-
pinned_activities: [pinnedActivity],
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
const event = generateActivityDeletedEvent({
|
|
91
|
-
activity: { id: sharedId },
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
handleActivityDeleted.call(feed, event);
|
|
95
|
-
|
|
96
|
-
const stateAfter = feed.currentState;
|
|
97
|
-
expect(stateAfter.activities).toHaveLength(0);
|
|
98
|
-
expect(stateAfter.pinned_activities).toHaveLength(0);
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
it('does nothing if the activity is not found in either list', () => {
|
|
102
|
-
const activity = generateActivityResponse();
|
|
103
|
-
const pinnedActivity = generateActivityPinResponse();
|
|
104
|
-
feed.state.partialNext({
|
|
105
|
-
activities: [activity],
|
|
106
|
-
pinned_activities: [pinnedActivity],
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
const event = generateActivityDeletedEvent({ activity: { id: 'unknown' } });
|
|
110
|
-
|
|
111
|
-
const stateBefore = feed.currentState;
|
|
112
|
-
handleActivityDeleted.call(feed, event);
|
|
113
|
-
const stateAfter = feed.currentState;
|
|
114
|
-
|
|
115
|
-
expect(stateAfter).toBe(stateBefore);
|
|
116
|
-
});
|
|
117
|
-
});
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach } from 'vitest';
|
|
2
|
-
|
|
3
|
-
import { Feed } from '../../../feed';
|
|
4
|
-
import { FeedsClient } from '../../../feeds-client';
|
|
5
|
-
import { handleActivityPinned } from './handle-activity-pinned';
|
|
6
|
-
import {
|
|
7
|
-
generateActivityPinnedEvent,
|
|
8
|
-
generateActivityPinResponse,
|
|
9
|
-
generateFeedResponse,
|
|
10
|
-
} from '../../../test-utils/response-generators';
|
|
11
|
-
import type { ActivityPinResponse } from '../../../gen/models';
|
|
12
|
-
|
|
13
|
-
describe(handleActivityPinned.name, () => {
|
|
14
|
-
let feed: Feed;
|
|
15
|
-
let client: FeedsClient;
|
|
16
|
-
let pinnedActivity: ActivityPinResponse;
|
|
17
|
-
let otherPinnedActivity: ActivityPinResponse;
|
|
18
|
-
|
|
19
|
-
beforeEach(() => {
|
|
20
|
-
client = new FeedsClient('mock-api-key');
|
|
21
|
-
const feedResponse = generateFeedResponse({ id: 'main', group_id: 'user' });
|
|
22
|
-
feed = new Feed(
|
|
23
|
-
client,
|
|
24
|
-
feedResponse.group_id,
|
|
25
|
-
feedResponse.id,
|
|
26
|
-
feedResponse,
|
|
27
|
-
);
|
|
28
|
-
pinnedActivity = generateActivityPinResponse();
|
|
29
|
-
otherPinnedActivity = generateActivityPinResponse();
|
|
30
|
-
feed.state.next((currentState) => ({
|
|
31
|
-
...currentState,
|
|
32
|
-
pinned_activities: [otherPinnedActivity],
|
|
33
|
-
}));
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it('adds a new activity to pinned_activities', () => {
|
|
37
|
-
const event = generateActivityPinnedEvent({
|
|
38
|
-
pinned_activity: pinnedActivity,
|
|
39
|
-
});
|
|
40
|
-
handleActivityPinned.call(feed, event);
|
|
41
|
-
const { pinned_activities } = feed.currentState;
|
|
42
|
-
expect(pinned_activities).toHaveLength(2);
|
|
43
|
-
expect(pinned_activities![0].activity.id).toBe(pinnedActivity.activity.id);
|
|
44
|
-
expect(pinned_activities![1]).toBe(otherPinnedActivity);
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it('creates pinned_activities if it was undefined', () => {
|
|
48
|
-
feed.state.next((currentState) => ({
|
|
49
|
-
...currentState,
|
|
50
|
-
pinned_activities: undefined,
|
|
51
|
-
}));
|
|
52
|
-
const event = generateActivityPinnedEvent({
|
|
53
|
-
pinned_activity: pinnedActivity,
|
|
54
|
-
});
|
|
55
|
-
handleActivityPinned.call(feed, event);
|
|
56
|
-
const { pinned_activities } = feed.currentState;
|
|
57
|
-
expect(pinned_activities).toHaveLength(1);
|
|
58
|
-
expect(pinned_activities![0].activity.id).toBe(pinnedActivity.activity.id);
|
|
59
|
-
});
|
|
60
|
-
});
|