@eohjsc/react-native-smart-city 0.2.87 → 0.2.88
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/assets/images/Common/Calendar.svg +3 -0
- package/assets/images/Common/SmartPhone.svg +3 -0
- package/assets/images/Hanet/CaptureFaceID.svg +25 -0
- package/assets/images/Hanet/FaceFrame.svg +6 -0
- package/package.json +2 -2
- package/src/Images/SmartIr/Remote.svg +15 -0
- package/src/Images/SmartIr/SmartIr.svg +4 -0
- package/src/Images/SmartIr/Union.svg +9 -0
- package/src/Images/SmartIr/index.js +4 -1
- package/src/commons/ActionGroup/ColorPickerTemplate.js +51 -0
- package/src/commons/ActionGroup/ColorPickerTemplateStyles.js +17 -0
- package/src/commons/ActionGroup/SliderRangeTemplate.js +64 -0
- package/src/commons/ActionGroup/{LightActionTemplateStyles.js → SliderRangeTemplateStyles.js} +0 -8
- package/src/commons/ActionGroup/SmartTiviActionTemplate/SmartTiviActionTemplate.js +47 -68
- package/src/commons/ActionGroup/index.js +6 -3
- package/src/commons/BottomSheet/index.js +2 -1
- package/src/commons/Device/Hanet/ItemHanetDevice.js +109 -0
- package/src/commons/Device/HistoryChart.js +2 -2
- package/src/commons/Device/HorizontalBarChart.js +7 -0
- package/src/commons/Device/ItemDevice.js +18 -15
- package/src/commons/Device/LinearChart.js +11 -1
- package/src/commons/SubUnit/Favorites/index.js +2 -2
- package/src/commons/SubUnit/ShortDetail.js +39 -20
- package/src/configs/API.js +22 -0
- package/src/configs/Constants.js +37 -0
- package/src/configs/SCConfig.js +1 -1
- package/src/context/actionType.ts +4 -0
- package/src/context/mockStore.ts +2 -0
- package/src/context/reducer.ts +20 -0
- package/src/iot/RemoteControl/Bluetooth.js +0 -19
- package/src/iot/RemoteControl/index.js +0 -1
- package/src/navigations/HanetCameraStack.js +41 -0
- package/src/navigations/UnitStack.js +34 -1
- package/src/screens/ActivityLog/hooks/index.js +1 -1
- package/src/screens/AddNewGateway/PlugAndPlay/ConnectWifiWarning.js +51 -66
- package/src/screens/AddNewGateway/PlugAndPlay/GatewayWifiList.js +68 -54
- package/src/screens/AddNewGateway/PlugAndPlay/__test__/ConnectWifiWarning.test.js +7 -0
- package/src/screens/Device/__test__/detail.test.js +0 -10
- package/src/screens/Device/detail.js +70 -29
- package/src/screens/Device/hooks/useDisconnectedDevice.js +16 -20
- package/src/screens/HanetCamera/CaptureFaceID.js +210 -0
- package/src/screens/HanetCamera/Detail.js +252 -0
- package/src/screens/HanetCamera/ManageAccess.js +173 -0
- package/src/screens/HanetCamera/MemberInfo.js +208 -0
- package/src/screens/HanetCamera/__test__/CaptureFaceID.test.js +133 -0
- package/src/screens/HanetCamera/__test__/Detail.test.js +185 -0
- package/src/screens/HanetCamera/__test__/ManageAccess.test.js +152 -0
- package/src/screens/HanetCamera/__test__/MemberInfo.test.js +178 -0
- package/src/screens/HanetCamera/components/CheckinHeader.js +37 -0
- package/src/screens/HanetCamera/hooks/__test__/useHanetCheckinData.test.js +151 -0
- package/src/screens/HanetCamera/hooks/__test__/useHanetPlaceMembers.test.js +71 -0
- package/src/screens/HanetCamera/hooks/index.js +5 -0
- package/src/screens/HanetCamera/hooks/useHanetCheckinData.js +116 -0
- package/src/screens/HanetCamera/hooks/useHanetPlaceMembers.js +86 -0
- package/src/screens/HanetCamera/hooks/useStateAlertAction.js +62 -0
- package/src/screens/HanetCamera/styles/captureFaceIDStyles.js +50 -0
- package/src/screens/HanetCamera/styles/checkinHeaderStyles.js +24 -0
- package/src/screens/HanetCamera/styles/detailStyles.js +107 -0
- package/src/screens/HanetCamera/styles/manageAccessStyles.js +49 -0
- package/src/screens/HanetCamera/styles/memberInfoStyles.js +73 -0
- package/src/screens/HanetCamera/utils/Monitor.js +52 -0
- package/src/screens/SmartIr/__test__/ButtonsBottom.test.js +31 -0
- package/src/screens/SmartIr/__test__/GroupButtonByType.test.js +35 -9
- package/src/screens/SmartIr/__test__/SelectBrand.test.js +0 -9
- package/src/screens/SmartIr/__test__/SelectDeviceType.test.js +1 -8
- package/src/screens/SmartIr/components/GroupButtonByType/ButtonsBottom.js +45 -0
- package/src/screens/SmartIr/components/GroupButtonByType/ButtonsBottomStyles.js +31 -0
- package/src/screens/SmartIr/components/GroupButtonByType/GroupButtonByType.js +156 -34
- package/src/screens/SmartIr/components/GroupButtonByType/GroupButtonByTypeStyles.js +52 -15
- package/src/screens/Unit/Detail.js +2 -10
- package/src/screens/Unit/__test__/Detail.test.js +0 -10
- package/src/utils/I18n/translations/en.json +28 -1
- package/src/utils/I18n/translations/vi.json +27 -0
- package/src/utils/Route/index.js +5 -0
- package/src/commons/ActionGroup/LightActionTemplate.js +0 -103
- package/src/commons/ActionGroup/__test__/LightActionTemplate.test.js +0 -59
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
|
+
import { View, TouchableOpacity, Image, Platform } from 'react-native';
|
|
3
|
+
import { useNavigation } from '@react-navigation/native';
|
|
4
|
+
import { IconFill } from '@ant-design/icons-react-native';
|
|
5
|
+
import { HeaderCustom } from '../../commons/Header';
|
|
6
|
+
import { AlertAction, FullLoading } from '../../commons';
|
|
7
|
+
import BottomButtonView from '../../commons/BottomButtonView';
|
|
8
|
+
import TextInput from '../../commons/Form/TextInput';
|
|
9
|
+
import Text from '../../commons/Text';
|
|
10
|
+
import { useStateAlertAction } from './hooks';
|
|
11
|
+
import { useTranslations } from '../../hooks/Common/useTranslations';
|
|
12
|
+
import useKeyboardAnimated from '../../hooks/Explore/useKeyboardAnimated';
|
|
13
|
+
import styles from './styles/memberInfoStyles';
|
|
14
|
+
import { Colors, API } from '../../configs';
|
|
15
|
+
import { axiosDelete, axiosPatch, axiosPost } from '../../utils/Apis/axios';
|
|
16
|
+
import Routes from '../../utils/Route';
|
|
17
|
+
|
|
18
|
+
const HanetMemberInfo = ({ route }) => {
|
|
19
|
+
const t = useTranslations();
|
|
20
|
+
const { navigate, goBack } = useNavigation();
|
|
21
|
+
const { hanetPlace, hanetMember, isAddNewMember } = route.params;
|
|
22
|
+
const [memberAvatar, setMemberAvatar] = useState(hanetMember.avatar_uri);
|
|
23
|
+
const [memberName, setMemberName] = useState(hanetMember.name);
|
|
24
|
+
const [inputName, setInputName] = useState(hanetMember.name);
|
|
25
|
+
const [error, setError] = useState('');
|
|
26
|
+
const [loading, setLoading] = useState(false);
|
|
27
|
+
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
setMemberAvatar(hanetMember.avatar_uri);
|
|
30
|
+
setMemberName(hanetMember.name);
|
|
31
|
+
}, [hanetMember]);
|
|
32
|
+
|
|
33
|
+
const { stateAlertAction, hideAlertAction, showRename, showDelete } =
|
|
34
|
+
useStateAlertAction();
|
|
35
|
+
|
|
36
|
+
const onShowRename = () => {
|
|
37
|
+
setInputName(memberName);
|
|
38
|
+
showRename(isAddNewMember);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const onShowDelete = () => {
|
|
42
|
+
showDelete();
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const setFaceID = () => {
|
|
46
|
+
navigate(Routes.HanetCaptureFaceID, {
|
|
47
|
+
title: t('set_photo_id'),
|
|
48
|
+
hanetPlace,
|
|
49
|
+
hanetMember: {
|
|
50
|
+
...hanetMember,
|
|
51
|
+
avatar_uri: memberAvatar,
|
|
52
|
+
name: memberName,
|
|
53
|
+
},
|
|
54
|
+
memberAvatar,
|
|
55
|
+
setMemberAvatar,
|
|
56
|
+
isAddNewMember,
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const finishRegister = async () => {
|
|
61
|
+
setLoading(true);
|
|
62
|
+
const formData = new FormData();
|
|
63
|
+
const name = memberAvatar.split('/').pop();
|
|
64
|
+
const ext = memberAvatar.split('.').pop();
|
|
65
|
+
formData.append('face_id', {
|
|
66
|
+
name: name,
|
|
67
|
+
type: `image/${ext}`,
|
|
68
|
+
uri: memberAvatar,
|
|
69
|
+
});
|
|
70
|
+
formData.append('name', memberName);
|
|
71
|
+
const { success, data } = await axiosPost(
|
|
72
|
+
API.CAMERA.HANET.REGISTER(hanetPlace.place_id),
|
|
73
|
+
formData,
|
|
74
|
+
{
|
|
75
|
+
headers: { 'Content-Type': 'multipart/form-data' },
|
|
76
|
+
}
|
|
77
|
+
);
|
|
78
|
+
if (success) {
|
|
79
|
+
navigate(Routes.HanetManageAccess, {
|
|
80
|
+
hanetPlace: hanetPlace,
|
|
81
|
+
});
|
|
82
|
+
} else {
|
|
83
|
+
setError(data.detail);
|
|
84
|
+
}
|
|
85
|
+
setLoading(false);
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const renameMember = async () => {
|
|
89
|
+
hideAlertAction();
|
|
90
|
+
if (isAddNewMember) {
|
|
91
|
+
setMemberName(inputName);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
setLoading(true);
|
|
96
|
+
const { success } = await axiosPatch(
|
|
97
|
+
API.CAMERA.HANET.RENAME_MEMBER(hanetPlace.place_id, hanetMember.alias_id),
|
|
98
|
+
{
|
|
99
|
+
name: inputName,
|
|
100
|
+
}
|
|
101
|
+
);
|
|
102
|
+
success && setMemberName(inputName);
|
|
103
|
+
setLoading(false);
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const removeMember = async () => {
|
|
107
|
+
hideAlertAction();
|
|
108
|
+
setLoading(true);
|
|
109
|
+
const { success } = await axiosDelete(
|
|
110
|
+
API.CAMERA.HANET.REMOVE_MEMBER(hanetPlace.place_id, hanetMember.alias_id)
|
|
111
|
+
);
|
|
112
|
+
success && goBack();
|
|
113
|
+
setLoading(false);
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const handleRenameOrDelete = () => {
|
|
117
|
+
if (stateAlertAction.isDelete) {
|
|
118
|
+
removeMember();
|
|
119
|
+
} else {
|
|
120
|
+
renameMember();
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
const [transY] = useKeyboardAnimated(-16);
|
|
125
|
+
const animatedStyle = Platform.select({
|
|
126
|
+
ios: {
|
|
127
|
+
marginBottom: transY,
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
return (
|
|
132
|
+
<View style={styles.container}>
|
|
133
|
+
<HeaderCustom title={t('member_info')} isShowSeparator />
|
|
134
|
+
<View style={styles.wrapAvatar}>
|
|
135
|
+
<Image source={{ uri: memberAvatar }} style={styles.avatar} />
|
|
136
|
+
</View>
|
|
137
|
+
<TouchableOpacity
|
|
138
|
+
onPress={setFaceID}
|
|
139
|
+
style={[styles.row, !!error && { borderBottomColor: Colors.Red6 }]}
|
|
140
|
+
>
|
|
141
|
+
<IconFill name="camera" size={27} color={Colors.Primary} />
|
|
142
|
+
<Text
|
|
143
|
+
type="Body"
|
|
144
|
+
bold
|
|
145
|
+
color={Colors.Primary}
|
|
146
|
+
style={styles.textSetPhoto}
|
|
147
|
+
>
|
|
148
|
+
{t('set_photo_id')}
|
|
149
|
+
</Text>
|
|
150
|
+
<Image source={{ uri: memberAvatar }} style={styles.photoID} />
|
|
151
|
+
</TouchableOpacity>
|
|
152
|
+
{!!error && (
|
|
153
|
+
<Text type="Label" style={styles.textError} color={Colors.Red6}>
|
|
154
|
+
{error}
|
|
155
|
+
</Text>
|
|
156
|
+
)}
|
|
157
|
+
<TouchableOpacity
|
|
158
|
+
onPress={onShowRename}
|
|
159
|
+
style={[styles.row, styles.spaceBetween]}
|
|
160
|
+
>
|
|
161
|
+
<Text type="H4" bold color={Colors.Gray9}>
|
|
162
|
+
{t('text_name')}
|
|
163
|
+
</Text>
|
|
164
|
+
<Text type="Body" color={Colors.Gray8}>
|
|
165
|
+
{memberName}
|
|
166
|
+
</Text>
|
|
167
|
+
</TouchableOpacity>
|
|
168
|
+
{!isAddNewMember && (
|
|
169
|
+
<TouchableOpacity onPress={onShowDelete} style={styles.buttonRemove}>
|
|
170
|
+
<Text type="H4" color={Colors.Red6} underline bold>
|
|
171
|
+
{t('remove_member')}
|
|
172
|
+
</Text>
|
|
173
|
+
</TouchableOpacity>
|
|
174
|
+
)}
|
|
175
|
+
{isAddNewMember && (
|
|
176
|
+
<BottomButtonView
|
|
177
|
+
mainTitle={t('finish')}
|
|
178
|
+
onPressMain={finishRegister}
|
|
179
|
+
style={styles.bottomButton}
|
|
180
|
+
/>
|
|
181
|
+
)}
|
|
182
|
+
{loading && <FullLoading />}
|
|
183
|
+
<AlertAction
|
|
184
|
+
visible={stateAlertAction.visible}
|
|
185
|
+
hideModal={hideAlertAction}
|
|
186
|
+
title={stateAlertAction.title}
|
|
187
|
+
message={stateAlertAction.message}
|
|
188
|
+
leftButtonTitle={stateAlertAction.leftButton}
|
|
189
|
+
leftButtonClick={hideAlertAction}
|
|
190
|
+
rightButtonTitle={stateAlertAction.rightButton}
|
|
191
|
+
rightButtonClick={handleRenameOrDelete}
|
|
192
|
+
rightButtonStyle={{ color: stateAlertAction.rightColor }}
|
|
193
|
+
animatedStyle={animatedStyle}
|
|
194
|
+
>
|
|
195
|
+
{!stateAlertAction.isDelete && (
|
|
196
|
+
<TextInput
|
|
197
|
+
onChange={(text) => setInputName(text)}
|
|
198
|
+
defaultValue={inputName}
|
|
199
|
+
textInputStyle={styles.textInput}
|
|
200
|
+
maxLength={64}
|
|
201
|
+
/>
|
|
202
|
+
)}
|
|
203
|
+
</AlertAction>
|
|
204
|
+
</View>
|
|
205
|
+
);
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
export default HanetMemberInfo;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { TouchableOpacity } from 'react-native';
|
|
3
|
+
import { create, act } from 'react-test-renderer';
|
|
4
|
+
import axios from 'axios';
|
|
5
|
+
import { SCProvider } from '../../../context';
|
|
6
|
+
import { mockSCStore } from '../../../context/mockStore';
|
|
7
|
+
import HanetCaptureFaceID from '../CaptureFaceID';
|
|
8
|
+
import { RNCamera } from 'react-native-camera';
|
|
9
|
+
|
|
10
|
+
const wrapComponent = (route) => (
|
|
11
|
+
<SCProvider initState={mockSCStore({})}>
|
|
12
|
+
<HanetCaptureFaceID route={route} />
|
|
13
|
+
</SCProvider>
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
jest.mock('react', () => {
|
|
17
|
+
return {
|
|
18
|
+
...jest.requireActual('react'),
|
|
19
|
+
memo: (x) => x,
|
|
20
|
+
};
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const mockedNavigate = jest.fn();
|
|
24
|
+
const mockedGoBack = jest.fn();
|
|
25
|
+
jest.mock('@react-navigation/native', () => {
|
|
26
|
+
return {
|
|
27
|
+
...jest.requireActual('@react-navigation/native'),
|
|
28
|
+
useNavigation: () => ({
|
|
29
|
+
navigate: mockedNavigate,
|
|
30
|
+
goBack: mockedGoBack,
|
|
31
|
+
}),
|
|
32
|
+
};
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
jest.mock('axios');
|
|
36
|
+
|
|
37
|
+
const mockSetAvatar = jest.fn();
|
|
38
|
+
describe('Test HanetCaptureFaceID', () => {
|
|
39
|
+
let tree, route;
|
|
40
|
+
|
|
41
|
+
beforeEach(() => {
|
|
42
|
+
mockedNavigate.mockClear();
|
|
43
|
+
mockedGoBack.mockClear();
|
|
44
|
+
mockSetAvatar.mockClear();
|
|
45
|
+
axios.patch.mockClear();
|
|
46
|
+
route = {
|
|
47
|
+
params: {
|
|
48
|
+
title: 'title',
|
|
49
|
+
hanetPlace: {
|
|
50
|
+
place_id: 1,
|
|
51
|
+
},
|
|
52
|
+
hanetMember: {
|
|
53
|
+
id: 1,
|
|
54
|
+
alias_id: 1,
|
|
55
|
+
name: 'name',
|
|
56
|
+
avatar_uri: 'uri',
|
|
57
|
+
},
|
|
58
|
+
setMemberAvatar: mockSetAvatar,
|
|
59
|
+
isAddNewMember: false,
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const captureFaceID = async (instance) => {
|
|
65
|
+
let touches = instance.findAllByType(TouchableOpacity);
|
|
66
|
+
await act(async () => {
|
|
67
|
+
await touches[1].props.onPress();
|
|
68
|
+
});
|
|
69
|
+
const camera = instance.findByType(RNCamera);
|
|
70
|
+
expect(camera).toBeDefined();
|
|
71
|
+
|
|
72
|
+
// capture
|
|
73
|
+
touches = instance.findAllByType(TouchableOpacity);
|
|
74
|
+
await act(async () => {
|
|
75
|
+
await touches[1].props.onPress();
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// resume capture
|
|
79
|
+
touches = instance.findAllByType(TouchableOpacity);
|
|
80
|
+
await act(async () => {
|
|
81
|
+
await touches[2].props.onPress();
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// capture
|
|
85
|
+
touches = instance.findAllByType(TouchableOpacity);
|
|
86
|
+
await act(async () => {
|
|
87
|
+
await touches[1].props.onPress();
|
|
88
|
+
});
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
test('Test update face id', async () => {
|
|
92
|
+
await act(async () => {
|
|
93
|
+
tree = await create(wrapComponent(route));
|
|
94
|
+
});
|
|
95
|
+
const instance = tree.root;
|
|
96
|
+
|
|
97
|
+
// capture face id
|
|
98
|
+
await captureFaceID(instance);
|
|
99
|
+
|
|
100
|
+
axios.patch.mockImplementationOnce(async () => ({
|
|
101
|
+
status: 200,
|
|
102
|
+
data: {
|
|
103
|
+
avatar_uri: 'avatar_uri',
|
|
104
|
+
},
|
|
105
|
+
}));
|
|
106
|
+
|
|
107
|
+
// continue
|
|
108
|
+
let touches = instance.findAllByType(TouchableOpacity);
|
|
109
|
+
await act(async () => {
|
|
110
|
+
await touches[1].props.onPress();
|
|
111
|
+
});
|
|
112
|
+
expect(axios.patch).toHaveBeenCalled();
|
|
113
|
+
expect(mockSetAvatar).toHaveBeenCalled();
|
|
114
|
+
expect(mockedGoBack).toHaveBeenCalled();
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
test('Test set face id for new member', async () => {
|
|
118
|
+
route.params.isAddNewMember = true;
|
|
119
|
+
await act(async () => {
|
|
120
|
+
tree = await create(wrapComponent(route));
|
|
121
|
+
});
|
|
122
|
+
const instance = tree.root;
|
|
123
|
+
|
|
124
|
+
await captureFaceID(instance);
|
|
125
|
+
|
|
126
|
+
// continue
|
|
127
|
+
let touches = instance.findAllByType(TouchableOpacity);
|
|
128
|
+
await act(async () => {
|
|
129
|
+
await touches[1].props.onPress();
|
|
130
|
+
});
|
|
131
|
+
expect(mockedNavigate).toHaveBeenCalled();
|
|
132
|
+
});
|
|
133
|
+
});
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { FlatList } from 'react-native';
|
|
3
|
+
import { create, act } from 'react-test-renderer';
|
|
4
|
+
import axios from 'axios';
|
|
5
|
+
import { SCProvider } from '../../../context';
|
|
6
|
+
import { mockSCStore } from '../../../context/mockStore';
|
|
7
|
+
import HanetCameraDetail from '../Detail';
|
|
8
|
+
import CheckinHeader from '../components/CheckinHeader';
|
|
9
|
+
import moment from 'moment';
|
|
10
|
+
import { TESTID } from '../../../configs/Constants';
|
|
11
|
+
import Calendar from '../../../commons/Calendar';
|
|
12
|
+
|
|
13
|
+
const wrapComponent = (route) => (
|
|
14
|
+
<SCProvider initState={mockSCStore({})}>
|
|
15
|
+
<HanetCameraDetail route={route} />
|
|
16
|
+
</SCProvider>
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
jest.mock('react', () => {
|
|
20
|
+
return {
|
|
21
|
+
...jest.requireActual('react'),
|
|
22
|
+
memo: (x) => x,
|
|
23
|
+
};
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
jest.mock('axios');
|
|
27
|
+
|
|
28
|
+
describe('Test HanetCameraDetail', () => {
|
|
29
|
+
Date.now = jest.fn(() => new Date('2021-09-09T10:00:00.000Z'));
|
|
30
|
+
let tree, route, responseDisplay, responseCheckin;
|
|
31
|
+
|
|
32
|
+
beforeEach(() => {
|
|
33
|
+
axios.get.mockClear();
|
|
34
|
+
route = {
|
|
35
|
+
params: {
|
|
36
|
+
unit: {
|
|
37
|
+
user_id: 1,
|
|
38
|
+
},
|
|
39
|
+
sensor: {
|
|
40
|
+
id: 1,
|
|
41
|
+
},
|
|
42
|
+
title: 'title',
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
responseDisplay = {
|
|
46
|
+
status: 200,
|
|
47
|
+
data: {
|
|
48
|
+
items: [
|
|
49
|
+
{
|
|
50
|
+
type: 'hanet_camera',
|
|
51
|
+
configuration: {
|
|
52
|
+
device_id: 2,
|
|
53
|
+
place: {
|
|
54
|
+
place_id: 3,
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
responseCheckin = {
|
|
62
|
+
status: 200,
|
|
63
|
+
data: {
|
|
64
|
+
count: 2,
|
|
65
|
+
count_member: 1,
|
|
66
|
+
count_stranger: 1,
|
|
67
|
+
results: [
|
|
68
|
+
{
|
|
69
|
+
id: 1,
|
|
70
|
+
person_name: 'name 1',
|
|
71
|
+
person_type: 'EMPLOYEE',
|
|
72
|
+
detected_image_uri: 'uri',
|
|
73
|
+
detected_mask: 'MASK_OFF',
|
|
74
|
+
created_at: moment(),
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
id: 2,
|
|
78
|
+
person_name: 'name 2',
|
|
79
|
+
person_type: 'STRANGER',
|
|
80
|
+
detected_image_uri: 'uri',
|
|
81
|
+
detected_mask: 'MASK_ON',
|
|
82
|
+
created_at: moment(),
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test('Test render HanetCameraDetail', async () => {
|
|
90
|
+
axios.get.mockImplementationOnce(async () => {
|
|
91
|
+
return responseDisplay;
|
|
92
|
+
});
|
|
93
|
+
axios.get.mockImplementationOnce(async () => {
|
|
94
|
+
return responseCheckin;
|
|
95
|
+
});
|
|
96
|
+
await act(async () => {
|
|
97
|
+
tree = await create(wrapComponent(route));
|
|
98
|
+
});
|
|
99
|
+
const instance = tree.root;
|
|
100
|
+
expect(axios.get).toHaveBeenCalledTimes(2);
|
|
101
|
+
const flatLists = instance.findAllByType(FlatList);
|
|
102
|
+
expect(flatLists).toHaveLength(1);
|
|
103
|
+
|
|
104
|
+
const textCountMember = instance.find(
|
|
105
|
+
(el) => el.props.testID === TESTID.TEXT_COUNT_MEMBER
|
|
106
|
+
);
|
|
107
|
+
const textCountStranger = instance.find(
|
|
108
|
+
(el) => el.props.testID === TESTID.TEXT_COUNT_STRANGER
|
|
109
|
+
);
|
|
110
|
+
expect(textCountMember.props.children).toBe(1);
|
|
111
|
+
expect(textCountStranger.props.children).toBe(1);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
test('Test change date', async () => {
|
|
115
|
+
axios.get.mockImplementationOnce(async () => {
|
|
116
|
+
return responseDisplay;
|
|
117
|
+
});
|
|
118
|
+
axios.get.mockImplementationOnce(async () => {
|
|
119
|
+
return responseCheckin;
|
|
120
|
+
});
|
|
121
|
+
await act(async () => {
|
|
122
|
+
tree = await create(wrapComponent(route));
|
|
123
|
+
});
|
|
124
|
+
const instance = tree.root;
|
|
125
|
+
expect(axios.get).toHaveBeenCalledTimes(2);
|
|
126
|
+
axios.get.mockClear();
|
|
127
|
+
|
|
128
|
+
const checkinHeader = instance.findByType(CheckinHeader);
|
|
129
|
+
|
|
130
|
+
// press arrow left
|
|
131
|
+
axios.get.mockImplementationOnce(async () => {
|
|
132
|
+
return responseCheckin;
|
|
133
|
+
});
|
|
134
|
+
await act(async () => {
|
|
135
|
+
await checkinHeader.props.onPickPreviousDate();
|
|
136
|
+
});
|
|
137
|
+
expect(checkinHeader.props.date.format('DD/MM/YYYY')).toBe(
|
|
138
|
+
moment().add(-1, 'days').format('DD/MM/YYYY')
|
|
139
|
+
);
|
|
140
|
+
expect(axios.get).toHaveBeenCalledTimes(1);
|
|
141
|
+
axios.get.mockClear();
|
|
142
|
+
|
|
143
|
+
// press arrow right
|
|
144
|
+
axios.get.mockImplementationOnce(async () => {
|
|
145
|
+
return responseCheckin;
|
|
146
|
+
});
|
|
147
|
+
await act(async () => {
|
|
148
|
+
await checkinHeader.props.onPickNextDate();
|
|
149
|
+
});
|
|
150
|
+
expect(checkinHeader.props.date.format('DD/MM/YYYY')).toBe(
|
|
151
|
+
moment().format('DD/MM/YYYY')
|
|
152
|
+
);
|
|
153
|
+
expect(axios.get).toHaveBeenCalledTimes(1);
|
|
154
|
+
axios.get.mockClear();
|
|
155
|
+
|
|
156
|
+
// press arrow right
|
|
157
|
+
await act(async () => {
|
|
158
|
+
await checkinHeader.props.onPickNextDate();
|
|
159
|
+
});
|
|
160
|
+
expect(checkinHeader.props.date.format('DD/MM/YYYY')).toBe(
|
|
161
|
+
moment().format('DD/MM/YYYY')
|
|
162
|
+
); // no change
|
|
163
|
+
expect(axios.get).toHaveBeenCalledTimes(0);
|
|
164
|
+
axios.get.mockClear();
|
|
165
|
+
|
|
166
|
+
// open calendar
|
|
167
|
+
await act(async () => {
|
|
168
|
+
await checkinHeader.props.setShowCalendar();
|
|
169
|
+
});
|
|
170
|
+
const calendar = instance.findByType(Calendar);
|
|
171
|
+
expect(calendar.props.isVisible).toBe(true);
|
|
172
|
+
|
|
173
|
+
// choose date on calendar
|
|
174
|
+
axios.get.mockImplementationOnce(async () => {
|
|
175
|
+
return responseCheckin;
|
|
176
|
+
});
|
|
177
|
+
await act(async () => {
|
|
178
|
+
await calendar.props.onConfirm(moment().add(-1, 'days'));
|
|
179
|
+
});
|
|
180
|
+
expect(checkinHeader.props.date.format('DD/MM/YYYY')).toBe(
|
|
181
|
+
moment().add(-1, 'days').format('DD/MM/YYYY')
|
|
182
|
+
);
|
|
183
|
+
expect(axios.get).toHaveBeenCalledTimes(1);
|
|
184
|
+
});
|
|
185
|
+
});
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { FlatList } from 'react-native';
|
|
3
|
+
import { create, act } from 'react-test-renderer';
|
|
4
|
+
import axios from 'axios';
|
|
5
|
+
import { SCProvider } from '../../../context';
|
|
6
|
+
import { mockSCStore } from '../../../context/mockStore';
|
|
7
|
+
import HanetManageAccess from '../ManageAccess';
|
|
8
|
+
import BottomSheet from '../../../commons/BottomSheet';
|
|
9
|
+
import { TESTID } from '../../../configs/Constants';
|
|
10
|
+
import Routes from '../../../utils/Route';
|
|
11
|
+
|
|
12
|
+
const wrapComponent = (route) => (
|
|
13
|
+
<SCProvider initState={mockSCStore({})}>
|
|
14
|
+
<HanetManageAccess route={route} />
|
|
15
|
+
</SCProvider>
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
jest.mock('react', () => {
|
|
19
|
+
return {
|
|
20
|
+
...jest.requireActual('react'),
|
|
21
|
+
memo: (x) => x,
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const mockedNavigate = jest.fn();
|
|
26
|
+
jest.mock('@react-navigation/native', () => {
|
|
27
|
+
return {
|
|
28
|
+
...jest.requireActual('@react-navigation/native'),
|
|
29
|
+
useNavigation: () => ({
|
|
30
|
+
navigate: mockedNavigate,
|
|
31
|
+
}),
|
|
32
|
+
useIsFocused: () => true,
|
|
33
|
+
};
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
jest.mock('axios');
|
|
37
|
+
|
|
38
|
+
describe('Test HanetManageAccess', () => {
|
|
39
|
+
let tree, route, response;
|
|
40
|
+
|
|
41
|
+
beforeEach(() => {
|
|
42
|
+
mockedNavigate.mockClear();
|
|
43
|
+
axios.get.mockClear();
|
|
44
|
+
route = {
|
|
45
|
+
params: {
|
|
46
|
+
hanetPlace: {
|
|
47
|
+
place_id: 1,
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test('Test render', async () => {
|
|
54
|
+
response = {
|
|
55
|
+
status: 200,
|
|
56
|
+
data: {
|
|
57
|
+
count: 2,
|
|
58
|
+
results: [
|
|
59
|
+
{
|
|
60
|
+
id: 1,
|
|
61
|
+
name: 'name 1',
|
|
62
|
+
avatar_uri: 'uri 1',
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
id: 2,
|
|
66
|
+
name: 'name 2',
|
|
67
|
+
avatar_uri: 'uri 2',
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
axios.get.mockImplementationOnce(async () => response);
|
|
73
|
+
await act(async () => {
|
|
74
|
+
tree = await create(wrapComponent(route));
|
|
75
|
+
});
|
|
76
|
+
const instance = tree.root;
|
|
77
|
+
const flatlists = instance.findAllByType(FlatList);
|
|
78
|
+
expect(flatlists).toHaveLength(1);
|
|
79
|
+
|
|
80
|
+
const touches = instance.findAll(
|
|
81
|
+
(el) => el.props.testID === TESTID.ROW_HANET_MANAGE_ACCESS
|
|
82
|
+
);
|
|
83
|
+
act(() => {
|
|
84
|
+
touches[0].props.onPress();
|
|
85
|
+
});
|
|
86
|
+
expect(mockedNavigate).toBeCalled();
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
const chooseAddMemberOption = async (instance, index) => {
|
|
90
|
+
const buttonAddNew = instance.find(
|
|
91
|
+
(el) => el.props.testID === TESTID.HANET_MANAGE_ACCESS_ADD_BUTTON
|
|
92
|
+
);
|
|
93
|
+
await act(async () => {
|
|
94
|
+
await buttonAddNew.props.onPress();
|
|
95
|
+
});
|
|
96
|
+
const option = instance.find(
|
|
97
|
+
(el) => el.props.testID === `${TESTID.HANET_ADD_MEMBER_OPTION}_${index}`
|
|
98
|
+
);
|
|
99
|
+
await act(async () => {
|
|
100
|
+
await option.props.onPress();
|
|
101
|
+
});
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
test('Test add new member capture face id', async () => {
|
|
105
|
+
await act(async () => {
|
|
106
|
+
tree = await create(wrapComponent(route));
|
|
107
|
+
});
|
|
108
|
+
const instance = tree.root;
|
|
109
|
+
|
|
110
|
+
const bottomSheet = instance.findByType(BottomSheet);
|
|
111
|
+
|
|
112
|
+
await chooseAddMemberOption(instance, 0);
|
|
113
|
+
|
|
114
|
+
expect(bottomSheet.props.isVisible).toBe(false);
|
|
115
|
+
expect(mockedNavigate).toBeCalledWith(Routes.HanetCaptureFaceID, {
|
|
116
|
+
title: 'Add new member',
|
|
117
|
+
hanetPlace: {
|
|
118
|
+
place_id: 1,
|
|
119
|
+
},
|
|
120
|
+
hanetMember: {
|
|
121
|
+
alias_id: null,
|
|
122
|
+
name: null,
|
|
123
|
+
},
|
|
124
|
+
isAddNewMember: true,
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
test('Test add new member choose file', async () => {
|
|
129
|
+
await act(async () => {
|
|
130
|
+
tree = await create(wrapComponent(route));
|
|
131
|
+
});
|
|
132
|
+
const instance = tree.root;
|
|
133
|
+
|
|
134
|
+
const bottomSheet = instance.findByType(BottomSheet);
|
|
135
|
+
|
|
136
|
+
await chooseAddMemberOption(instance, 1);
|
|
137
|
+
|
|
138
|
+
expect(bottomSheet.props.isVisible).toBe(false);
|
|
139
|
+
expect(mockedNavigate).toBeCalledWith(Routes.HanetMemberInfo, {
|
|
140
|
+
hanetPlace: {
|
|
141
|
+
place_id: 1,
|
|
142
|
+
},
|
|
143
|
+
hanetMember: {
|
|
144
|
+
alias_id: null,
|
|
145
|
+
name: null,
|
|
146
|
+
avatar_uri:
|
|
147
|
+
'file:///data/user/0/com.eohjsc.eohmobile/cache/Camera/80fbbd4b-926d-425f-a081-e21b13f2f7d0.jpg',
|
|
148
|
+
},
|
|
149
|
+
isAddNewMember: true,
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
});
|