@stream-io/feeds-client 0.2.18 → 0.2.20
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 +23 -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-Zde8UE5f.mjs → feeds-client-BObWT4vl.mjs} +191 -92
- package/dist/feeds-client-BObWT4vl.mjs.map +1 -0
- package/dist/{index--koeDtxd.js → feeds-client-BlR_3zy2.js} +178 -79
- package/dist/feeds-client-BlR_3zy2.js.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/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.map +1 -1
- package/dist/types/feed/event-handlers/activity/handle-activity-updated.d.ts.map +1 -1
- package/dist/types/feed/feed.d.ts +1 -1
- package/dist/types/feed/feed.d.ts.map +1 -1
- package/dist/types/feeds-client/feeds-client.d.ts +9 -1
- package/dist/types/feeds-client/feeds-client.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 +9 -1
- package/src/feed/event-handlers/activity/handle-activity-updated.ts +4 -0
- package/src/feed/feed.ts +18 -3
- package/src/feeds-client/feeds-client.ts +106 -3
- 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 +44 -0
- package/dist/index--koeDtxd.js.map +0 -1
- package/dist/index-Zde8UE5f.mjs.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/handle-activity-added.test.ts +0 -97
- 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/add-aggregated-activities-to-state.test.ts +0 -510
- 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/event-handlers/notification-feed/handle-notification-feed-updated.test.ts +0 -182
- package/src/feed/event-handlers/story-feeds/handle-story-feeds-updated.test.ts +0 -45
- 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,82 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it } from 'vitest';
|
|
2
|
-
import { Feed } from '../../../feed';
|
|
3
|
-
import { FeedsClient } from '../../../feeds-client';
|
|
4
|
-
import { handleFeedMemberRemoved } from './handle-feed-member-removed';
|
|
5
|
-
import {
|
|
6
|
-
generateFeedResponse,
|
|
7
|
-
generateFeedMemberRemovedEvent,
|
|
8
|
-
generateFeedMemberResponse,
|
|
9
|
-
generateOwnUser,
|
|
10
|
-
getHumanId,
|
|
11
|
-
} from '../../../test-utils/response-generators';
|
|
12
|
-
|
|
13
|
-
describe(handleFeedMemberRemoved.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
|
-
const feedResponse = generateFeedResponse({
|
|
25
|
-
id: 'main',
|
|
26
|
-
group_id: 'user',
|
|
27
|
-
created_by: { id: currentUserId },
|
|
28
|
-
});
|
|
29
|
-
feed = new Feed(
|
|
30
|
-
client,
|
|
31
|
-
feedResponse.group_id,
|
|
32
|
-
feedResponse.id,
|
|
33
|
-
feedResponse,
|
|
34
|
-
);
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it('removes from members if present', () => {
|
|
38
|
-
const memberToRemove = generateFeedMemberResponse();
|
|
39
|
-
const memberToKeep = generateFeedMemberResponse();
|
|
40
|
-
feed.state.partialNext({ members: [memberToRemove, memberToKeep] });
|
|
41
|
-
|
|
42
|
-
const event = generateFeedMemberRemovedEvent({
|
|
43
|
-
member_id: memberToRemove.user.id,
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
handleFeedMemberRemoved.call(feed, event);
|
|
47
|
-
|
|
48
|
-
const stateAfter = feed.currentState;
|
|
49
|
-
expect(stateAfter.members).toHaveLength(1);
|
|
50
|
-
expect(stateAfter.members?.[0]).toBe(memberToKeep);
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it('does not change state when members array is undefined', () => {
|
|
54
|
-
const event = generateFeedMemberRemovedEvent();
|
|
55
|
-
|
|
56
|
-
const stateBefore = feed.currentState;
|
|
57
|
-
expect(stateBefore.members).toBeUndefined();
|
|
58
|
-
|
|
59
|
-
handleFeedMemberRemoved.call(feed, event);
|
|
60
|
-
|
|
61
|
-
const stateAfter = feed.currentState;
|
|
62
|
-
expect(stateAfter).toBe(stateBefore);
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
it('deletes own_membership when the removed member is the connected user', () => {
|
|
66
|
-
const ownMember = generateFeedMemberResponse({
|
|
67
|
-
user: { id: currentUserId },
|
|
68
|
-
});
|
|
69
|
-
feed.state.partialNext({ own_membership: ownMember, members: [] });
|
|
70
|
-
|
|
71
|
-
const event = generateFeedMemberRemovedEvent({ member_id: currentUserId });
|
|
72
|
-
|
|
73
|
-
const stateBefore = feed.currentState;
|
|
74
|
-
expect(stateBefore.own_membership).toBe(ownMember);
|
|
75
|
-
|
|
76
|
-
handleFeedMemberRemoved.call(feed, event);
|
|
77
|
-
|
|
78
|
-
const stateAfter = feed.currentState;
|
|
79
|
-
expect(stateAfter.own_membership).toBeUndefined();
|
|
80
|
-
expect(stateAfter.members).toBe(stateBefore.members);
|
|
81
|
-
});
|
|
82
|
-
});
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it } from 'vitest';
|
|
2
|
-
import { Feed } from '../../../feed';
|
|
3
|
-
import { FeedsClient } from '../../../feeds-client';
|
|
4
|
-
import { handleFeedMemberUpdated } from './handle-feed-member-updated';
|
|
5
|
-
import {
|
|
6
|
-
generateFeedResponse,
|
|
7
|
-
generateFeedMemberUpdatedEvent,
|
|
8
|
-
generateFeedMemberResponse,
|
|
9
|
-
generateOwnUser,
|
|
10
|
-
getHumanId,
|
|
11
|
-
} from '../../../test-utils/response-generators';
|
|
12
|
-
|
|
13
|
-
describe(handleFeedMemberUpdated.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
|
-
const feedResponse = generateFeedResponse({
|
|
25
|
-
id: 'main',
|
|
26
|
-
group_id: 'user',
|
|
27
|
-
created_by: { id: currentUserId },
|
|
28
|
-
});
|
|
29
|
-
feed = new Feed(
|
|
30
|
-
client,
|
|
31
|
-
feedResponse.group_id,
|
|
32
|
-
feedResponse.id,
|
|
33
|
-
feedResponse,
|
|
34
|
-
);
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it('updates an existing member in members array', () => {
|
|
38
|
-
const member1 = generateFeedMemberResponse();
|
|
39
|
-
const member2 = generateFeedMemberResponse();
|
|
40
|
-
feed.state.partialNext({ members: [member1, member2] });
|
|
41
|
-
|
|
42
|
-
const event = generateFeedMemberUpdatedEvent({
|
|
43
|
-
member: { user: { id: member1.user.id }, role: 'admin' },
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
handleFeedMemberUpdated.call(feed, event);
|
|
47
|
-
|
|
48
|
-
const stateAfter = feed.currentState;
|
|
49
|
-
expect(stateAfter.members).toHaveLength(2);
|
|
50
|
-
expect(stateAfter.members?.[0]).toBe(event.member);
|
|
51
|
-
expect(stateAfter.members?.[1]).toBe(member2);
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it('does not modify members when target is not present', () => {
|
|
55
|
-
const existingMember = generateFeedMemberResponse();
|
|
56
|
-
feed.state.partialNext({ members: [existingMember] });
|
|
57
|
-
|
|
58
|
-
const event = generateFeedMemberUpdatedEvent();
|
|
59
|
-
|
|
60
|
-
const stateBefore = feed.currentState;
|
|
61
|
-
handleFeedMemberUpdated.call(feed, event);
|
|
62
|
-
|
|
63
|
-
const stateAfter = feed.currentState;
|
|
64
|
-
expect(stateAfter).toBe(stateBefore);
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
it('sets own_membership when the updated member is the connected user', () => {
|
|
68
|
-
const event = generateFeedMemberUpdatedEvent({
|
|
69
|
-
member: {
|
|
70
|
-
user: { id: currentUserId },
|
|
71
|
-
role: 'owner',
|
|
72
|
-
status: 'member',
|
|
73
|
-
},
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
const stateBefore = feed.currentState;
|
|
77
|
-
expect(stateBefore.own_membership).toBeUndefined();
|
|
78
|
-
|
|
79
|
-
handleFeedMemberUpdated.call(feed, event);
|
|
80
|
-
|
|
81
|
-
const stateAfter = feed.currentState;
|
|
82
|
-
expect(stateAfter.own_membership).toBe(event.member);
|
|
83
|
-
});
|
|
84
|
-
});
|
|
@@ -1,219 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it } from 'vitest';
|
|
2
|
-
import type { FollowResponse } from '../../../gen/models';
|
|
3
|
-
import { shouldUpdateState } from '../../../utils/state-update-queue';
|
|
4
|
-
import { handleFollowUpdated } from './handle-follow-updated';
|
|
5
|
-
import { Feed, handleFollowCreated, handleFollowDeleted } from '../../../feed';
|
|
6
|
-
import { FeedsClient } from '../../../feeds-client';
|
|
7
|
-
import {
|
|
8
|
-
generateFeedResponse,
|
|
9
|
-
generateFollowResponse,
|
|
10
|
-
generateOwnUser,
|
|
11
|
-
getHumanId,
|
|
12
|
-
} from '../../../test-utils';
|
|
13
|
-
|
|
14
|
-
describe(`Follow ${shouldUpdateState.name} integration`, () => {
|
|
15
|
-
let feed: Feed;
|
|
16
|
-
let client: FeedsClient;
|
|
17
|
-
let follow: FollowResponse;
|
|
18
|
-
let otherFollow: FollowResponse;
|
|
19
|
-
let ownFollow: FollowResponse;
|
|
20
|
-
let userId: string;
|
|
21
|
-
|
|
22
|
-
beforeEach(() => {
|
|
23
|
-
userId = getHumanId();
|
|
24
|
-
client = new FeedsClient('mock-api-key');
|
|
25
|
-
|
|
26
|
-
client.state.partialNext({
|
|
27
|
-
connected_user: generateOwnUser({ id: userId }),
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
const feedResponse = generateFeedResponse({
|
|
31
|
-
id: 'main',
|
|
32
|
-
group_id: 'user',
|
|
33
|
-
created_by: { id: userId },
|
|
34
|
-
});
|
|
35
|
-
feed = new Feed(client, 'user', 'main', feedResponse);
|
|
36
|
-
// Setup follows
|
|
37
|
-
follow = generateFollowResponse({
|
|
38
|
-
source_feed: generateFeedResponse({
|
|
39
|
-
id: 'main',
|
|
40
|
-
group_id: 'user',
|
|
41
|
-
created_by: { id: userId },
|
|
42
|
-
}),
|
|
43
|
-
target_feed: generateFeedResponse({
|
|
44
|
-
id: 'target',
|
|
45
|
-
group_id: 'user',
|
|
46
|
-
}),
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
otherFollow = generateFollowResponse({
|
|
50
|
-
source_feed: generateFeedResponse({
|
|
51
|
-
id: 'other',
|
|
52
|
-
group_id: 'user',
|
|
53
|
-
created_by: { id: getHumanId() },
|
|
54
|
-
}),
|
|
55
|
-
target_feed: generateFeedResponse({
|
|
56
|
-
id: 'main',
|
|
57
|
-
group_id: 'user',
|
|
58
|
-
}),
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
ownFollow = generateFollowResponse({
|
|
62
|
-
source_feed: generateFeedResponse({
|
|
63
|
-
id: 'other',
|
|
64
|
-
group_id: 'user',
|
|
65
|
-
created_by: { id: userId },
|
|
66
|
-
}),
|
|
67
|
-
target_feed: generateFeedResponse({
|
|
68
|
-
id: 'main',
|
|
69
|
-
group_id: 'user',
|
|
70
|
-
}),
|
|
71
|
-
});
|
|
72
|
-
// Set up initial state
|
|
73
|
-
feed.state.next((currentState) => ({
|
|
74
|
-
...currentState,
|
|
75
|
-
following: [follow],
|
|
76
|
-
followers: [otherFollow],
|
|
77
|
-
own_follows: [ownFollow],
|
|
78
|
-
}));
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
describe.each(
|
|
82
|
-
[
|
|
83
|
-
{
|
|
84
|
-
handler: handleFollowCreated,
|
|
85
|
-
state: {
|
|
86
|
-
status: 'accepted',
|
|
87
|
-
},
|
|
88
|
-
count: 2,
|
|
89
|
-
},
|
|
90
|
-
{
|
|
91
|
-
handler: handleFollowUpdated,
|
|
92
|
-
state: {
|
|
93
|
-
status: 'accepted',
|
|
94
|
-
},
|
|
95
|
-
count: 1,
|
|
96
|
-
},
|
|
97
|
-
{ handler: handleFollowDeleted, state: undefined, count: 0 },
|
|
98
|
-
].map(({ handler, state, count }) => [
|
|
99
|
-
handler.name,
|
|
100
|
-
handler,
|
|
101
|
-
state as Partial<FollowResponse>,
|
|
102
|
-
count,
|
|
103
|
-
]),
|
|
104
|
-
)(`%s`, (_name, handler, state, count) => {
|
|
105
|
-
it(`skips update if ${shouldUpdateState.name} returns false`, () => {
|
|
106
|
-
// Prepare feed, set as watched
|
|
107
|
-
feed.state.partialNext({ watch: true });
|
|
108
|
-
|
|
109
|
-
const updatedFollow: FollowResponse = { ...follow, status: 'pending' };
|
|
110
|
-
|
|
111
|
-
// 1. HTTP and then WS event
|
|
112
|
-
|
|
113
|
-
// Call once as HTTP response to populate the queue
|
|
114
|
-
handler.call(
|
|
115
|
-
feed,
|
|
116
|
-
{
|
|
117
|
-
follow: { ...updatedFollow, ...state },
|
|
118
|
-
},
|
|
119
|
-
false,
|
|
120
|
-
);
|
|
121
|
-
|
|
122
|
-
// Call again as WS event, should be skipped
|
|
123
|
-
let stateBefore = feed.currentState;
|
|
124
|
-
handler.call(feed, { follow: updatedFollow });
|
|
125
|
-
|
|
126
|
-
// State should not change
|
|
127
|
-
let stateAfter = feed.currentState;
|
|
128
|
-
expect(stateAfter).toBe(stateBefore);
|
|
129
|
-
// @ts-expect-error Using Feed internals for tests only
|
|
130
|
-
expect(feed.stateUpdateQueue.size).toEqual(0);
|
|
131
|
-
|
|
132
|
-
// 2. WS and then HTTP
|
|
133
|
-
|
|
134
|
-
// Call once as WS event to populate the queue
|
|
135
|
-
handler.call(
|
|
136
|
-
feed,
|
|
137
|
-
{
|
|
138
|
-
follow: { ...updatedFollow, ...state },
|
|
139
|
-
},
|
|
140
|
-
);
|
|
141
|
-
|
|
142
|
-
// Call again as HTTP response, should be skipped
|
|
143
|
-
stateBefore = feed.currentState;
|
|
144
|
-
handler.call(feed, { follow: updatedFollow }, false);
|
|
145
|
-
|
|
146
|
-
// State should not change
|
|
147
|
-
stateAfter = feed.currentState;
|
|
148
|
-
expect(stateAfter).toBe(stateBefore);
|
|
149
|
-
// @ts-expect-error Using Feed internals for tests only
|
|
150
|
-
expect(feed.stateUpdateQueue.size).toEqual(0);
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
it('allows update again from WS after clearing the stateUpdateQueue', () => {
|
|
154
|
-
const updatedFollow: FollowResponse = { ...follow, status: 'pending' };
|
|
155
|
-
|
|
156
|
-
handler.call(feed, { follow: updatedFollow });
|
|
157
|
-
|
|
158
|
-
// Clear the queue
|
|
159
|
-
(feed as any).stateUpdateQueue.clear();
|
|
160
|
-
|
|
161
|
-
// Now update should be allowed from another WS event
|
|
162
|
-
handler.call(feed, {
|
|
163
|
-
follow: { ...updatedFollow, ...state },
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
const following = feed.currentState.following!;
|
|
167
|
-
const [updatedFollowAfter] = following;
|
|
168
|
-
|
|
169
|
-
expect(following.length).toEqual(count);
|
|
170
|
-
expect(updatedFollowAfter).toMatchObject(state!);
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
it('allows update again from HTTP response after clearing the stateUpdateQueue', () => {
|
|
174
|
-
const updatedFollow: FollowResponse = { ...follow, status: 'pending' };
|
|
175
|
-
|
|
176
|
-
handler.call(feed, { follow: updatedFollow }, false);
|
|
177
|
-
|
|
178
|
-
// Clear the queue
|
|
179
|
-
(feed as any).stateUpdateQueue.clear();
|
|
180
|
-
|
|
181
|
-
// Now update should be allowed from another HTTP response
|
|
182
|
-
handler.call(
|
|
183
|
-
feed,
|
|
184
|
-
{
|
|
185
|
-
follow: { ...updatedFollow, ...state },
|
|
186
|
-
},
|
|
187
|
-
false,
|
|
188
|
-
);
|
|
189
|
-
|
|
190
|
-
const following = feed.currentState.following!;
|
|
191
|
-
const [updatedFollowAfter] = following;
|
|
192
|
-
|
|
193
|
-
expect(following.length).toEqual(count);
|
|
194
|
-
expect(updatedFollowAfter).toMatchObject(state!);
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
it('should not insert anything into the stateUpdateQueue if the connected_user did not trigger the follow', () => {
|
|
198
|
-
const updatedFollow: FollowResponse = {
|
|
199
|
-
...otherFollow,
|
|
200
|
-
status: 'pending',
|
|
201
|
-
};
|
|
202
|
-
|
|
203
|
-
handler.call(feed, { follow: updatedFollow });
|
|
204
|
-
|
|
205
|
-
expect((feed as any).stateUpdateQueue).toEqual(new Set());
|
|
206
|
-
|
|
207
|
-
handler.call(feed, {
|
|
208
|
-
follow: { ...updatedFollow, ...state },
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
const following = feed.currentState.following!;
|
|
212
|
-
const [updatedFollowAfter] = following;
|
|
213
|
-
|
|
214
|
-
expect((feed as any).stateUpdateQueue).toEqual(new Set());
|
|
215
|
-
expect(following.length).toEqual(1);
|
|
216
|
-
expect(updatedFollowAfter).toMatchObject(follow);
|
|
217
|
-
});
|
|
218
|
-
});
|
|
219
|
-
});
|
|
@@ -1,250 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
FeedResponse,
|
|
3
|
-
FollowResponse,
|
|
4
|
-
UserResponse,
|
|
5
|
-
} from '../../../gen/models';
|
|
6
|
-
import { generateFollowResponse } from '../../../test-utils';
|
|
7
|
-
import { updateStateFollowCreated } from './handle-follow-created';
|
|
8
|
-
|
|
9
|
-
import { describe, it, expect, beforeEach } from 'vitest';
|
|
10
|
-
|
|
11
|
-
describe('handle-follow-created', () => {
|
|
12
|
-
describe(updateStateFollowCreated.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 return unchanged state for non-accepted follows', () => {
|
|
24
|
-
const follow: FollowResponse = {
|
|
25
|
-
...mockFollow,
|
|
26
|
-
status: 'pending',
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
// @ts-expect-error - we're not testing the full state here
|
|
30
|
-
const currentState: FeedState = {
|
|
31
|
-
followers: [],
|
|
32
|
-
following: [],
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
const result = updateStateFollowCreated(
|
|
36
|
-
follow,
|
|
37
|
-
currentState,
|
|
38
|
-
'user:feed-1',
|
|
39
|
-
'user-1',
|
|
40
|
-
);
|
|
41
|
-
|
|
42
|
-
expect(result.changed).toBe(false);
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it('should handle when this feed follows someone', () => {
|
|
46
|
-
const follow: FollowResponse = {
|
|
47
|
-
...mockFollow,
|
|
48
|
-
source_feed: {
|
|
49
|
-
...mockFeed,
|
|
50
|
-
id: 'feed-x',
|
|
51
|
-
feed: 'user:feed-x',
|
|
52
|
-
created_by: {
|
|
53
|
-
...mockUser,
|
|
54
|
-
id: 'user-x',
|
|
55
|
-
},
|
|
56
|
-
following_count: 1,
|
|
57
|
-
},
|
|
58
|
-
target_feed: {
|
|
59
|
-
...mockFeed,
|
|
60
|
-
id: 'other-feed',
|
|
61
|
-
feed: 'user:other-feed',
|
|
62
|
-
created_by: mockUser,
|
|
63
|
-
},
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
// @ts-expect-error - we're not testing the full state here
|
|
67
|
-
const currentState: FeedState = {
|
|
68
|
-
following: [],
|
|
69
|
-
following_count: 0,
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
const result = updateStateFollowCreated(
|
|
73
|
-
follow,
|
|
74
|
-
currentState,
|
|
75
|
-
'user:feed-x',
|
|
76
|
-
'user-1',
|
|
77
|
-
);
|
|
78
|
-
|
|
79
|
-
expect(result.changed).toBe(true);
|
|
80
|
-
expect(result.data.following).toHaveLength(1);
|
|
81
|
-
expect(result.data.following?.[0]).toBe(follow);
|
|
82
|
-
expect(result.data).toMatchObject(follow.source_feed);
|
|
83
|
-
expect(result.data.own_follows).toBeUndefined();
|
|
84
|
-
expect(result.data.following_count).toBe(1);
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it('should handle when someone follows this feed', () => {
|
|
88
|
-
const follow: FollowResponse = {
|
|
89
|
-
...mockFollow,
|
|
90
|
-
source_feed: {
|
|
91
|
-
...mockFeed,
|
|
92
|
-
id: 'other-feed',
|
|
93
|
-
feed: 'user:other-feed',
|
|
94
|
-
created_by: {
|
|
95
|
-
...mockUser,
|
|
96
|
-
id: 'other-user',
|
|
97
|
-
},
|
|
98
|
-
},
|
|
99
|
-
target_feed: {
|
|
100
|
-
...mockFeed,
|
|
101
|
-
id: 'feed-1',
|
|
102
|
-
feed: 'user:feed-1',
|
|
103
|
-
created_by: mockUser,
|
|
104
|
-
follower_count: 1,
|
|
105
|
-
},
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
// @ts-expect-error - we're not testing the full state here
|
|
109
|
-
const currentState: FeedState = {
|
|
110
|
-
followers: [],
|
|
111
|
-
follower_count: 0,
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
const result = updateStateFollowCreated(
|
|
115
|
-
follow,
|
|
116
|
-
currentState,
|
|
117
|
-
'user:feed-1',
|
|
118
|
-
'user-1',
|
|
119
|
-
);
|
|
120
|
-
|
|
121
|
-
expect(result.changed).toBe(true);
|
|
122
|
-
expect(result.data.followers).toHaveLength(1);
|
|
123
|
-
expect(result.data.followers?.[0]).toBe(follow);
|
|
124
|
-
expect(result.data).toMatchObject(follow.target_feed);
|
|
125
|
-
expect(result.data.own_follows).toBeUndefined();
|
|
126
|
-
expect(result.data.follower_count).toBe(1);
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
it('should add to own_follows when connected user is the source', () => {
|
|
130
|
-
const follow: FollowResponse = {
|
|
131
|
-
...mockFollow,
|
|
132
|
-
source_feed: {
|
|
133
|
-
...mockFeed,
|
|
134
|
-
id: 'feed-1',
|
|
135
|
-
feed: 'user:feed-1',
|
|
136
|
-
created_by: { ...mockUser, id: 'user-1' },
|
|
137
|
-
},
|
|
138
|
-
target_feed: {
|
|
139
|
-
...mockFeed,
|
|
140
|
-
id: 'feed-x',
|
|
141
|
-
feed: 'user:feed-x',
|
|
142
|
-
created_by: {
|
|
143
|
-
...mockUser,
|
|
144
|
-
id: 'user-x',
|
|
145
|
-
},
|
|
146
|
-
},
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
// @ts-expect-error - we're not testing the full state here
|
|
150
|
-
const currentState: FeedState = {
|
|
151
|
-
followers: [],
|
|
152
|
-
own_follows: [],
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
const result = updateStateFollowCreated(
|
|
156
|
-
follow,
|
|
157
|
-
currentState,
|
|
158
|
-
'user:feed-x',
|
|
159
|
-
'user-1',
|
|
160
|
-
);
|
|
161
|
-
|
|
162
|
-
expect(result.changed).toBe(true);
|
|
163
|
-
expect(result.data.own_follows).toHaveLength(1);
|
|
164
|
-
expect(result.data.own_follows?.[0]).toBe(follow);
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
it('should not update followers/following when they are undefined', () => {
|
|
168
|
-
const follow: FollowResponse = {
|
|
169
|
-
...mockFollow,
|
|
170
|
-
source_feed: {
|
|
171
|
-
...mockFeed,
|
|
172
|
-
id: 'other-feed',
|
|
173
|
-
feed: 'user:other-feed',
|
|
174
|
-
created_by: mockUser,
|
|
175
|
-
},
|
|
176
|
-
target_feed: {
|
|
177
|
-
...mockFeed,
|
|
178
|
-
id: 'feed-1',
|
|
179
|
-
feed: 'user:feed-1',
|
|
180
|
-
created_by: mockUser,
|
|
181
|
-
},
|
|
182
|
-
};
|
|
183
|
-
|
|
184
|
-
// @ts-expect-error - we're not testing the full state here
|
|
185
|
-
const currentState: FeedState = {
|
|
186
|
-
followers: undefined,
|
|
187
|
-
following: undefined,
|
|
188
|
-
own_follows: undefined,
|
|
189
|
-
};
|
|
190
|
-
|
|
191
|
-
const result = updateStateFollowCreated(
|
|
192
|
-
follow,
|
|
193
|
-
currentState,
|
|
194
|
-
'user:feed-1',
|
|
195
|
-
'user-1',
|
|
196
|
-
);
|
|
197
|
-
|
|
198
|
-
expect(result.changed).toBe(true);
|
|
199
|
-
expect(result.data.followers).toBeUndefined();
|
|
200
|
-
expect(result.data).toMatchObject(follow.target_feed);
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
it('should add new followers to the top of existing arrays', () => {
|
|
204
|
-
const existingFollow: FollowResponse = {
|
|
205
|
-
...mockFollow,
|
|
206
|
-
source_feed: {
|
|
207
|
-
...mockFeed,
|
|
208
|
-
id: 'existing-feed',
|
|
209
|
-
feed: 'user:existing-feed',
|
|
210
|
-
created_by: mockUser,
|
|
211
|
-
},
|
|
212
|
-
};
|
|
213
|
-
|
|
214
|
-
const follow: FollowResponse = {
|
|
215
|
-
...mockFollow,
|
|
216
|
-
source_feed: {
|
|
217
|
-
...mockFeed,
|
|
218
|
-
id: 'other-feed',
|
|
219
|
-
feed: 'user:other-feed',
|
|
220
|
-
created_by: mockUser,
|
|
221
|
-
},
|
|
222
|
-
target_feed: {
|
|
223
|
-
...mockFeed,
|
|
224
|
-
id: 'feed-1',
|
|
225
|
-
feed: 'user:feed-1',
|
|
226
|
-
created_by: mockUser,
|
|
227
|
-
},
|
|
228
|
-
};
|
|
229
|
-
|
|
230
|
-
// @ts-expect-error - we're not testing the full state here
|
|
231
|
-
const currentState: FeedState = {
|
|
232
|
-
followers: [existingFollow],
|
|
233
|
-
following: undefined,
|
|
234
|
-
own_follows: undefined,
|
|
235
|
-
};
|
|
236
|
-
|
|
237
|
-
const result = updateStateFollowCreated(
|
|
238
|
-
follow,
|
|
239
|
-
currentState,
|
|
240
|
-
'user:feed-1',
|
|
241
|
-
'user-1',
|
|
242
|
-
);
|
|
243
|
-
|
|
244
|
-
expect(result.changed).toBe(true);
|
|
245
|
-
expect(result.data.followers).toHaveLength(2);
|
|
246
|
-
expect(result.data.followers?.[0]).toBe(follow);
|
|
247
|
-
expect(result.data.followers?.[1]).toBe(existingFollow);
|
|
248
|
-
});
|
|
249
|
-
});
|
|
250
|
-
});
|