@eohjsc/react-native-smart-city 0.3.48 → 0.3.49

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 (164) hide show
  1. package/package.json +4 -4
  2. package/src/Images/DevMode/file_copy.svg +3 -0
  3. package/src/Images/DevMode/inforCode.png +0 -0
  4. package/src/Images/DevMode/inforCode@2x.png +0 -0
  5. package/src/Images/DevMode/inforCode@3x.png +0 -0
  6. package/src/commons/Action/__test__/ItemQuickAction.test.js +0 -7
  7. package/src/commons/ActionGroup/__test__/ColorPickerTemplate.test.js +1 -8
  8. package/src/commons/ActionGroup/__test__/OnOffTemplate.test.js +1 -1
  9. package/src/commons/ActionGroup/__test__/SliderRangeTemplate.test.js +1 -8
  10. package/src/commons/ActionTemplate/__test__/index.test.js +0 -7
  11. package/src/commons/Dashboard/MyPinnedSharedUnit/index.js +3 -3
  12. package/src/commons/Dashboard/MyUnit/__test__/MyUnit.test.js +1 -1
  13. package/src/commons/Dashboard/MyUnit/index.js +30 -4
  14. package/src/commons/DevMode/Styles/ItemStyles.js +1 -1
  15. package/src/commons/Device/PMSensor/PMSensorIndicatior.js +2 -1
  16. package/src/commons/FourButtonFilterHistory/__test__/FourButtonFilterHistory.test.js +0 -7
  17. package/src/commons/Header/HeaderCustom.js +13 -6
  18. package/src/commons/MediaPlayer/__test__/index.test.js +0 -7
  19. package/src/commons/MediaPlayerDetail/__test__/MediaPlayerFull.test.js +0 -1
  20. package/src/commons/MenuActionMore/index.js +4 -1
  21. package/src/commons/NavBar/index.js +1 -1
  22. package/src/commons/OneTapTemplate/OptionsDropdownActionTemplate.js +1 -1
  23. package/src/commons/OneTapTemplate/__test__/NumberUpDownActionTemplate.test.js +0 -7
  24. package/src/commons/OneTapTemplate/__test__/OptionsDropdownActionTemplate.test.js +0 -7
  25. package/src/commons/OneTapTemplate/__test__/StatesGridActionTemplate.test.js +0 -7
  26. package/src/commons/RowItem/index.js +6 -1
  27. package/src/commons/SelectUnit/index.js +4 -1
  28. package/src/commons/StatusBox/styles.js +8 -3
  29. package/src/commons/SubUnit/__test__/Favorites.test.js +0 -7
  30. package/src/commons/SubUnit/__test__/ShortDetail.test.js +0 -7
  31. package/src/commons/Tabbar/__test__/index.test.js +0 -7
  32. package/src/commons/Unit/__test__/HeaderUnit.test.js +0 -5
  33. package/src/commons/UnitSummary/ConfigHistoryChart/__test__/ConfigHistoryChart.test.js +0 -7
  34. package/src/configs/API.js +28 -0
  35. package/src/configs/AccessibilityLabel.js +13 -0
  36. package/src/configs/Colors.js +4 -0
  37. package/src/configs/Constants.js +6 -0
  38. package/src/configs/Images.js +1 -0
  39. package/src/context/actionType.ts +8 -1
  40. package/src/context/mockStore.ts +8 -2
  41. package/src/context/reducer.ts +27 -4
  42. package/src/hooks/IoT/__test__/useWatchConfigs.test.js +46 -0
  43. package/src/hooks/IoT/useBluetoothConnection.js +78 -4
  44. package/src/hooks/IoT/useBluetoothDeviceConnected.js +1 -1
  45. package/src/iot/RemoteControl/Bluetooth.js +0 -16
  46. package/src/iot/RemoteControl/__test__/Bluetooth.test.js +0 -25
  47. package/src/navigations/Main.js +39 -0
  48. package/src/navigations/UnitStack.js +18 -5
  49. package/src/screens/ActivityLog/__test__/FilterPopup.test.js +0 -7
  50. package/src/screens/ActivityLog/__test__/ItemLog.test.js +0 -7
  51. package/src/screens/ActivityLog/__test__/index.test.js +0 -7
  52. package/src/screens/AddLocationMaps/__test__/index.test.js +0 -7
  53. package/src/screens/AddNewAction/SelectAction.js +22 -18
  54. package/src/screens/AddNewAction/__test__/SelectAction.test.js +35 -16
  55. package/src/screens/AddNewAction/__test__/SelectSensorDevices.test.js +0 -7
  56. package/src/screens/AddNewDevice/__test__/AddNewDevice.test.js +0 -4
  57. package/src/screens/AddNewGateway/ConnectingZigbeeDevice.js +17 -4
  58. package/src/screens/AddNewGateway/__test__/AddNewGateway.test.js +0 -4
  59. package/src/screens/AddNewGateway/__test__/ConnectingModbusDevice.test.js +0 -4
  60. package/src/screens/AddNewGateway/__test__/ConnectingWifiDevice.test.js +0 -4
  61. package/src/screens/AddNewGateway/__test__/ConnectingZigbeeDevice.test.js +4 -7
  62. package/src/screens/AddNewGateway/__test__/RenameNewDevices.test.js +0 -7
  63. package/src/screens/AddNewGateway/__test__/SelectDeviceType.test.js +0 -4
  64. package/src/screens/AddNewGateway/__test__/SelectModbusGateway.test.js +0 -4
  65. package/src/screens/AddNewGateway/__test__/SelectZigbeeGateway.test.js +0 -4
  66. package/src/screens/AddNewOneTap/__test__/AddNewOneTap.test.js +0 -7
  67. package/src/screens/ConfirmUnitDeletion/__test__/ConfirmUnitDeletion.test.js +0 -1
  68. package/src/screens/Device/EditDevice/__test__/EditDevice.test.js +0 -7
  69. package/src/screens/Device/__test__/detail.test.js +1 -1
  70. package/src/screens/Device/detail.js +11 -3
  71. package/src/screens/Device/hooks/useDisconnectedDevice.js +26 -7
  72. package/src/screens/EmergencyContacts/__test__/hooks.test.js +79 -0
  73. package/src/screens/Gateway/DetailConfigActionModbus/__test__/index.test.js +138 -0
  74. package/src/screens/Gateway/DetailConfigActionModbus/index.js +180 -0
  75. package/src/screens/Gateway/DetailConfigActionModbus/styles.js +9 -0
  76. package/src/screens/Gateway/DetailConfigActionZigbee/__test__/index.test.js +73 -0
  77. package/src/screens/Gateway/DetailConfigActionZigbee/index.js +62 -0
  78. package/src/screens/Gateway/DetailConfigActionZigbee/styles.js +9 -0
  79. package/src/screens/Gateway/DeviceGatewayInfo/__test__/index.test.js +73 -0
  80. package/src/screens/Gateway/DeviceGatewayInfo/index.js +96 -0
  81. package/src/screens/Gateway/DeviceGatewayInfo/styles.js +9 -0
  82. package/src/screens/Gateway/DeviceModbusDetail/__test__/index.test.js +393 -0
  83. package/src/screens/Gateway/DeviceModbusDetail/index.js +176 -0
  84. package/src/screens/Gateway/DeviceModbusDetail/styles.js +12 -0
  85. package/src/screens/Gateway/DeviceZigbeeDetail/__test__/index.test.js +265 -0
  86. package/src/screens/Gateway/DeviceZigbeeDetail/index.js +148 -0
  87. package/src/screens/Gateway/DeviceZigbeeDetail/styles.js +12 -0
  88. package/src/screens/Gateway/GatewayConnectionMethods/__test__/index.test.js +37 -0
  89. package/src/screens/Gateway/GatewayConnectionMethods/index.js +73 -0
  90. package/src/screens/Gateway/GatewayConnectionMethods/styles.js +45 -0
  91. package/src/screens/Gateway/GatewayDetail/__test__/index.test.js +298 -0
  92. package/src/screens/Gateway/GatewayDetail/index.js +148 -0
  93. package/src/screens/Gateway/GatewayDetail/styles.js +12 -0
  94. package/src/screens/Gateway/GatewayInfo/__test__/index.test.js +137 -0
  95. package/src/screens/Gateway/GatewayInfo/index.js +115 -0
  96. package/src/screens/Gateway/GatewayInfo/styles.js +9 -0
  97. package/src/screens/Gateway/__test__/index.test.js +58 -0
  98. package/src/screens/Gateway/components/Detail/__test__/index.test.js +46 -0
  99. package/src/screens/Gateway/components/Detail/index.js +62 -0
  100. package/src/screens/Gateway/components/Detail/styles.js +27 -0
  101. package/src/screens/Gateway/components/DetailActionModbus/__test__/index.test.js +49 -0
  102. package/src/screens/Gateway/components/DetailActionModbus/index.js +52 -0
  103. package/src/screens/Gateway/components/DetailActionModbus/styles.js +32 -0
  104. package/src/screens/Gateway/components/DetailConfigAction/__test__/index.test.js +59 -0
  105. package/src/screens/Gateway/components/DetailConfigAction/index.js +69 -0
  106. package/src/screens/Gateway/components/DetailConfigAction/styles.js +21 -0
  107. package/src/screens/Gateway/components/GatewayItem/__test__/index.test.js +1 -1
  108. package/src/screens/Gateway/components/GatewayItem/styles.js +4 -33
  109. package/src/screens/Gateway/components/Information/__test__/index.test.js +70 -0
  110. package/src/screens/Gateway/components/Information/index.js +116 -0
  111. package/src/screens/Gateway/components/Information/styles.js +59 -0
  112. package/src/screens/Gateway/components/RowItem/__test__/index.test.js +67 -0
  113. package/src/screens/Gateway/components/RowItem/index.js +65 -0
  114. package/src/screens/Gateway/components/RowItem/styles.js +25 -0
  115. package/src/screens/Gateway/components/TabPaneCT/__test__/index.test.js +98 -0
  116. package/src/screens/Gateway/components/TabPaneCT/index.js +134 -0
  117. package/src/screens/Gateway/components/TabPaneCT/styles.js +58 -0
  118. package/src/screens/Gateway/hooks/__test__/index.test.js +93 -0
  119. package/src/screens/Gateway/hooks/useGateway.js +110 -16
  120. package/src/screens/Gateway/index.js +19 -3
  121. package/src/screens/Gateway/styles.js +6 -8
  122. package/src/screens/Gateway/utils/index.js +16 -0
  123. package/src/screens/GuestInfo/__test__/index.test.js +0 -7
  124. package/src/screens/HanetCamera/__test__/CaptureFaceID.test.js +0 -7
  125. package/src/screens/HanetCamera/__test__/Detail.test.js +0 -7
  126. package/src/screens/HanetCamera/__test__/ManageAccess.test.js +0 -7
  127. package/src/screens/HanetCamera/__test__/MemberInfo.test.js +0 -7
  128. package/src/screens/ManageAccess/__test__/ManageAccess.test.js +0 -6
  129. package/src/screens/ManageAccess/hooks/__test__/useManageAccess.test.js +0 -7
  130. package/src/screens/MoveToAnotherSubUnit/__test__/index.test.js +0 -7
  131. package/src/screens/Notification/__test__/Notification.test.js +0 -7
  132. package/src/screens/PlayBackCamera/__test__/index.test.js +0 -1
  133. package/src/screens/ScriptDetail/__test__/index.test.js +0 -7
  134. package/src/screens/SelectUnit/__test__/index.test.js +0 -1
  135. package/src/screens/SetSchedule/__test__/index.test.js +0 -7
  136. package/src/screens/Sharing/Components/__test__/DeviceItem.test.js +0 -7
  137. package/src/screens/Sharing/Components/__test__/ItemChangeRole.test.js +0 -7
  138. package/src/screens/Sharing/Components/__test__/TitleCheckBox.test.js +0 -7
  139. package/src/screens/Sharing/__test__/InfoMemberUnit.test.js +0 -6
  140. package/src/screens/Sharing/hooks/__test__/index.test.js +80 -0
  141. package/src/screens/SmartAccount/ListDevice/__test__/DeviceItem.test.js +0 -7
  142. package/src/screens/SmartIr/__test__/ButtonsBottom.test.js +0 -6
  143. package/src/screens/SmartIr/__test__/GroupButtonByType.test.js +1 -6
  144. package/src/screens/SmartIr/__test__/SelectBrand.test.js +1 -6
  145. package/src/screens/SmartIr/__test__/SelectDeviceType.test.js +1 -6
  146. package/src/screens/SubUnit/AddSubUnit.js +1 -0
  147. package/src/screens/SubUnit/ManageSubUnit.js +4 -1
  148. package/src/screens/SubUnit/hooks/__test__/useEmergencyContacts.test.js +34 -0
  149. package/src/screens/SubUnit/hooks/__test__/useManageSubUnit.test.js +0 -7
  150. package/src/screens/SyncLGDevice/__test__/AddLGDevice.test.js +0 -7
  151. package/src/screens/Unit/__test__/AddMenu.test.js +0 -7
  152. package/src/screens/Unit/__test__/CheckSendEmail.test.js +1 -1
  153. package/src/screens/Unit/__test__/ChooseLocation.test.js +0 -7
  154. package/src/screens/Unit/__test__/Detail.test.js +1 -8
  155. package/src/screens/Unit/__test__/SelectAddToFavorites.test.js +0 -7
  156. package/src/screens/Unit/__test__/SelectAddress.test.js +0 -7
  157. package/src/screens/Unit/__test__/SmartAccount.test.js +0 -7
  158. package/src/screens/Unit/__test__/SmartAccountItem.test.js +0 -7
  159. package/src/screens/Unit/__test__/Summaries.test.js +0 -7
  160. package/src/screens/Unit/hook/useUnitConnectRemoteDevices.js +4 -3
  161. package/src/screens/UnitSummary/components/RunningDevices/__test__/index.test.js +2 -2
  162. package/src/utils/I18n/translations/en.json +28 -0
  163. package/src/utils/I18n/translations/vi.json +28 -0
  164. package/src/utils/Route/index.js +8 -0
