@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.
- package/README.md +35 -14
- package/package.json +4 -2
- package/src/commons/Action/ItemQuickAction.js +5 -2
- package/src/commons/ActionGroup/ColorPickerTemplate.js +1 -1
- package/src/commons/ActionGroup/CurtainButtonTemplate.js +10 -5
- package/src/commons/ActionGroup/NumberUpDownActionTemplate.js +12 -4
- package/src/commons/ActionGroup/OnOffSmartLock/AutoLock/__test__/index.test.js +4 -0
- package/src/commons/ActionGroup/OnOffSmartLock/OnOffSmartLock.js +7 -4
- package/src/commons/ActionGroup/OnOffSmartLock/PasscodeList/ItemPasscode.js +1 -1
- package/src/commons/ActionGroup/OnOffSmartLock/PasscodeList/__test__/ItemPasscode.test.js +24 -0
- package/src/commons/ActionGroup/OnOffSmartLock/SetupGeneratePasscode/__test__/index.test.js +14 -0
- package/src/commons/ActionGroup/OnOffSmartLock/SetupGeneratePasscode/index.js +1 -0
- package/src/commons/ActionGroup/OnOffTemplate/OnOffSimpleTemplate.js +10 -10
- package/src/commons/ActionGroup/OnOffTemplate/index.js +18 -15
- package/src/commons/ActionGroup/OptionsDropdownActionTemplate.js +9 -3
- package/src/commons/ActionGroup/SliderRangeTemplate.js +1 -1
- package/src/commons/ActionGroup/SmartTiviActionTemplate/SmartTiviActionTemplate.js +4 -1
- package/src/commons/ActionGroup/StatesGridActionTemplate.js +22 -8
- package/src/commons/ActionGroup/TimerActionTemplate.js +11 -3
- package/src/commons/ActionGroup/TwoButtonTemplate/index.js +13 -9
- package/src/commons/ActionGroup/__test__/CurtainButtonTemplate.test.js +53 -4
- package/src/commons/ActionGroup/__test__/OnOffButtonTemplate.test.js +14 -14
- package/src/commons/ActionGroup/__test__/OnOffTemplate.test.js +53 -78
- package/src/commons/ActionGroup/__test__/OneBigButtonTemplate.test.js +36 -20
- package/src/commons/ActionGroup/__test__/StatesGridActionTemplate.test.js +77 -0
- package/src/commons/ActionGroup/__test__/TimerActionTemplate.test.js +58 -6
- package/src/commons/ActionGroup/__test__/TwoButtonTemplate.test.js +49 -1
- package/src/commons/ActionGroup/__test__/index.test.js +135 -0
- package/src/commons/Auth/AccountList.js +1 -1
- package/src/commons/Automate/ItemAutomate.js +1 -3
- package/src/commons/Calendar/__test__/Calendar.test.js +33 -0
- package/src/commons/Connecting/__test__/Connecting.test.js +19 -2
- package/src/commons/ConnectingProcess/__test__/Connecting.test.js +136 -3
- package/src/commons/ConnectingProcess/index.js +1 -1
- package/src/commons/Dashboard/MyPinnedSharedUnit/__test__/MyPinnedSharedUnit.test.js +16 -13
- package/src/commons/Dashboard/MyPinnedSharedUnit/index.js +1 -1
- package/src/commons/Dashboard/MyUnit/__test__/MyUnit.test.js +0 -5
- package/src/commons/Device/Hanet/ItemHanetDevice.test.js +58 -0
- package/src/commons/Device/HistoryChart.js +4 -0
- package/src/commons/Device/LinearChart.js +15 -0
- package/src/commons/Device/PMSensor/PMSensorIndicatior.js +16 -12
- package/src/commons/Device/PMSensor/PMSensorIndicatorStyles.js +3 -0
- package/src/commons/Device/WaterQualitySensor/ListQualityIndicator.js +1 -0
- package/src/commons/Explore/__test__/CityItem.test.js +33 -54
- package/src/commons/FieldTemplate/ChooseUserField/ChooseFieldStyles.js +25 -0
- package/src/commons/FieldTemplate/ChooseUserField/ChoosePopup.js +96 -0
- package/src/commons/FieldTemplate/ChooseUserField/ChoosePopupStyles.js +39 -0
- package/src/commons/FieldTemplate/ChooseUserField/__test__/index.test.js +118 -0
- package/src/commons/FieldTemplate/ChooseUserField/index.js +62 -0
- package/src/commons/FieldTemplate/PasscodeField/PasscodeFieldStyles.js +30 -0
- package/src/commons/FieldTemplate/PasscodeField/__test__/index.test.js +90 -0
- package/src/commons/FieldTemplate/PasscodeField/index.js +43 -0
- package/src/commons/FieldTemplate/ScheduleField/ScheduleFieldStyles.js +13 -0
- package/src/commons/FieldTemplate/ScheduleField/__test__/index.test.js +179 -0
- package/src/commons/FieldTemplate/ScheduleField/index.js +176 -0
- package/src/commons/FullLoading/index.js +2 -1
- package/src/commons/MenuActionAddnew/index.js +1 -0
- package/src/commons/MenuActionList/index.js +1 -0
- package/src/commons/MenuActionMore/index.js +1 -1
- package/src/commons/PreventAccess/__test__/PreventAccess.test.js +62 -0
- package/src/commons/PreventAccess/index.js +9 -1
- package/src/commons/Sharing/__test__/DevicePermissionsCheckbox.test.js +0 -1
- package/src/commons/SubUnit/OneTap/__test__/SubUnitAutomate.test.js +8 -35
- package/src/commons/SubUnit/OneTap/index.js +1 -2
- package/src/commons/Unit/SharedUnit.js +1 -0
- package/src/commons/Unit/__test__/SharedUnit.test.js +38 -183
- package/src/commons/WheelDateTimePicker/index.js +2 -1
- package/src/configs/API.js +87 -138
- package/src/configs/Constants.js +27 -1
- package/src/configs/SCConfig.js +2 -0
- package/src/iot/RemoteControl/__test__/GoogleHome.test.js +8 -30
- package/src/iot/RemoteControl/__test__/Internet.test.js +18 -7
- package/src/iot/RemoteControl/__test__/LgThinq.test.js +36 -177
- package/src/navigations/UnitStack.js +8 -0
- package/src/screens/AQIGuide/index.js +1 -1
- package/src/screens/ActivityLog/FilterPopup.js +2 -0
- package/src/screens/ActivityLog/__test__/index.test.js +38 -23
- package/src/screens/ActivityLog/hooks/__test__/index.test.js +51 -90
- package/src/screens/ActivityLog/index.js +2 -2
- package/src/screens/AddCommon/SelectSubUnit.js +1 -0
- package/src/screens/AddCommon/SelectUnit.js +1 -0
- package/src/screens/AddCommon/__test__/SelectSubUnit.test.js +13 -24
- package/src/screens/AddCommon/__test__/SelectUnit.test.js +9 -33
- package/src/screens/AddLocationMaps/index.js +4 -1
- package/src/screens/AddNewAction/SelectSensorDevices.js +8 -2
- package/src/screens/AddNewAction/__test__/SelectAction.test.js +10 -91
- package/src/screens/AddNewAction/__test__/SelectSensorDevices.test.js +40 -26
- package/src/screens/AddNewAutoSmart/__test__/AddNewAutoSmart.test.js +3 -1
- package/src/screens/AddNewAutoSmart/index.js +5 -2
- package/src/screens/AddNewDevice/ConnectingDevices.js +3 -3
- package/src/screens/AddNewDevice/__test__/AddNewDevice.test.js +34 -33
- package/src/screens/AddNewDevice/__test__/ConnectDevices.test.js +0 -4
- package/src/screens/AddNewDevice/__test__/ConnectingDevices.test.js +21 -21
- package/src/screens/AddNewDevice/index.js +1 -0
- package/src/screens/AddNewGateway/PlugAndPlay/GatewayWifiList.js +4 -1
- package/src/screens/AddNewGateway/SelectGateway.js +1 -0
- package/src/screens/AddNewGateway/SetupGatewayWifi.js +1 -0
- package/src/screens/AddNewGateway/__test__/AddNewGateway.test.js +4 -6
- package/src/screens/AddNewGateway/__test__/ConnectedGateway.test.js +0 -4
- package/src/screens/AddNewGateway/__test__/ConnectingGateway.test.js +5 -29
- package/src/screens/AddNewGateway/__test__/SelectGateway.test.js +0 -4
- package/src/screens/AddNewGateway/__test__/SetupGateway.test.js +0 -4
- package/src/screens/AddNewGateway/index.js +1 -0
- package/src/screens/AddNewOneTap/__test__/AddNewOneTap.test.js +10 -24
- package/src/screens/AddNewOneTap/index.js +3 -2
- package/src/screens/Automate/__test__/MultiUnits.test.js +6 -9
- package/src/screens/Automate/__test__/index.test.js +7 -12
- package/src/screens/Automate/index.js +2 -0
- package/src/screens/ConfirmUnitDeletion/__test__/ConfirmUnitDeletion.test.js +36 -8
- package/src/screens/ConfirmUnitDeletion/index.js +7 -1
- package/src/screens/Device/EditDevice/__test__/EditDevice.test.js +71 -22
- package/src/screens/Device/__test__/detail.test.js +23 -84
- package/src/screens/Device/detail.js +31 -8
- package/src/screens/Device/hooks/useFavoriteDevice.js +5 -9
- package/src/screens/DeviceInfo/__test__/index.test.js +0 -2
- package/src/screens/EmergencyContacts/EmergencyContactsSelectContacts.js +6 -3
- package/src/screens/EmergencyContacts/__test__/EmergencyContactAddNew.test.js +7 -19
- package/src/screens/EmergencyContacts/__test__/EmergencyContactList.test.js +20 -2
- package/src/screens/EmergencyContacts/__test__/EmergencyContactsSelectContacts.test.js +40 -23
- package/src/screens/EmergencySetting/index.js +4 -1
- package/src/screens/EnterPassword/__test__/EnterPassword.test.js +41 -25
- package/src/screens/Explore/index.js +2 -0
- package/src/screens/GuestInfo/__test__/index.test.js +14 -41
- package/src/screens/GuestInfo/components/RecurringDetail.js +1 -0
- package/src/screens/GuestInfo/components/TemporaryDetail.js +2 -2
- package/src/screens/HanetCamera/__test__/CaptureFaceID.test.js +8 -12
- package/src/screens/HanetCamera/__test__/Detail.test.js +27 -42
- package/src/screens/HanetCamera/__test__/ManageAccess.test.js +8 -5
- package/src/screens/HanetCamera/__test__/MemberInfo.test.js +10 -32
- package/src/screens/HanetCamera/hooks/__test__/useHanetCheckinData.test.js +43 -35
- package/src/screens/HanetCamera/hooks/__test__/useHanetPlaceMembers.test.js +10 -21
- package/src/screens/ManageAccess/__test__/ManageAccess.test.js +33 -22
- package/src/screens/ManageAccess/hooks/__test__/useManageAccess.test.js +44 -45
- package/src/screens/ManageAccess/index.js +2 -1
- package/src/screens/MoveToAnotherSubUnit/__test__/index.test.js +35 -12
- package/src/screens/MoveToAnotherSubUnit/index.js +5 -5
- package/src/screens/Notification/__test__/Notification.test.js +14 -25
- package/src/screens/Notification/__test__/NotificationItem.test.js +4 -3
- package/src/screens/PlayBackCamera/__test__/index.test.js +87 -2
- package/src/screens/PlayBackCamera/index.js +19 -3
- package/src/screens/ScanChipQR/__test__/ScanChipQR.test.js +7 -20
- package/src/screens/ScanChipQR/components/QRScan/index.js +1 -0
- package/src/screens/ScanSensorQR/__test__/ScanSensorQR.test.js +8 -24
- package/src/screens/ScriptDetail/__test__/index.test.js +17 -86
- package/src/screens/ScriptDetail/index.js +5 -4
- package/src/screens/SelectUnit/__test__/index.test.js +12 -55
- package/src/screens/SelectUnit/index.js +5 -2
- package/src/screens/SetSchedule/index.js +6 -2
- package/src/screens/SharedUnit/__test__/TabHeader.test.js +0 -2
- package/src/screens/SharedUnit/index.js +2 -0
- package/src/screens/Sharing/InfoMemberUnit.js +1 -1
- package/src/screens/Sharing/MemberList.js +12 -11
- package/src/screens/Sharing/SelectPermission.js +107 -70
- package/src/screens/Sharing/__test__/InfoMemberUnit.test.js +47 -29
- package/src/screens/Sharing/__test__/MemberList.test.js +13 -127
- package/src/screens/Sharing/__test__/MemberList2.test.js +80 -0
- package/src/screens/Sharing/__test__/SelectPermission.test.js +28 -38
- package/src/screens/Sharing/__test__/SelectUser.test.js +17 -38
- package/src/screens/Sharing/hooks/index.js +3 -0
- package/src/screens/SideMenuDetail/SideMenuDetailStyles.js +28 -0
- package/src/screens/SideMenuDetail/__test__/index.test.js +154 -0
- package/src/screens/SideMenuDetail/index.js +149 -0
- package/src/screens/SmartIr/components/SelectBrand.js +1 -1
- package/src/screens/SubUnit/ManageSubUnit.js +1 -0
- package/src/screens/SubUnit/__test__/AddSubUnit.test.js +21 -67
- package/src/screens/SubUnit/__test__/Detail.test.js +31 -8
- package/src/screens/SubUnit/__test__/EditSubUnit.test.js +21 -89
- package/src/screens/SubUnit/hooks/__test__/useManageSubUnit.test.js +47 -44
- package/src/screens/SyncLGDevice/AddLGDevice.js +1 -0
- package/src/screens/SyncLGDevice/__test__/AddLGDevice.test.js +14 -90
- package/src/screens/TDSGuide/index.js +4 -1
- package/src/screens/UVIndexGuide/index.js +1 -1
- package/src/screens/Unit/ChooseLocation.js +1 -1
- package/src/screens/Unit/ManageUnit.js +1 -0
- package/src/screens/Unit/SelectAddress.js +4 -1
- package/src/screens/Unit/Station/index.js +1 -0
- package/src/screens/Unit/Summaries.js +1 -1
- package/src/screens/Unit/__test__/CheckSendEmail.test.js +15 -28
- package/src/screens/Unit/__test__/ChooseLocation.test.js +27 -14
- package/src/screens/Unit/__test__/Detail.test.js +83 -185
- package/src/screens/Unit/__test__/ManageUnit.test.js +18 -42
- package/src/screens/Unit/__test__/SelectAddress.test.js +13 -39
- package/src/screens/Unit/__test__/SmartAccount.test.js +17 -9
- package/src/screens/Unit/__test__/SmartAccountItem.test.js +0 -1
- package/src/screens/Unit/components/MyAllUnit/__test__/MyAllUnit.test.js +36 -0
- package/src/screens/Unit/components/MyAllUnit/__test__/index.test.js +54 -0
- package/src/screens/Unit/components/SharedUnit/index.js +1 -0
- package/src/screens/Unit/components/__test__/SharedUnit.test.js +31 -34
- package/src/screens/UnitSummary/__test__/index.test.js +38 -31
- package/src/screens/UnitSummary/components/PowerConsumeHistoryChart/__test__/index.test.js +7 -4
- package/src/screens/UnitSummary/components/PowerConsumption/__test__/PowerConsumption.test.js +14 -16
- package/src/screens/WaterQualityGuide/index.js +1 -1
- package/src/utils/Apis/axios.js +37 -13
- package/src/utils/I18n/translations/en.json +1 -0
- package/src/utils/I18n/translations/vi.json +1 -0
- package/src/utils/Route/index.js +1 -0
- 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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
227
|
-
|
|
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
|
-
|
|
243
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
190
|
-
|
|
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) => {
|