@eohjsc/react-native-smart-city 0.2.97 → 0.3.0

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 (197) hide show
  1. package/README.md +35 -14
  2. package/package.json +4 -2
  3. package/src/commons/Action/ItemQuickAction.js +5 -2
  4. package/src/commons/ActionGroup/ColorPickerTemplate.js +1 -1
  5. package/src/commons/ActionGroup/CurtainButtonTemplate.js +10 -5
  6. package/src/commons/ActionGroup/NumberUpDownActionTemplate.js +12 -4
  7. package/src/commons/ActionGroup/OnOffSmartLock/AutoLock/__test__/index.test.js +4 -0
  8. package/src/commons/ActionGroup/OnOffSmartLock/OnOffSmartLock.js +7 -4
  9. package/src/commons/ActionGroup/OnOffSmartLock/PasscodeList/ItemPasscode.js +1 -1
  10. package/src/commons/ActionGroup/OnOffSmartLock/PasscodeList/__test__/ItemPasscode.test.js +24 -0
  11. package/src/commons/ActionGroup/OnOffSmartLock/SetupGeneratePasscode/__test__/index.test.js +14 -0
  12. package/src/commons/ActionGroup/OnOffSmartLock/SetupGeneratePasscode/index.js +1 -0
  13. package/src/commons/ActionGroup/OnOffTemplate/OnOffSimpleTemplate.js +10 -10
  14. package/src/commons/ActionGroup/OnOffTemplate/index.js +18 -15
  15. package/src/commons/ActionGroup/OptionsDropdownActionTemplate.js +9 -3
  16. package/src/commons/ActionGroup/SliderRangeTemplate.js +1 -1
  17. package/src/commons/ActionGroup/SmartTiviActionTemplate/SmartTiviActionTemplate.js +4 -1
  18. package/src/commons/ActionGroup/StatesGridActionTemplate.js +22 -8
  19. package/src/commons/ActionGroup/TimerActionTemplate.js +11 -3
  20. package/src/commons/ActionGroup/TwoButtonTemplate/index.js +13 -9
  21. package/src/commons/ActionGroup/__test__/CurtainButtonTemplate.test.js +53 -4
  22. package/src/commons/ActionGroup/__test__/OnOffButtonTemplate.test.js +14 -14
  23. package/src/commons/ActionGroup/__test__/OnOffTemplate.test.js +53 -78
  24. package/src/commons/ActionGroup/__test__/OneBigButtonTemplate.test.js +36 -20
  25. package/src/commons/ActionGroup/__test__/StatesGridActionTemplate.test.js +77 -0
  26. package/src/commons/ActionGroup/__test__/TimerActionTemplate.test.js +58 -6
  27. package/src/commons/ActionGroup/__test__/TwoButtonTemplate.test.js +49 -1
  28. package/src/commons/ActionGroup/__test__/index.test.js +135 -0
  29. package/src/commons/Auth/AccountList.js +1 -1
  30. package/src/commons/Automate/ItemAutomate.js +1 -3
  31. package/src/commons/Calendar/__test__/Calendar.test.js +33 -0
  32. package/src/commons/Connecting/__test__/Connecting.test.js +19 -2
  33. package/src/commons/ConnectingProcess/__test__/Connecting.test.js +136 -3
  34. package/src/commons/ConnectingProcess/index.js +1 -1
  35. package/src/commons/Dashboard/MyPinnedSharedUnit/__test__/MyPinnedSharedUnit.test.js +16 -13
  36. package/src/commons/Dashboard/MyPinnedSharedUnit/index.js +1 -1
  37. package/src/commons/Dashboard/MyUnit/__test__/MyUnit.test.js +0 -5
  38. package/src/commons/Device/Hanet/ItemHanetDevice.test.js +58 -0
  39. package/src/commons/Device/HistoryChart.js +4 -0
  40. package/src/commons/Device/LinearChart.js +15 -0
  41. package/src/commons/Device/PMSensor/PMSensorIndicatior.js +16 -12
  42. package/src/commons/Device/PMSensor/PMSensorIndicatorStyles.js +3 -0
  43. package/src/commons/Device/WaterQualitySensor/ListQualityIndicator.js +1 -0
  44. package/src/commons/Explore/__test__/CityItem.test.js +33 -54
  45. package/src/commons/FieldTemplate/ChooseUserField/ChooseFieldStyles.js +25 -0
  46. package/src/commons/FieldTemplate/ChooseUserField/ChoosePopup.js +96 -0
  47. package/src/commons/FieldTemplate/ChooseUserField/ChoosePopupStyles.js +39 -0
  48. package/src/commons/FieldTemplate/ChooseUserField/__test__/index.test.js +118 -0
  49. package/src/commons/FieldTemplate/ChooseUserField/index.js +62 -0
  50. package/src/commons/FieldTemplate/PasscodeField/PasscodeFieldStyles.js +30 -0
  51. package/src/commons/FieldTemplate/PasscodeField/__test__/index.test.js +90 -0
  52. package/src/commons/FieldTemplate/PasscodeField/index.js +43 -0
  53. package/src/commons/FieldTemplate/ScheduleField/ScheduleFieldStyles.js +13 -0
  54. package/src/commons/FieldTemplate/ScheduleField/__test__/index.test.js +179 -0
  55. package/src/commons/FieldTemplate/ScheduleField/index.js +176 -0
  56. package/src/commons/FullLoading/index.js +2 -1
  57. package/src/commons/MenuActionAddnew/index.js +1 -0
  58. package/src/commons/MenuActionList/index.js +1 -0
  59. package/src/commons/MenuActionMore/index.js +1 -1
  60. package/src/commons/PreventAccess/__test__/PreventAccess.test.js +62 -0
  61. package/src/commons/PreventAccess/index.js +9 -1
  62. package/src/commons/Sharing/__test__/DevicePermissionsCheckbox.test.js +0 -1
  63. package/src/commons/SubUnit/OneTap/__test__/SubUnitAutomate.test.js +8 -35
  64. package/src/commons/SubUnit/OneTap/index.js +1 -2
  65. package/src/commons/Unit/SharedUnit.js +1 -0
  66. package/src/commons/Unit/__test__/SharedUnit.test.js +38 -183
  67. package/src/commons/WheelDateTimePicker/index.js +2 -1
  68. package/src/configs/API.js +87 -138
  69. package/src/configs/Constants.js +27 -1
  70. package/src/configs/SCConfig.js +2 -0
  71. package/src/iot/RemoteControl/__test__/GoogleHome.test.js +8 -30
  72. package/src/iot/RemoteControl/__test__/Internet.test.js +18 -7
  73. package/src/iot/RemoteControl/__test__/LgThinq.test.js +36 -177
  74. package/src/navigations/UnitStack.js +8 -0
  75. package/src/screens/AQIGuide/index.js +1 -1
  76. package/src/screens/ActivityLog/FilterPopup.js +2 -0
  77. package/src/screens/ActivityLog/__test__/index.test.js +38 -23
  78. package/src/screens/ActivityLog/hooks/__test__/index.test.js +51 -90
  79. package/src/screens/ActivityLog/index.js +2 -2
  80. package/src/screens/AddCommon/SelectSubUnit.js +1 -0
  81. package/src/screens/AddCommon/SelectUnit.js +1 -0
  82. package/src/screens/AddCommon/__test__/SelectSubUnit.test.js +13 -24
  83. package/src/screens/AddCommon/__test__/SelectUnit.test.js +9 -33
  84. package/src/screens/AddLocationMaps/index.js +4 -1
  85. package/src/screens/AddNewAction/SelectSensorDevices.js +8 -2
  86. package/src/screens/AddNewAction/__test__/SelectAction.test.js +10 -91
  87. package/src/screens/AddNewAction/__test__/SelectSensorDevices.test.js +40 -26
  88. package/src/screens/AddNewAutoSmart/__test__/AddNewAutoSmart.test.js +3 -1
  89. package/src/screens/AddNewAutoSmart/index.js +5 -2
  90. package/src/screens/AddNewDevice/ConnectingDevices.js +3 -3
  91. package/src/screens/AddNewDevice/__test__/AddNewDevice.test.js +34 -33
  92. package/src/screens/AddNewDevice/__test__/ConnectDevices.test.js +0 -4
  93. package/src/screens/AddNewDevice/__test__/ConnectingDevices.test.js +21 -21
  94. package/src/screens/AddNewDevice/index.js +1 -0
  95. package/src/screens/AddNewGateway/PlugAndPlay/GatewayWifiList.js +4 -1
  96. package/src/screens/AddNewGateway/SelectGateway.js +1 -0
  97. package/src/screens/AddNewGateway/SetupGatewayWifi.js +1 -0
  98. package/src/screens/AddNewGateway/__test__/AddNewGateway.test.js +4 -6
  99. package/src/screens/AddNewGateway/__test__/ConnectedGateway.test.js +0 -4
  100. package/src/screens/AddNewGateway/__test__/ConnectingGateway.test.js +5 -29
  101. package/src/screens/AddNewGateway/__test__/SelectGateway.test.js +0 -4
  102. package/src/screens/AddNewGateway/__test__/SetupGateway.test.js +0 -4
  103. package/src/screens/AddNewGateway/index.js +1 -0
  104. package/src/screens/AddNewOneTap/__test__/AddNewOneTap.test.js +10 -24
  105. package/src/screens/AddNewOneTap/index.js +3 -2
  106. package/src/screens/Automate/__test__/MultiUnits.test.js +6 -9
  107. package/src/screens/Automate/__test__/index.test.js +7 -12
  108. package/src/screens/Automate/index.js +2 -0
  109. package/src/screens/ConfirmUnitDeletion/__test__/ConfirmUnitDeletion.test.js +36 -8
  110. package/src/screens/ConfirmUnitDeletion/index.js +7 -1
  111. package/src/screens/Device/EditDevice/__test__/EditDevice.test.js +71 -22
  112. package/src/screens/Device/__test__/detail.test.js +23 -84
  113. package/src/screens/Device/detail.js +31 -8
  114. package/src/screens/Device/hooks/useFavoriteDevice.js +5 -9
  115. package/src/screens/DeviceInfo/__test__/index.test.js +0 -2
  116. package/src/screens/EmergencyContacts/EmergencyContactsSelectContacts.js +6 -3
  117. package/src/screens/EmergencyContacts/__test__/EmergencyContactAddNew.test.js +7 -19
  118. package/src/screens/EmergencyContacts/__test__/EmergencyContactList.test.js +20 -2
  119. package/src/screens/EmergencyContacts/__test__/EmergencyContactsSelectContacts.test.js +40 -23
  120. package/src/screens/EmergencySetting/index.js +4 -1
  121. package/src/screens/EnterPassword/__test__/EnterPassword.test.js +41 -25
  122. package/src/screens/Explore/index.js +2 -0
  123. package/src/screens/GuestInfo/__test__/index.test.js +14 -41
  124. package/src/screens/GuestInfo/components/RecurringDetail.js +1 -0
  125. package/src/screens/GuestInfo/components/TemporaryDetail.js +2 -2
  126. package/src/screens/HanetCamera/__test__/CaptureFaceID.test.js +8 -12
  127. package/src/screens/HanetCamera/__test__/Detail.test.js +27 -42
  128. package/src/screens/HanetCamera/__test__/ManageAccess.test.js +8 -5
  129. package/src/screens/HanetCamera/__test__/MemberInfo.test.js +10 -32
  130. package/src/screens/HanetCamera/hooks/__test__/useHanetCheckinData.test.js +43 -35
  131. package/src/screens/HanetCamera/hooks/__test__/useHanetPlaceMembers.test.js +10 -21
  132. package/src/screens/ManageAccess/__test__/ManageAccess.test.js +33 -22
  133. package/src/screens/ManageAccess/hooks/__test__/useManageAccess.test.js +44 -45
  134. package/src/screens/ManageAccess/index.js +2 -1
  135. package/src/screens/MoveToAnotherSubUnit/__test__/index.test.js +35 -12
  136. package/src/screens/MoveToAnotherSubUnit/index.js +5 -5
  137. package/src/screens/Notification/__test__/Notification.test.js +14 -25
  138. package/src/screens/Notification/__test__/NotificationItem.test.js +4 -3
  139. package/src/screens/PlayBackCamera/__test__/index.test.js +87 -2
  140. package/src/screens/PlayBackCamera/index.js +19 -3
  141. package/src/screens/ScanChipQR/__test__/ScanChipQR.test.js +7 -20
  142. package/src/screens/ScanChipQR/components/QRScan/index.js +1 -0
  143. package/src/screens/ScanSensorQR/__test__/ScanSensorQR.test.js +8 -24
  144. package/src/screens/ScriptDetail/__test__/index.test.js +17 -86
  145. package/src/screens/ScriptDetail/index.js +5 -4
  146. package/src/screens/SelectUnit/__test__/index.test.js +12 -55
  147. package/src/screens/SelectUnit/index.js +5 -2
  148. package/src/screens/SetSchedule/index.js +6 -2
  149. package/src/screens/SharedUnit/__test__/TabHeader.test.js +0 -2
  150. package/src/screens/SharedUnit/index.js +2 -0
  151. package/src/screens/Sharing/InfoMemberUnit.js +1 -1
  152. package/src/screens/Sharing/MemberList.js +12 -11
  153. package/src/screens/Sharing/SelectPermission.js +107 -70
  154. package/src/screens/Sharing/__test__/InfoMemberUnit.test.js +47 -29
  155. package/src/screens/Sharing/__test__/MemberList.test.js +13 -127
  156. package/src/screens/Sharing/__test__/MemberList2.test.js +80 -0
  157. package/src/screens/Sharing/__test__/SelectPermission.test.js +28 -38
  158. package/src/screens/Sharing/__test__/SelectUser.test.js +17 -38
  159. package/src/screens/Sharing/hooks/index.js +3 -0
  160. package/src/screens/SideMenuDetail/SideMenuDetailStyles.js +28 -0
  161. package/src/screens/SideMenuDetail/__test__/index.test.js +154 -0
  162. package/src/screens/SideMenuDetail/index.js +149 -0
  163. package/src/screens/SmartIr/components/SelectBrand.js +1 -1
  164. package/src/screens/SubUnit/ManageSubUnit.js +1 -0
  165. package/src/screens/SubUnit/__test__/AddSubUnit.test.js +21 -67
  166. package/src/screens/SubUnit/__test__/Detail.test.js +31 -8
  167. package/src/screens/SubUnit/__test__/EditSubUnit.test.js +21 -89
  168. package/src/screens/SubUnit/hooks/__test__/useManageSubUnit.test.js +47 -44
  169. package/src/screens/SyncLGDevice/AddLGDevice.js +1 -0
  170. package/src/screens/SyncLGDevice/__test__/AddLGDevice.test.js +14 -90
  171. package/src/screens/TDSGuide/index.js +4 -1
  172. package/src/screens/UVIndexGuide/index.js +1 -1
  173. package/src/screens/Unit/ChooseLocation.js +1 -1
  174. package/src/screens/Unit/ManageUnit.js +1 -0
  175. package/src/screens/Unit/SelectAddress.js +4 -1
  176. package/src/screens/Unit/Station/index.js +1 -0
  177. package/src/screens/Unit/Summaries.js +1 -1
  178. package/src/screens/Unit/__test__/CheckSendEmail.test.js +15 -28
  179. package/src/screens/Unit/__test__/ChooseLocation.test.js +27 -14
  180. package/src/screens/Unit/__test__/Detail.test.js +83 -185
  181. package/src/screens/Unit/__test__/ManageUnit.test.js +18 -42
  182. package/src/screens/Unit/__test__/SelectAddress.test.js +13 -39
  183. package/src/screens/Unit/__test__/SmartAccount.test.js +17 -9
  184. package/src/screens/Unit/__test__/SmartAccountItem.test.js +0 -1
  185. package/src/screens/Unit/components/MyAllUnit/__test__/MyAllUnit.test.js +36 -0
  186. package/src/screens/Unit/components/MyAllUnit/__test__/index.test.js +54 -0
  187. package/src/screens/Unit/components/SharedUnit/index.js +1 -0
  188. package/src/screens/Unit/components/__test__/SharedUnit.test.js +31 -34
  189. package/src/screens/UnitSummary/__test__/index.test.js +38 -31
  190. package/src/screens/UnitSummary/components/PowerConsumeHistoryChart/__test__/index.test.js +7 -4
  191. package/src/screens/UnitSummary/components/PowerConsumption/__test__/PowerConsumption.test.js +14 -16
  192. package/src/screens/WaterQualityGuide/index.js +1 -1
  193. package/src/utils/Apis/axios.js +37 -13
  194. package/src/utils/I18n/translations/en.json +1 -0
  195. package/src/utils/I18n/translations/vi.json +1 -0
  196. package/src/utils/Route/index.js +1 -0
  197. package/src/utils/Utils.js +6 -6
