@eohjsc/react-native-smart-city 0.7.27 → 0.7.31

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 (71) hide show
  1. package/index.js +2 -0
  2. package/package.json +2 -1
  3. package/src/commons/Dashboard/MyDashboardDevice/__test__/index.test.js +68 -0
  4. package/src/commons/Dashboard/MyDashboardDevice/index.js +46 -11
  5. package/src/commons/Dashboard/MyUnit/__test__/MyUnit.test.js +43 -11
  6. package/src/commons/Dashboard/MyUnit/index.js +40 -32
  7. package/src/commons/ModalAlert/index.js +51 -0
  8. package/src/commons/ModalAlert/styles.js +54 -0
  9. package/src/commons/SubUnit/ShortDetail.js +20 -4
  10. package/src/commons/SubUnit/__test__/ShortDetail.test.js +46 -1
  11. package/src/configs/API.js +8 -0
  12. package/src/configs/AccessibilityLabel.js +3 -0
  13. package/src/configs/Constants.js +7 -0
  14. package/src/configs/SCConfig.js +6 -0
  15. package/src/context/SCContext.tsx +12 -1
  16. package/src/context/SCStore.ts +14 -0
  17. package/src/context/actionType.ts +10 -0
  18. package/src/context/mockStore.ts +30 -1
  19. package/src/context/reducer.ts +35 -0
  20. package/src/hooks/IoT/useRemoteControl.js +4 -1
  21. package/src/hooks/IoT/useWatchSharedChips.js +130 -0
  22. package/src/hooks/Review/__test__/useInAppReview.test.js +99 -0
  23. package/src/hooks/Review/useInAppReview.js +70 -0
  24. package/src/hooks/useMqtt.js +78 -27
  25. package/src/iot/Monitor.js +149 -26
  26. package/src/iot/UpdateStates.js +60 -0
  27. package/src/iot/mqtt.js +177 -22
  28. package/src/navigations/UnitStack.js +16 -0
  29. package/src/screens/ActivityLog/ItemLog.js +1 -0
  30. package/src/screens/AddNewGateway/RenameNewDevices.js +5 -0
  31. package/src/screens/AddNewGateway/__test__/RenameNewDevices.test.js +18 -0
  32. package/src/screens/Automate/AddNewAction/ReceiverSelect.js +210 -0
  33. package/src/screens/Automate/AddNewAction/SetupScriptEmail.js +1 -1
  34. package/src/screens/Automate/AddNewAction/SetupScriptNotify.js +18 -28
  35. package/src/screens/Automate/AddNewAction/SetupScriptReceiverEmail.js +22 -129
  36. package/src/screens/Automate/AddNewAction/SetupScriptReceiverNotify.js +59 -0
  37. package/src/screens/Automate/AddNewAction/SetupScriptReceiverSms.js +22 -129
  38. package/src/screens/Automate/AddNewAction/SetupScriptSms.js +1 -1
  39. package/src/screens/Automate/AddNewAction/Styles/{SetupScriptReceiverEmailStyles.js → ReceiverSelectStyles.js} +18 -1
  40. package/src/screens/Automate/AddNewAction/__test__/SetupScriptNotify.test.js +16 -33
  41. package/src/screens/Automate/AddNewAction/__test__/SetupScriptReceiverEmail.test.js +10 -8
  42. package/src/screens/Automate/AddNewAction/__test__/SetupScriptReceiverNotify.test.js +217 -0
  43. package/src/screens/Automate/AddNewAction/__test__/SetupScriptReceiverSms.test.js +10 -8
  44. package/src/screens/Automate/Components/InputName.js +5 -1
  45. package/src/screens/Automate/EditActionsList/UpdateReceiverEmailScript.js +4 -3
  46. package/src/screens/Automate/EditActionsList/UpdateReceiverSmsScript.js +5 -4
  47. package/src/screens/Automate/OneTap/__test__/AddNewOneTap.test.js +18 -0
  48. package/src/screens/Automate/ScriptDetail/Styles/indexStyles.js +1 -1
  49. package/src/screens/Automate/ScriptDetail/__test__/index.test.js +116 -2
  50. package/src/screens/Automate/ScriptDetail/index.js +47 -9
  51. package/src/screens/CreatePassword/__test__/index.test.js +133 -0
  52. package/src/screens/CreatePassword/index.js +134 -0
  53. package/src/screens/CreatePassword/styles.js +45 -0
  54. package/src/screens/Device/__test__/DeviceDetail-3rdparty.test.js +447 -0
  55. package/src/screens/Device/__test__/DeviceDetail-arduino.test.js +344 -0
  56. package/src/screens/Device/__test__/{mqttDetail.test.js → DeviceDetail-modbus.test.js} +287 -320
  57. package/src/screens/Device/__test__/DeviceDetail-zigbee.test.js +451 -0
  58. package/src/screens/Device/__test__/DeviceDetail.test.js +502 -0
  59. package/src/screens/Device/__test__/detail.test.js +61 -3
  60. package/src/screens/Device/__test__/sensorDisplayItem.test.js +28 -3
  61. package/src/screens/Device/detail.js +14 -6
  62. package/src/screens/Device/hooks/useDeviceWatchConfigControl.js +3 -2
  63. package/src/screens/EnterPassword/__test__/EnterPassword.test.js +76 -1
  64. package/src/screens/EnterPassword/index.js +34 -4
  65. package/src/screens/EnterPassword/styles.js +1 -1
  66. package/src/utils/FactoryGateway.js +597 -0
  67. package/src/utils/I18n/translations/en.js +11 -0
  68. package/src/utils/I18n/translations/vi.js +11 -0
  69. package/src/utils/Route/index.js +3 -1
  70. package/src/utils/Validation.js +5 -0
  71. package/src/utils/store.js +5 -0
