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

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 (179) 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/domains/category.d.ts +7 -0
  5. package/dist/@types/domains/category.d.ts.map +1 -1
  6. package/dist/@types/domains/community.d.ts +12 -0
  7. package/dist/@types/domains/community.d.ts.map +1 -1
  8. package/dist/@types/global.d.ts +5 -0
  9. package/dist/@types/global.d.ts.map +1 -1
  10. package/dist/category/api/queryCategories.d.ts +1 -5
  11. package/dist/category/api/queryCategories.d.ts.map +1 -1
  12. package/dist/category/observers/index.d.ts +2 -0
  13. package/dist/category/observers/index.d.ts.map +1 -0
  14. package/dist/category/observers/liveCategories.d.ts +18 -0
  15. package/dist/category/observers/liveCategories.d.ts.map +1 -0
  16. package/dist/category/observers/tests/liveCategories.test.d.ts +2 -0
  17. package/dist/category/observers/tests/liveCategories.test.d.ts.map +1 -0
  18. package/dist/channel/api/tests/getChannels.test.d.ts +2 -0
  19. package/dist/channel/api/tests/getChannels.test.d.ts.map +1 -0
  20. package/dist/channel/api/tests/leaveChannel.test.d.ts +2 -0
  21. package/dist/channel/api/tests/leaveChannel.test.d.ts.map +1 -0
  22. package/dist/channel/observers/liveChannel.d.ts.map +1 -1
  23. package/dist/client/api/accessTokenExpiryWatcher.d.ts +4 -1
  24. package/dist/client/api/accessTokenExpiryWatcher.d.ts.map +1 -1
  25. package/dist/client/api/getToken.d.ts +3 -1
  26. package/dist/client/api/getToken.d.ts.map +1 -1
  27. package/dist/client/utils/setClientToken.d.ts +3 -3
  28. package/dist/comment/api/deleteComment.d.ts.map +1 -1
  29. package/dist/comment/api/getComment.d.ts.map +1 -1
  30. package/dist/comment/observers/index.d.ts +1 -0
  31. package/dist/comment/observers/index.d.ts.map +1 -1
  32. package/dist/comment/observers/liveComment.d.ts +21 -0
  33. package/dist/comment/observers/liveComment.d.ts.map +1 -0
  34. package/dist/comment/observers/tests/liveComment.test.d.ts +2 -0
  35. package/dist/comment/observers/tests/liveComment.test.d.ts.map +1 -0
  36. package/dist/community/api/queryCommunities.d.ts +1 -10
  37. package/dist/community/api/queryCommunities.d.ts.map +1 -1
  38. package/dist/community/events/index.d.ts +1 -0
  39. package/dist/community/events/index.d.ts.map +1 -1
  40. package/dist/community/events/onCommunityUserChanged.d.ts +17 -0
  41. package/dist/community/events/onCommunityUserChanged.d.ts.map +1 -0
  42. package/dist/community/events/utils.d.ts +1 -0
  43. package/dist/community/events/utils.d.ts.map +1 -1
  44. package/dist/community/observers/index.d.ts +1 -0
  45. package/dist/community/observers/index.d.ts.map +1 -1
  46. package/dist/community/observers/liveCommunities.d.ts +20 -0
  47. package/dist/community/observers/liveCommunities.d.ts.map +1 -0
  48. package/dist/community/observers/tests/liveCommunities.test.d.ts +2 -0
  49. package/dist/community/observers/tests/liveCommunities.test.d.ts.map +1 -0
  50. package/dist/core/events.d.ts +3 -3
  51. package/dist/core/events.d.ts.map +1 -1
  52. package/dist/core/query/sorting.d.ts +6 -0
  53. package/dist/core/query/sorting.d.ts.map +1 -1
  54. package/dist/core/transports/http.d.ts +0 -5
  55. package/dist/core/transports/http.d.ts.map +1 -1
  56. package/dist/file/api/test/createImage.test.d.ts +2 -0
  57. package/dist/file/api/test/createImage.test.d.ts.map +1 -0
  58. package/dist/file/api/test/createVideo.test.d.ts +2 -0
  59. package/dist/file/api/test/createVideo.test.d.ts.map +1 -0
  60. package/dist/index.cjs.js +441 -195
  61. package/dist/index.d.ts +1 -0
  62. package/dist/index.d.ts.map +1 -1
  63. package/dist/index.esm.js +436 -195
  64. package/dist/index.umd.js +4 -4
  65. package/dist/message/observers/liveMessage.d.ts.map +1 -1
  66. package/dist/post/observers/index.d.ts +1 -0
  67. package/dist/post/observers/index.d.ts.map +1 -1
  68. package/dist/post/observers/livePost.d.ts +21 -0
  69. package/dist/post/observers/livePost.d.ts.map +1 -0
  70. package/dist/post/observers/tests/livePost.test.d.ts +2 -0
  71. package/dist/post/observers/tests/livePost.test.d.ts.map +1 -0
  72. package/dist/subChannel/api/tests/deleteSubChannel.test.d.ts +2 -0
  73. package/dist/subChannel/api/tests/deleteSubChannel.test.d.ts.map +1 -0
  74. package/dist/subChannel/api/tests/getSubChannel.test.d.ts +2 -0
  75. package/dist/subChannel/api/tests/getSubChannel.test.d.ts.map +1 -0
  76. package/dist/subChannel/api/tests/getSubChannels.test.d.ts +2 -0
  77. package/dist/subChannel/api/tests/getSubChannels.test.d.ts.map +1 -0
  78. package/dist/subChannel/api/tests/updateSubChannel.test.d.ts +2 -0
  79. package/dist/subChannel/api/tests/updateSubChannel.test.d.ts.map +1 -0
  80. package/dist/subChannel/observers/liveSubChannel.d.ts.map +1 -1
  81. package/dist/user/api/tests/updateUser.test.d.ts +2 -0
  82. package/dist/user/api/tests/updateUser.test.d.ts.map +1 -0
  83. package/dist/user/observers/liveUser.d.ts.map +1 -1
  84. package/dist/utils/liveObject.d.ts +2 -0
  85. package/dist/utils/liveObject.d.ts.map +1 -0
  86. package/dist/utils/tests/dummy/category.d.ts +64 -0
  87. package/dist/utils/tests/dummy/category.d.ts.map +1 -0
  88. package/dist/utils/tests/dummy/channel.d.ts +50 -0
  89. package/dist/utils/tests/dummy/channel.d.ts.map +1 -1
  90. package/dist/utils/tests/dummy/community.d.ts +132 -0
  91. package/dist/utils/tests/dummy/community.d.ts.map +1 -1
  92. package/dist/utils/tests/dummy/file.d.ts +3 -0
  93. package/dist/utils/tests/dummy/file.d.ts.map +1 -1
  94. package/dist/utils/tests/dummy/index.d.ts +1 -0
  95. package/dist/utils/tests/dummy/index.d.ts.map +1 -1
  96. package/dist/utils/tests/dummy/post.d.ts +2 -0
  97. package/dist/utils/tests/dummy/post.d.ts.map +1 -1
  98. package/dist/utils/tests/dummy/subChannel.d.ts +0 -20
  99. package/dist/utils/tests/dummy/subChannel.d.ts.map +1 -1
  100. package/dist/utils/tests/dummy/user.d.ts +18 -0
  101. package/dist/utils/tests/dummy/user.d.ts.map +1 -1
  102. package/dist/utils/tests/liveObject.test.d.ts +2 -0
  103. package/dist/utils/tests/liveObject.test.d.ts.map +1 -0
  104. package/package.json +4 -4
  105. package/src/@types/core/events.ts +1 -0
  106. package/src/@types/domains/category.ts +13 -0
  107. package/src/@types/domains/community.ts +25 -0
  108. package/src/@types/global.ts +5 -0
  109. package/src/category/api/queryCategories.ts +3 -5
  110. package/src/category/observers/index.ts +1 -0
  111. package/src/category/observers/liveCategories.ts +141 -0
  112. package/src/category/observers/tests/liveCategories.test.ts +147 -0
  113. package/src/channel/api/tests/createChannel.test.ts +30 -6
  114. package/src/channel/api/tests/getChannel.test.ts +3 -1
  115. package/src/channel/api/tests/getChannels.test.ts +97 -0
  116. package/src/channel/api/tests/joinChannel.test.ts +62 -3
  117. package/src/channel/api/tests/leaveChannel.test.ts +90 -0
  118. package/src/channel/api/tests/queryChannels.test.ts +38 -1
  119. package/src/channel/observers/liveChannel.ts +8 -80
  120. package/src/client/api/accessTokenExpiryWatcher.ts +7 -5
  121. package/src/client/api/tests/accessTokenExpiryWatcher.test.ts +8 -5
  122. package/src/comment/api/deleteComment.ts +5 -5
  123. package/src/comment/api/getComment.ts +8 -3
  124. package/src/comment/observers/index.ts +1 -0
  125. package/src/comment/observers/liveComment.ts +43 -0
  126. package/src/comment/observers/tests/liveComment.test.ts +95 -0
  127. package/src/community/api/queryCommunities.ts +3 -10
  128. package/src/community/api/test/addCommunityMember.test.ts +14 -2
  129. package/src/community/api/test/joinCommunity.test.ts +14 -2
  130. package/src/community/api/test/leaveCommunity.test.ts +11 -1
  131. package/src/community/api/test/removeCommunityMembers.test.ts +11 -1
  132. package/src/community/events/index.ts +1 -0
  133. package/src/community/events/onCommunityUserChanged.ts +20 -0
  134. package/src/community/events/test/onCommunityJoined.test.ts +1 -1
  135. package/src/community/events/test/onCommunityUserAdded.test.ts +1 -1
  136. package/src/community/events/test/onCommunityUserBanned.test.ts +1 -1
  137. package/src/community/events/test/onCommunityUserUnbaned.test.ts +1 -1
  138. package/src/community/events/test/utils.test.ts +52 -3
  139. package/src/community/events/utils.ts +49 -0
  140. package/src/community/observers/index.ts +1 -0
  141. package/src/community/observers/liveCommunities.ts +188 -0
  142. package/src/community/observers/tests/liveCommunities.test.ts +284 -0
  143. package/src/core/query/sorting.ts +8 -0
  144. package/src/core/transports/http.ts +17 -13
  145. package/src/core/transports/test/http.test.ts +49 -60
  146. package/src/file/api/createFile.ts +1 -1
  147. package/src/file/api/createImage.ts +1 -1
  148. package/src/file/api/createVideo.ts +1 -1
  149. package/src/file/api/test/createImage.test.ts +69 -0
  150. package/src/file/api/test/createVideo.test.ts +81 -0
  151. package/src/index.ts +1 -0
  152. package/src/message/observers/liveMessage.ts +11 -83
  153. package/src/message/tests/observers/liveMessage.test.ts +1 -143
  154. package/src/post/observers/index.ts +1 -0
  155. package/src/post/observers/livePost.ts +47 -0
  156. package/src/post/observers/tests/livePost.test.ts +97 -0
  157. package/src/stream/api/tests/createStream.test.ts +3 -11
  158. package/src/stream/api/tests/deleteStream.test.ts +5 -3
  159. package/src/subChannel/api/tests/createSubChannel.test.ts +21 -14
  160. package/src/subChannel/api/tests/deleteSubChannel.test.ts +112 -0
  161. package/src/subChannel/api/tests/getSubChannel.test.ts +97 -0
  162. package/src/subChannel/api/tests/getSubChannels.test.ts +97 -0
  163. package/src/subChannel/api/tests/updateSubChannel.test.ts +86 -0
  164. package/src/subChannel/observers/liveSubChannel.ts +6 -56
  165. package/src/subChannel/observers/tests/liveSubChannel.test.ts +0 -82
  166. package/src/user/api/tests/updateUser.test.ts +60 -0
  167. package/src/user/observers/liveUser.ts +9 -61
  168. package/src/user/tests/observers/liveUser.test.ts +1 -154
  169. package/src/utils/liveObject.ts +86 -0
  170. package/src/utils/tests/dummy/category.ts +57 -0
  171. package/src/utils/tests/dummy/channel.ts +51 -1
  172. package/src/utils/tests/dummy/community.ts +94 -0
  173. package/src/utils/tests/dummy/file.ts +32 -0
  174. package/src/utils/tests/dummy/index.ts +1 -0
  175. package/src/utils/tests/dummy/post.ts +56 -45
  176. package/src/utils/tests/dummy/stream.ts +73 -73
  177. package/src/utils/tests/dummy/subChannel.ts +0 -22
  178. package/src/utils/tests/dummy/user.ts +21 -0
  179. package/src/utils/tests/liveObject.test.ts +172 -0
