@stream-io/feeds-client 0.2.1 → 0.2.3

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 (92) hide show
  1. package/@react-bindings/hooks/feed-state-hooks/index.ts +4 -0
  2. package/CHANGELOG.md +16 -0
  3. package/dist/@react-bindings/contexts/StreamSearchContext.d.ts +1 -1
  4. package/dist/@react-bindings/contexts/StreamSearchResultsContext.d.ts +1 -1
  5. package/dist/@react-bindings/hooks/feed-state-hooks/index.d.ts +4 -0
  6. package/dist/@react-bindings/hooks/feed-state-hooks/useAggregatedActivities.d.ts +11 -0
  7. package/dist/@react-bindings/hooks/feed-state-hooks/useIsAggregatedActivityRead.d.ts +6 -0
  8. package/dist/@react-bindings/hooks/feed-state-hooks/useIsAggregatedActivitySeen.d.ts +6 -0
  9. package/dist/@react-bindings/hooks/feed-state-hooks/useNotificationStatus.d.ts +13 -0
  10. package/dist/@react-bindings/hooks/search-state-hooks/useSearchQuery.d.ts +1 -1
  11. package/dist/@react-bindings/hooks/search-state-hooks/useSearchResult.d.ts +1 -1
  12. package/dist/@react-bindings/hooks/search-state-hooks/useSearchSources.d.ts +2 -2
  13. package/dist/@react-bindings/wrappers/StreamFeed.d.ts +1 -1
  14. package/dist/@react-bindings/wrappers/StreamSearch.d.ts +1 -1
  15. package/dist/@react-bindings/wrappers/StreamSearchResults.d.ts +1 -1
  16. package/dist/index-react-bindings.browser.cjs +178 -35
  17. package/dist/index-react-bindings.browser.cjs.map +1 -1
  18. package/dist/index-react-bindings.browser.js +175 -36
  19. package/dist/index-react-bindings.browser.js.map +1 -1
  20. package/dist/index-react-bindings.node.cjs +178 -35
  21. package/dist/index-react-bindings.node.cjs.map +1 -1
  22. package/dist/index-react-bindings.node.js +175 -36
  23. package/dist/index-react-bindings.node.js.map +1 -1
  24. package/dist/index.browser.cjs +328 -180
  25. package/dist/index.browser.cjs.map +1 -1
  26. package/dist/index.browser.js +328 -181
  27. package/dist/index.browser.js.map +1 -1
  28. package/dist/index.d.ts +1 -5
  29. package/dist/index.node.cjs +328 -180
  30. package/dist/index.node.cjs.map +1 -1
  31. package/dist/index.node.js +328 -181
  32. package/dist/index.node.js.map +1 -1
  33. package/dist/src/common/{ActivitySearchSource.d.ts → search/ActivitySearchSource.d.ts} +3 -3
  34. package/dist/src/common/{BaseSearchSource.d.ts → search/BaseSearchSource.d.ts} +41 -35
  35. package/dist/src/common/{FeedSearchSource.d.ts → search/FeedSearchSource.d.ts} +3 -3
  36. package/dist/src/common/{SearchController.d.ts → search/SearchController.d.ts} +1 -3
  37. package/dist/src/common/{UserSearchSource.d.ts → search/UserSearchSource.d.ts} +4 -4
  38. package/dist/src/common/search/index.d.ts +6 -0
  39. package/dist/src/common/search/types.d.ts +22 -0
  40. package/dist/src/common/types.d.ts +1 -0
  41. package/dist/src/feed/event-handlers/activity/handle-activity-deleted.d.ts +5 -12
  42. package/dist/src/feed/event-handlers/activity/handle-activity-marked.d.ts +11 -0
  43. package/dist/src/feed/event-handlers/activity/index.d.ts +1 -0
  44. package/dist/src/feed/event-handlers/notification-feed/handle-notification-feed-updated.d.ts +8 -1
  45. package/dist/src/feed/feed.d.ts +2 -2
  46. package/dist/src/gen/models/index.d.ts +58 -26
  47. package/dist/tsconfig.tsbuildinfo +1 -1
  48. package/index.ts +1 -5
  49. package/package.json +1 -1
  50. package/src/common/{ActivitySearchSource.ts → search/ActivitySearchSource.ts} +3 -3
  51. package/src/common/{BaseSearchSource.ts → search/BaseSearchSource.ts} +137 -69
  52. package/src/common/{FeedSearchSource.ts → search/FeedSearchSource.ts} +3 -3
  53. package/src/common/{SearchController.ts → search/SearchController.ts} +2 -7
  54. package/src/common/{UserSearchSource.ts → search/UserSearchSource.ts} +3 -3
  55. package/src/common/search/index.ts +6 -0
  56. package/src/common/search/types.ts +21 -0
  57. package/src/common/types.ts +2 -0
  58. package/src/feed/event-handlers/activity/activity-marked-utils.test.ts +208 -0
  59. package/src/feed/event-handlers/activity/activity-utils.test.ts +2 -2
  60. package/src/feed/event-handlers/activity/handle-activity-added.test.ts +86 -0
  61. package/src/feed/event-handlers/activity/handle-activity-deleted.test.ts +117 -0
  62. package/src/feed/event-handlers/activity/handle-activity-deleted.ts +8 -4
  63. package/src/feed/event-handlers/activity/handle-activity-marked.ts +68 -0
  64. package/src/feed/event-handlers/activity/handle-activity-reaction-added.test.ts +15 -15
  65. package/src/feed/event-handlers/activity/handle-activity-reaction-deleted.test.ts +14 -14
  66. package/src/feed/event-handlers/activity/handle-activity-unpinned.test.ts +4 -3
  67. package/src/feed/event-handlers/activity/handle-activity-updated.test.ts +4 -4
  68. package/src/feed/event-handlers/activity/index.ts +2 -1
  69. package/src/feed/event-handlers/bookmark/handle-bookmark-added.test.ts +14 -14
  70. package/src/feed/event-handlers/bookmark/handle-bookmark-deleted.test.ts +14 -14
  71. package/src/feed/event-handlers/bookmark/handle-bookmark-updated.test.ts +16 -16
  72. package/src/feed/event-handlers/comment/handle-comment-added.test.ts +147 -0
  73. package/src/feed/event-handlers/comment/handle-comment-deleted.test.ts +133 -0
  74. package/src/feed/event-handlers/comment/handle-comment-deleted.ts +24 -10
  75. package/src/feed/event-handlers/comment/handle-comment-reaction.test.ts +315 -0
  76. package/src/feed/event-handlers/comment/handle-comment-updated.test.ts +131 -0
  77. package/src/feed/event-handlers/feed-member/handle-feed-member-added.test.ts +75 -0
  78. package/src/feed/event-handlers/feed-member/handle-feed-member-removed.test.ts +82 -0
  79. package/src/feed/event-handlers/feed-member/handle-feed-member-removed.ts +19 -9
  80. package/src/feed/event-handlers/feed-member/handle-feed-member-updated.test.ts +84 -0
  81. package/src/feed/event-handlers/follow/handle-follow-created.test.ts +7 -7
  82. package/src/feed/event-handlers/follow/handle-follow-deleted.test.ts +2 -2
  83. package/src/feed/event-handlers/follow/handle-follow-updated.test.ts +1 -1
  84. package/src/feed/event-handlers/notification-feed/handle-notification-feed-updated.test.ts +120 -0
  85. package/src/feed/event-handlers/notification-feed/handle-notification-feed-updated.ts +47 -3
  86. package/src/feed/feed.ts +4 -2
  87. package/src/gen/feeds/FeedsApi.ts +6 -0
  88. package/src/gen/model-decoders/decoders.ts +12 -0
  89. package/src/gen/models/index.ts +90 -34
  90. package/src/test-utils/response-generators.ts +230 -0
  91. package/dist/src/test-utils/index.d.ts +0 -1
  92. package/dist/src/test-utils/response-generators.d.ts +0 -54