@@ -0,0 +1,502 @@
1
+ import { NavigationContext } from '@react-navigation/native';
2
+ import AsyncStorage from '@react-native-async-storage/async-storage';
3
+ import MockAdapter from 'axios-mock-adapter';
4
+ import moment from 'moment';
5
+ import mqtt from 'precompiled-mqtt/dist/mqtt.browser';
6
+ import React from 'react';
7
+ import { Alert } from 'react-native';
8
+ import { act, create } from 'react-test-renderer';
9
+
10
+ import QualityIndicatorItem from '../../../commons/Device/WaterQualitySensor/QualityIndicatorsItem';
11
+ import { API } from '../../../configs';
12
+ import { SCProvider } from '../../../context';
13
+ import { mockSCStore } from '../../../context/mockStore';
14
+ import { mqttClientsPool } from '../../../hooks/useMqtt';
15
+ import { unwatchMultiDataChips, watchMultiConfigs } from '../../../iot/Monitor';
16
+ import { setConfigGlobalState } from '../../../iot/states';
17
+ import api from '../../../utils/Apis/axios';
18
+ import { gatewayDataFactory } from '../../../utils/FactoryGateway';
19
+ import DeviceDetail from '../detail';
20
+
21
+ const mock = new MockAdapter(api.axiosInstance);
22
+
23
+ jest.mock('../../../iot/Monitor', () => {
24
+ return {
25
+ ...jest.requireActual('../../../iot/Monitor'),
26
+ watchMultiConfigs: jest.fn(),
27
+ unwatchMultiDataChips: jest.fn(),
28
+ };
29
+ });
30
+
31
+ let store = mockSCStore({});
32
+
33
+ const mockAxios = (
34
+ responseDisplay,
35
+ responseDisplayValueV2,
36
+ responseRemoteControl = {}
37
+ ) => {
38
+ mock.onGet(API.DEVICE.DISPLAY(1)).reply(200, responseDisplay);
39
+ mock
40
+ .onGet(API.DEVICE.REMOTE_CONTROL_OPTIONS(1))
41
+ .reply(200, responseRemoteControl);
42
+ mock
43
+ .onGet(API.DEVICE.DISPLAY_VALUES_V2(1))
44
+ .reply(200, responseDisplayValueV2);
45
+ };
46
+
47
+ const navContextValue = {
48
+ isFocused: () => false,
49
+ addListener: jest.fn(() => jest.fn()),
50
+ };
51
+ const wrapComponent = (state, account, route) => (
52
+ <SCProvider initState={state}>
53
+ <NavigationContext.Provider
54
+ value={{
55
+ ...navContextValue,
56
+ isFocused: () => true,
57
+ }}
58
+ >
59
+ <DeviceDetail account={account} route={route} />
60
+ </NavigationContext.Provider>
61
+ </SCProvider>
62
+ );
63
+
64
+ const mockAlertShow = jest.fn();
65
+ Alert.alert = mockAlertShow;
66
+
67
+ describe('test DeviceDetail', () => {
68
+ let tree;
69
+ let route;
70
+ let account;
71
+ let gatewayData;
72
+
73
+ beforeEach(() => {
74
+ route = {
75
+ params: {
76
+ unitData: {
77
+ id: 1,
78
+ name: 'Unit name',
79
+ address: '298 Dien Bien Phu',
80
+ remote_control_options: {
81
+ googlehome: [
82
+ {
83
+ config_maps: [],
84
+ auth: {},
85
+ chip_id: 1,
86
+ },
87
+ ],
88
+ },
89
+ },
90
+ station: {
91
+ id: 2,
92
+ name: 'Station name',
93
+ },
94
+ sensorData: {
95
+ id: 1,
96
+ is_managed_by_backend: true,
97
+ station: { id: 2, name: 'Station name' },
98
+ name: 'Sensor name',
99
+ chip_id: 7689,
100
+ },
101
+ title: 'Button',
102
+ },
103
+ };
104
+ account = {
105
+ token: 'abc',
106
+ };
107
+ jest.useFakeTimers();
108
+ mock.reset();
109
+ watchMultiConfigs.mockClear();
110
+ unwatchMultiDataChips.mockClear();
111
+ AsyncStorage.clear();
112
+ mqttClientsPool.clear();
113
+ act(() => {
114
+ setConfigGlobalState('configValues', {});
115
+ });
116
+ gatewayData = JSON.parse(JSON.stringify(gatewayDataFactory));
117
+ mock.onGet(API.CHIP.SHARED_CONFIGURATION).reply(200, []);
118
+ });
119
+
120
+ it('should render device detail, connect will call subscribe', async () => {
121
+ mock.onGet(API.CHIP.JSON_CONFIGURATION).reply(200, [gatewayData]);
122
+ const client = mqtt.connect();
123
+ await act(async () => {
124
+ await create(
125
+ wrapComponent(store, account, {
126
+ ...route,
127
+ params: { ...route.params },
128
+ })
129
+ );
130
+ });
131
+ await act(async () => {
132
+ client.trigger('connect');
133
+ });
134
+
135
+ expect(client.subscribe).toHaveBeenCalledWith(
136
+ `eoh/chip/${gatewayData.code}/#`
137
+ );
138
+ });
139
+
140
+ it('should render device detail, mqtt_server will not call mqtt connect', async () => {
141
+ gatewayData.mqtt_server = null;
142
+ mock.onGet(API.CHIP.JSON_CONFIGURATION).reply(200, [gatewayData]);
143
+ const mockMqttConnect = jest.spyOn(mqtt, 'connect');
144
+ await act(async () => {
145
+ await create(
146
+ wrapComponent(store, account, {
147
+ ...route,
148
+ params: { ...route.params },
149
+ })
150
+ );
151
+ });
152
+ expect(mockMqttConnect).not.toHaveBeenCalled();
153
+ });
154
+
155
+ it('should render device detail, allow_frontend_connect is false will not call mqtt connect', async () => {
156
+ gatewayData.mqtt_server = {
157
+ host: 'example.cloudmqtt.com',
158
+ allow_frontend_connect: false,
159
+ };
160
+
161
+ mock.onGet(API.CHIP.JSON_CONFIGURATION).reply(200, [gatewayData]);
162
+ const mockMqttConnect = jest.spyOn(mqtt, 'connect');
163
+
164
+ await act(async () => {
165
+ await create(
166
+ wrapComponent(store, account, {
167
+ ...route,
168
+ params: { ...route.params },
169
+ })
170
+ );
171
+ });
172
+ expect(mockMqttConnect).not.toHaveBeenCalled();
173
+ });
174
+
175
+ it('should render device detail, call mqtt connect', async () => {
176
+ mock.onGet(API.CHIP.JSON_CONFIGURATION).reply(200, [gatewayData]);
177
+ const mockMqttConnect = jest.spyOn(mqtt, 'connect');
178
+ await act(async () => {
179
+ await create(
180
+ wrapComponent(store, account, {
181
+ ...route,
182
+ params: { ...route.params },
183
+ })
184
+ );
185
+ });
186
+ expect(mockMqttConnect).toHaveBeenCalledTimes(1);
187
+ });
188
+
189
+ it('should render device detail, unmount will call mqtt end', async () => {
190
+ mock.onGet(API.CHIP.JSON_CONFIGURATION).reply(200, [gatewayData]);
191
+ await act(async () => {
192
+ tree = await create(
193
+ wrapComponent(store, account, {
194
+ ...route,
195
+ params: { ...route.params, unitId: 1 },
196
+ })
197
+ );
198
+ });
199
+
200
+ const client = mqtt.connect();
201
+ await act(async () => {
202
+ tree.unmount();
203
+ });
204
+
205
+ await act(async () => {
206
+ jest.runOnlyPendingTimers();
207
+ });
208
+ expect(client.end).toHaveBeenCalled();
209
+ });
210
+
211
+ it('test back and render device detail again, unmount call mqtt end', async () => {
212
+ mock.onGet(API.CHIP.JSON_CONFIGURATION).reply(200, [gatewayData]);
213
+ await act(async () => {
214
+ tree = await create(
215
+ wrapComponent(store, account, {
216
+ ...route,
217
+ params: { ...route.params, unitId: 1 },
218
+ })
219
+ );
220
+ });
221
+
222
+ const client = mqtt.connect();
223
+ await act(async () => {
224
+ tree.unmount();
225
+ });
226
+ expect(client.end).not.toHaveBeenCalled();
227
+
228
+ await act(async () => {
229
+ tree = await create(
230
+ wrapComponent(store, account, {
231
+ ...route,
232
+ params: { ...route.params, unitId: 1 },
233
+ })
234
+ );
235
+ });
236
+ await act(async () => {
237
+ tree.unmount();
238
+ });
239
+ expect(client.end).not.toHaveBeenCalled();
240
+
241
+ await act(async () => {
242
+ jest.runOnlyPendingTimers();
243
+ });
244
+ expect(client.end).toHaveBeenCalled();
245
+ });
246
+
247
+ it('test render multi, unmount call mqtt end', async () => {
248
+ mock.onGet(API.CHIP.JSON_CONFIGURATION).reply(200, [gatewayData]);
249
+ const tree1 = await act(async () => {
250
+ return await create(
251
+ wrapComponent(store, account, {
252
+ ...route,
253
+ params: { ...route.params, unitId: 1 },
254
+ })
255
+ );
256
+ });
257
+ const tree2 = await act(async () => {
258
+ return await create(
259
+ wrapComponent(store, account, {
260
+ ...route,
261
+ params: { ...route.params, unitId: 1 },
262
+ })
263
+ );
264
+ });
265
+
266
+ const client = mqtt.connect();
267
+ await act(async () => {
268
+ tree1.unmount();
269
+ });
270
+ expect(client.end).not.toHaveBeenCalled();
271
+
272
+ await act(async () => {
273
+ tree2.unmount();
274
+ });
275
+ expect(client.end).not.toHaveBeenCalled();
276
+
277
+ await act(async () => {
278
+ jest.runOnlyPendingTimers();
279
+ });
280
+ expect(client.end).toHaveBeenCalled();
281
+ });
282
+
283
+ const _receiveDataMqtt = async (widgetConfigs, topic, message) => {
284
+ mock.onGet(API.CHIP.JSON_CONFIGURATION).reply(200, [gatewayData]);
285
+
286
+ const responseDisplay = {
287
+ items: [
288
+ {
289
+ id: 1,
290
+ order: 0,
291
+ template: 'value',
292
+ type: 'value',
293
+ configuration: {
294
+ template: 'simple_list',
295
+ configs: widgetConfigs,
296
+ },
297
+ },
298
+ ],
299
+ };
300
+
301
+ const responseRemoteControl = {
302
+ bluetooth: {
303
+ address: 'JUvfa06PMDU8Cqlo',
304
+ password: 'MYcNoskxspWTPsnh',
305
+ },
306
+ internet: {},
307
+ };
308
+
309
+ const responseDisplayValueV2 = {
310
+ configs: [],
311
+ is_connected: true,
312
+ last_updated: '2021-01-24T12:00:00.000Z',
313
+ };
314
+
315
+ mockAxios(responseDisplay, responseDisplayValueV2, responseRemoteControl);
316
+
317
+ await act(async () => {
318
+ tree = await create(
319
+ wrapComponent(store, account, {
320
+ ...route,
321
+ params: { ...route.params },
322
+ })
323
+ );
324
+ });
325
+ const instance = tree.root;
326
+ const client = mqtt.connect();
327
+ await act(async () => {
328
+ await client.trigger('message', topic, JSON.stringify(message), 'packet');
329
+ });
330
+
331
+ const valueBox = instance.findAllByType(QualityIndicatorItem);
332
+ expect(valueBox.length).toBe(widgetConfigs.length);
333
+ return valueBox;
334
+ };
335
+
336
+ test('should render device detail, receive is_online message', async () => {
337
+ const valueBoxs = await _receiveDataMqtt(
338
+ [{ id: 2547 }],
339
+ `eoh/chip/${gatewayData.code}/is_online`,
340
+ {
341
+ ol: 1,
342
+ }
343
+ );
344
+ expect(valueBoxs[0].props.value).toEqual(1);
345
+ });
346
+
347
+ test('should render device detail, receive self_sensor message', async () => {
348
+ const valueBoxs = await _receiveDataMqtt(
349
+ [
350
+ { id: 2540 },
351
+ { id: 2541 },
352
+ { id: 2542 },
353
+ { id: 2543 },
354
+ { id: 2544 },
355
+ { id: 2545 },
356
+ { id: 2546 },
357
+ ],
358
+ `eoh/chip/${gatewayData.code}/self_sensor`,
359
+ {
360
+ temperature: 27.6,
361
+ volt: 3.3,
362
+ signal: 100,
363
+ modbus_fail: 0,
364
+ modbus_total: 100,
365
+ internal_temperature: 45,
366
+ is_battery: 0,
367
+ }
368
+ );
369
+ expect(valueBoxs[0].props.value).toEqual(27.6);
370
+ expect(valueBoxs[1].props.value).toEqual(3.3);
371
+ expect(valueBoxs[2].props.value).toEqual(100);
372
+ expect(valueBoxs[3].props.value).toEqual(0);
373
+ expect(valueBoxs[4].props.value).toEqual(100);
374
+ expect(valueBoxs[5].props.value).toEqual(45);
375
+ expect(valueBoxs[6].props.value).toEqual(0);
376
+ });
377
+
378
+ const _watchDataChipsOnDeviceDetail = async (expects) => {
379
+ const widgetConfigs = [
380
+ { id: 2540 },
381
+ { id: 2541 },
382
+ { id: 2542 },
383
+ { id: 2543 },
384
+ { id: 2544 },
385
+ { id: 2545 },
386
+ { id: 2546 },
387
+ ];
388
+ mock.onGet(API.CHIP.JSON_CONFIGURATION).reply(200, []);
389
+ mock.onPost(API.IOT.CHIP_MANAGER.WATCH_DATA_CHIPS()).reply(200, {
390
+ 7689: {
391
+ last_self_data: {
392
+ temperature: 27.6,
393
+ volt: 3.3,
394
+ signal: 100,
395
+ modbus_fail: 0,
396
+ modbus_total: 100,
397
+ internal_temperature: 45,
398
+ is_battery: 0,
399
+ last_updated: '2025-09-09T12:00:00Z',
400
+ },
401
+ },
402
+ });
403
+ mock.onGet(API.CHIP.SHARED_CONFIGURATION).reply(200, [gatewayData]);
404
+
405
+ const responseDisplay = {
406
+ items: [
407
+ {
408
+ id: 1,
409
+ order: 0,
410
+ template: 'value',
411
+ type: 'value',
412
+ configuration: {
413
+ template: 'simple_list',
414
+ configs: widgetConfigs,
415
+ },
416
+ },
417
+ ],
418
+ };
419
+
420
+ const responseRemoteControl = {
421
+ bluetooth: {
422
+ address: 'JUvfa06PMDU8Cqlo',
423
+ password: 'MYcNoskxspWTPsnh',
424
+ },
425
+ internet: {},
426
+ };
427
+
428
+ const responseDisplayValueV2 = {
429
+ configs: [],
430
+ is_connected: true,
431
+ last_updated: '2021-01-24T12:00:00.000Z',
432
+ };
433
+
434
+ mockAxios(responseDisplay, responseDisplayValueV2, responseRemoteControl);
435
+
436
+ await act(async () => {
437
+ tree = await create(
438
+ wrapComponent(store, account, {
439
+ ...route,
440
+ params: { ...route.params },
441
+ })
442
+ );
443
+ });
444
+
445
+ const instance = tree.root;
446
+ const valueBoxs = instance.findAllByType(QualityIndicatorItem);
447
+ for (let i = 0; i < widgetConfigs.length; i++) {
448
+ expect(valueBoxs[i].props.value).toEqual(expects[i]);
449
+ }
450
+
451
+ expect(
452
+ mock.history.post.filter(
453
+ (req) => req.url === API.IOT.CHIP_MANAGER.WATCH_DATA_CHIPS()
454
+ )
455
+ ).toHaveLength(1);
456
+
457
+ await act(async () => {
458
+ jest.runOnlyPendingTimers();
459
+ });
460
+ expect(
461
+ mock.history.post.filter(
462
+ (req) => req.url === API.IOT.CHIP_MANAGER.WATCH_DATA_CHIPS()
463
+ )
464
+ ).toHaveLength(2);
465
+ expect(unwatchMultiDataChips).not.toHaveBeenCalled();
466
+
467
+ await act(async () => {
468
+ await tree.unmount();
469
+ });
470
+ expect(unwatchMultiDataChips).toHaveBeenCalledWith([gatewayData.id]);
471
+ };
472
+
473
+ test('should render device detail, watch data chips self sensorr', async () => {
474
+ await _watchDataChipsOnDeviceDetail([27.6, 3.3, 100, 0, 100, 45, 0]);
475
+ });
476
+
477
+ test('should render device detail, watch data chips self sensorr with past last_updated', async () => {
478
+ setConfigGlobalState('configValues', {
479
+ 2540: { value: 0, last_updated: moment('2025-09-09T12:00:01Z') },
480
+ 2541: { value: 0, last_updated: moment('2025-09-09T12:00:01Z') },
481
+ 2542: { value: 0, last_updated: moment('2025-09-09T12:00:01Z') },
482
+ 2543: { value: 0, last_updated: moment('2025-09-09T12:00:01Z') },
483
+ 2544: { value: 0, last_updated: moment('2025-09-09T12:00:01Z') },
484
+ 2545: { value: 0, last_updated: moment('2025-09-09T12:00:01Z') },
485
+ 2546: { value: 0, last_updated: moment('2025-09-09T12:00:01Z') },
486
+ });
487
+ await _watchDataChipsOnDeviceDetail([0, 0, 0, 0, 0, 0, 0]);
488
+ });
489
+
490
+ test('should render device detail, watch data chips self sensorr with future last_updated', async () => {
491
+ setConfigGlobalState('configValues', {
492
+ 2540: { value: 0, last_updated: moment('2025-09-09T11:59:59Z') },
493
+ 2541: { value: 0, last_updated: moment('2025-09-09T11:59:59Z') },
494
+ 2542: { value: 0, last_updated: moment('2025-09-09T11:59:59Z') },
495
+ 2543: { value: 0, last_updated: moment('2025-09-09T11:59:59Z') },
496
+ 2544: { value: 0, last_updated: moment('2025-09-09T11:59:59Z') },
497
+ 2545: { value: 0, last_updated: moment('2025-09-09T11:59:59Z') },
498
+ 2546: { value: 0, last_updated: moment('2025-09-09T11:59:59Z') },
499
+ });
500
+ await _watchDataChipsOnDeviceDetail([27.6, 3.3, 100, 0, 100, 45, 0]);
501
+ });
502
+ });
@@ -1,5 +1,6 @@
1
1
  import { NavigationContext, useNavigation } from '@react-navigation/native';