@@ -2,16 +2,17 @@ import { act } from '@testing-library/react-hooks';
2
2
  import React, { useState } from 'react';
3
3
  import { FlatList, Text, Platform } from 'react-native';
4
4
  import { create } from 'react-test-renderer';
5
+ import MockAdapter from 'axios-mock-adapter';
6
+
5
7
  import SelectPermission from '../SelectPermission';
6
- import axios from 'axios';
7
8
  import { SensorItem, TitleCheckBox } from '../Components';
8
9
  import { ViewButtonBottom } from '../../../commons';
9
- import Routes from '../../../utils/Route';
10
10
  import { SCProvider } from '../../../context';
11
11
  import { mockSCStore } from '../../../context/mockStore';
12
12
  import API from '../../../configs/API';
13
+ import api from '../../../utils/Apis/axios';
13
14
 
14
- jest.mock('axios');
15
+ const mock = new MockAdapter(api.axiosInstance);
15
16
 
16
17
  const mockSetState = jest.fn();
17
18
  jest.mock('react', () => {
@@ -63,7 +64,6 @@ describe('Test SelectPermission', () => {
63
64
  const mockSetDataStations = jest.fn();
64
65
 
65
66
  afterEach(() => {
66
- axios.mockClear();
67
67
  mockSetState.mockClear();
68
68
  mockSetTickAllDevice.mockClear();
69
69
  mockSetActiveItemId.mockClear();
@@ -92,15 +92,16 @@ describe('Test SelectPermission', () => {
92
92
  act(() => {
93
93
  tree = create(wrapComponent(route));
94
94
  });
95
- expect(axios.get).not.toBeCalled();
95
+ const instance = tree.root;
96
+ const ViewButtonBottoms = instance.findAllByType(ViewButtonBottom);
97
+ expect(ViewButtonBottoms).toHaveLength(1);
96
98
  });
97
99
 
98
100
  it('render empty list', () => {
99
101
  mockLoading();
100
102
  Platform.OS = 'ios';
101
-
102
103
  route.params.unit = 1;
103
- axios.get.mockImplementationOnce(() => ({ status: 200, data: [] }));
104
+ mock.onGet(API.SHARE.UNIT_MEMBER_SHARE_DEVICE(1, 1)).reply(200);
104
105
  act(() => {
105
106
  tree = create(wrapComponent(route));
106
107
  });
@@ -111,9 +112,8 @@ describe('Test SelectPermission', () => {
111
112
 
112
113
  it('test get unit fail', () => {
113
114
  mockLoading();
114
-
115
115
  route.params.unit = 1;
116
- axios.get.mockImplementationOnce(() => ({ status: 400, data: [] }));
116
+ mock.onGet(API.SHARE.UNIT_MEMBER_SHARE_DEVICE(1, 1)).reply(400);
117
117
  act(() => {
118
118
  tree = create(wrapComponent(route));
119
119
  });
@@ -183,27 +183,15 @@ describe('Test SelectPermission', () => {
183
183
  act(() => {
184
184
  ViewButtonBottomElement[0].props.onRightClick();
185
185
  });
186
- expect(mockNavigate).toBeCalledWith(Routes.SharingInviteMembers, {
187
- permissions: {
188
- control_permissions: [{ id: 123, values: [136] }],
189
- read_permissions: [{ id: 123, values: [137] }],
190
- },
191
- unit: 1,
192
- });
193
186
  act(() => {
194
187
  ViewButtonBottomElement[0].props.onLeftClick();
195
188
  });
196
189
  expect(mockGoBack).toBeCalled();
197
190
  });
191
+
198
192
  it('test selectPermission type share_device', () => {
199
193
  mocSetdata();
200
- const routes = {
201
- params: {
202
- unit: { id: 1 },
203
- type: 'share_device',
204
- member: { id: 1, name: 'a', phone_number: '89898888' },
205
- },
206
- };
194
+ useState.mockImplementationOnce((init) => [true, mockSetState]);
207
195
  const response = {
208
196
  status: 200,
209
197
  data: [
@@ -223,28 +211,30 @@ describe('Test SelectPermission', () => {
223
211
  },
224
212
  ],
225
213
  };
226
- axios.get.mockImplementation(async () => {
227
- return response;
228
- });
214
+ mock
215
+ .onGet(API.SHARE.UNIT_MEMBER_SHARE_DEVICE(1, 1))
216
+ .reply(200, response.data);
217
+ const routes = {
218
+ params: {
219
+ unit: { id: 1 },
220
+ type: 'update_shared',
221
+ member: {
222
+ id: 1,
223
+ name: 'a',
224
+ phone_number: '89898888',
225
+ email: 'abcderfg@gmail.com',
226
+ },
227
+ },
228
+ };
229
229
  act(() => {
230
230
  tree = create(wrapComponent(routes));
231
231
  });
232
232
  const instance = tree.root;
233
233
  const ViewButtonBottomElement = instance.findAllByType(ViewButtonBottom);
234
- expect(ViewButtonBottomElement).toHaveLength(1);
235
- expect(axios.get).toHaveBeenCalledWith(
236
- API.SHARE.UNIT_MEMBER_SHARE_DEVICE(1, 1),
237
- {}
238
- );
239
234
  act(() => {
240
235
  ViewButtonBottomElement[0].props.onRightClick();
241
236
  });
242
- expect(mockNavigate).toBeCalledWith(Routes.SharingInviteMembers, {
243
- permissions: {
244
- control_permissions: [{ id: 123, values: [136] }],
245
- read_permissions: [{ id: 123, values: [137] }],
246
- },
247
- unit: 1,
248
- });
237
+ mock.onPost(API.SHARE.SHARE()).reply(200);
238
+ expect(mockGoBack).toBeCalled();
249
239
  });
250
240
  });
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { create, act } from 'react-test-renderer';
3
- import axios from 'axios';
3
+ import MockAdapter from 'axios-mock-adapter';
4
4
 
5
5
  import SelectUser from '../SelectUser';
6
6
  import { TESTID } from '../../../configs/Constants';
@@ -11,6 +11,7 @@ import { API } from '../../../configs';
11
11
  import { getTranslate } from '../../../utils/I18n';
12
12
  import { SCProvider } from '../../../context';
13
13
  import { mockSCStore } from '../../../context/mockStore';
14
+ import api from '../../../utils/Apis/axios';
14
15
 
15
16
  const wrapComponent = (route) => (
16
17
  <SCProvider initState={mockSCStore({})}>
@@ -18,13 +19,13 @@ const wrapComponent = (route) => (
18
19
  </SCProvider>
19
20
  );
20
21
 
22
+ const mock = new MockAdapter(api.axiosInstance);
23
+
21
24
  const mockedNavigate = jest.fn();
22
25
  const mockedGoBack = jest.fn();
23
26
  const mockedDangerouslyGetState = jest.fn();
24
27
  const mockedDangerouslyGetParentGoBack = jest.fn();
25
28
 
26
- jest.mock('axios');
27
-
28
29
  jest.mock('react-redux', () => {
29
30
  return {
30
31
  ...jest.requireActual('react-redux'),
@@ -52,7 +53,6 @@ describe('test SelectUser container', () => {
52
53
  let route;
53
54
 
54
55
  beforeEach(() => {
55
- axios.post.mockClear();
56
56
  route = {
57
57
  params: {
58
58
  unit: {
@@ -70,12 +70,6 @@ describe('test SelectUser container', () => {
70
70
  return instance.find((el) => el.props.testID === id);
71
71
  };
72
72
 
73
- const mockAxiosPost = (response) => {
74
- axios.post.mockImplementation(async () => {
75
- return await response;
76
- });
77
- };
78
-
79
73
  test('create', async () => {
80
74
  await act(async () => {
81
75
  tree = create(wrapComponent(route));
@@ -125,11 +119,7 @@ describe('test SelectUser container', () => {
125
119
  });
126
120
 
127
121
  test('_TextInput onChange phone, invalidate and not call api sharedPermission', async () => {
128
- const response = {
129
- status: 200,
130
- };
131
- mockAxiosPost(response);
132
-
122
+ mock.onPost(API.SHARE.SHARE()).reply(200);
133
123
  await act(async () => {
134
124
  tree = create(wrapComponent(route));
135
125
  });
@@ -151,48 +141,37 @@ describe('test SelectUser container', () => {
151
141
  expect(textInput.props.errorText).toEqual(
152
142
  getTranslate('en', 'invalid_phone_number_or_email')
153
143
  );
154
- expect(axios.post).not.toHaveBeenCalled();
155
144
  });
156
145
 
157
146
  test('_TextInput onChange phone, validated and call api sharedPermission', async () => {
158
- const response = {
159
- status: 200,
160
- data: {
161
- user: {
162
- id: 2,
163
- name: 'user add',
164
- },
165
- },
166
- };
167
- mockAxiosPost(response);
168
-
169
147
  await act(async () => {
170
148
  tree = create(wrapComponent(route));
171
149
  });
172
150
  const instance = tree.root;
173
-
174
151
  const textInput = instance.findByType(_TextInput);
175
152
  const button = instance.findByType(Button);
176
-
177
153
  let accountList = instance.findAllByType(AccountList);
178
154
  expect(accountList).toHaveLength(0);
179
-
180
155
  await act(async () => {
181
156
  await textInput.props.onChange('0909123456');
182
157
  });
183
-
158
+ mock.onPost(API.SHARE.SHARE()).reply(200, {
159
+ user: {
160
+ id: 2,
161
+ name: 'user add',
162
+ phone_number: '0909123456',
163
+ },
164
+ });
184
165
  await act(async () => {
185
166
  await button.props.onPress();
186
167
  });
187
-
168
+ await act(async () => {
169
+ await textInput.props.onChange('test123@gmail.com');
170
+ });
188
171
  expect(textInput.props.errorText).toEqual('');
189
- expect(axios.post).toHaveBeenCalledWith(API.SHARE.SHARE(), {
190
- phone: '0909123456',
191
- email: '',
192
- unit: 1,
193
- permissions: { controlPermissions: {}, readPermissions: {} },
172
+ await act(async () => {
173
+ await button.props.onPress();
194
174
  });
195
-
196
175
  accountList = instance.findAllByType(AccountList);
197
176
  expect(accountList).toHaveLength(1);
198
177
  });
@@ -13,6 +13,7 @@ const useDataMember = (unitId, userUnitId = undefined) => {
13
13
  const { navigate, goBack } = useNavigation();
14
14
  const [dataMembers, setDataMembers] = useState([]);
15
15
  const [isRefresh, setRefresh] = useState(false);
16
+ const [loading, setLoading] = useState(true);
16
17
  const user = useSCContextSelector((state) => state?.auth?.account?.user);
17
18
  const { isOwner } = useIsOwnerOfUnit(userUnitId);
18
19
 
@@ -42,6 +43,7 @@ const useDataMember = (unitId, userUnitId = undefined) => {
42
43
  const arrChanged = changePositionOwnerAndMe(data);
43
44
  setDataMembers(arrChanged);
44
45
  }
46
+ setLoading(false);
45
47
  },
46
48
  [changePositionOwnerAndMe]
47
49
  );
@@ -82,6 +84,7 @@ const useDataMember = (unitId, userUnitId = undefined) => {
82
84
  loadMembers,
83
85
  isRefresh,
84
86
  onRefresh,
87
+ loading,
85
88
  };
86
89
  };
87
90
 
@@ -0,0 +1,28 @@
1
+ import { Colors } from '../../configs';
2
+ import { StyleSheet } from 'react-native';
3
+ import { getBottomSpace } from 'react-native-iphone-x-helper';
4
+
5
+ export default StyleSheet.create({
6
+ container: {
7
+ flex: 1,
8
+ backgroundColor: Colors.White,
9
+ },
10
+ scrollview: {
11
+ flex: 1,
12
+ marginHorizontal: 16,
13
+ },
14
+ wrap: {
15
+ paddingBottom: 100,
16
+ },
17
+ viewBottomFixed: {
18
+ position: 'absolute',
19
+ bottom: 0,
20
+ left: 0,
21
+ right: 0,
22
+ paddingBottom: getBottomSpace() > 0 ? getBottomSpace() : 32,
23
+ paddingTop: 24,
24
+ backgroundColor: Colors.White,
25
+ borderColor: Colors.ShadownTransparent,
26
+ borderTopWidth: 1,
27
+ },
28
+ });
@@ -0,0 +1,154 @@
1
+ import React from 'react';
2
+ import MockAdapter from 'axios-mock-adapter';
3
+ import { act, create } from 'react-test-renderer';
4
+
5
+ import { TESTID } from '../../../configs/Constants';
6
+
7
+ import { SCProvider } from '../../../context';
8
+ import { mockSCStore } from '../../../context/mockStore';
9
+ import SideMenuDetail from '../index';
10
+ import { API } from '../../../configs';
11
+ import { TouchableOpacity } from 'react-native';
12
+ import { ModalCustom } from '../../../commons/Modal';
13
+ import { ToastBottomHelper } from '../../../utils/Utils';
14
+ import api from '../../../utils/Apis/axios';
15
+
16
+ const mock = new MockAdapter(api.axiosInstance);
17
+
18
+ const wrapComponent = (route) => (
19
+ <SCProvider initState={mockSCStore({})}>
20
+ <SideMenuDetail route={route} />
21
+ </SCProvider>
22
+ );
23
+
24
+ describe('Test SideMenuDetail', () => {
25
+ let tree;
26
+ const spyToastSuccess = jest.spyOn(ToastBottomHelper, 'success');
27
+ const spyToastError = jest.spyOn(ToastBottomHelper, 'error');
28
+
29
+ afterEach(() => {
30
+ spyToastSuccess.mockReset();
31
+ spyToastSuccess.mockRestore();
32
+ });
33
+
34
+ const chooseUser = async (instance) => {
35
+ const ChooseField = instance.find(
36
+ (item) =>
37
+ item.props.testID === TESTID.CHOOSE_FIELD &&
38
+ item.type === TouchableOpacity
39
+ );
40
+ await act(async () => {
41
+ await ChooseField.props.onPress();
42
+ });
43
+
44
+ const popup = instance.find(
45
+ (item) =>
46
+ item.props.testID === TESTID.CHOOSE_POPUP && item.type === ModalCustom
47
+ );
48
+ expect(popup.props.isVisible).toBeTruthy();
49
+
50
+ const button_choose_done = instance.find(
51
+ (el) =>
52
+ el.props.testID === TESTID.CHOOSE_POPUP + TESTID.BOTTOM_VIEW_MAIN &&
53
+ el.type === TouchableOpacity
54
+ );
55
+
56
+ await act(async () => {
57
+ await button_choose_done.props.onPress();
58
+ });
59
+ expect(popup.props.isVisible).toBeFalsy();
60
+ };
61
+
62
+ const inputPasscode = async (instance) => {
63
+ const inputPasscode = instance.find(
64
+ (item) => item.props.testID === TESTID.PASSCODE_FIELD
65
+ );
66
+
67
+ await act(async () => {
68
+ await inputPasscode.props.onChangeText('123456');
69
+ });
70
+ };
71
+
72
+ const onPressSubmitData = async (instance) => {
73
+ const buttonSubmit = instance.find(
74
+ (el) =>
75
+ el.props.testID === TESTID.SUBMIT + TESTID.BOTTOM_VIEW_MAIN &&
76
+ el.type === TouchableOpacity
77
+ );
78
+ await act(async () => {
79
+ await buttonSubmit.props.onPress();
80
+ });
81
+ };
82
+
83
+ test('render SideMenuDetail template choose field', async () => {
84
+ const response_side_menu = {
85
+ status: 200,
86
+ data: {
87
+ id: 1,
88
+ action: '3df74a11-1a95-4a65-8e08-936b88c8b5ca',
89
+ fields: [
90
+ {
91
+ type: 'choose_user',
92
+ key: 'user_id',
93
+ action: {
94
+ type: 'action_zigbee',
95
+ id: 1,
96
+ },
97
+ },
98
+ {
99
+ type: 'passcode',
100
+ key: 'passcode',
101
+ action: {
102
+ type: 'action_zigbee',
103
+ id: 1,
104
+ },
105
+ },
106
+ {
107
+ type: 'schedule',
108
+ key: 'schedule',
109
+ action: {
110
+ type: 'action_zigbee',
111
+ id: {
112
+ always: 2,
113
+ recurring: 4,
114
+ temporary: 5,
115
+ },
116
+ },
117
+ },
118
+ ],
119
+ },
120
+ };
121
+ const response_unit_members = {
122
+ status: 200,
123
+ data: [{ id: 1, name: 'Ken' }],
124
+ };
125
+
126
+ mock
127
+ .onGet(API.SENSOR.SIDE_MENU_DETAIL(1, 1))
128
+ .reply(200, response_side_menu.data);
129
+ mock
130
+ .onGet(API.SHARE.UNITS_MEMBERS(1))
131
+ .reply(200, response_unit_members.data);
132
+ mock.onPost(API.SENSOR.QUICK_ACTION(1)).reply(200, []);
133
+
134
+ const route = {
135
+ params: {
136
+ unit: { id: 1 },
137
+ sensor: { id: 1 },
138
+ side_menu: { id: 1, name: 'Setup generate pass code' },
139
+ },
140
+ };
141
+ await act(async () => {
142
+ tree = await create(wrapComponent(route));
143
+ });
144
+
145
+ const instance = tree.root;
146
+ await chooseUser(instance);
147
+ await onPressSubmitData(instance);
148
+ expect(spyToastError).toBeCalled();
149
+
150
+ await inputPasscode(instance);
151
+ await onPressSubmitData(instance);
152
+ expect(spyToastSuccess).toBeCalled();
153
+ });
154
+ });
@@ -0,0 +1,149 @@
1
+ import React, { memo, useCallback, useEffect, useState } from 'react';
2
+ import { View, ScrollView } from 'react-native';
3
+ import { useTranslations } from '../../hooks/Common/useTranslations';
4
+
5
+ import styles from './SideMenuDetailStyles';
6
+ import { HeaderCustom } from '../../commons/Header';
7
+ import BottomButtonView from '../../commons/BottomButtonView';
8
+ import { axiosGet, axiosPost } from '../../utils/Apis/axios';
9
+ import { API } from '../../configs';
10
+ import PasscodeField from '../../commons/FieldTemplate/PasscodeField';
11
+ import ChooseUserField from '../../commons/FieldTemplate/ChooseUserField';
12
+ import ScheduleField from '../../commons/FieldTemplate/ScheduleField';
13
+ import { TESTID } from '../../configs/Constants';
14
+ import { ToastBottomHelper } from '../../utils/Utils';
15
+ import { useNavigation } from '@react-navigation/native';
16
+
17
+ const SideMenuDetail = memo(({ route }) => {
18
+ const t = useTranslations();
19
+ const { goBack } = useNavigation();
20
+ const { unit, sensor, side_menu } = route?.params || {};
21
+ const [sideMenu, setSideMenu] = useState({});
22
+ const [dataForm, setDataForm] = useState([]);
23
+
24
+ const renderTemplateField = useCallback(
25
+ (item, index) => {
26
+ const keyItem = item.key;
27
+ const dataItem = item;
28
+ switch (item.type) {
29
+ case 'choose_user':
30
+ return (
31
+ <ChooseUserField
32
+ key={index} // Todo avoid waring unique "key" prop
33
+ unit={unit}
34
+ dataItem={dataItem}
35
+ index={index}
36
+ setDataForm={setDataForm}
37
+ dataForm={dataForm}
38
+ />
39
+ );
40
+ case 'passcode':
41
+ return (
42
+ <PasscodeField
43
+ key={index}
44
+ dataItem={dataItem}
45
+ index={index}
46
+ setDataForm={setDataForm}
47
+ dataForm={dataForm}
48
+ />
49
+ );
50
+ case 'schedule':
51
+ return (
52
+ <ScheduleField
53
+ key={index}
54
+ dataItem={dataItem}
55
+ keyItem={keyItem}
56
+ setDataForm={setDataForm}
57
+ dataForm={dataForm}
58
+ />
59
+ );
60
+ default:
61
+ return null;
62
+ }
63
+ },
64
+ // eslint-disable-next-line react-hooks/exhaustive-deps
65
+ [unit, dataForm]
66
+ );
67
+
68
+ const onPressSubmit = useCallback(async () => {
69
+ const data = {};
70
+ const actionZigbee = [];
71
+ for (let i = 0; i < dataForm.length; i++) {
72
+ if (!dataForm[i].valid) {
73
+ ToastBottomHelper.error(t('invaild_data'));
74
+ return;
75
+ }
76
+ if (dataForm[i].data) {
77
+ data[dataForm[i].key] = dataForm[i].data;
78
+ if (
79
+ dataForm[i].action_zigbee &&
80
+ !actionZigbee.includes(dataForm[i].action_zigbee)
81
+ ) {
82
+ actionZigbee.push(dataForm[i].action_zigbee);
83
+ }
84
+ } else {
85
+ data[dataForm[i].key] = null;
86
+ }
87
+ }
88
+
89
+ data.action_zigbee = actionZigbee;
90
+
91
+ const { success } = await axiosPost(API.SENSOR.QUICK_ACTION(sensor.id), {
92
+ key: sideMenu.action,
93
+ data,
94
+ source: 'smart_lock',
95
+ });
96
+
97
+ if (success) {
98
+ ToastBottomHelper.success(t('activated_successfully'));
99
+ goBack();
100
+ } else {
101
+ ToastBottomHelper.error(t('activation_failed'));
102
+ }
103
+ // eslint-disable-next-line react-hooks/exhaustive-deps
104
+ }, [dataForm]);
105
+
106
+ const fetchSideMenuDetail = useCallback(async () => {
107
+ const { success, data } = await axiosGet(
108
+ API.SENSOR.SIDE_MENU_DETAIL(sensor.id, side_menu.id)
109
+ );
110
+ if (success) {
111
+ setSideMenu(data);
112
+ setDataForm(data.fields);
113
+ }
114
+ }, [sensor.id, side_menu.id]);
115
+
116
+ useEffect(() => {
117
+ fetchSideMenuDetail();
118
+ // eslint-disable-next-line react-hooks/exhaustive-deps
119
+ }, []);
120
+
121
+ return (
122
+ <View style={styles.container}>
123
+ <HeaderCustom
124
+ title={side_menu.name}
125
+ titleStyle={styles.title}
126
+ isShowSeparator
127
+ />
128
+ <ScrollView
129
+ showsVerticalScrollIndicator={false}
130
+ showsHorizontalScrollIndicator={false}
131
+ style={styles.scrollview}
132
+ >
133
+ <View style={styles.wrap}>
134
+ {dataForm.map((item, index) => {
135
+ return renderTemplateField(item, index);
136
+ })}
137
+ </View>
138
+ </ScrollView>
139
+ <BottomButtonView
140
+ style={styles.viewBottomFixed}
141
+ testIDPrefix={TESTID.SUBMIT}
142
+ mainTitle={t('done')}
143
+ onPressMain={onPressSubmit}
144
+ />
145
+ </View>
146
+ );
147
+ });
148
+
149
+ export default SideMenuDetail;
@@ -36,7 +36,7 @@ const SelectDeviceType = memo(({ route }) => {
36
36
  return (
37
37
  <View style={styles.container}>
38
38
  <HeaderCustom title={t('select_brand')} />
39
- <ScrollView>
39
+ <ScrollView scrollIndicatorInsets={{ right: 1 }}>
40
40
  <View style={styles.listBrands}>
41
41
  {!!deviceBrand &&
42
42
  deviceBrand.map((item, index) => {
@@ -81,6 +81,7 @@ const ManageSubUnit = memo((props) => {
81
81
  refreshControl={
82
82
  <RefreshControl refreshing={false} onRefresh={onRefresh} />
83
83
  }
84
+ scrollIndicatorInsets={{ right: 1 }}
84
85
  >
85
86
  <View>
86
87
  {!!station.length &&