@@ -0,0 +1,298 @@
1
+ import React from 'react';
2
+ import { create, act } from 'react-test-renderer';
3
+ import { SCProvider } from '../../../../context';
4
+ import { mockSCStore } from '../../../../context/mockStore';
5
+ import GatewayDetail from '..';
6
+ import { useRoute } from '@react-navigation/native';
7
+ import { HeaderCustom } from '../../../../commons';
8
+ import { AccessibilityLabel } from '../../../../configs/Constants';
9
+ import Routes from '../../../../utils/Route';
10
+ import TabPaneCT from '../../components/TabPaneCT';
11
+ import MenuActionMore from '../../../../commons/MenuActionMore';
12
+ import { Alert } from 'react-native';
13
+ import Toast from 'react-native-toast-message';
14
+ import SegmentedControl from '@react-native-community/segmented-control';
15
+ import MockAdapter from 'axios-mock-adapter';
16
+ import api from '../../../../utils/Apis/axios';
17
+ import { API } from '../../../../configs';
18
+ import { DEVICE_TYPE } from '../../../../configs/Constants';
19
+ import Detail from '../../components/Detail';
20
+
21
+ const mock = new MockAdapter(api.axiosInstance);
22
+
23
+ const wrapComponent = () => (
24
+ <SCProvider initState={mockSCStore({})}>
25
+ <GatewayDetail />
26
+ </SCProvider>
27
+ );
28
+
29
+ jest.mock('react-native', () => {
30
+ const RN = jest.requireActual('react-native');
31
+ return Object.setPrototypeOf(
32
+ {
33
+ Alert: {
34
+ ...RN.Alert,
35
+ alert: jest.fn(),
36
+ },
37
+ },
38
+ RN
39
+ );
40
+ });
41
+
42
+ const mockPop = jest.fn();
43
+ const mockNavigate = jest.fn();
44
+ jest.mock('@react-navigation/native', () => {
45
+ return {
46
+ ...jest.requireActual('@react-navigation/native'),
47
+ useNavigation: () => ({
48
+ navigate: mockNavigate,
49
+ pop: mockPop,
50
+ }),
51
+ useRoute: jest.fn(),
52
+ useIsFocused: () => true,
53
+ };
54
+ });
55
+
56
+ const headerCustomOnPressMore = async (instance) => {
57
+ const headerCustom = instance?.findAllByType(HeaderCustom);
58
+ const buttonMore = headerCustom[0].findByProps({
59
+ accessibilityLabel: AccessibilityLabel.MENU_POPPER_MORE,
60
+ });
61
+ await act(async () => {
62
+ buttonMore.props.onPress();
63
+ });
64
+ };
65
+
66
+ describe('Test GatewayDetail', () => {
67
+ let tree;
68
+ beforeEach(() => {
69
+ useRoute.mockReturnValue({
70
+ params: {
71
+ item: {
72
+ id: 1,
73
+ modbus_gateway: 1,
74
+ zigbee_gateway: 1,
75
+ },
76
+ },
77
+ });
78
+ });
79
+ afterEach(() => {
80
+ mock.reset();
81
+ mock.resetHistory();
82
+ mockNavigate.mockClear();
83
+ Toast.show.mockClear();
84
+ });
85
+
86
+ it('test render GatewayDetail', async () => {
87
+ await act(async () => {
88
+ tree = await create(wrapComponent());
89
+ });
90
+ const instance = tree.root;
91
+ const detail = instance?.findByType(Detail);
92
+ const headerCustom = detail.findAllByType(HeaderCustom);
93
+ const tabPaneCT = detail.findAllByType(TabPaneCT);
94
+ const menuActionMore = detail.findAllByType(MenuActionMore);
95
+
96
+ expect(headerCustom).toHaveLength(1);
97
+ expect(tabPaneCT).toHaveLength(1);
98
+ expect(menuActionMore).toHaveLength(1);
99
+ });
100
+
101
+ it('test render GatewayDetail onPress more and onPress gateway info', async () => {
102
+ await act(async () => {
103
+ tree = await create(wrapComponent());
104
+ });
105
+ const instance = tree.root;
106
+ const detail = instance?.findByType(Detail);
107
+ headerCustomOnPressMore(detail);
108
+ const menuActionMore = detail?.findAllByType(MenuActionMore);
109
+ expect(menuActionMore[0].props.isVisible).toEqual(true);
110
+ await act(async () => {
111
+ menuActionMore[0].props.listMenuItem[0].doAction();
112
+ });
113
+ expect(mockNavigate).toHaveBeenCalledWith(Routes.GatewayInfo, {
114
+ chipId: 1,
115
+ });
116
+ });
117
+
118
+ it('test render GatewayDetail onPress more and onPress reboot', async () => {
119
+ await act(async () => {
120
+ tree = await create(wrapComponent());
121
+ });
122
+ const instance = tree.root;
123
+ const detail = instance?.findByType(Detail);
124
+ headerCustomOnPressMore(detail);
125
+ const menuActionMore = detail?.findAllByType(MenuActionMore);
126
+ expect(menuActionMore[0].props.isVisible).toEqual(true);
127
+ await act(async () => {
128
+ menuActionMore[0].props.listMenuItem[1].doAction();
129
+ });
130
+ expect(Alert.alert).toHaveBeenCalled();
131
+ });
132
+
133
+ it('test render GatewayDetail onPress more and onPress Delete', async () => {
134
+ await act(async () => {
135
+ tree = await create(wrapComponent());
136
+ });
137
+ const instance = tree.root;
138
+ const detail = instance?.findByType(Detail);
139
+ headerCustomOnPressMore(detail);
140
+ const menuActionMore = detail?.findByType(MenuActionMore);
141
+ expect(menuActionMore.props.isVisible).toEqual(true);
142
+ await act(async () => {
143
+ menuActionMore.props.listMenuItem[2].doAction();
144
+ });
145
+ expect(Alert.alert.mock.calls[1][0]).toEqual(
146
+ 'Are you sure you want to delete gateway "undefined" ?'
147
+ );
148
+ mock.onDelete(API.DEV_MODE.GATEWAY.DETAIL(1)).reply(200);
149
+ await act(async () => {
150
+ await Alert.alert.mock.calls[1][2][1].onPress();
151
+ });
152
+ expect(mockPop).toBeCalledWith(1);
153
+ expect(Toast.show).toBeCalledWith({
154
+ position: 'bottom',
155
+ text1: 'Delete successfully!',
156
+ text2: undefined,
157
+ type: 'success',
158
+ visibilityTime: 1000,
159
+ });
160
+ });
161
+
162
+ it('test render GatewayDetail onPress TabPanel zigbee', async () => {
163
+ mock
164
+ .onGet(API.DEV_MODE.ZIGBEE.DEVICE(1))
165
+ .reply(200, [{ id: 1, name: 'device 1' }]);
166
+ await act(async () => {
167
+ tree = await create(wrapComponent());
168
+ });
169
+ const instance = tree.root;
170
+ const detail = instance?.findByType(Detail);
171
+ const tabPaneCT = detail.findByType(TabPaneCT);
172
+ const segmentedControl = tabPaneCT.findByType(SegmentedControl);
173
+ await act(async () => {
174
+ await segmentedControl.props.onChange({
175
+ nativeEvent: { selectedSegmentIndex: 0 },
176
+ });
177
+ });
178
+ expect(tabPaneCT.props.listTabs[0].data).toEqual([
179
+ { id: 1, name: 'device 1' },
180
+ ]);
181
+ expect(tabPaneCT.props.listTabs[0].title).toEqual(DEVICE_TYPE.ZIGBEE);
182
+ });
183
+
184
+ it('test render GatewayDetail onPress TabPanel modbus', async () => {
185
+ mock
186
+ .onGet(API.DEV_MODE.MODBUS.DEVICE(1))
187
+ .reply(200, [{ id: 1, name: 'device 1' }]);
188
+ await act(async () => {
189
+ tree = await create(wrapComponent());
190
+ });
191
+ const instance = tree.root;
192
+ const detail = instance?.findByType(Detail);
193
+ const tabPaneCT = detail.findByType(TabPaneCT);
194
+ const segmentedControl = tabPaneCT.findByType(SegmentedControl);
195
+ await act(async () => {
196
+ await segmentedControl.props.onChange({
197
+ nativeEvent: { selectedSegmentIndex: 1 },
198
+ });
199
+ });
200
+ expect(tabPaneCT.props.listTabs[1].data).toEqual([
201
+ { id: 1, name: 'device 1' },
202
+ ]);
203
+ expect(tabPaneCT.props.listTabs[1].title).toEqual(DEVICE_TYPE.MODBUS);
204
+ });
205
+
206
+ it('test render GatewayDetail onPress TabPanel zigbee onPressRow', async () => {
207
+ mock
208
+ .onGet(API.DEV_MODE.ZIGBEE.DEVICE(1))
209
+ .reply(200, [{ id: 1, name: 'device 1' }]);
210
+ await act(async () => {
211
+ tree = await create(wrapComponent());
212
+ });
213
+ const instance = tree.root;
214
+ const detail = instance?.findByType(Detail);
215
+ await act(async () => {
216
+ await detail.props.onPressRow(1);
217
+ });
218
+ expect(mockNavigate).toBeCalledWith(Routes.DeviceZigbeeDetail, {
219
+ device: 1,
220
+ gatewayId: 1,
221
+ isModbus: false,
222
+ isZigbee: true,
223
+ });
224
+ });
225
+
226
+ it('test render GatewayDetail onPress TabPanel modbus onPressRow', async () => {
227
+ mock
228
+ .onGet(API.DEV_MODE.MODBUS.DEVICE(1))
229
+ .reply(200, [{ id: 1, name: 'device 1' }]);
230
+ await act(async () => {
231
+ tree = await create(wrapComponent());
232
+ });
233
+ const instance = tree.root;
234
+ const detail = instance?.findByType(Detail);
235
+ const tabPaneCT = detail.findByType(TabPaneCT);
236
+ const segmentedControl = tabPaneCT.findByType(SegmentedControl);
237
+ await act(async () => {
238
+ await segmentedControl.props.onChange({
239
+ nativeEvent: { selectedSegmentIndex: 1 },
240
+ });
241
+ });
242
+ await act(async () => {
243
+ await detail.props.onPressRow(1);
244
+ });
245
+ expect(mockNavigate).toBeCalledWith(Routes.DeviceModbusDetail, {
246
+ device: 1,
247
+ gatewayId: 1,
248
+ isModbus: true,
249
+ isZigbee: false,
250
+ });
251
+ });
252
+
253
+ it('test render GatewayDetail onPress TabPanel error onPressRow', async () => {
254
+ mock
255
+ .onGet(API.DEV_MODE.MODBUS.DEVICE(1))
256
+ .reply(200, [{ id: 1, name: 'device 1' }]);
257
+ await act(async () => {
258
+ tree = await create(wrapComponent());
259
+ });
260
+ const instance = tree.root;
261
+ const detail = instance?.findByType(Detail);
262
+ const tabPaneCT = detail.findByType(TabPaneCT);
263
+ const segmentedControl = tabPaneCT.findByType(SegmentedControl);
264
+ await act(async () => {
265
+ await segmentedControl.props.onChange({
266
+ nativeEvent: { selectedSegmentIndex: -1 },
267
+ });
268
+ });
269
+ await act(async () => {
270
+ await detail.props.onPressRow(1);
271
+ });
272
+ expect(mockNavigate).toBeCalledWith('', {
273
+ device: 1,
274
+ gatewayId: null,
275
+ isModbus: false,
276
+ isZigbee: false,
277
+ });
278
+ });
279
+
280
+ it('test render GatewayDetail onPress TabPanel modbus onRefresh', async () => {
281
+ mock
282
+ .onGet(API.DEV_MODE.ZIGBEE.DEVICE(1))
283
+ .reply(200, [{ id: 1, name: 'device 1' }]);
284
+ await act(async () => {
285
+ tree = await create(wrapComponent());
286
+ });
287
+ const instance = tree.root;
288
+ const detail = instance?.findByType(Detail);
289
+ const tabPaneCT = detail.findByType(TabPaneCT);
290
+ await act(async () => {
291
+ await detail.props.onRefresh();
292
+ });
293
+ expect(tabPaneCT.props.listTabs[0].data).toEqual([
294
+ { id: 1, name: 'device 1' },
295
+ ]);
296
+ expect(tabPaneCT.props.listTabs[0].title).toEqual(DEVICE_TYPE.ZIGBEE);
297
+ });
298
+ });
@@ -0,0 +1,148 @@
1
+ import React, { memo, useMemo, useEffect, useCallback } from 'react';
2
+ import { View, Alert } from 'react-native';
3
+ import t from '../../../hooks/Common/useTranslations';
4
+ import {
5
+ useRoute,
6
+ useNavigation,
7
+ useIsFocused,
8
+ } from '@react-navigation/native';
9
+
10
+ import { useGateway } from '../hooks/useGateway';
11
+ import Routes from '../../../utils/Route';
12
+ import { DEVICE_TYPE } from '../../../configs/Constants';
13
+ import Detail from '../components/Detail';
14
+ import styles from './styles';
15
+
16
+ const GatewayDetail = () => {
17
+ const { params = {} } = useRoute();
18
+ const { item = {} } = params;
19
+ const { navigate } = useNavigation();
20
+ const isFocused = useIsFocused();
21
+
22
+ const {
23
+ selectedIndex,
24
+ setSelectedIndex,
25
+ fetchDevicesGateway,
26
+ deleteGatewayDetail,
27
+ setRefresh,
28
+ refresh,
29
+ gatewayDevices,
30
+ } = useGateway();
31
+
32
+ const listTabs = useMemo(
33
+ () => [
34
+ {
35
+ id: 1,
36
+ title: DEVICE_TYPE.ZIGBEE,
37
+ data: gatewayDevices?.zigbee,
38
+ },
39
+ {
40
+ id: 2,
41
+ title: DEVICE_TYPE.MODBUS,
42
+ data: gatewayDevices?.modbus,
43
+ },
44
+ ],
45
+ [gatewayDevices?.modbus, gatewayDevices?.zigbee]
46
+ );
47
+
48
+ const listMenuItem = useMemo(() => {
49
+ const RouteGatewayInformation = {
50
+ id: 1,
51
+ text: t('gateway_information'),
52
+ doAction: () =>
53
+ navigate(Routes.GatewayInfo, {
54
+ chipId: item?.id,
55
+ gatewayName: item?.name,
56
+ }),
57
+ };
58
+ const RouteRebootGateway = {
59
+ id: 2,
60
+ text: t('reboot'),
61
+ textStyle: styles.textColorRed,
62
+ doAction: () => Alert.alert(t('feature_under_development')),
63
+ };
64
+ const ListDeleteGateway = {
65
+ id: 3,
66
+ text: t('delete'),
67
+ textStyle: styles.textColorRed,
68
+ doAction: () =>
69
+ Alert.alert(t('message_delete_gateway', { name: item?.name }), '', [
70
+ {
71
+ text: t('cancel'),
72
+ },
73
+ {
74
+ text: t('ok'),
75
+ onPress: () => deleteGatewayDetail(item?.id),
76
+ style: 'destructive',
77
+ },
78
+ ]),
79
+ };
80
+ return [RouteGatewayInformation, RouteRebootGateway, ListDeleteGateway];
81
+ }, [deleteGatewayDetail, item?.id, item?.name, navigate]);
82
+
83
+ const isModbus = useMemo(() => {
84
+ return listTabs[selectedIndex]?.title === DEVICE_TYPE.MODBUS;
85
+ }, [listTabs, selectedIndex]);
86
+
87
+ const isZigbee = useMemo(() => {
88
+ return listTabs[selectedIndex]?.title === DEVICE_TYPE.ZIGBEE;
89
+ }, [listTabs, selectedIndex]);
90
+
91
+ const gatewayId = useMemo(() => {
92
+ return isModbus
93
+ ? item?.modbus_gateway
94
+ : isZigbee
95
+ ? item?.zigbee_gateway
96
+ : null;
97
+ }, [isModbus, isZigbee, item?.modbus_gateway, item?.zigbee_gateway]);
98
+
99
+ useEffect(() => {
100
+ if (isFocused) {
101
+ fetchDevicesGateway(gatewayId, isModbus, isZigbee);
102
+ }
103
+ }, [fetchDevicesGateway, gatewayId, isModbus, isZigbee, isFocused]);
104
+
105
+ const onPressRow = useCallback(
106
+ (device) => {
107
+ navigate(
108
+ (isZigbee && Routes.DeviceZigbeeDetail) ||
109
+ (isModbus && Routes.DeviceModbusDetail) ||
110
+ '',
111
+ {
112
+ device: device,
113
+ gatewayId,
114
+ isZigbee,
115
+ isModbus,
116
+ }
117
+ );
118
+ },
119
+ [isModbus, isZigbee, gatewayId, navigate]
120
+ );
121
+
122
+ const title = useMemo(() => {
123
+ return item?.name || '';
124
+ }, [item?.name]);
125
+
126
+ const onRefresh = useCallback(() => {
127
+ setRefresh(true);
128
+ fetchDevicesGateway(gatewayId, isModbus, isZigbee);
129
+ setRefresh(false);
130
+ }, [fetchDevicesGateway, isModbus, isZigbee, gatewayId, setRefresh]);
131
+
132
+ return (
133
+ <View style={styles.wrap}>
134
+ <Detail
135
+ title={title}
136
+ listMenuItem={listMenuItem}
137
+ listTabs={listTabs}
138
+ selectedIndex={selectedIndex}
139
+ setSelectedIndex={setSelectedIndex}
140
+ onPressRow={onPressRow}
141
+ onRefresh={onRefresh}
142
+ refresh={refresh}
143
+ />
144
+ </View>
145
+ );
146
+ };
147
+
148
+ export default memo(GatewayDetail);
@@ -0,0 +1,12 @@
1
+ import { StyleSheet } from 'react-native';
2
+ import { Colors } from '../../../configs';
3
+
4
+ export default StyleSheet.create({
5
+ wrap: {
6
+ flex: 1,
7
+ backgroundColor: Colors.White,
8
+ },
9
+ textColorRed: {
10
+ color: Colors.Red,
11
+ },
12
+ });
@@ -0,0 +1,137 @@
1
+ import React from 'react';
2
+ import { create, act } from 'react-test-renderer';
3
+ import { FlatList, Alert } from 'react-native';
4
+ import MockAdapter from 'axios-mock-adapter';
5
+ import { useRoute } from '@react-navigation/native';
6
+
7
+ import { SCProvider } from '../../../../context';
8
+ import { mockSCStore } from '../../../../context/mockStore';
9
+ import { HeaderCustom, Text } from '../../../../commons';
10
+ import { AccessibilityLabel } from '../../../../configs/Constants';
11
+ import API from '../../../../configs/API';
12
+ import Routes from '../../../../utils/Route';
13
+ import api from '../../../../utils/Apis/axios';
14
+ import GatewayInfo from '..';
15
+ import t from '../../../../hooks/Common/useTranslations';
16
+
17
+ const mockPop = jest.fn();
18
+ const mock = new MockAdapter(api.axiosInstance);
19
+ const wrapComponent = () => (
20
+ <SCProvider initState={mockSCStore({})}>
21
+ <GatewayInfo />
22
+ </SCProvider>
23
+ );
24
+
25
+ jest.mock('react-native', () => {
26
+ const RN = jest.requireActual('react-native');
27
+ return Object.setPrototypeOf(
28
+ {
29
+ Alert: {
30
+ ...RN.Alert,
31
+ alert: jest.fn(),
32
+ },
33
+ },
34
+ RN
35
+ );
36
+ });
37
+
38
+ const mockNavigate = jest.fn();
39
+ jest.mock('@react-navigation/native', () => {
40
+ return {
41
+ ...jest.requireActual('@react-navigation/native'),
42
+ useNavigation: () => ({
43
+ navigate: mockNavigate,
44
+ pop: mockPop,
45
+ }),
46
+ useIsFocused: () => true,
47
+ useRoute: jest.fn(),
48
+ };
49
+ });
50
+
51
+ const buttonConnect = (instance) => {
52
+ return instance?.findByProps({
53
+ accessibilityLabel:
54
+ AccessibilityLabel.GATEWAY_INFO_BUTTON_GOTO_CONNECTION_METHODS,
55
+ });
56
+ };
57
+ const buttonDelete = (instance) => {
58
+ return instance?.findByProps({
59
+ accessibilityLabel: AccessibilityLabel.GATEWAY_INFO_BUTTON_DELETE_GATEWAY,
60
+ });
61
+ };
62
+
63
+ describe('Test GatewayInfo', () => {
64
+ let tree;
65
+ beforeEach(() => {
66
+ useRoute.mockReturnValue({
67
+ params: {
68
+ chipId: 1,
69
+ },
70
+ });
71
+ mockNavigate.mockClear();
72
+ });
73
+
74
+ it('test render GatewayInfo', async () => {
75
+ useRoute.mockReturnValue({
76
+ params: { chipId: 1 },
77
+ });
78
+ mock
79
+ .onGet(API.DEV_MODE.GATEWAY.DETAIL(1))
80
+ .reply(200, { results: [{ id: 1, name: 'device 1' }] });
81
+ await act(async () => {
82
+ tree = await create(wrapComponent());
83
+ });
84
+ const instance = tree.root;
85
+
86
+ const headerCustom = instance.findAllByType(HeaderCustom);
87
+ const alert = instance.findByProps({
88
+ accessibilityLabel: AccessibilityLabel.GATEWAY_INFO_ALERT,
89
+ });
90
+ const flatList = instance.findAllByType(FlatList);
91
+ const btnConnect = buttonConnect(instance);
92
+ const btnDelete = buttonDelete(instance);
93
+ expect(headerCustom).toHaveLength(1);
94
+ expect(alert.props.children[1].props.children).toEqual(
95
+ t('go_to_eoh_web_to_see_firmware')
96
+ );
97
+ expect(flatList).toHaveLength(1);
98
+ const textConnect = btnConnect.findAllByType(Text);
99
+ expect(textConnect[0].props.children).toEqual(t('connection_methods'));
100
+ const textDelete = btnDelete.findAllByType(Text);
101
+ expect(textDelete[0].props.children).toEqual(t('delete_gateway'));
102
+ });
103
+
104
+ it('test render GatewayInfo onPress method connect', async () => {
105
+ await act(async () => {
106
+ tree = await create(wrapComponent());
107
+ });
108
+ const instance = tree.root;
109
+ const btnConnect = buttonConnect(instance);
110
+ await act(async () => {
111
+ btnConnect.props.onPress();
112
+ });
113
+ expect(mockNavigate).toBeCalledWith(Routes.GatewayConnectionMethods);
114
+ });
115
+
116
+ it('test render GatewayInfo onPress delete gateway', async () => {
117
+ await act(async () => {
118
+ tree = await create(wrapComponent());
119
+ });
120
+ const instance = tree.root;
121
+ const btnDelete = buttonDelete(instance);
122
+ await act(async () => {
123
+ await btnDelete.props.onPress();
124
+ });
125
+ expect(Alert.alert.mock.calls[0][0]).toEqual(
126
+ t('message_delete_gateway', { name: '' })
127
+ );
128
+ expect(Alert.alert.mock.calls[0][2][1].text).toEqual('OK');
129
+ mock
130
+ .onDelete(API.DEV_MODE.GATEWAY.DETAIL(1))
131
+ .reply(200, { results: [{ id: 1, name: 'device 1' }] });
132
+ await act(async () => {
133
+ await Alert.alert.mock.calls[0][2][1].onPress();
134
+ });
135
+ expect(mockPop).toBeCalledWith(2);
136
+ });
137
+ });
@@ -0,0 +1,115 @@
1
+ import React, { memo, useMemo, useEffect, useCallback } from 'react';
2
+ import { View, Alert } from 'react-native';
3
+ import {
4
+ useIsFocused,
5
+ useRoute,
6
+ useNavigation,
7
+ } from '@react-navigation/native';
8
+
9
+ import Routes from '../../../utils/Route';
10
+ import Information from '../components/Information';
11
+ import t from '../../../hooks/Common/useTranslations';
12
+ import styles from './styles';
13
+ import { useGateway } from '../hooks/useGateway';
14
+
15
+ const GatewayInfo = () => {
16
+ const { params = {} } = useRoute();
17
+ const isFocused = useIsFocused();
18
+ const { navigate } = useNavigation();
19
+ const { chipId = undefined, gatewayName = '' } = params;
20
+
21
+ const { fetchDataDetailGateway, gatewayDetail, deleteGatewayDetail } =
22
+ useGateway();
23
+
24
+ const {
25
+ connection_time = '',
26
+ wifi_ssid = '',
27
+ id,
28
+ date_active = '',
29
+ expired_at = '',
30
+ } = gatewayDetail || {};
31
+
32
+ const gatewayInformation = useMemo(
33
+ () => [
34
+ {
35
+ id: 1,
36
+ title: 'system',
37
+ data: '--',
38
+ },
39
+ {
40
+ id: 2,
41
+ title: 'connection_time',
42
+ data: connection_time,
43
+ },
44
+ {
45
+ id: 3,
46
+ title: 'wifi',
47
+ data: wifi_ssid || '--',
48
+ },
49
+ {
50
+ id: 4,
51
+ title: 'device_id',
52
+ data: id || '--',
53
+ },
54
+ {
55
+ id: 5,
56
+ title: 'auth_token',
57
+ data: 'sdfjkhsakdjfaskdjfkalsdsfjghsdklf',
58
+ },
59
+ {
60
+ id: 7,
61
+ title: 'activate_date',
62
+ data: date_active || '--',
63
+ },
64
+ {
65
+ id: 8,
66
+ title: 'warranty_expiration_date',
67
+ data: expired_at || '--',
68
+ },
69
+ {
70
+ id: 9,
71
+ title: 'firmware_version',
72
+ data: '--',
73
+ },
74
+ ],
75
+ [connection_time, date_active, expired_at, id, wifi_ssid]
76
+ );
77
+
78
+ const handleDeleteGateway = useCallback(() => {
79
+ return Alert.alert(
80
+ t('message_delete_gateway', { name: gatewayName || '' }),
81
+ '',
82
+ [
83
+ {
84
+ text: t('cancel'),
85
+ },
86
+ {
87
+ text: t('ok'),
88
+ onPress: () => deleteGatewayDetail(chipId, 2),
89
+ style: 'destructive',
90
+ },
91
+ ]
92
+ );
93
+ }, [chipId, deleteGatewayDetail, gatewayName]);
94
+
95
+ const handleConnectionMethods = useCallback(() => {
96
+ navigate(Routes.GatewayConnectionMethods);
97
+ }, [navigate]);
98
+
99
+ useEffect(() => {
100
+ isFocused && fetchDataDetailGateway(chipId);
101
+ }, [isFocused, fetchDataDetailGateway, chipId]);
102
+
103
+ return (
104
+ <View style={styles.wrap}>
105
+ <Information
106
+ data={gatewayDetail}
107
+ listInformation={gatewayInformation}
108
+ handleDeleteGateway={handleDeleteGateway}
109
+ handleConnectionMethods={handleConnectionMethods}
110
+ />
111
+ </View>
112
+ );
113
+ };
114
+
115
+ export default memo(GatewayInfo);