@eohjsc/react-native-smart-city 0.4.59 → 0.4.61
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/package.json +1 -2
- package/src/commons/Action/ItemQuickAction.js +1 -1
- package/src/commons/Action/__test__/ItemQuickAction.test.js +22 -8
- package/src/commons/Automate/ItemAutomate.js +4 -9
- package/src/commons/Button/index.js +4 -2
- package/src/commons/Device/RainningSensor/CurrentRainSensor.js +49 -36
- package/src/commons/Grid/GridItem.js +20 -0
- package/src/commons/Grid/GridItemStyles.js +32 -0
- package/src/configs/API.js +0 -2
- package/src/configs/Constants.js +0 -1
- package/src/context/actionType.ts +1 -0
- package/src/context/reducer.ts +19 -1
- package/src/screens/Automate/AddNewAction/ChooseAction.js +0 -2
- package/src/screens/Automate/AddNewAction/ChooseConfig.js +46 -161
- package/src/screens/Automate/AddNewAction/Components/SelectDevices.js +2 -6
- package/src/screens/Automate/AddNewAction/NewActionWrapper.js +10 -6
- package/src/screens/Automate/AddNewAction/SelectMonitorDevices.js +1 -0
- package/src/screens/Automate/AddNewAction/SetupConfigCondition.js +143 -173
- package/src/screens/Automate/AddNewAction/Styles/SelectActionStyles.js +8 -0
- package/src/screens/Automate/AddNewAction/Styles/SetupSensorStyles.js +29 -62
- package/src/screens/Automate/AddNewAction/__test__/ChooseAction.test.js +77 -9
- package/src/screens/Automate/AddNewAction/__test__/ChooseConfig.test.js +23 -83
- package/src/screens/Automate/AddNewAction/__test__/SelectControlDevices.test.js +2 -19
- package/src/screens/Automate/AddNewAction/__test__/SetupConfigCondition.test.js +125 -94
- package/src/screens/Automate/AddNewAutoSmart/AddAutomationTypeSmart.js +0 -4
- package/src/screens/Automate/AddNewAutoSmart/AddTypeSmart.js +24 -27
- package/src/screens/Automate/AddNewAutoSmart/AddUnknownTypeSmart.js +0 -4
- package/src/screens/Automate/AddNewAutoSmart/__test__/AddNewAutoSmart.test.js +1 -21
- package/src/screens/Automate/ScriptDetail/utils.js +42 -19
- package/src/screens/Automate/index.js +2 -4
- package/src/screens/Device/__test__/sensorDisplayItem.test.js +9 -0
- package/src/screens/Device/components/SensorDisplayItem.js +3 -0
- package/src/screens/Device/hooks/__test__/useEvaluateValue.test.js +1 -1
- package/src/screens/Device/hooks/useEvaluateValue.js +10 -6
- package/src/screens/Notification/__test__/Notification.test.js +10 -0
- package/src/screens/Unit/__test__/AddMenu.test.js +76 -0
- package/src/screens/WaterQualityGuide/__test__/index.test.js +0 -5
- package/src/utils/I18n/translations/en.js +2 -0
- package/src/utils/I18n/translations/vi.js +2 -0
- package/src/utils/Route/index.js +5 -0
|
@@ -12,10 +12,9 @@ import TitleCheckBox from '../../../Sharing/Components/TitleCheckBox';
|
|
|
12
12
|
import Text from '../../../../commons/Text';
|
|
13
13
|
import t from '../../../../hooks/Common/useTranslations';
|
|
14
14
|
import Routes from '../../../../utils/Route';
|
|
15
|
-
import CheckBoxCustom from '../../../Sharing/Components/CheckBoxCustom';
|
|
16
|
-
import BottomButtonView from '../../../../commons/BottomButtonView';
|
|
17
|
-
import { ToastBottomHelper } from '../../../../utils/Utils';
|
|
18
15
|
import { useNavigation } from '@react-navigation/native';
|
|
16
|
+
import { TouchableWithoutFeedback } from 'react-native';
|
|
17
|
+
import GridItem from '../../../../commons/Grid/GridItem';
|
|
19
18
|
|
|
20
19
|
const mock = new MockAdapter(api.axiosInstance);
|
|
21
20
|
|
|
@@ -56,10 +55,10 @@ describe('Test ChooseConfig', () => {
|
|
|
56
55
|
await act(async () => {
|
|
57
56
|
tree = await renderer.create(wrapComponent(route));
|
|
58
57
|
});
|
|
59
|
-
const checkBoxs = tree.root.findAllByType(
|
|
58
|
+
const checkBoxs = tree.root.findAllByType(GridItem);
|
|
60
59
|
expect(checkBoxs).toHaveLength(2);
|
|
61
|
-
expect(checkBoxs[0].props.
|
|
62
|
-
expect(checkBoxs[1].props.
|
|
60
|
+
expect(checkBoxs[0].props.selected).toBeFalsy();
|
|
61
|
+
expect(checkBoxs[1].props.selected).toBeFalsy();
|
|
63
62
|
});
|
|
64
63
|
|
|
65
64
|
it('choose config', async () => {
|
|
@@ -69,11 +68,11 @@ describe('Test ChooseConfig', () => {
|
|
|
69
68
|
await act(async () => {
|
|
70
69
|
tree = await renderer.create(wrapComponent(route));
|
|
71
70
|
});
|
|
72
|
-
const checkBoxs = tree.root.findAllByType(
|
|
71
|
+
const checkBoxs = tree.root.findAllByType(GridItem);
|
|
73
72
|
await act(async () => {
|
|
74
|
-
await checkBoxs[0].findByType(
|
|
73
|
+
await checkBoxs[0].findByType(TouchableWithoutFeedback).props.onPress();
|
|
75
74
|
});
|
|
76
|
-
expect(checkBoxs[0].props.
|
|
75
|
+
expect(checkBoxs[0].props.selected).toBeTruthy();
|
|
77
76
|
});
|
|
78
77
|
|
|
79
78
|
it('test fetchData with data and default', async () => {
|
|
@@ -93,17 +92,19 @@ describe('Test ChooseConfig', () => {
|
|
|
93
92
|
})
|
|
94
93
|
);
|
|
95
94
|
});
|
|
96
|
-
const checkBoxs = tree.root.findAllByType(
|
|
97
|
-
expect(checkBoxs[1].props.
|
|
95
|
+
const checkBoxs = tree.root.findAllByType(GridItem);
|
|
96
|
+
expect(checkBoxs[1].props.selected).toBeTruthy();
|
|
98
97
|
});
|
|
99
98
|
|
|
100
99
|
it('not checked but is default', async () => {
|
|
101
100
|
mock.onGet(API.AUTOMATE.DISPLAY_CONFIGS(1)).reply(200, [
|
|
102
101
|
{
|
|
103
102
|
id: 1,
|
|
103
|
+
name: 'Config 1',
|
|
104
104
|
},
|
|
105
105
|
{
|
|
106
106
|
id: 2,
|
|
107
|
+
name: 'Config 2',
|
|
107
108
|
},
|
|
108
109
|
]);
|
|
109
110
|
await act(async () => {
|
|
@@ -115,10 +116,10 @@ describe('Test ChooseConfig', () => {
|
|
|
115
116
|
);
|
|
116
117
|
});
|
|
117
118
|
const conditionTexts = tree.root.findAll(
|
|
118
|
-
(el) => el.type === Text && el.props.type === '
|
|
119
|
+
(el) => el.type === Text && el.props.type === 'Body'
|
|
119
120
|
);
|
|
120
|
-
expect(conditionTexts[0].props.children).toEqual(t('
|
|
121
|
-
expect(conditionTexts[1].props.children).
|
|
121
|
+
expect(conditionTexts[0].props.children).toEqual(t('Config 1'));
|
|
122
|
+
expect(conditionTexts[1].props.children).toEqual(t('Config 2'));
|
|
122
123
|
});
|
|
123
124
|
|
|
124
125
|
it('go to setup', async () => {
|
|
@@ -130,80 +131,19 @@ describe('Test ChooseConfig', () => {
|
|
|
130
131
|
await act(async () => {
|
|
131
132
|
tree = await renderer.create(wrapComponent(route));
|
|
132
133
|
});
|
|
133
|
-
const conditionTouch = tree.root.
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
conditionTouch.props.onPress();
|
|
138
|
-
});
|
|
139
|
-
expect(mockedNavigate).toHaveBeenCalledWith(Routes.SetupConfigCondition, {
|
|
140
|
-
item: { id: 1 },
|
|
141
|
-
closeScreen: undefined,
|
|
142
|
-
defaultCondition: undefined,
|
|
143
|
-
});
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
it('render condition from setup', async () => {
|
|
147
|
-
mock.onGet(API.AUTOMATE.DISPLAY_CONFIGS(1)).reply(200, [
|
|
148
|
-
{
|
|
149
|
-
id: 1,
|
|
150
|
-
},
|
|
151
|
-
{
|
|
152
|
-
id: 2,
|
|
153
|
-
},
|
|
154
|
-
]);
|
|
155
|
-
await act(async () => {
|
|
156
|
-
tree = await renderer.create(
|
|
157
|
-
wrapComponent({
|
|
158
|
-
...route,
|
|
159
|
-
params: {
|
|
160
|
-
...route.params,
|
|
161
|
-
newCondition: { config: 2, value: 1 }, // condition from setup
|
|
162
|
-
},
|
|
163
|
-
})
|
|
134
|
+
const conditionTouch = tree.root.find((el) => {
|
|
135
|
+
return (
|
|
136
|
+
el.props.accessibilityLabel === 'config-1' &&
|
|
137
|
+
el.type === TouchableWithoutFeedback
|
|
164
138
|
);
|
|
165
139
|
});
|
|
166
|
-
const conditionTexts = tree.root.findAll(
|
|
167
|
-
(el) => el.type === Text && el.props.type === 'H4'
|
|
168
|
-
);
|
|
169
|
-
expect(conditionTexts[1].props.children).not.toEqual(t('no_condition'));
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
it('on save without select condition', async () => {
|
|
173
|
-
mock.onGet(API.AUTOMATE.DISPLAY_CONFIGS(1)).reply(200, [{ id: 1 }]);
|
|
174
140
|
await act(async () => {
|
|
175
|
-
|
|
176
|
-
});
|
|
177
|
-
const button = tree.root.findByType(BottomButtonView);
|
|
178
|
-
const spyToastError = jest.spyOn(ToastBottomHelper, 'error');
|
|
179
|
-
await act(async () => {
|
|
180
|
-
await button.props.onPressMain();
|
|
141
|
+
conditionTouch.props.onPress();
|
|
181
142
|
});
|
|
182
|
-
expect(spyToastError).toHaveBeenCalledWith(
|
|
183
|
-
t('please_choose_condition_before_continue')
|
|
184
|
-
);
|
|
185
|
-
});
|
|
186
143
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
tree = await renderer.create(
|
|
191
|
-
wrapComponent({
|
|
192
|
-
...route,
|
|
193
|
-
params: {
|
|
194
|
-
...route.params,
|
|
195
|
-
automate: { config_id: 1 },
|
|
196
|
-
newSensorData: [{ id: 1, value: 1 }],
|
|
197
|
-
},
|
|
198
|
-
})
|
|
199
|
-
);
|
|
200
|
-
});
|
|
201
|
-
const button = tree.root.findByType(BottomButtonView);
|
|
202
|
-
await act(async () => {
|
|
203
|
-
await button.props.onPressMain();
|
|
204
|
-
});
|
|
205
|
-
expect(mockedNavigate).toHaveBeenCalledWith(Routes.ValueChangeName, {
|
|
206
|
-
automate: { config_id: 1 },
|
|
144
|
+
expect(mockedNavigate).toHaveBeenCalledWith(Routes.SetupConfigCondition, {
|
|
145
|
+
automate: { config: 1 },
|
|
146
|
+
config: { id: 1 },
|
|
207
147
|
closeScreen: undefined,
|
|
208
148
|
});
|
|
209
149
|
});
|
|
@@ -4,7 +4,6 @@ import MockAdapter from 'axios-mock-adapter';
|
|
|
4
4
|
import { SCProvider } from '../../../../context';
|
|
5
5
|
import { mockSCStore } from '../../../../context/mockStore';
|
|
6
6
|
import Device from '../Device';
|
|
7
|
-
import BottomButtonView from '../../../../commons/BottomButtonView';
|
|
8
7
|
import NavBar from '../../../../commons/NavBar';
|
|
9
8
|
import API from '../../../../configs/API';
|
|
10
9
|
import { AccessibilityLabel } from '../../../../configs/Constants';
|
|
@@ -63,20 +62,6 @@ describe('Test SelectMonitorDevices', () => {
|
|
|
63
62
|
expect(navBar.props.listStation).toHaveLength(1);
|
|
64
63
|
});
|
|
65
64
|
|
|
66
|
-
it('onPress continue', async () => {
|
|
67
|
-
mock.onGet(API.UNIT.DEVICE_CONTROL(1)).reply(200, response);
|
|
68
|
-
await act(async () => {
|
|
69
|
-
tree = await renderer.create(wrapComponent(route));
|
|
70
|
-
});
|
|
71
|
-
const instance = tree.root;
|
|
72
|
-
|
|
73
|
-
const bottomButton = instance.findByType(BottomButtonView);
|
|
74
|
-
await act(async () => {
|
|
75
|
-
bottomButton.props.onPressMain();
|
|
76
|
-
});
|
|
77
|
-
expect(mockedNavigate).toHaveBeenCalled();
|
|
78
|
-
});
|
|
79
|
-
|
|
80
65
|
it('test onPressDevice', async () => {
|
|
81
66
|
mock.onGet(API.UNIT.DEVICE_CONTROL(1)).reply(200, response);
|
|
82
67
|
await act(async () => {
|
|
@@ -90,10 +75,8 @@ describe('Test SelectMonitorDevices', () => {
|
|
|
90
75
|
device[0].props.onPress({ id: 1, name: 'sensor' });
|
|
91
76
|
});
|
|
92
77
|
expect(device[0].props.isSelectDevice).toBeTruthy();
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
});
|
|
96
|
-
expect(device[0].props.isSelectDevice).toBeFalsy();
|
|
78
|
+
|
|
79
|
+
expect(mockedNavigate).toHaveBeenCalled();
|
|
97
80
|
});
|
|
98
81
|
|
|
99
82
|
it('test onSnapItem', async () => {
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { TouchableOpacity } from 'react-native';
|
|
3
2
|
import { act, create } from 'react-test-renderer';
|
|
4
3
|
import { SCProvider } from '../../../../context';
|
|
5
4
|
import { mockSCStore } from '../../../../context/mockStore';
|
|
6
|
-
import BottomButtonView from '../../../../commons/BottomButtonView';
|
|
7
5
|
import SetupConfigCondition from '../SetupConfigCondition';
|
|
8
6
|
import { useNavigation, useRoute } from '@react-navigation/native';
|
|
9
|
-
import _TextInput from '../../../../commons/Form/TextInput';
|
|
10
7
|
import { ToastBottomHelper } from '../../../../utils/Utils';
|
|
11
|
-
import { ModalCustom } from '../../../../commons/Modal';
|
|
12
8
|
import { Text } from '../../../../commons';
|
|
9
|
+
import { Button, InputItem, Radio } from '@ant-design/react-native';
|
|
10
|
+
import GridItem from '../../../../commons/Grid/GridItem';
|
|
11
|
+
import { TouchableWithoutFeedback } from 'react-native';
|
|
12
|
+
import Routes from '../../../../utils/Route';
|
|
13
|
+
import { ModalCustom } from '../../../../commons/Modal';
|
|
13
14
|
|
|
14
15
|
jest.mock('react', () => {
|
|
15
16
|
return {
|
|
@@ -18,6 +19,19 @@ jest.mock('react', () => {
|
|
|
18
19
|
};
|
|
19
20
|
});
|
|
20
21
|
|
|
22
|
+
const BOOLEAN_VALUE_EVALUATION_CONFIGURATION = {
|
|
23
|
+
id: 1,
|
|
24
|
+
template: 'boolean',
|
|
25
|
+
configuration: {
|
|
26
|
+
on: {
|
|
27
|
+
text: 'Case On',
|
|
28
|
+
},
|
|
29
|
+
off: {
|
|
30
|
+
text: 'Case Off',
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
|
|
21
35
|
const wrapComponent = (configuration, onPress) => (
|
|
22
36
|
<SCProvider initState={mockSCStore({})}>
|
|
23
37
|
<SetupConfigCondition />
|
|
@@ -35,19 +49,41 @@ describe('Test SetupConfigCondition', () => {
|
|
|
35
49
|
mockGoBack.mockReset();
|
|
36
50
|
useRoute.mockClear();
|
|
37
51
|
spyToastError.mockClear();
|
|
52
|
+
mockNavigate.mockClear();
|
|
38
53
|
});
|
|
39
54
|
|
|
40
|
-
it('
|
|
55
|
+
it('render range value evaluation', async () => {
|
|
41
56
|
useRoute.mockReturnValue({
|
|
42
57
|
params: {
|
|
43
|
-
|
|
58
|
+
config: {
|
|
44
59
|
id: 1,
|
|
45
|
-
value: 10,
|
|
46
|
-
range_min: 0,
|
|
47
|
-
range_max: 1000,
|
|
48
60
|
decimal_behind: 0,
|
|
49
61
|
title: 'is below (<)',
|
|
50
62
|
sensor_type: 'air_quality',
|
|
63
|
+
value_evaluations: [
|
|
64
|
+
{
|
|
65
|
+
template: 'range',
|
|
66
|
+
configuration: {
|
|
67
|
+
ranges: [
|
|
68
|
+
{
|
|
69
|
+
evaluate: {
|
|
70
|
+
text: 'Case 1',
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
evaluate: {
|
|
75
|
+
text: 'Case 2',
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
evaluate: {
|
|
80
|
+
text: 'Case 3',
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
],
|
|
51
87
|
},
|
|
52
88
|
sensorData: [],
|
|
53
89
|
},
|
|
@@ -57,60 +93,48 @@ describe('Test SetupConfigCondition', () => {
|
|
|
57
93
|
});
|
|
58
94
|
const instance = tree.root;
|
|
59
95
|
|
|
60
|
-
|
|
61
|
-
instance.findAllByType(TouchableOpacity)[0].props.onPress();
|
|
62
|
-
instance.findAllByType(TouchableOpacity)[1].props.onPress();
|
|
63
|
-
instance.findAllByType(TouchableOpacity)[2].props.onPress();
|
|
64
|
-
});
|
|
96
|
+
const gridItems = instance.findAllByType(GridItem);
|
|
65
97
|
|
|
66
|
-
|
|
67
|
-
expect(
|
|
98
|
+
expect(gridItems[0].findByType(Text).props.children).toEqual('Case 1');
|
|
99
|
+
expect(gridItems[1].findByType(Text).props.children).toEqual('Case 2');
|
|
100
|
+
expect(gridItems[2].findByType(Text).props.children).toEqual('Case 3');
|
|
101
|
+
});
|
|
68
102
|
|
|
69
|
-
|
|
70
|
-
|
|
103
|
+
it('render boolean value evaluation', async () => {
|
|
104
|
+
useRoute.mockReturnValue({
|
|
105
|
+
params: {
|
|
106
|
+
config: {
|
|
107
|
+
id: 1,
|
|
108
|
+
title: 'is below (<)',
|
|
109
|
+
sensor_type: 'air_quality',
|
|
110
|
+
value_evaluations: [BOOLEAN_VALUE_EVALUATION_CONFIGURATION],
|
|
111
|
+
},
|
|
112
|
+
sensorData: [],
|
|
113
|
+
},
|
|
71
114
|
});
|
|
72
|
-
const inputs = instance.findAllByType(_TextInput);
|
|
73
|
-
expect(inputs).toHaveLength(1);
|
|
74
115
|
await act(async () => {
|
|
75
|
-
|
|
116
|
+
tree = await create(wrapComponent());
|
|
76
117
|
});
|
|
118
|
+
const instance = tree.root;
|
|
77
119
|
|
|
78
|
-
const
|
|
79
|
-
expect(
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
120
|
+
const gridItems = instance.findAllByType(GridItem);
|
|
121
|
+
expect(gridItems).toHaveLength(3);
|
|
122
|
+
expect(gridItems[0].findByType(Text).props.children).toEqual('Case Off');
|
|
123
|
+
expect(gridItems[1].findByType(Text).props.children).toEqual('Case On');
|
|
124
|
+
expect(gridItems[2].findByType(Text).props.children).toEqual(
|
|
125
|
+
'Customize...'
|
|
126
|
+
);
|
|
84
127
|
});
|
|
85
128
|
|
|
86
|
-
it('
|
|
129
|
+
it('choose config value evaluation', async () => {
|
|
87
130
|
useRoute.mockReturnValue({
|
|
88
131
|
params: {
|
|
89
|
-
|
|
132
|
+
automate: {},
|
|
133
|
+
config: {
|
|
90
134
|
id: 1,
|
|
91
|
-
decimal_behind: 0,
|
|
92
135
|
title: 'is below (<)',
|
|
93
136
|
sensor_type: 'air_quality',
|
|
94
|
-
|
|
95
|
-
ranges: [
|
|
96
|
-
{
|
|
97
|
-
evaluate: {
|
|
98
|
-
text: 'Case 1',
|
|
99
|
-
},
|
|
100
|
-
},
|
|
101
|
-
{
|
|
102
|
-
evaluate: {
|
|
103
|
-
text: 'Case 2',
|
|
104
|
-
},
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
evaluate: {
|
|
108
|
-
text: 'Case 3',
|
|
109
|
-
},
|
|
110
|
-
},
|
|
111
|
-
],
|
|
112
|
-
},
|
|
113
|
-
evaluate_template: 'range',
|
|
137
|
+
value_evaluations: [BOOLEAN_VALUE_EVALUATION_CONFIGURATION],
|
|
114
138
|
},
|
|
115
139
|
sensorData: [],
|
|
116
140
|
},
|
|
@@ -120,40 +144,29 @@ describe('Test SetupConfigCondition', () => {
|
|
|
120
144
|
});
|
|
121
145
|
const instance = tree.root;
|
|
122
146
|
|
|
147
|
+
const gridItems = instance.findAllByType(GridItem);
|
|
148
|
+
|
|
123
149
|
await act(async () => {
|
|
124
|
-
|
|
125
|
-
.findByProps({ accessibilityLabel: 'open-modal' })
|
|
126
|
-
.props.onPress();
|
|
150
|
+
gridItems[0].findByType(TouchableWithoutFeedback).props.onPress();
|
|
127
151
|
});
|
|
128
152
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
expect(texts[2].props.children).toEqual('Case 3');
|
|
153
|
+
expect(mockNavigate).toBeCalledWith(Routes.ValueChangeName, {
|
|
154
|
+
automate: {
|
|
155
|
+
condition: 'value_evaluation',
|
|
156
|
+
value: [1, 0],
|
|
157
|
+
},
|
|
158
|
+
closeScreen: undefined,
|
|
159
|
+
});
|
|
137
160
|
});
|
|
138
161
|
|
|
139
|
-
it('
|
|
162
|
+
it('choose config custom condition', async () => {
|
|
140
163
|
useRoute.mockReturnValue({
|
|
141
164
|
params: {
|
|
142
|
-
|
|
165
|
+
automate: {},
|
|
166
|
+
config: {
|
|
143
167
|
id: 1,
|
|
144
168
|
title: 'is below (<)',
|
|
145
|
-
sensor_type: 'air_quality',
|
|
146
|
-
evaluate_configuration: {
|
|
147
|
-
on: {
|
|
148
|
-
text: 'Case On',
|
|
149
|
-
},
|
|
150
|
-
off: {
|
|
151
|
-
text: 'Case Off',
|
|
152
|
-
},
|
|
153
|
-
},
|
|
154
|
-
evaluate_template: 'boolean',
|
|
155
169
|
},
|
|
156
|
-
sensorData: [],
|
|
157
170
|
},
|
|
158
171
|
});
|
|
159
172
|
await act(async () => {
|
|
@@ -161,19 +174,43 @@ describe('Test SetupConfigCondition', () => {
|
|
|
161
174
|
});
|
|
162
175
|
const instance = tree.root;
|
|
163
176
|
|
|
177
|
+
const gridItems = instance.findAllByType(GridItem);
|
|
178
|
+
|
|
164
179
|
await act(async () => {
|
|
165
|
-
|
|
166
|
-
.findByProps({ accessibilityLabel: 'open-modal' })
|
|
167
|
-
.props.onPress();
|
|
180
|
+
gridItems[0].findByType(TouchableWithoutFeedback).props.onPress();
|
|
168
181
|
});
|
|
169
182
|
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
expect(
|
|
183
|
+
const modal = instance.findAllByType(ModalCustom)[0];
|
|
184
|
+
expect(modal.props.isVisible).toBeTruthy();
|
|
185
|
+
|
|
186
|
+
await act(async () => {
|
|
187
|
+
modal.props.onBackdropPress();
|
|
188
|
+
});
|
|
189
|
+
expect(modal.props.isVisible).toBeFalsy();
|
|
190
|
+
|
|
191
|
+
await act(async () => {
|
|
192
|
+
instance.findAllByType(Radio.RadioItem)[0].props.onChange();
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
const input = instance.findByType(InputItem);
|
|
196
|
+
|
|
197
|
+
await act(async () => {
|
|
198
|
+
input.props.onChange('123');
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
const bottomButtonView = instance.findByType(Button);
|
|
202
|
+
|
|
203
|
+
await act(async () => {
|
|
204
|
+
bottomButtonView.props.onPress();
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
expect(mockNavigate).toBeCalledWith(Routes.ValueChangeName, {
|
|
208
|
+
automate: {
|
|
209
|
+
condition: '<',
|
|
210
|
+
value: 123,
|
|
211
|
+
},
|
|
212
|
+
closeScreen: undefined,
|
|
213
|
+
});
|
|
177
214
|
});
|
|
178
215
|
|
|
179
216
|
const testConditionValue = async (value, message) => {
|
|
@@ -185,22 +222,23 @@ describe('Test SetupConfigCondition', () => {
|
|
|
185
222
|
title: 'is below (<)',
|
|
186
223
|
sensor_type: 'air_quality',
|
|
187
224
|
},
|
|
225
|
+
automate: {},
|
|
188
226
|
},
|
|
189
227
|
});
|
|
190
228
|
await act(async () => {
|
|
191
229
|
tree = await create(wrapComponent());
|
|
192
230
|
});
|
|
193
231
|
const instance = tree.root;
|
|
194
|
-
const input = instance.findByType(
|
|
232
|
+
const input = instance.findByType(InputItem);
|
|
195
233
|
|
|
196
234
|
await act(async () => {
|
|
197
235
|
input.props.onChange(value);
|
|
198
236
|
});
|
|
199
237
|
|
|
200
|
-
const bottomButtonView = instance.findByType(
|
|
238
|
+
const bottomButtonView = instance.findByType(Button);
|
|
201
239
|
|
|
202
240
|
await act(async () => {
|
|
203
|
-
bottomButtonView.props.
|
|
241
|
+
bottomButtonView.props.onPress();
|
|
204
242
|
});
|
|
205
243
|
|
|
206
244
|
if (message === null) {
|
|
@@ -213,11 +251,4 @@ describe('Test SetupConfigCondition', () => {
|
|
|
213
251
|
it('Test render when have input not number', async () => {
|
|
214
252
|
await testConditionValue('abc', 'Please enter a number');
|
|
215
253
|
});
|
|
216
|
-
|
|
217
|
-
it('Test render when have input value must be 6 digits or less', async () => {
|
|
218
|
-
await testConditionValue(
|
|
219
|
-
'123456789',
|
|
220
|
-
'Value must be less than or equal to 8 characters'
|
|
221
|
-
);
|
|
222
|
-
});
|
|
223
254
|
});
|
|
@@ -4,9 +4,7 @@ import { useNavigation } from '@react-navigation/native';
|
|
|
4
4
|
import { HeaderCustom } from '../../../commons/Header';
|
|
5
5
|
import styles from './styles/AddNewAutoSmartStyles';
|
|
6
6
|
import Text from '../../../commons/Text';
|
|
7
|
-
import BottomButtonView from '../../../commons/BottomButtonView';
|
|
8
7
|
import ItemAutomate from '../../../commons/Automate/ItemAutomate';
|
|
9
|
-
import { AccessibilityLabel } from '../../../configs/Constants';
|
|
10
8
|
import { useTranslations } from '../../../hooks/Common/useTranslations';
|
|
11
9
|
import Routes from '../../../utils/Route';
|
|
12
10
|
|
|
@@ -21,23 +19,31 @@ const AddTypeSmart = ({ smartTypes, route }) => {
|
|
|
21
19
|
: -1
|
|
22
20
|
);
|
|
23
21
|
|
|
24
|
-
const handleOnContinue = useCallback(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
22
|
+
const handleOnContinue = useCallback(
|
|
23
|
+
(index) => {
|
|
24
|
+
const dataAutomate = smartTypes[index];
|
|
25
|
+
const params = {
|
|
26
|
+
automate: {
|
|
27
|
+
...automate,
|
|
28
|
+
type: dataAutomate?.type,
|
|
29
|
+
},
|
|
30
|
+
closeScreen: closeScreen,
|
|
31
|
+
};
|
|
33
32
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
if (!automate?.unit) {
|
|
34
|
+
navigate(Routes.SelectUnit, params);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
38
37
|
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
navigate(dataAutomate.route, params);
|
|
39
|
+
},
|
|
40
|
+
[smartTypes, automate, closeScreen, navigate]
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
const onSelectType = (index) => {
|
|
44
|
+
setSelectedIndex(index);
|
|
45
|
+
handleOnContinue(index);
|
|
46
|
+
};
|
|
41
47
|
|
|
42
48
|
return (
|
|
43
49
|
<View style={styles.wrap}>
|
|
@@ -57,20 +63,11 @@ const AddTypeSmart = ({ smartTypes, route }) => {
|
|
|
57
63
|
key={item?.type?.toString()}
|
|
58
64
|
index={index}
|
|
59
65
|
selectedIndex={selectedIndex}
|
|
60
|
-
setSelectedIndex={
|
|
66
|
+
setSelectedIndex={onSelectType}
|
|
61
67
|
/>
|
|
62
68
|
))}
|
|
63
69
|
</View>
|
|
64
70
|
</View>
|
|
65
|
-
<BottomButtonView
|
|
66
|
-
accessibilityLabelPrefix={
|
|
67
|
-
AccessibilityLabel.PREFIX.BUTTON_ADD_AUTO_SMART
|
|
68
|
-
}
|
|
69
|
-
onPressMain={handleOnContinue}
|
|
70
|
-
style={styles.bottomButton}
|
|
71
|
-
mainTitle={t('continue')}
|
|
72
|
-
typeMain={selectedIndex === -1 ? 'disabled' : 'primary'}
|
|
73
|
-
/>
|
|
74
71
|
</View>
|
|
75
72
|
);
|
|
76
73
|
};
|
|
@@ -3,7 +3,6 @@ import { act, create } from 'react-test-renderer';
|
|
|
3
3
|
import AddUnknownTypeSmart from '../AddUnknownTypeSmart';
|
|
4
4
|
import { SCProvider } from '../../../../context';
|
|
5
5
|
import { mockSCStore } from '../../../../context/mockStore';
|
|
6
|
-
import { AccessibilityLabel } from '../../../../configs/Constants';
|
|
7
6
|
import ItemAutomate from '../../../../commons/Automate/ItemAutomate';
|
|
8
7
|
import Routes from '../../../../utils/Route';
|
|
9
8
|
import { TouchableOpacity } from 'react-native';
|
|
@@ -34,7 +33,7 @@ describe('test AddNewAutoSmart', () => {
|
|
|
34
33
|
});
|
|
35
34
|
const instance = tree.root;
|
|
36
35
|
const items = instance.findAllByType(ItemAutomate);
|
|
37
|
-
expect(items).toHaveLength(
|
|
36
|
+
expect(items).toHaveLength(3);
|
|
38
37
|
|
|
39
38
|
const touchItem = items[1].findByType(TouchableOpacity);
|
|
40
39
|
|
|
@@ -42,17 +41,6 @@ describe('test AddNewAutoSmart', () => {
|
|
|
42
41
|
await touchItem.props.onPress();
|
|
43
42
|
});
|
|
44
43
|
|
|
45
|
-
const bottomButton = instance.find(
|
|
46
|
-
(item) =>
|
|
47
|
-
item.props.accessibilityLabel ===
|
|
48
|
-
`${AccessibilityLabel.PREFIX.BUTTON_ADD_AUTO_SMART}${AccessibilityLabel.BOTTOM_VIEW_MAIN}`
|
|
49
|
-
);
|
|
50
|
-
expect(bottomButton).toBeDefined();
|
|
51
|
-
|
|
52
|
-
await act(async () => {
|
|
53
|
-
await bottomButton.props.onPress();
|
|
54
|
-
});
|
|
55
|
-
|
|
56
44
|
expect(mockNavigate).toBeCalledWith(Routes.SelectMonitorDevices, {
|
|
57
45
|
automate: { unit: 1, type: 'value_change' },
|
|
58
46
|
closeScreen: undefined,
|
|
@@ -71,14 +59,6 @@ describe('test AddNewAutoSmart', () => {
|
|
|
71
59
|
});
|
|
72
60
|
expect(items[2].props.isSelected).toBeTruthy();
|
|
73
61
|
|
|
74
|
-
const bottomButton = instance.find(
|
|
75
|
-
(item) =>
|
|
76
|
-
item.props.accessibilityLabel ===
|
|
77
|
-
`${AccessibilityLabel.PREFIX.BUTTON_ADD_AUTO_SMART}${AccessibilityLabel.BOTTOM_VIEW_MAIN}`
|
|
78
|
-
);
|
|
79
|
-
await act(async () => {
|
|
80
|
-
await bottomButton.props.onPress();
|
|
81
|
-
});
|
|
82
62
|
expect(mockNavigate).toHaveBeenCalledWith(Routes.SetSchedule, {
|
|
83
63
|
automate: { type: 'schedule', unit: 1 },
|
|
84
64
|
closeScreen: undefined,
|