2
2
  import MockAdapter from 'axios-mock-adapter';
3
+ import mqtt from 'precompiled-mqtt/dist/mqtt.browser';
3
4
  import React from 'react';
4
5
  import { Alert, ScrollView } from 'react-native';
5
6
  import { act, create } from 'react-test-renderer';
@@ -14,6 +15,8 @@ import { AccessibilityLabel } from '../../../configs/Constants';
14
15
  import { SCProvider } from '../../../context';
15
16
  import { mockSCStore } from '../../../context/mockStore';
16
17
  import { useWatchConfigs } from '../../../hooks/IoT';
18
+ import { gatewayDataFactory } from '../../../utils/FactoryGateway';
19
+ import { watchMultiDataChips } from '../../../iot/Monitor';
17
20
  import api from '../../../utils/Apis/axios';
18
21
  import { getTranslate } from '../../../utils/I18n';
19
22
  import Routes from '../../../utils/Route';
@@ -29,6 +32,13 @@ jest.mock('../../../hooks/IoT', () => {
29
32
  };
30
33
  });
31
34
 
35
+ jest.mock('../../../iot/Monitor', () => {
36
+ return {
37
+ ...jest.requireActual('../../../iot/Monitor'),
38
+ watchMultiDataChips: jest.fn(),
39
+ };
40
+ });
41
+
32
42
  jest.mock('../../../hooks/Common', () => {
33
43
  return {
34
44
  ...jest.requireActual('../../../hooks/Common'),
@@ -198,6 +208,10 @@ describe('test DeviceDetail', () => {
198
208
  useWatchConfigs.mockReset();
199
209
  });
200
210
 
211
+ afterEach(() => {
212
+ jest.useRealTimers();
213
+ });
214
+
201
215
  it('render DeviceDetail render SensorDisplayItem', async () => {
202
216
  const responseDisplay = data_sensor_display;
203
217
 
@@ -898,7 +912,7 @@ describe('test DeviceDetail', () => {
898
912
  el.props.accessibilityLabel === AccessibilityLabel.SENSOR_DISPLAY_ITEM
899
913
  );
900
914
  expect(sensorDisplayItem.length).toEqual(1);
901
- expect(useWatchConfigs).toHaveBeenCalledWith([]);
915
+ expect(useWatchConfigs).toHaveBeenLastCalledWith([1]);
902
916
  });
903
917
 
904
918
  it('watch action config', async () => {
@@ -926,7 +940,7 @@ describe('test DeviceDetail', () => {
926
940
  tree = await create(wrapComponent(store, account, route));
927
941
  });
928
942
 
929
- expect(useWatchConfigs).toHaveBeenCalledWith([]);
943
+ expect(useWatchConfigs).toHaveBeenLastCalledWith([2]);
930
944
  });
931
945
 
932
946
  it('watch stages grid action config', async () => {
@@ -957,6 +971,50 @@ describe('test DeviceDetail', () => {
957
971
  tree = await create(wrapComponent(store, account, route));
958
972
  });
959
973
 
960
- expect(useWatchConfigs).toHaveBeenCalledWith([]);
974
+ expect(useWatchConfigs).toHaveBeenLastCalledWith([3]);
975
+ });
976
+
977
+ it('test connect mqtt, watch data chips and config', async () => {
978
+ mock.onGet(API.CHIP.JSON_CONFIGURATION).reply(200, [
979
+ { ...gatewayDataFactory, id: 1 },
980
+ { ...gatewayDataFactory, code: 'xxx' },
981
+ ]);
982
+ mock.onGet(API.CHIP.SHARED_CONFIGURATION).reply(200, [
983
+ { ...gatewayDataFactory, id: 1 },
984
+ { ...gatewayDataFactory, code: 'yyy' },
985
+ ]);
986
+ const responseDisplay = {
987
+ items: [
988
+ {
989
+ id: 1,
990
+ order: 0,
991
+ template: 'on_off_button_action_template',
992
+ type: 'on_off_button_action_template',
993
+ configuration: {
994
+ config: 2,
995
+ },
996
+ },
997
+ ],
998
+ };
999
+ const responseDisplayValueV2 = {
1000
+ configs: [{ id: 2 }],
1001
+ is_connected: true,
1002
+ last_updated: '2021-01-24T12:00:00.000Z',
1003
+ };
1004
+ mockAxios(responseDisplay, responseDisplayValueV2);
1005
+ await act(async () => {
1006
+ tree = await create(wrapComponent(store, account, route));
1007
+ });
1008
+
1009
+ const client = mqtt.connect();
1010
+ await act(async () => {
1011
+ client.trigger('connect');
1012
+ });
1013
+ expect(client.subscribe).toHaveBeenCalledWith(
1014
+ `eoh/chip/${gatewayDataFactory.code}/#`
1015
+ );
1016
+
1017
+ expect(useWatchConfigs).toHaveBeenLastCalledWith([2]);
1018
+ expect(watchMultiDataChips).toHaveBeenCalledWith([1]);
961
1019
  });
962
1020
  });
@@ -1,3 +1,4 @@
1
+ import MockAdapter from 'axios-mock-adapter';
1
2
  import React from 'react';
2
3
  import renderer, { act } from 'react-test-renderer';
3
4
 
@@ -8,17 +9,28 @@ import ActionGroup from '../../../commons/ActionGroup';
8
9
  import MediaPlayerDetail from '../../../commons/MediaPlayerDetail';
9
10
  import FlatListItems from '../../../commons/Device/FlatListItems';
10
11
  import VisualChart from '../components/VisualChart';
11
- import SmartIr from '../../SmartIr';
12
12
  import FooterInfo from '../../../commons/Device/FooterInfo';
13
13
  import Anemometer from '../../../commons/Device/WindSpeed/Anemometer';
14
14
  import ProgressBar from '../../../commons/Device/ProgressBar';
15
15
  import Compass from '../../../commons/Device/WindDirection/Compass';
16
16
  import DeviceAlertStatus from '../../../commons/Device/DeviceAlertStatus';
17
- import MockAdapter from 'axios-mock-adapter';
18
- import api from '../../../utils/Apis/axios';
19
17
  import CurrentRainSensor from '../../../commons/Device/RainningSensor/CurrentRainSensor';
20
18
  import LabelValue from '../../../commons/Device/LabelValue';
21
19
  import Text from '../../../commons/Text';
20
+ import SmartIr from '../../SmartIr';
21
+ import api from '../../../utils/Apis/axios';
22
+
23
+ const mockIncrementReviewTrigger = jest.fn();
24
+ const mockAskReview = jest.fn();
25
+ jest.mock('../../../hooks/Review/useInAppReview', () => {
26
+ return {
27
+ __esModule: true,
28
+ default: jest.fn(() => ({
29
+ askReview: mockAskReview,
30
+ incrementReviewTrigger: mockIncrementReviewTrigger,
31
+ })),
32
+ };
33
+ });
22
34
 
23
35
  jest.mock('../../../iot/states', () => ({
24
36
  useConfigGlobalState: () => [{}, null],
@@ -35,6 +47,11 @@ const wrapComponent = ({ ...rest }) => (
35
47
 
36
48
  describe('Test SensorDisplayItem', () => {
37
49
  let tree;
50
+
51
+ beforeEach(() => {
52
+ mockIncrementReviewTrigger.mockClear();
53
+ });
54
+
38
55
  it('render visualChart', async () => {
39
56
  const item = {
40
57
  id: 10452,
@@ -103,6 +120,14 @@ describe('Test SensorDisplayItem', () => {
103
120
  expect(actionGroup).toHaveLength(1);
104
121
  const labels = instance.findAllByType(Text);
105
122
  expect(labels[0].props.children).toEqual('LED');
123
+
124
+ await act(async () => {
125
+ actionGroup[0].props.doAction(
126
+ { id: 1, name: 'sensor name' },
127
+ { key: 'action key' }
128
+ );
129
+ });
130
+ expect(mockIncrementReviewTrigger).toHaveBeenCalled();
106
131
  });
107
132
 
108
133
  it('render camera', async () => {