@@ -0,0 +1,86 @@
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/response-generators';
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
+ });
@@ -0,0 +1,117 @@
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
+ });
@@ -3,12 +3,14 @@ import type {
3
3
  ActivityPinResponse,
4
4
  ActivityResponse,
5
5
  } from '../../../gen/models';
6
- import type { EventPayload } from '../../../types-internal';
6
+ import type { EventPayload, UpdateStateResult } from '../../../types-internal';
7
7
 
8
8
  export const removeActivityFromState = (
9
9
  activityResponse: ActivityResponse,
10
10
  activities: ActivityResponse[] | undefined,
11
- ) => {
11
+ ): UpdateStateResult<{
12
+ activities: ActivityResponse[] | undefined;
13
+ }> => {
12
14
  const index =
13
15
  activities?.findIndex((activity) => activity.id === activityResponse.id) ??
14
16
  -1;
@@ -25,7 +27,9 @@ export const removeActivityFromState = (
25
27
  export const removePinnedActivityFromState = (
26
28
  activityResponse: ActivityResponse,
27
29
  pinnedActivities: ActivityPinResponse[] | undefined,
28
- ) => {
30
+ ): UpdateStateResult<{
31
+ pinned_activities: ActivityPinResponse[] | undefined;
32
+ }> => {
29
33
  const index =
30
34
  pinnedActivities?.findIndex(
31
35
  (pinnedActivity) => pinnedActivity.activity.id === activityResponse.id,
@@ -34,7 +38,7 @@ export const removePinnedActivityFromState = (
34
38
  if (index !== -1) {
35
39
  const newActivities = [...pinnedActivities!];
36
40
  newActivities.splice(index, 1);
37
- return { changed: true, activities: newActivities };
41
+ return { changed: true, pinned_activities: newActivities };
38
42
  } else {
39
43
  return { changed: false, pinned_activities: pinnedActivities };
40
44
  }
@@ -0,0 +1,68 @@
1
+ import {
2
+ ActivityMarkEvent,
3
+ NotificationStatusResponse,
4
+ } from '../../../gen/models';
5
+ import { EventPayload, UpdateStateResult } from '../../../types-internal';
6
+ import { Feed } from '../../feed';
7
+
8
+ export const updateNotificationStatusFromActivityMarked = (
9
+ event: ActivityMarkEvent,
10
+ currentNotificationStatus: NotificationStatusResponse | undefined,
11
+ aggregatedActivities: Array<{ group: string }> = [],
12
+ ): UpdateStateResult<{
13
+ data?: { notification_status: NotificationStatusResponse };
14
+ }> => {
15
+ if (!currentNotificationStatus) {
16
+ return {
17
+ changed: false,
18
+ };
19
+ }
20
+
21
+ const newState = {
22
+ ...currentNotificationStatus,
23
+ };
24
+
25
+ if (event.mark_all_read) {
26
+ const allGroupIds = aggregatedActivities.map((activity) => activity.group);
27
+ newState.read_activities = [
28
+ ...new Set([
29
+ ...(currentNotificationStatus.read_activities ?? []),
30
+ ...allGroupIds,
31
+ ]),
32
+ ];
33
+ }
34
+
35
+ if (event.mark_read && event.mark_read.length > 0) {
36
+ newState.read_activities = [
37
+ ...new Set([
38
+ ...(currentNotificationStatus?.read_activities ?? []),
39
+ ...event.mark_read,
40
+ ]),
41
+ ];
42
+ }
43
+
44
+ if (event.mark_all_seen) {
45
+ newState.last_seen_at = new Date();
46
+ }
47
+
48
+ return {
49
+ changed: true,
50
+ data: { notification_status: newState },
51
+ };
52
+ };
53
+
54
+ export function handleActivityMarked(
55
+ this: Feed,
56
+ event: EventPayload<'feeds.activity.marked'>,
57
+ ) {
58
+ const result = updateNotificationStatusFromActivityMarked(
59
+ event,
60
+ this.currentState.notification_status,
61
+ this.currentState.aggregated_activities,
62
+ );
63
+ if (result.changed) {
64
+ this.state.partialNext({
65
+ notification_status: result.data?.notification_status,
66
+ });
67
+ }
68
+ }
@@ -58,8 +58,8 @@ describe(handleActivityReactionAdded.name, () => {
58
58
 
59
59
  const stateBefore = feed.currentState;
60
60
 
61
- expect(stateBefore.activities![0].reaction_count).toEqual(0);
62
- expect(stateBefore.pinned_activities![0].activity.reaction_count).toEqual(
61
+ expect(stateBefore.activities![0].reaction_count).toBe(0);
62
+ expect(stateBefore.pinned_activities![0].activity.reaction_count).toBe(
63
63
  0,
64
64
  );
65
65
 
@@ -71,14 +71,14 @@ describe(handleActivityReactionAdded.name, () => {
71
71
  expect(stateAfter.pinned_activities![0].activity.own_reactions).toContain(
72
72
  event.reaction,
73
73
  );
74
- expect(stateAfter.activities![0].own_bookmarks).toEqual(
74
+ expect(stateAfter.activities![0].own_bookmarks).toBe(
75
75
  stateBefore.activities![0].own_bookmarks,
76
76
  );
77
- expect(stateAfter.pinned_activities![0].activity.own_bookmarks).toEqual(
77
+ expect(stateAfter.pinned_activities![0].activity.own_bookmarks).toBe(
78
78
  stateBefore.pinned_activities![0].activity.own_bookmarks,
79
79
  );
80
- expect(stateAfter.activities![0].reaction_count).toEqual(1);
81
- expect(stateAfter.pinned_activities![0].activity.reaction_count).toEqual(1);
80
+ expect(stateAfter.activities![0].reaction_count).toBe(1);
81
+ expect(stateAfter.pinned_activities![0].activity.reaction_count).toBe(1);
82
82
  });
83
83
 
84
84
  it('does not add to own_reactions if reaction is from another user but still updates activity', () => {
@@ -102,8 +102,8 @@ describe(handleActivityReactionAdded.name, () => {
102
102
 
103
103
  const stateBefore = feed.currentState;
104
104
 
105
- expect(stateBefore.activities![0].reaction_count).toEqual(0);
106
- expect(stateBefore.pinned_activities![0].activity.reaction_count).toEqual(
105
+ expect(stateBefore.activities![0].reaction_count).toBe(0);
106
+ expect(stateBefore.pinned_activities![0].activity.reaction_count).toBe(
107
107
  0,
108
108
  );
109
109
 
@@ -115,18 +115,18 @@ describe(handleActivityReactionAdded.name, () => {
115
115
  expect(
116
116
  stateAfter.pinned_activities![0].activity.own_reactions,
117
117
  ).toHaveLength(0);
118
- expect(stateAfter.activities![0].reaction_count).toEqual(1);
119
- expect(stateAfter.pinned_activities![0].activity.reaction_count).toEqual(1);
120
- expect(stateAfter.activities![0].own_bookmarks).toEqual(
118
+ expect(stateAfter.activities![0].reaction_count).toBe(1);
119
+ expect(stateAfter.pinned_activities![0].activity.reaction_count).toBe(1);
120
+ expect(stateAfter.activities![0].own_bookmarks).toBe(
121
121
  stateBefore.activities![0].own_bookmarks,
122
122
  );
123
- expect(stateAfter.pinned_activities![0].activity.own_bookmarks).toEqual(
123
+ expect(stateAfter.pinned_activities![0].activity.own_bookmarks).toBe(
124
124
  stateBefore.pinned_activities![0].activity.own_bookmarks,
125
125
  );
126
- expect(stateAfter.activities![0].own_reactions).toEqual(
126
+ expect(stateAfter.activities![0].own_reactions).toBe(
127
127
  stateBefore.activities![0].own_reactions,
128
128
  );
129
- expect(stateAfter.pinned_activities![0].activity.own_reactions).toEqual(
129
+ expect(stateAfter.pinned_activities![0].activity.own_reactions).toBe(
130
130
  stateBefore.pinned_activities![0].activity.own_reactions,
131
131
  );
132
132
  });
@@ -152,6 +152,6 @@ describe(handleActivityReactionAdded.name, () => {
152
152
 
153
153
  const stateAfter = feed.currentState;
154
154
 
155
- expect(stateAfter).toEqual(stateBefore);
155
+ expect(stateAfter).toBe(stateBefore);
156
156
  });
157
157
  });
@@ -72,8 +72,8 @@ describe(handleActivityReactionDeleted.name, () => {
72
72
  expect(
73
73
  stateBefore.pinned_activities![0].activity.own_reactions,
74
74
  ).toHaveLength(1);
75
- expect(stateBefore.activities![0].reaction_count).toEqual(1);
76
- expect(stateBefore.pinned_activities![0].activity.reaction_count).toEqual(
75
+ expect(stateBefore.activities![0].reaction_count).toBe(1);
76
+ expect(stateBefore.pinned_activities![0].activity.reaction_count).toBe(
77
77
  1,
78
78
  );
79
79
 
@@ -84,12 +84,12 @@ describe(handleActivityReactionDeleted.name, () => {
84
84
  expect(
85
85
  stateAfter.pinned_activities![0].activity.own_reactions,
86
86
  ).toHaveLength(0);
87
- expect(stateAfter.activities![0].reaction_count).toEqual(0);
88
- expect(stateAfter.pinned_activities![0].activity.reaction_count).toEqual(0);
89
- expect(stateAfter.activities![0].own_bookmarks).toEqual(
87
+ expect(stateAfter.activities![0].reaction_count).toBe(0);
88
+ expect(stateAfter.pinned_activities![0].activity.reaction_count).toBe(0);
89
+ expect(stateAfter.activities![0].own_bookmarks).toBe(
90
90
  stateBefore.activities![0].own_bookmarks,
91
91
  );
92
- expect(stateAfter.pinned_activities![0].activity.own_bookmarks).toEqual(
92
+ expect(stateAfter.pinned_activities![0].activity.own_bookmarks).toBe(
93
93
  stateBefore.pinned_activities![0].activity.own_bookmarks,
94
94
  );
95
95
  });
@@ -130,8 +130,8 @@ describe(handleActivityReactionDeleted.name, () => {
130
130
  expect(
131
131
  stateBefore.pinned_activities![0].activity.own_reactions,
132
132
  ).toHaveLength(1);
133
- expect(stateBefore.activities![0].reaction_count).toEqual(1);
134
- expect(stateBefore.pinned_activities![0].activity.reaction_count).toEqual(
133
+ expect(stateBefore.activities![0].reaction_count).toBe(1);
134
+ expect(stateBefore.pinned_activities![0].activity.reaction_count).toBe(
135
135
  1,
136
136
  );
137
137
 
@@ -139,23 +139,23 @@ describe(handleActivityReactionDeleted.name, () => {
139
139
 
140
140
  const stateAfter = feed.currentState;
141
141
  expect(stateAfter.activities![0].own_reactions).toHaveLength(1);
142
- expect(stateAfter.activities![0].own_reactions).toEqual(
142
+ expect(stateAfter.activities![0].own_reactions).toBe(
143
143
  stateBefore.activities![0].own_reactions,
144
144
  );
145
- expect(stateAfter.pinned_activities![0].activity.own_reactions).toEqual(
145
+ expect(stateAfter.pinned_activities![0].activity.own_reactions).toBe(
146
146
  stateBefore.pinned_activities![0].activity.own_reactions,
147
147
  );
148
- expect(stateAfter.activities![0].own_bookmarks).toEqual(
148
+ expect(stateAfter.activities![0].own_bookmarks).toBe(
149
149
  stateBefore.activities![0].own_bookmarks,
150
150
  );
151
- expect(stateAfter.pinned_activities![0].activity.own_bookmarks).toEqual(
151
+ expect(stateAfter.pinned_activities![0].activity.own_bookmarks).toBe(
152
152
  stateBefore.pinned_activities![0].activity.own_bookmarks,
153
153
  );
154
154
  expect(
155
155
  stateAfter.pinned_activities![0].activity.own_reactions,
156
156
  ).toHaveLength(1);
157
- expect(stateAfter.activities![0].reaction_count).toEqual(0);
158
- expect(stateAfter.pinned_activities![0].activity.reaction_count).toEqual(0);
157
+ expect(stateAfter.activities![0].reaction_count).toBe(0);
158
+ expect(stateAfter.pinned_activities![0].activity.reaction_count).toBe(0);
159
159
  });
160
160
 
161
161
  it('does nothing if activity is not found', () => {
@@ -22,7 +22,7 @@ function makeUnpinnedEvent(
22
22
  pinned_activity: {
23
23
  created_at: pinnedActivity.created_at,
24
24
  duration: '0',
25
- fid: pinnedActivity.feed,
25
+ feed: pinnedActivity.feed,
26
26
  user_id: pinnedActivity.user.id,
27
27
  activity: pinnedActivity.activity,
28
28
  },
@@ -67,7 +67,7 @@ describe(handleActivityUnpinned.name, () => {
67
67
  const stateBefore = feed.currentState;
68
68
  handleActivityUnpinned.call(feed, event);
69
69
  const stateAfter = feed.currentState;
70
- expect(stateAfter.pinned_activities).toEqual(stateBefore.pinned_activities);
70
+ expect(stateAfter.pinned_activities).toBe(stateBefore.pinned_activities);
71
71
  });
72
72
 
73
73
  it('does nothing if pinned_activities is empty', () => {
@@ -76,9 +76,10 @@ describe(handleActivityUnpinned.name, () => {
76
76
  pinned_activities: [],
77
77
  }));
78
78
  const event = makeUnpinnedEvent(pinnedActivity);
79
+ const stateBefore = feed.currentState;
79
80
  handleActivityUnpinned.call(feed, event);
80
81
  const stateAfter = feed.currentState;
81
- expect(stateAfter.pinned_activities).toEqual([]);
82
+ expect(stateAfter).toBe(stateBefore);
82
83
  });
83
84
 
84
85
  it('does nothing if pinned_activities is undefined', () => {
@@ -77,16 +77,16 @@ describe(handleActivityUpdated.name, () => {
77
77
  id: 'activity-1',
78
78
  text: 'updated text',
79
79
  });
80
- expect(stateAfter.activities![0].own_reactions).toEqual(
80
+ expect(stateAfter.activities![0].own_reactions).toBe(
81
81
  stateBefore.activities![0].own_reactions,
82
82
  );
83
- expect(stateAfter.activities![0].own_bookmarks).toEqual(
83
+ expect(stateAfter.activities![0].own_bookmarks).toBe(
84
84
  stateBefore.activities![0].own_bookmarks,
85
85
  );
86
- expect(stateAfter.pinned_activities![0].activity.own_reactions).toEqual(
86
+ expect(stateAfter.pinned_activities![0].activity.own_reactions).toBe(
87
87
  stateBefore.pinned_activities![0].activity.own_reactions,
88
88
  );
89
- expect(stateAfter.pinned_activities![0].activity.own_bookmarks).toEqual(
89
+ expect(stateAfter.pinned_activities![0].activity.own_bookmarks).toBe(
90
90
  stateBefore.pinned_activities![0].activity.own_bookmarks,
91
91
  );
92
92
  });
@@ -3,4 +3,5 @@ export * from './handle-activity-deleted';
3
3
  export * from './handle-activity-removed-from-feed';
4
4
  export * from './handle-activity-updated';
5
5
  export * from './handle-activity-reaction-added';
6
- export * from './handle-activity-reaction-deleted';
6
+ export * from './handle-activity-reaction-deleted';
7
+ export * from './handle-activity-marked';
@@ -65,8 +65,8 @@ describe(handleBookmarkAdded.name, () => {
65
65
  expect(
66
66
  stateBefore.pinned_activities![0].activity.own_bookmarks,
67
67
  ).toHaveLength(0);
68
- expect(stateBefore.activities![0].bookmark_count).toEqual(0);
69
- expect(stateBefore.pinned_activities![0].activity.bookmark_count).toEqual(
68
+ expect(stateBefore.activities![0].bookmark_count).toBe(0);
69
+ expect(stateBefore.pinned_activities![0].activity.bookmark_count).toBe(
70
70
  0,
71
71
  );
72
72
 
@@ -81,14 +81,14 @@ describe(handleBookmarkAdded.name, () => {
81
81
  expect(stateAfter.pinned_activities![0].activity.own_bookmarks).toContain(
82
82
  event.bookmark,
83
83
  );
84
- expect(stateAfter.activities![0].own_reactions).toEqual(
84
+ expect(stateAfter.activities![0].own_reactions).toBe(
85
85
  stateBefore.activities![0].own_reactions,
86
86
  );
87
- expect(stateAfter.pinned_activities![0].activity.own_reactions).toEqual(
87
+ expect(stateAfter.pinned_activities![0].activity.own_reactions).toBe(
88
88
  stateBefore.pinned_activities![0].activity.own_reactions,
89
89
  );
90
- expect(stateAfter.activities![0].bookmark_count).toEqual(1);
91
- expect(stateAfter.pinned_activities![0].activity.bookmark_count).toEqual(1);
90
+ expect(stateAfter.activities![0].bookmark_count).toBe(1);
91
+ expect(stateAfter.pinned_activities![0].activity.bookmark_count).toBe(1);
92
92
  });
93
93
 
94
94
  it('does not add to own_bookmarks if bookmark is from another user but still updates activity', () => {
@@ -120,28 +120,28 @@ describe(handleBookmarkAdded.name, () => {
120
120
  expect(
121
121
  stateBefore.pinned_activities![0].activity.own_bookmarks,
122
122
  ).toHaveLength(0);
123
- expect(stateBefore.activities![0].bookmark_count).toEqual(0);
124
- expect(stateBefore.pinned_activities![0].activity.bookmark_count).toEqual(
123
+ expect(stateBefore.activities![0].bookmark_count).toBe(0);
124
+ expect(stateBefore.pinned_activities![0].activity.bookmark_count).toBe(
125
125
  0,
126
126
  );
127
127
 
128
128
  handleBookmarkAdded.call(feed, event);
129
129
 
130
130
  const stateAfter = feed.currentState;
131
- expect(stateAfter.activities![0].own_bookmarks).toEqual(
131
+ expect(stateAfter.activities![0].own_bookmarks).toBe(
132
132
  stateBefore.activities![0].own_bookmarks,
133
133
  );
134
- expect(stateAfter.pinned_activities![0].activity.own_bookmarks).toEqual(
134
+ expect(stateAfter.pinned_activities![0].activity.own_bookmarks).toBe(
135
135
  stateBefore.pinned_activities![0].activity.own_bookmarks,
136
136
  );
137
- expect(stateAfter.activities![0].own_reactions).toEqual(
137
+ expect(stateAfter.activities![0].own_reactions).toBe(
138
138
  stateBefore.activities![0].own_reactions,
139
139
  );
140
- expect(stateAfter.pinned_activities![0].activity.own_reactions).toEqual(
140
+ expect(stateAfter.pinned_activities![0].activity.own_reactions).toBe(
141
141
  stateBefore.pinned_activities![0].activity.own_reactions,
142
142
  );
143
- expect(stateAfter.activities![0].bookmark_count).toEqual(1);
144
- expect(stateAfter.pinned_activities![0].activity.bookmark_count).toEqual(1);
143
+ expect(stateAfter.activities![0].bookmark_count).toBe(1);
144
+ expect(stateAfter.pinned_activities![0].activity.bookmark_count).toBe(1);
145
145
  });
146
146
 
147
147
  it('does nothing if activity is not found', () => {
@@ -71,8 +71,8 @@ describe(handleBookmarkDeleted.name, () => {
71
71
  expect(
72
72
  stateBefore.pinned_activities![0].activity.own_bookmarks,
73
73
  ).toHaveLength(1);
74
- expect(stateBefore.activities![0].bookmark_count).toEqual(1);
75
- expect(stateBefore.pinned_activities![0].activity.bookmark_count).toEqual(
74
+ expect(stateBefore.activities![0].bookmark_count).toBe(1);
75
+ expect(stateBefore.pinned_activities![0].activity.bookmark_count).toBe(
76
76
  1,
77
77
  );
78
78
 
@@ -83,14 +83,14 @@ describe(handleBookmarkDeleted.name, () => {
83
83
  expect(
84
84
  stateAfter.pinned_activities![0].activity.own_bookmarks,
85
85
  ).toHaveLength(0);
86
- expect(stateAfter.activities![0].own_reactions).toEqual(
86
+ expect(stateAfter.activities![0].own_reactions).toBe(
87
87
  stateBefore.activities![0].own_reactions,
88
88
  );
89
- expect(stateAfter.pinned_activities![0].activity.own_reactions).toEqual(
89
+ expect(stateAfter.pinned_activities![0].activity.own_reactions).toBe(
90
90
  stateBefore.pinned_activities![0].activity.own_reactions,
91
91
  );
92
- expect(stateAfter.activities![0].bookmark_count).toEqual(0);
93
- expect(stateAfter.pinned_activities![0].activity.bookmark_count).toEqual(0);
92
+ expect(stateAfter.activities![0].bookmark_count).toBe(0);
93
+ expect(stateAfter.pinned_activities![0].activity.bookmark_count).toBe(0);
94
94
  });
95
95
 
96
96
  it('does not remove from own_bookmarks if bookmark is from another user but still updates activity', () => {
@@ -127,28 +127,28 @@ describe(handleBookmarkDeleted.name, () => {
127
127
  expect(
128
128
  stateBefore.pinned_activities![0].activity.own_bookmarks,
129
129
  ).toHaveLength(1);
130
- expect(stateBefore.activities![0].bookmark_count).toEqual(1);
131
- expect(stateBefore.pinned_activities![0].activity.bookmark_count).toEqual(
130
+ expect(stateBefore.activities![0].bookmark_count).toBe(1);
131
+ expect(stateBefore.pinned_activities![0].activity.bookmark_count).toBe(
132
132
  1,
133
133
  );
134
134
 
135
135
  handleBookmarkDeleted.call(feed, event);
136
136
 
137
137
  const stateAfter = feed.currentState;
138
- expect(stateAfter.activities![0].own_bookmarks).toEqual(
138
+ expect(stateAfter.activities![0].own_bookmarks).toBe(
139
139
  stateBefore.activities![0].own_bookmarks,
140
140
  );
141
- expect(stateAfter.pinned_activities![0].activity.own_bookmarks).toEqual(
141
+ expect(stateAfter.pinned_activities![0].activity.own_bookmarks).toBe(
142
142
  stateBefore.pinned_activities![0].activity.own_bookmarks,
143
143
  );
144
- expect(stateAfter.activities![0].own_reactions).toEqual(
144
+ expect(stateAfter.activities![0].own_reactions).toBe(
145
145
  stateBefore.activities![0].own_reactions,
146
146
  );
147
- expect(stateAfter.pinned_activities![0].activity.own_reactions).toEqual(
147
+ expect(stateAfter.pinned_activities![0].activity.own_reactions).toBe(
148
148
  stateBefore.pinned_activities![0].activity.own_reactions,
149
149
  );
150
- expect(stateAfter.activities![0].bookmark_count).toEqual(0);
151
- expect(stateAfter.pinned_activities![0].activity.bookmark_count).toEqual(0);
150
+ expect(stateAfter.activities![0].bookmark_count).toBe(0);
151
+ expect(stateAfter.pinned_activities![0].activity.bookmark_count).toBe(0);
152
152
  });
153
153
 
154
154
  it('does nothing if activity is not found', () => {