@amityco/ts-sdk 0.0.1-beta.37 → 0.0.1-beta.39

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 (251) hide show
  1. package/.eslintrc.json +3 -5
  2. package/dist/@types/core/events.d.ts +1 -0
  3. package/dist/@types/core/events.d.ts.map +1 -1
  4. package/dist/@types/core/model.d.ts +2 -0
  5. package/dist/@types/core/model.d.ts.map +1 -1
  6. package/dist/@types/domains/category.d.ts +7 -0
  7. package/dist/@types/domains/category.d.ts.map +1 -1
  8. package/dist/@types/domains/channel.d.ts +2 -2
  9. package/dist/@types/domains/channel.d.ts.map +1 -1
  10. package/dist/@types/domains/community.d.ts +12 -0
  11. package/dist/@types/domains/community.d.ts.map +1 -1
  12. package/dist/@types/domains/feed.d.ts +1 -2
  13. package/dist/@types/domains/feed.d.ts.map +1 -1
  14. package/dist/@types/domains/message.d.ts +1 -1
  15. package/dist/@types/domains/message.d.ts.map +1 -1
  16. package/dist/@types/domains/post.d.ts +1 -1
  17. package/dist/@types/domains/post.d.ts.map +1 -1
  18. package/dist/@types/domains/user.d.ts +8 -0
  19. package/dist/@types/domains/user.d.ts.map +1 -1
  20. package/dist/@types/global.d.ts +5 -0
  21. package/dist/@types/global.d.ts.map +1 -1
  22. package/dist/category/api/queryCategories.d.ts +1 -5
  23. package/dist/category/api/queryCategories.d.ts.map +1 -1
  24. package/dist/category/observers/index.d.ts +2 -0
  25. package/dist/category/observers/index.d.ts.map +1 -0
  26. package/dist/category/observers/liveCategories.d.ts +18 -0
  27. package/dist/category/observers/liveCategories.d.ts.map +1 -0
  28. package/dist/category/observers/tests/liveCategories.test.d.ts +2 -0
  29. package/dist/category/observers/tests/liveCategories.test.d.ts.map +1 -0
  30. package/dist/channel/api/tests/getChannels.test.d.ts +2 -0
  31. package/dist/channel/api/tests/getChannels.test.d.ts.map +1 -0
  32. package/dist/channel/api/tests/leaveChannel.test.d.ts +2 -0
  33. package/dist/channel/api/tests/leaveChannel.test.d.ts.map +1 -0
  34. package/dist/channel/observers/liveChannel.d.ts.map +1 -1
  35. package/dist/channel/observers/liveChannels.d.ts.map +1 -1
  36. package/dist/client/api/accessTokenExpiryWatcher.d.ts +4 -1
  37. package/dist/client/api/accessTokenExpiryWatcher.d.ts.map +1 -1
  38. package/dist/client/api/connectClient.d.ts.map +1 -1
  39. package/dist/client/api/getToken.d.ts +3 -1
  40. package/dist/client/api/getToken.d.ts.map +1 -1
  41. package/dist/client/utils/setClientToken.d.ts +3 -3
  42. package/dist/comment/api/deleteComment.d.ts.map +1 -1
  43. package/dist/comment/api/getComment.d.ts.map +1 -1
  44. package/dist/comment/observers/index.d.ts +1 -0
  45. package/dist/comment/observers/index.d.ts.map +1 -1
  46. package/dist/comment/observers/liveComment.d.ts +21 -0
  47. package/dist/comment/observers/liveComment.d.ts.map +1 -0
  48. package/dist/comment/observers/tests/liveComment.test.d.ts +2 -0
  49. package/dist/comment/observers/tests/liveComment.test.d.ts.map +1 -0
  50. package/dist/community/api/queryCommunities.d.ts +1 -10
  51. package/dist/community/api/queryCommunities.d.ts.map +1 -1
  52. package/dist/community/events/index.d.ts +1 -0
  53. package/dist/community/events/index.d.ts.map +1 -1
  54. package/dist/community/events/onCommunityUserChanged.d.ts +17 -0
  55. package/dist/community/events/onCommunityUserChanged.d.ts.map +1 -0
  56. package/dist/community/events/utils.d.ts +1 -0
  57. package/dist/community/events/utils.d.ts.map +1 -1
  58. package/dist/community/observers/index.d.ts +1 -0
  59. package/dist/community/observers/index.d.ts.map +1 -1
  60. package/dist/community/observers/liveCommunities.d.ts +20 -0
  61. package/dist/community/observers/liveCommunities.d.ts.map +1 -0
  62. package/dist/community/observers/tests/liveCommunities.test.d.ts +2 -0
  63. package/dist/community/observers/tests/liveCommunities.test.d.ts.map +1 -0
  64. package/dist/core/events.d.ts +3 -3
  65. package/dist/core/events.d.ts.map +1 -1
  66. package/dist/core/model/idResolvers.d.ts.map +1 -1
  67. package/dist/core/model/identifyModel.d.ts.map +1 -1
  68. package/dist/core/model/index.d.ts.map +1 -1
  69. package/dist/core/query/filtering.d.ts +10 -0
  70. package/dist/core/query/filtering.d.ts.map +1 -1
  71. package/dist/core/query/paging.d.ts +2 -2
  72. package/dist/core/query/paging.d.ts.map +1 -1
  73. package/dist/core/query/sorting.d.ts +6 -0
  74. package/dist/core/query/sorting.d.ts.map +1 -1
  75. package/dist/core/query/tests/paging.test.d.ts +2 -0
  76. package/dist/core/query/tests/paging.test.d.ts.map +1 -0
  77. package/dist/core/transports/http.d.ts +0 -5
  78. package/dist/core/transports/http.d.ts.map +1 -1
  79. package/dist/file/api/test/createImage.test.d.ts +2 -0
  80. package/dist/file/api/test/createImage.test.d.ts.map +1 -0
  81. package/dist/file/api/test/createVideo.test.d.ts +2 -0
  82. package/dist/file/api/test/createVideo.test.d.ts.map +1 -0
  83. package/dist/index.cjs.js +607 -252
  84. package/dist/index.d.ts +1 -0
  85. package/dist/index.d.ts.map +1 -1
  86. package/dist/index.esm.js +599 -251
  87. package/dist/index.umd.js +4 -4
  88. package/dist/message/api/queryMessages.d.ts +2 -2
  89. package/dist/message/api/queryMessages.d.ts.map +1 -1
  90. package/dist/message/observers/liveMessage.d.ts.map +1 -1
  91. package/dist/post/observers/index.d.ts +1 -0
  92. package/dist/post/observers/index.d.ts.map +1 -1
  93. package/dist/post/observers/livePost.d.ts +21 -0
  94. package/dist/post/observers/livePost.d.ts.map +1 -0
  95. package/dist/post/observers/livePosts.d.ts +2 -2
  96. package/dist/post/observers/livePosts.d.ts.map +1 -1
  97. package/dist/post/observers/tests/livePost.test.d.ts +2 -0
  98. package/dist/post/observers/tests/livePost.test.d.ts.map +1 -0
  99. package/dist/report/api/createReport.d.ts.map +1 -1
  100. package/dist/report/api/deleteReport.d.ts.map +1 -1
  101. package/dist/report/api/tests/createReport.test.d.ts +2 -0
  102. package/dist/report/api/tests/createReport.test.d.ts.map +1 -0
  103. package/dist/report/api/tests/deleteReport.test.d.ts +2 -0
  104. package/dist/report/api/tests/deleteReport.test.d.ts.map +1 -0
  105. package/dist/subChannel/api/tests/deleteSubChannel.test.d.ts +2 -0
  106. package/dist/subChannel/api/tests/deleteSubChannel.test.d.ts.map +1 -0
  107. package/dist/subChannel/api/tests/getSubChannel.test.d.ts +2 -0
  108. package/dist/subChannel/api/tests/getSubChannel.test.d.ts.map +1 -0
  109. package/dist/subChannel/api/tests/getSubChannels.test.d.ts +2 -0
  110. package/dist/subChannel/api/tests/getSubChannels.test.d.ts.map +1 -0
  111. package/dist/subChannel/api/tests/updateSubChannel.test.d.ts +2 -0
  112. package/dist/subChannel/api/tests/updateSubChannel.test.d.ts.map +1 -0
  113. package/dist/subChannel/observers/liveSubChannel.d.ts.map +1 -1
  114. package/dist/user/api/queryUsers.d.ts +1 -6
  115. package/dist/user/api/queryUsers.d.ts.map +1 -1
  116. package/dist/user/api/tests/updateUser.test.d.ts +2 -0
  117. package/dist/user/api/tests/updateUser.test.d.ts.map +1 -0
  118. package/dist/user/observers/index.d.ts +1 -0
  119. package/dist/user/observers/index.d.ts.map +1 -1
  120. package/dist/user/observers/liveUser.d.ts.map +1 -1
  121. package/dist/user/observers/liveUsers.d.ts +18 -0
  122. package/dist/user/observers/liveUsers.d.ts.map +1 -0
  123. package/dist/user/observers/tests/liveUsers.test.d.ts +2 -0
  124. package/dist/user/observers/tests/liveUsers.test.d.ts.map +1 -0
  125. package/dist/utils/liveObject.d.ts +2 -0
  126. package/dist/utils/liveObject.d.ts.map +1 -0
  127. package/dist/utils/tests/dummy/category.d.ts +64 -0
  128. package/dist/utils/tests/dummy/category.d.ts.map +1 -0
  129. package/dist/utils/tests/dummy/channel.d.ts +50 -0
  130. package/dist/utils/tests/dummy/channel.d.ts.map +1 -1
  131. package/dist/utils/tests/dummy/community.d.ts +132 -0
  132. package/dist/utils/tests/dummy/community.d.ts.map +1 -1
  133. package/dist/utils/tests/dummy/feed.d.ts +21 -0
  134. package/dist/utils/tests/dummy/feed.d.ts.map +1 -0
  135. package/dist/utils/tests/dummy/file.d.ts +3 -0
  136. package/dist/utils/tests/dummy/file.d.ts.map +1 -1
  137. package/dist/utils/tests/dummy/index.d.ts +2 -0
  138. package/dist/utils/tests/dummy/index.d.ts.map +1 -1
  139. package/dist/utils/tests/dummy/post.d.ts +11 -0
  140. package/dist/utils/tests/dummy/post.d.ts.map +1 -1
  141. package/dist/utils/tests/dummy/subChannel.d.ts +0 -20
  142. package/dist/utils/tests/dummy/subChannel.d.ts.map +1 -1
  143. package/dist/utils/tests/dummy/user.d.ts +81 -0
  144. package/dist/utils/tests/dummy/user.d.ts.map +1 -1
  145. package/dist/utils/tests/liveObject.test.d.ts +2 -0
  146. package/dist/utils/tests/liveObject.test.d.ts.map +1 -0
  147. package/package.json +4 -4
  148. package/src/@types/core/events.ts +1 -0
  149. package/src/@types/core/model.ts +4 -0
  150. package/src/@types/domains/category.ts +13 -0
  151. package/src/@types/domains/channel.ts +2 -2
  152. package/src/@types/domains/community.ts +25 -0
  153. package/src/@types/domains/feed.ts +1 -3
  154. package/src/@types/domains/message.ts +4 -1
  155. package/src/@types/domains/post.ts +1 -1
  156. package/src/@types/domains/user.ts +14 -0
  157. package/src/@types/global.ts +5 -0
  158. package/src/cache/api/tests/ingestInCache.test.ts +2 -0
  159. package/src/category/api/queryCategories.ts +3 -5
  160. package/src/category/observers/index.ts +1 -0
  161. package/src/category/observers/liveCategories.ts +141 -0
  162. package/src/category/observers/tests/liveCategories.test.ts +147 -0
  163. package/src/channel/api/tests/createChannel.test.ts +30 -6
  164. package/src/channel/api/tests/getChannel.test.ts +3 -1
  165. package/src/channel/api/tests/getChannels.test.ts +97 -0
  166. package/src/channel/api/tests/joinChannel.test.ts +62 -3
  167. package/src/channel/api/tests/leaveChannel.test.ts +90 -0
  168. package/src/channel/api/tests/queryChannels.test.ts +38 -1
  169. package/src/channel/observers/liveChannel.ts +8 -80
  170. package/src/channel/observers/liveChannels.ts +29 -24
  171. package/src/client/api/accessTokenExpiryWatcher.ts +7 -5
  172. package/src/client/api/connectClient.ts +0 -2
  173. package/src/client/api/tests/accessTokenExpiryWatcher.test.ts +8 -5
  174. package/src/comment/api/deleteComment.ts +5 -5
  175. package/src/comment/api/getComment.ts +8 -3
  176. package/src/comment/observers/index.ts +1 -0
  177. package/src/comment/observers/liveComment.ts +43 -0
  178. package/src/comment/observers/tests/liveComment.test.ts +95 -0
  179. package/src/community/api/queryCommunities.ts +3 -10
  180. package/src/community/api/test/addCommunityMember.test.ts +14 -2
  181. package/src/community/api/test/joinCommunity.test.ts +14 -2
  182. package/src/community/api/test/leaveCommunity.test.ts +11 -1
  183. package/src/community/api/test/removeCommunityMembers.test.ts +11 -1
  184. package/src/community/events/index.ts +1 -0
  185. package/src/community/events/onCommunityUserChanged.ts +20 -0
  186. package/src/community/events/test/onCommunityJoined.test.ts +1 -1
  187. package/src/community/events/test/onCommunityUserAdded.test.ts +1 -1
  188. package/src/community/events/test/onCommunityUserBanned.test.ts +1 -1
  189. package/src/community/events/test/onCommunityUserUnbaned.test.ts +1 -1
  190. package/src/community/events/test/utils.test.ts +52 -3
  191. package/src/community/events/utils.ts +49 -0
  192. package/src/community/observers/index.ts +1 -0
  193. package/src/community/observers/liveCommunities.ts +188 -0
  194. package/src/community/observers/tests/liveCommunities.test.ts +284 -0
  195. package/src/core/model/idResolvers.ts +2 -0
  196. package/src/core/model/identifyModel.ts +1 -0
  197. package/src/core/model/index.ts +2 -0
  198. package/src/core/query/filtering.ts +33 -3
  199. package/src/core/query/paging.ts +5 -4
  200. package/src/core/query/sorting.ts +8 -0
  201. package/src/core/query/tests/paging.test.ts +66 -0
  202. package/src/core/transports/http.ts +17 -13
  203. package/src/core/transports/test/http.test.ts +49 -60
  204. package/src/file/api/createFile.ts +1 -1
  205. package/src/file/api/createImage.ts +1 -1
  206. package/src/file/api/createVideo.ts +1 -1
  207. package/src/file/api/test/createImage.test.ts +69 -0
  208. package/src/file/api/test/createVideo.test.ts +81 -0
  209. package/src/index.ts +1 -0
  210. package/src/message/api/queryMessages.ts +7 -7
  211. package/src/message/api/tests/queryMessages.test.ts +6 -6
  212. package/src/message/observers/liveMessage.ts +11 -83
  213. package/src/message/tests/observers/liveMessage.test.ts +1 -143
  214. package/src/message/tests/observers/liveMessages.test.ts +4 -4
  215. package/src/post/observers/index.ts +1 -0
  216. package/src/post/observers/livePost.ts +47 -0
  217. package/src/post/observers/livePosts.ts +14 -22
  218. package/src/post/observers/tests/livePost.test.ts +97 -0
  219. package/src/post/observers/tests/livePosts.test.ts +65 -8
  220. package/src/report/api/createReport.ts +1 -6
  221. package/src/report/api/deleteReport.ts +2 -6
  222. package/src/report/api/tests/createReport.test.ts +93 -0
  223. package/src/report/api/tests/deleteReport.test.ts +93 -0
  224. package/src/stream/api/tests/createStream.test.ts +3 -11
  225. package/src/stream/api/tests/deleteStream.test.ts +5 -3
  226. package/src/subChannel/api/tests/createSubChannel.test.ts +21 -14
  227. package/src/subChannel/api/tests/deleteSubChannel.test.ts +112 -0
  228. package/src/subChannel/api/tests/getSubChannel.test.ts +97 -0
  229. package/src/subChannel/api/tests/getSubChannels.test.ts +97 -0
  230. package/src/subChannel/api/tests/updateSubChannel.test.ts +86 -0
  231. package/src/subChannel/observers/liveSubChannel.ts +6 -56
  232. package/src/subChannel/observers/tests/liveSubChannel.test.ts +0 -82
  233. package/src/user/api/queryUsers.ts +1 -6
  234. package/src/user/api/tests/updateUser.test.ts +60 -0
  235. package/src/user/observers/index.ts +1 -0
  236. package/src/user/observers/liveUser.ts +9 -61
  237. package/src/user/observers/liveUsers.ts +162 -0
  238. package/src/user/observers/tests/liveUsers.test.ts +202 -0
  239. package/src/user/tests/observers/liveUser.test.ts +1 -154
  240. package/src/utils/liveObject.ts +86 -0
  241. package/src/utils/tests/dummy/category.ts +57 -0
  242. package/src/utils/tests/dummy/channel.ts +52 -1
  243. package/src/utils/tests/dummy/community.ts +94 -0
  244. package/src/utils/tests/dummy/feed.ts +13 -0
  245. package/src/utils/tests/dummy/file.ts +32 -0
  246. package/src/utils/tests/dummy/index.ts +3 -0
  247. package/src/utils/tests/dummy/post.ts +62 -47
  248. package/src/utils/tests/dummy/stream.ts +73 -73
  249. package/src/utils/tests/dummy/subChannel.ts +0 -22
  250. package/src/utils/tests/dummy/user.ts +57 -0
  251. package/src/utils/tests/liveObject.test.ts +172 -0