@@ -20,11 +20,9 @@ import { getResolver } from '~/core/model';
20
20
  * @category Category API
21
21
  * @async
22
22
  * */
23
- export const queryCategories = async (query?: {
24
- sortBy?: 'lastCreated' | 'firstCreated' | 'name';
25
- isDeleted?: Amity.Category['isDeleted'];
26
- page?: Amity.Page;
27
- }): Promise<Amity.Cached<Amity.Paged<Amity.Category, Amity.Page>>> => {
23
+ export const queryCategories = async (
24
+ query?: Amity.QueryCategories,
25
+ ): Promise<Amity.Cached<Amity.Paged<Amity.Category, Amity.Page>>> => {
28
26
  const client = getActiveClient();
29
27
  client.log('category/queryCategories', query);
30
28
 
@@ -0,0 +1 @@
1
+ export * from './liveCategories';
@@ -0,0 +1,141 @@
1
+ /* eslint-disable no-use-before-define */
2
+ import { getResolver } from '~/core/model';
3
+ import { pullFromCache, pushToCache } from '~/cache/api';
4
+ import { getActiveClient } from '~/client/api';
5
+ import {
6
+ createQuery,
7
+ runQuery,
8
+ queryOptions,
9
+ filterByPropEquality,
10
+ sortByLastCreated,
11
+ sortByName,
12
+ sortByFirstCreated,
13
+ } from '~/core/query';
14
+ import {
15
+ COLLECTION_DEFAULT_CACHING_POLICY,
16
+ COLLECTION_DEFAULT_PAGINATION_LIMIT,
17
+ ENABLE_CACHE_MESSAGE,
18
+ } from '~/utils/constants';
19
+ import { queryCategories } from '../api';
20
+
21
+ /**
22
+ * ```js
23
+ * import { liveCategories } from '@amityco/ts-sdk'
24
+ *
25
+ * let categories = []
26
+ * const unsub = liveCategories({}, response => merge(categories, response.data))
27
+ * ```
28
+ *
29
+ * Observe all mutations on a list of {@link Amity.Category}s
30
+ *
31
+ * @param params for querying categories
32
+ * @param callback the function to call when new data are available
33
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the categories
34
+ *
35
+ * @category Category Live Collection
36
+ */
37
+ export const liveCategories = (
38
+ params: Amity.CategoryLiveCollection,
39
+ callback: Amity.LiveCollectionCallback<Amity.Category>,
40
+ config?: Amity.LiveCollectionConfig,
41
+ ) => {
42
+ const { log, cache } = getActiveClient();
43
+
44
+ if (!cache) {
45
+ console.log(ENABLE_CACHE_MESSAGE);
46
+ }
47
+
48
+ const timestamp = Date.now();
49
+ log(`liveCategories(tmpid: ${timestamp}) > listen`);
50
+
51
+ const { limit: queryLimit, ...queryParams } = params;
52
+
53
+ const limit = queryLimit ?? COLLECTION_DEFAULT_PAGINATION_LIMIT;
54
+ const { policy = COLLECTION_DEFAULT_CACHING_POLICY } = config ?? {};
55
+
56
+ const disposers: Amity.Unsubscriber[] = [];
57
+ const cacheKey = ['category', 'collection', {}];
58
+
59
+ const responder = (data: Amity.CategoryLiveCollectionCache) => {
60
+ let categories: Amity.Category[] =
61
+ data.data
62
+ .map(categoryId => pullFromCache<Amity.Category>(['category', 'get', categoryId])!)
63
+ .filter(Boolean)
64
+ .map(({ data }) => data) ?? [];
65
+
66
+ categories = filterByPropEquality(categories, 'isDeleted', params.isDeleted);
67
+
68
+ switch (params.sortBy) {
69
+ case 'firstCreated':
70
+ categories = categories.sort(sortByFirstCreated);
71
+ break;
72
+
73
+ case 'lastCreated':
74
+ categories = categories.sort(sortByLastCreated);
75
+ break;
76
+
77
+ default:
78
+ categories = categories.sort(sortByName);
79
+ }
80
+
81
+ callback({
82
+ onNextPage: onFetch,
83
+ data: categories,
84
+ hasNextPage: !!data.params?.page,
85
+ loading: data.loading,
86
+ error: data.error,
87
+ });
88
+ };
89
+
90
+ /*
91
+ * const realtimeRouter = () => {
92
+ * @TODO: At the time of creating this method category does not have any
93
+ * observers
94
+ *};
95
+ */
96
+
97
+ const onFetch = () => {
98
+ const collection = pullFromCache<Amity.CategoryLiveCollectionCache>(cacheKey)?.data;
99
+
100
+ const categories = collection?.data ?? [];
101
+
102
+ if (categories.length > 0 && !collection?.params.page) return;
103
+
104
+ const query = createQuery(queryCategories, {
105
+ ...queryParams,
106
+ page: collection?.params.page ?? { limit },
107
+ });
108
+
109
+ runQuery(
110
+ query,
111
+ ({ data: result, error, loading, nextPage: page }) => {
112
+ const data = {
113
+ loading,
114
+ error,
115
+ params: { page },
116
+ data: categories,
117
+ };
118
+
119
+ if (result) {
120
+ data.data = [...new Set([...categories, ...result.map(getResolver('category'))])];
121
+ }
122
+
123
+ pushToCache(cacheKey, data);
124
+
125
+ responder(data);
126
+ },
127
+ queryOptions(policy),
128
+ );
129
+ };
130
+
131
+ disposers.push(() => {
132
+ // @TODO -> update once observers added
133
+ });
134
+
135
+ onFetch();
136
+
137
+ return () => {
138
+ log(`liveCategories(tmpid: ${timestamp}) > dispose`);
139
+ disposers.forEach(fn => fn());
140
+ };
141
+ };
@@ -0,0 +1,147 @@
1
+ import { disableCache, enableCache } from '~/cache/api';
2
+ import {
3
+ client,
4
+ connectClient,
5
+ disconnectClient,
6
+ pause,
7
+ categoryQueryResponse,
8
+ categoryQueryResponsePage2,
9
+ category11,
10
+ category12,
11
+ category13,
12
+ } from '~/utils/tests';
13
+ import { sortByName } from '~/core/query';
14
+
15
+ import { liveCategories } from '../liveCategories';
16
+
17
+ const getSnapshot = (params?: Record<string, any>) => {
18
+ return {
19
+ data: [] as Amity.Category[],
20
+ loading: true,
21
+ error: undefined as any,
22
+ ...params,
23
+ };
24
+ };
25
+
26
+ describe('live Caategories', () => {
27
+ beforeAll(connectClient);
28
+ afterAll(disconnectClient);
29
+
30
+ beforeEach(enableCache);
31
+
32
+ afterEach(disableCache);
33
+
34
+ const payload = categoryQueryResponse.data;
35
+ const payloadPage2 = categoryQueryResponsePage2.data;
36
+
37
+ test('it should return category collection', async () => {
38
+ const callback = jest.fn();
39
+ client.http.get = jest.fn().mockResolvedValue(categoryQueryResponse);
40
+
41
+ liveCategories({}, callback);
42
+ await pause();
43
+
44
+ expect(callback).toHaveBeenCalledTimes(2);
45
+ expect(callback).toHaveBeenNthCalledWith(1, expect.objectContaining(getSnapshot()));
46
+ expect(callback).toHaveBeenNthCalledWith(
47
+ 2,
48
+ expect.objectContaining(
49
+ getSnapshot({
50
+ data: payload.categories,
51
+ loading: false,
52
+ }),
53
+ ),
54
+ );
55
+ });
56
+
57
+ test('it should return data from cache', async () => {
58
+ const callback = jest.fn();
59
+ client.http.get = jest.fn().mockResolvedValue(categoryQueryResponse);
60
+
61
+ liveCategories({}, () => undefined);
62
+ await pause();
63
+ liveCategories({}, callback);
64
+ await pause();
65
+
66
+ expect(callback).toHaveBeenCalledTimes(2);
67
+ expect(callback).toHaveBeenNthCalledWith(
68
+ 1,
69
+ expect.objectContaining(
70
+ getSnapshot({
71
+ data: payload.categories,
72
+ }),
73
+ ),
74
+ );
75
+ expect(callback).toHaveBeenNthCalledWith(
76
+ 2,
77
+ expect.objectContaining(
78
+ getSnapshot({
79
+ data: payload.categories,
80
+ loading: false,
81
+ }),
82
+ ),
83
+ );
84
+ });
85
+
86
+ const filters: [string, Amity.CategoryLiveCollection, Amity.Category[]][] = [
87
+ ['deleted', { isDeleted: true }, [category13]],
88
+ ['not deleted', { isDeleted: false }, [category11, category12]],
89
+ ];
90
+
91
+ test.each(filters)('it should filter by %s categories', async (filter, params, expected) => {
92
+ const callback = jest.fn();
93
+ client.http.get = jest.fn().mockResolvedValue(categoryQueryResponse);
94
+
95
+ liveCategories(params, callback);
96
+
97
+ expect(callback).toHaveBeenCalledTimes(1);
98
+ // check if cache data returned (should be empty)
99
+ expect(callback).toHaveBeenCalledWith(expect.objectContaining(getSnapshot()));
100
+
101
+ await pause();
102
+
103
+ expect(callback).toHaveBeenCalledTimes(2);
104
+ expect(callback).toHaveBeenCalledWith(
105
+ expect.objectContaining(
106
+ getSnapshot({
107
+ loading: false,
108
+ data: expected,
109
+ }),
110
+ ),
111
+ );
112
+ });
113
+
114
+ test('it should return method to fetch next page', async () => {
115
+ const callback = jest.fn();
116
+ client.http.get = jest
117
+ .fn()
118
+ .mockResolvedValue(categoryQueryResponse)
119
+ .mockResolvedValueOnce(categoryQueryResponsePage2);
120
+
121
+ liveCategories({}, callback);
122
+ await pause();
123
+
124
+ expect(callback).toHaveBeenCalled();
125
+ expect(callback.mock.lastCall).toHaveLength(1);
126
+
127
+ const { onNextPage, hasNextPage } = callback.mock.lastCall[0];
128
+
129
+ expect(hasNextPage).toBe(true);
130
+ expect(onNextPage).toBeTruthy();
131
+
132
+ onNextPage();
133
+ await pause();
134
+
135
+ // 4 -> because 1 local & server call each per call (2)
136
+ expect(callback).toHaveBeenCalledTimes(4);
137
+ expect(callback).toHaveBeenNthCalledWith(
138
+ 4,
139
+ expect.objectContaining(
140
+ getSnapshot({
141
+ loading: false,
142
+ data: [...payloadPage2.categories, ...payload.categories].sort(sortByName),
143
+ }),
144
+ ),
145
+ );
146
+ });
147
+ });
@@ -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
+ });