@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.
Files changed (76) hide show
  1. package/assets/images/Common/Calendar.svg +3 -0
  2. package/assets/images/Common/SmartPhone.svg +3 -0
  3. package/assets/images/Hanet/CaptureFaceID.svg +25 -0
  4. package/assets/images/Hanet/FaceFrame.svg +6 -0
  5. package/package.json +2 -2
  6. package/src/Images/SmartIr/Remote.svg +15 -0
  7. package/src/Images/SmartIr/SmartIr.svg +4 -0
  8. package/src/Images/SmartIr/Union.svg +9 -0
  9. package/src/Images/SmartIr/index.js +4 -1
  10. package/src/commons/ActionGroup/ColorPickerTemplate.js +51 -0
  11. package/src/commons/ActionGroup/ColorPickerTemplateStyles.js +17 -0
  12. package/src/commons/ActionGroup/SliderRangeTemplate.js +64 -0
  13. package/src/commons/ActionGroup/{LightActionTemplateStyles.js → SliderRangeTemplateStyles.js} +0 -8
  14. package/src/commons/ActionGroup/SmartTiviActionTemplate/SmartTiviActionTemplate.js +47 -68
  15. package/src/commons/ActionGroup/index.js +6 -3
  16. package/src/commons/BottomSheet/index.js +2 -1
  17. package/src/commons/Device/Hanet/ItemHanetDevice.js +109 -0
  18. package/src/commons/Device/HistoryChart.js +2 -2
  19. package/src/commons/Device/HorizontalBarChart.js +7 -0
  20. package/src/commons/Device/ItemDevice.js +18 -15
  21. package/src/commons/Device/LinearChart.js +11 -1
  22. package/src/commons/SubUnit/Favorites/index.js +2 -2
  23. package/src/commons/SubUnit/ShortDetail.js +39 -20
  24. package/src/configs/API.js +22 -0
  25. package/src/configs/Constants.js +37 -0
  26. package/src/configs/SCConfig.js +1 -1
  27. package/src/context/actionType.ts +4 -0
  28. package/src/context/mockStore.ts +2 -0
  29. package/src/context/reducer.ts +20 -0
  30. package/src/iot/RemoteControl/Bluetooth.js +0 -19
  31. package/src/iot/RemoteControl/index.js +0 -1
  32. package/src/navigations/HanetCameraStack.js +41 -0
  33. package/src/navigations/UnitStack.js +34 -1
  34. package/src/screens/ActivityLog/hooks/index.js +1 -1
  35. package/src/screens/AddNewGateway/PlugAndPlay/ConnectWifiWarning.js +51 -66
  36. package/src/screens/AddNewGateway/PlugAndPlay/GatewayWifiList.js +68 -54
  37. package/src/screens/AddNewGateway/PlugAndPlay/__test__/ConnectWifiWarning.test.js +7 -0
  38. package/src/screens/Device/__test__/detail.test.js +0 -10
  39. package/src/screens/Device/detail.js +70 -29
  40. package/src/screens/Device/hooks/useDisconnectedDevice.js +16 -20
  41. package/src/screens/HanetCamera/CaptureFaceID.js +210 -0
  42. package/src/screens/HanetCamera/Detail.js +252 -0
  43. package/src/screens/HanetCamera/ManageAccess.js +173 -0
  44. package/src/screens/HanetCamera/MemberInfo.js +208 -0
  45. package/src/screens/HanetCamera/__test__/CaptureFaceID.test.js +133 -0
  46. package/src/screens/HanetCamera/__test__/Detail.test.js +185 -0
  47. package/src/screens/HanetCamera/__test__/ManageAccess.test.js +152 -0
  48. package/src/screens/HanetCamera/__test__/MemberInfo.test.js +178 -0
  49. package/src/screens/HanetCamera/components/CheckinHeader.js +37 -0
  50. package/src/screens/HanetCamera/hooks/__test__/useHanetCheckinData.test.js +151 -0
  51. package/src/screens/HanetCamera/hooks/__test__/useHanetPlaceMembers.test.js +71 -0
  52. package/src/screens/HanetCamera/hooks/index.js +5 -0
  53. package/src/screens/HanetCamera/hooks/useHanetCheckinData.js +116 -0
  54. package/src/screens/HanetCamera/hooks/useHanetPlaceMembers.js +86 -0
  55. package/src/screens/HanetCamera/hooks/useStateAlertAction.js +62 -0
  56. package/src/screens/HanetCamera/styles/captureFaceIDStyles.js +50 -0
  57. package/src/screens/HanetCamera/styles/checkinHeaderStyles.js +24 -0
  58. package/src/screens/HanetCamera/styles/detailStyles.js +107 -0
  59. package/src/screens/HanetCamera/styles/manageAccessStyles.js +49 -0
  60. package/src/screens/HanetCamera/styles/memberInfoStyles.js +73 -0
  61. package/src/screens/HanetCamera/utils/Monitor.js +52 -0
  62. package/src/screens/SmartIr/__test__/ButtonsBottom.test.js +31 -0
  63. package/src/screens/SmartIr/__test__/GroupButtonByType.test.js +35 -9
  64. package/src/screens/SmartIr/__test__/SelectBrand.test.js +0 -9
  65. package/src/screens/SmartIr/__test__/SelectDeviceType.test.js +1 -8
  66. package/src/screens/SmartIr/components/GroupButtonByType/ButtonsBottom.js +45 -0
  67. package/src/screens/SmartIr/components/GroupButtonByType/ButtonsBottomStyles.js +31 -0
  68. package/src/screens/SmartIr/components/GroupButtonByType/GroupButtonByType.js +156 -34
  69. package/src/screens/SmartIr/components/GroupButtonByType/GroupButtonByTypeStyles.js +52 -15
  70. package/src/screens/Unit/Detail.js +2 -10
  71. package/src/screens/Unit/__test__/Detail.test.js +0 -10
  72. package/src/utils/I18n/translations/en.json +28 -1
  73. package/src/utils/I18n/translations/vi.json +27 -0
  74. package/src/utils/Route/index.js +5 -0
  75. package/src/commons/ActionGroup/LightActionTemplate.js +0 -103
  76. 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
+ });