@@ -1,20 +1,44 @@
1
1
  import { disableCache, enableCache, pullFromCache } from '~/cache/api';
2
- import { channelPayload, client } from '~/utils/tests';
2
+ import {
3
+ channelPayload,
4
+ client,
5
+ conversationChannelPayload,
6
+ liveChannelPayload,
7
+ } from '~/utils/tests';
3
8
  import { prepareChannelPayload } from '~/channel/utils';
4
9
  import { createChannel } from '../createChannel';
5
10
 
6
11
  const resPayload = { data: channelPayload };
7
12
 
8
13
  describe('createChannel', () => {
9
- const channel = prepareChannelPayload(channelPayload).channels[0];
10
-
11
- test('it should create a channel', async () => {
14
+ // integration_test_id: 9d80fd54-9e6d-454d-8344-6f9436b8e495
15
+ test('it should create a channel for community', async () => {
12
16
  client.http.post = jest.fn().mockResolvedValueOnce(resPayload);
13
17
 
14
18
  const res = await createChannel({ type: 'community' });
15
19
 
16
20
  expect(res).toBeDefined();
17
- expect(res.data).toStrictEqual(channel);
21
+ expect(res.data).toStrictEqual(prepareChannelPayload(channelPayload).channels[0]);
22
+ });
23
+
24
+ // integration_test_id: cef520ab-027d-4c5b-836c-a7f63ddc5146
25
+ test('it should create a channel for live', async () => {
26
+ client.http.post = jest.fn().mockResolvedValueOnce({ data: liveChannelPayload });
27
+
28
+ const res = await createChannel({ type: 'live' });
29
+
30
+ expect(res).toBeDefined();
31
+ expect(res.data).toStrictEqual(prepareChannelPayload(liveChannelPayload).channels[0]);
32
+ });
33
+
34
+ // integration_test_id: 11a43612-ff6f-4262-874c-4419d342cff1
35
+ test('it should create a channel for conversation', async () => {
36
+ client.http.post = jest.fn().mockResolvedValueOnce({ data: conversationChannelPayload });
37
+
38
+ const res = await createChannel({ type: 'conversation' });
39
+
40
+ expect(res).toBeDefined();
41
+ expect(res.data).toStrictEqual(prepareChannelPayload(conversationChannelPayload).channels[0]);
18
42
  });
19
43
 
20
44
  test('it should add channel to cache', async () => {
@@ -27,7 +51,7 @@ describe('createChannel', () => {
27
51
  const data = pullFromCache(['channel', 'get', channelId]);
28
52
 
29
53
  expect(data).toBeDefined();
30
- expect(data?.data).toStrictEqual(channel);
54
+ expect(data?.data).toStrictEqual(prepareChannelPayload(channelPayload).channels[0]);
31
55
 
32
56
  disableCache();
33
57
  });
@@ -12,7 +12,8 @@ const { channelId } = channelQueryResponse.data.channels[0];
12
12
  const channel = prepareChannelPayload(channelQueryResponse.data).channels[0];
13
13
 
14
14
  describe('getChannel', () => {
15
- test('it should return a channel', async () => {
15
+ // integration_test_id: b331e01c-20db-4f17-979b-b280d8818792
16
+ test('it should return a valid channel', async () => {
16
17
  client.http.get = jest.fn().mockResolvedValueOnce(channelQueryResponse);
17
18
 
18
19
  const expected = channel;
@@ -31,6 +32,7 @@ describe('getChannel', () => {
31
32
  disableCache();
32
33
  });
33
34
 
35
+ // integration_test_id: da9dc3e8-01fd-4e76-a26b-ac8333a69b23
34
36
  test('it should return an error', async () => {
35
37
  client.http.get = jest.fn().mockRejectedValueOnce(new Error('error'));
36
38
 
@@ -0,0 +1,97 @@
1
+ import { disableCache, enableCache, pushToCache, pullFromCache } from '~/cache/api';
2
+ import { client, getChannelsResponse } from '~/utils/tests';
3
+
4
+ import { getChannels } from '../getChannels';
5
+ import { prepareChannelPayload } from '~/channel/utils';
6
+ import { ASCApiError } from '~/core/errors';
7
+
8
+ const channelIds = [
9
+ getChannelsResponse.data.channels[0].channelId,
10
+ getChannelsResponse.data.channels[1].channelId,
11
+ getChannelsResponse.data.channels[2].channelId,
12
+ ];
13
+ const channel = prepareChannelPayload(getChannelsResponse.data).channels;
14
+
15
+ describe('getChannels', () => {
16
+ // integration_test_id: ced0cd3b-1714-499d-862e-0284da1c8bb1
17
+ test('it should return a valid channels', async () => {
18
+ client.http.get = jest.fn().mockResolvedValueOnce(getChannelsResponse);
19
+
20
+ const expected = channel;
21
+ const { data: received } = await getChannels(channelIds);
22
+
23
+ expect(received).toStrictEqual(expected);
24
+ });
25
+
26
+ test('it should update cache after fetch from server', async () => {
27
+ enableCache();
28
+ client.http.get = jest.fn().mockResolvedValue(getChannelsResponse);
29
+ await getChannels(channelIds);
30
+
31
+ const data = getChannels.locally(channelIds);
32
+
33
+ expect(data).toBeDefined();
34
+ expect(data?.data).toEqual(channel);
35
+
36
+ disableCache();
37
+ });
38
+
39
+ // integration_test_id: 344a8f3d-0e54-4eb9-850f-80283e638352
40
+ test('it should return an error 400400 when try to get channels by invalid channel id', async () => {
41
+ const error = new ASCApiError(
42
+ 'Some channel not found',
43
+ Amity.ServerError.ITEM_NOT_FOUND,
44
+ Amity.ErrorLevel.ERROR,
45
+ );
46
+
47
+ client.http.get = jest.fn().mockRejectedValueOnce(error);
48
+
49
+ await expect(getChannels(channelIds)).rejects.toThrow(error);
50
+ });
51
+ });
52
+
53
+ describe('getChannels locally', () => {
54
+ test('it should return data from cache', () => {
55
+ enableCache();
56
+
57
+ const cachedAt = Date.now();
58
+
59
+ pushToCache(['channel', 'get', channelIds[0]], channel[0], { cachedAt });
60
+ pushToCache(['channel', 'get', channelIds[1]], channel[1], { cachedAt });
61
+ pushToCache(['channel', 'get', channelIds[2]], channel[2], { cachedAt });
62
+
63
+ const data = getChannels.locally(channelIds);
64
+
65
+ expect(data).toBeDefined();
66
+ expect(data?.data).toEqual(channel);
67
+ expect(data?.cachedAt).toEqual(cachedAt);
68
+
69
+ disableCache();
70
+ });
71
+
72
+ test('should return undefined if channel not in cache', () => {
73
+ expect(
74
+ getChannels.locally(['non-existent-channel-1', 'non-existent-channel-2']),
75
+ ).toBeUndefined();
76
+ });
77
+
78
+ test('should return undefined if cache not enabled', () => {
79
+ expect(getChannels.locally(channelIds)).toBeUndefined();
80
+ });
81
+
82
+ test('it should return cachedAt same date with oldest record', () => {
83
+ enableCache();
84
+
85
+ const cachedAt = Date.now();
86
+
87
+ pushToCache(['channel', 'get', channelIds[0]], channel[0], { cachedAt });
88
+ pushToCache(['channel', 'get', channelIds[1]], channel[1], { cachedAt: cachedAt + 1 });
89
+ pushToCache(['channel', 'get', channelIds[2]], channel[2], { cachedAt: cachedAt + 2 });
90
+
91
+ const data = getChannels.locally(channelIds);
92
+
93
+ expect(data?.cachedAt).toEqual(cachedAt);
94
+
95
+ disableCache();
96
+ });
97
+ });
@@ -1,4 +1,5 @@
1
1
  import { pullFromCache, enableCache, disableCache } from '~/cache/api';
2
+ import { ASCApiError } from '~/core/errors';
2
3
  import { getResolver } from '~/core/model';
3
4
 
4
5
  import {
@@ -19,6 +20,7 @@ describe('joinChannel', () => {
19
20
 
20
21
  const { channelId } = channel1;
21
22
 
23
+ // integration_test_id: efef33a8-bf09-4dfe-8ed9-e7c3615ad74d
22
24
  test('it should return channelUser', async () => {
23
25
  client.http.post = jest.fn().mockResolvedValueOnce(channelUserQueryResponse);
24
26
 
@@ -44,9 +46,66 @@ describe('joinChannel', () => {
44
46
  disableCache();
45
47
  });
46
48
 
47
- test('it should throw error', async () => {
48
- client.http.post = jest.fn().mockRejectedValueOnce(new Error('error'));
49
+ // integration_test_id: 402a8cd8-6522-42d0-8f40-ccccae0093a1
50
+ test('it should throw error 400400 when user joins channel which does not exist', async () => {
51
+ const apiError = new ASCApiError(
52
+ 'ChannelId Not Found',
53
+ Amity.ServerError.ITEM_NOT_FOUND,
54
+ Amity.ErrorLevel.ERROR,
55
+ );
49
56
 
50
- await expect(joinChannel(channelId)).rejects.toThrow('error');
57
+ client.http.post = jest.fn().mockRejectedValueOnce({
58
+ status: 403,
59
+ data: apiError,
60
+ });
61
+
62
+ try {
63
+ await joinChannel(channelId);
64
+ } catch ({ status = null, data = null }) {
65
+ expect(status).toEqual(403);
66
+ expect(data).toEqual(apiError);
67
+ }
68
+ });
69
+
70
+ // integration_test_id: dcad7f35-586c-400f-8eca-2334d6d7b3e0
71
+ test("it should throw error 400300 when user tries to join channel in which he doesn't have permission", async () => {
72
+ const apiError = new ASCApiError(
73
+ "Can't join the conversation channel",
74
+ Amity.ServerError.FORBIDDEN,
75
+ Amity.ErrorLevel.ERROR,
76
+ );
77
+
78
+ client.http.post = jest.fn().mockRejectedValueOnce({
79
+ status: 403,
80
+ data: apiError,
81
+ });
82
+
83
+ try {
84
+ await joinChannel(channelId);
85
+ } catch ({ status = null, data = null }) {
86
+ expect(status).toEqual(403);
87
+ expect(data).toEqual(apiError);
88
+ }
89
+ });
90
+
91
+ // integration_test_id: 8ccb81b7-a89c-486a-81ed-7371b3ef1c4f
92
+ test('it should throw error 400304 when user tries to join channel in which he is banned', async () => {
93
+ const apiError = new ASCApiError(
94
+ 'User is banned from this channel',
95
+ Amity.ServerError.CHANNEL_BAN,
96
+ Amity.ErrorLevel.ERROR,
97
+ );
98
+
99
+ client.http.post = jest.fn().mockRejectedValueOnce({
100
+ status: 403,
101
+ data: apiError,
102
+ });
103
+
104
+ try {
105
+ await joinChannel(channelId);
106
+ } catch ({ status = null, data = null }) {
107
+ expect(status).toEqual(403);
108
+ expect(data).toEqual(apiError);
109
+ }
51
110
  });
52
111
  });
@@ -0,0 +1,90 @@
1
+ import { pullFromCache, enableCache, disableCache } from '~/cache/api';
2
+ import { ASCApiError } from '~/core/errors';
3
+ import { getResolver } from '~/core/model';
4
+
5
+ import {
6
+ client,
7
+ connectClient,
8
+ disconnectClient,
9
+ channel1,
10
+ user11,
11
+ rawChannelUser,
12
+ channelUserQueryResponse,
13
+ } from '~/utils/tests';
14
+
15
+ import { leaveChannel } from '../leaveChannel';
16
+
17
+ describe('leaveChannel', () => {
18
+ beforeAll(connectClient);
19
+ afterAll(disconnectClient);
20
+
21
+ const { channelId } = channel1;
22
+
23
+ // integration_test_id: 3b4408dd-0f45-4270-9384-73d9ddac4511
24
+ test('it should return channelUser', async () => {
25
+ client.http.delete = jest.fn().mockResolvedValueOnce(channelUserQueryResponse);
26
+
27
+ const recieved = await leaveChannel(channelId);
28
+
29
+ expect(recieved).toBe(true);
30
+ });
31
+
32
+ test('it should update cache', async () => {
33
+ enableCache();
34
+
35
+ const expected = rawChannelUser;
36
+ client.http.delete = jest.fn().mockResolvedValueOnce(channelUserQueryResponse);
37
+
38
+ const didleaveChannel = await leaveChannel(channelId);
39
+
40
+ const resolverId = getResolver('channelUsers')({ channelId, userId: user11.userId });
41
+ const recieved = pullFromCache(['channelUsers', 'get', resolverId]);
42
+
43
+ expect(didleaveChannel).toBe(true);
44
+ expect(recieved?.data).toStrictEqual(expected);
45
+
46
+ disableCache();
47
+ });
48
+
49
+ // integration_test_id: 4f56790e-5fa0-4d04-8c20-ab0c39d0776f
50
+ test('it should throw error 400301 when user try to leave a channel which user is not a member', async () => {
51
+ const apiError = new ASCApiError(
52
+ 'User is not member of channel',
53
+ Amity.ServerError.PERMISSION_DENIED,
54
+ Amity.ErrorLevel.ERROR,
55
+ );
56
+
57
+ client.http.delete = jest.fn().mockRejectedValueOnce({
58
+ status: 403,
59
+ data: apiError,
60
+ });
61
+
62
+ try {
63
+ await leaveChannel(channelId);
64
+ } catch ({ status = null, data = null }) {
65
+ expect(status).toEqual(403);
66
+ expect(data).toEqual(apiError);
67
+ }
68
+ });
69
+
70
+ // integration_test_id: 818d2317-e138-4d66-bdc0-bcc858580df5
71
+ test('it should throw error 400304 when user try to leave channel which he got banned', async () => {
72
+ const apiError = new ASCApiError(
73
+ 'User is banned from this channel',
74
+ Amity.ServerError.CHANNEL_BAN,
75
+ Amity.ErrorLevel.ERROR,
76
+ );
77
+
78
+ client.http.delete = jest.fn().mockRejectedValueOnce({
79
+ status: 403,
80
+ data: apiError,
81
+ });
82
+
83
+ try {
84
+ await leaveChannel(channelId);
85
+ } catch ({ status = null, data = null }) {
86
+ expect(status).toEqual(403);
87
+ expect(data).toEqual(apiError);
88
+ }
89
+ });
90
+ });
@@ -4,11 +4,17 @@ import { disableCache, enableCache, pushToCache } from '~/cache/api';
4
4
  import { ingestInCache } from '~/cache/api/ingestInCache';
5
5
 
6
6
  import { prepareChannelPayload } from '~/channel/utils';
7
- import { client, channelQueryResponse } from '~/utils/tests';
7
+ import {
8
+ client,
9
+ channelQueryResponse,
10
+ channelTagQueryResponse,
11
+ channelExcludeTagQueryResponse,
12
+ } from '~/utils/tests';
8
13
 
9
14
  import { queryChannels } from '../queryChannels';
10
15
 
11
16
  describe('queryChannels', () => {
17
+ // integration_test_id: 06c14dab-4799-4f26-9e52-be7c12b3bdb3
12
18
  test('it should return channels', async () => {
13
19
  const expected = prepareChannelPayload(channelQueryResponse.data).channels;
14
20
  client.http.get = jest.fn().mockResolvedValue(channelQueryResponse);
@@ -18,6 +24,37 @@ describe('queryChannels', () => {
18
24
  expect(data).toEqual(expected);
19
25
  });
20
26
 
27
+ // integration_test_id: 253fb0ac-f868-4570-9b1e-98b08861aa53
28
+ test('it should return channels match with membership type', async () => {
29
+ // Actually there is no any flag to tell about this list is relate to membership type
30
+ // But need to implement this case to match with our test list
31
+ const expected = prepareChannelPayload(channelQueryResponse.data).channels;
32
+ client.http.get = jest.fn().mockResolvedValue(channelQueryResponse);
33
+ const { data } = await queryChannels({ membership: 'member' });
34
+ expect(data).toEqual(expected);
35
+ });
36
+
37
+ // integration_test_id: 92329d41-9403-44e7-979f-ed227e6ab120
38
+ test('it should return channels match with tags query type', async () => {
39
+ const expected = prepareChannelPayload(channelTagQueryResponse.data).channels;
40
+ client.http.get = jest.fn().mockResolvedValue(channelTagQueryResponse);
41
+ const { data } = await queryChannels({ tags: ['tag1'] });
42
+ expect(data).toEqual(expected);
43
+ expect(data[0].tags).toContain('tag1');
44
+ });
45
+
46
+ // integration_test_id: 5249778c-6d99-4e2f-9b80-2f4ea6ae1833
47
+ test('it should return channels without tags which defined in exclude options', async () => {
48
+ const expected = prepareChannelPayload(channelExcludeTagQueryResponse.data).channels;
49
+ client.http.get = jest.fn().mockResolvedValue(channelExcludeTagQueryResponse);
50
+ const { data } = await queryChannels({ excludeTags: ['tag1'] });
51
+ expect(data).toEqual(expected);
52
+
53
+ data.forEach(item => {
54
+ expect(item.tags).not.toContain('tag1');
55
+ });
56
+ });
57
+
21
58
  test('it should throw error', async () => {
22
59
  client.http.get = jest.fn().mockRejectedValueOnce(new Error('error'));
23
60
 
@@ -1,12 +1,4 @@
1
- import { ASCApiError } from '~/core/errors';
2
- import { getActiveClient } from '~/client/api';
3
- import { createQuery, runQuery } from '~/core/query';
4
- import {
5
- LIVE_OBJECT_ENABLE_CACHE_MESSAGE,
6
- UNSYNCED_OBJECT_CACHED_AT_MESSAGE,
7
- UNSYNCED_OBJECT_CACHED_AT_VALUE,
8
- } from '~/utils/constants';
9
- import { hasUpdates } from '~/core/model';
1
+ import { liveObject } from '~/utils/liveObject';
10
2
  import { onMessageCreated } from '~/message/events';
11
3
  import { getChannel } from '../api';
12
4
  import { onChannelDeleted, onChannelJoined, onChannelMuted, onChannelUpdated } from '../events';
@@ -34,75 +26,11 @@ export const liveChannel = (
34
26
  channelId: Amity.Channel['channelId'],
35
27
  callback: Amity.LiveObjectCallback<Amity.Channel>,
36
28
  ): Amity.Unsubscriber => {
37
- const { log, cache } = getActiveClient();
38
- const timestamp = Date.now();
39
- log(`liveChannel(tmpid: ${timestamp}) > listen`);
40
-
41
- if (!cache) {
42
- console.log(LIVE_OBJECT_ENABLE_CACHE_MESSAGE);
43
- }
44
-
45
- let channel: Amity.Channel;
46
- let isUnsyncedObject = false;
47
- const disposers: Amity.Unsubscriber[] = [];
48
-
49
- const dispatcher = (data: Amity.LiveObject<Amity.Channel>) => {
50
- channel = data.data;
51
- callback(data);
52
- };
53
-
54
- const realtimeRouter = (eventChannel: Amity.Channel) => {
55
- if (channelId !== eventChannel.channelId) {
56
- return;
57
- }
58
-
59
- if (channel && !hasUpdates(channel, eventChannel)) {
60
- return;
61
- }
62
-
63
- dispatcher({ loading: false, data: eventChannel, origin: 'event' });
64
- };
65
-
66
- const onFetch = () => {
67
- const query = createQuery(getChannel, channelId);
68
-
69
- runQuery(query, ({ loading, data, error, origin, cachedAt }) => {
70
- if (cachedAt === UNSYNCED_OBJECT_CACHED_AT_VALUE) {
71
- dispatcher({
72
- data,
73
- origin,
74
- loading: false,
75
- error: new ASCApiError(
76
- UNSYNCED_OBJECT_CACHED_AT_MESSAGE,
77
- Amity.ClientError.DISALOOW_UNSYNCED_OBJECT,
78
- Amity.ErrorLevel.ERROR,
79
- ),
80
- });
81
-
82
- isUnsyncedObject = true;
83
- disposers.forEach(fn => fn());
84
- } else if (!isUnsyncedObject) {
85
- dispatcher({ loading, data, origin, error });
86
- }
87
-
88
- if (error) {
89
- disposers.forEach(fn => fn());
90
- }
91
- });
92
- };
93
-
94
- disposers.push(
95
- onChannelUpdated(realtimeRouter),
96
- onChannelDeleted(realtimeRouter),
97
- onChannelJoined(realtimeRouter),
98
- onChannelMuted(realtimeRouter),
99
- onMessageCreated(() => null), // watch unread count
100
- );
101
-
102
- onFetch();
103
-
104
- return () => {
105
- log(`liveChannel(tmpid: ${timestamp}) > dispose`);
106
- disposers.forEach(fn => fn());
107
- };
29
+ return liveObject(channelId, callback, 'channelId', getChannel, [
30
+ onChannelUpdated,
31
+ onChannelDeleted,
32
+ onChannelJoined,
33
+ onChannelMuted,
34
+ () => onMessageCreated(() => null), // watch unread count
35
+ ]);
108
36
  };
@@ -10,6 +10,7 @@ import {
10
10
  filterByChannelMembership,
11
11
  sortByLastCreated,
12
12
  sortByDisplayName,
13
+ sortByLastActivity,
13
14
  sortByFirstCreated,
14
15
  } from '~/core/query';
15
16
  import {
@@ -97,24 +98,32 @@ export const liveChannels = (
97
98
  channels = filterByChannelMembership(channels, params.membership, userId);
98
99
  }
99
100
 
100
- const sortBy = params.sortBy || 'lastCreated';
101
-
102
- if (sortBy === 'lastCreated' || sortBy === 'firstCreated') {
103
- channels = channels.sort(sortBy === 'lastCreated' ? sortByLastCreated : sortByFirstCreated);
104
- }
105
-
106
- /*
107
- * The server returns channels with empty | null displayName's first before
108
- * returning sorted list of channels with displayNames
109
- *
110
- * This section needs to be updated as displayNames can be null as well
111
- */
112
- if (sortBy === 'displayName') {
113
- channels = channels
114
- // this needs to be aligned with the backend data type
115
- .map(c => (c.displayName ? c : { ...c, displayName: '' }))
116
- // @ts-ignore
117
- .sort(sortByDisplayName);
101
+ switch (params.sortBy) {
102
+ case 'firstCreated':
103
+ channels = channels.sort(sortByFirstCreated);
104
+ break;
105
+
106
+ case 'lastCreated':
107
+ channels = channels.sort(sortByLastCreated);
108
+ break;
109
+
110
+ case 'displayName':
111
+ /*
112
+ * The server returns channels with empty | null displayName's first before
113
+ * returning sorted list of channels with displayNames
114
+ *
115
+ * This section needs to be updated as displayNames can be null as well
116
+ */
117
+ channels = channels
118
+ // this needs to be aligned with the backend data type
119
+ .map(c => (c.displayName ? c : { ...c, displayName: '' }))
120
+ // @ts-ignore
121
+ .sort(sortByDisplayName);
122
+ break;
123
+
124
+ default:
125
+ channels = channels.sort(sortByLastActivity);
126
+ break;
118
127
  }
119
128
 
120
129
  callback({
@@ -126,15 +135,11 @@ export const liveChannels = (
126
135
  });
127
136
  };
128
137
 
129
- const realtimeRouter = (action: Amity.ChannelActionType) => (channel: Amity.Channel) => {
138
+ const realtimeRouter = (_: Amity.ChannelActionType) => (channel: Amity.Channel) => {
130
139
  const collection = pullFromCache<Amity.ChannelLiveCollectionCache>(cacheKey)?.data;
131
140
  if (!collection) return;
132
141
 
133
- if (action === 'onDelete' && params.isDeleted === false) {
134
- collection.data = collection.data.filter(c => c !== channel.channelId);
135
- } else {
136
- collection.data = [...new Set([channel.channelId, ...collection.data])];
137
- }
142
+ collection.data = [...new Set([channel.channelId, ...collection.data])];
138
143
 
139
144
  pushToCache(cacheKey, collection);
140
145
  responder(collection);
@@ -26,10 +26,12 @@ export const isExpired = (expiresAt: Amity.Tokens['expiresAt']): boolean =>
26
26
  *
27
27
  * @category private
28
28
  */
29
- export const isAboutToExpire = (
30
- expiresAt: Amity.Tokens['expiresAt'],
31
- issuedAt: Amity.Tokens['issuedAt'],
32
- ): boolean => {
29
+ export const isAboutToExpire = (params: {
30
+ expiresAt: Amity.Tokens['expiresAt'];
31
+ issuedAt: Amity.Tokens['issuedAt'];
32
+ }): boolean => {
33
+ const { expiresAt, issuedAt } = params;
34
+
33
35
  const expires = Date.parse(expiresAt);
34
36
  const issued = Date.parse(issuedAt);
35
37
  const now = Date.now();
@@ -74,7 +76,7 @@ export const accessTokenExpiryWatcher = (
74
76
  return;
75
77
  }
76
78
 
77
- if (isAboutToExpire(issuedAt, expiresAt)) {
79
+ if (isAboutToExpire({ expiresAt, issuedAt })) {
78
80
  sessionHandler.sessionWillRenewAccessToken(renewal());
79
81
  }
80
82
  }, ACCESS_TOKEN_WATCHER_INTERVAL);
@@ -164,8 +164,6 @@ export const connectClient = async (
164
164
 
165
165
  subscriptions.forEach(fn => fn());
166
166
  }),
167
-
168
- onUserDeleted(() => null),
169
167
  );
170
168
 
171
169
  return client.ws.connected;
@@ -96,19 +96,22 @@ describe('accessTokenExpiryWatcher > aboutToExpire', () => {
96
96
 
97
97
  aboutToExpireTime.setHours(aboutToExpireTime.getHours() + 1);
98
98
 
99
- expect(isAboutToExpire(aboutToExpireTime.toISOString(), oldIssuedAtTime.toISOString())).toBe(
100
- true,
101
- );
99
+ expect(
100
+ isAboutToExpire({
101
+ expiresAt: aboutToExpireTime.toISOString(),
102
+ issuedAt: oldIssuedAtTime.toISOString(),
103
+ }),
104
+ ).toBe(true);
102
105
  });
103
106
 
104
107
  test('it should return false if token expired', () => {
105
- expect(isAboutToExpire(expiresAt, issuedAt)).toBe(false);
108
+ expect(isAboutToExpire({ expiresAt, issuedAt })).toBe(false);
106
109
  });
107
110
 
108
111
  test('it should return false if not about to expire', () => {
109
112
  oldIssuedAtTime.setDate(oldIssuedAtTime.getDate() - 10);
110
113
 
111
- expect(isAboutToExpire(expiresAt, issuedAt)).toBe(false);
114
+ expect(isAboutToExpire({ expiresAt, issuedAt })).toBe(false);
112
115
  });
113
116
  });
114
117
 
@@ -1,10 +1,12 @@
1
1
  import { getActiveClient } from '~/client/api';
2
2
 
3
- import { dropFromCache, upsertInCache } from '~/cache/api';
3
+ import { upsertInCache } from '~/cache/api';
4
4
  import { fireEvent } from '~/core/events';
5
5
 
6
- import { getComment } from './getComment';
7
6
  import { getPost } from '~/post/api/getPost';
7
+ import { pushToTombstone } from '~/cache/api/pushToTombstone';
8
+ import { scheduleTask } from '~/core/microtasks';
9
+ import { getComment } from './getComment';
8
10
 
9
11
  /**
10
12
  * ```js
@@ -49,9 +51,7 @@ export const deleteComment = async (
49
51
  fireEvent('comment.deleted', { comments: [deleted] });
50
52
 
51
53
  if (permanent) {
52
- setTimeout(() => {
53
- dropFromCache(['comment', 'get', commentId], true);
54
- }, 0);
54
+ scheduleTask(() => pushToTombstone('comment', commentId));
55
55
  } else {
56
56
  upsertInCache(['comment', 'get', commentId], { isDeleted: true });
57
57
  }