@eohjsc/react-native-smart-city 0.5.5 → 0.5.7-rc1

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 (32) hide show
  1. package/package.json +2 -1
  2. package/src/commons/ActionGroup/OnOffTemplate/OnOffButtonTemplate.js +27 -3
  3. package/src/commons/ActionGroup/OnOffTemplate/index.js +47 -32
  4. package/src/commons/ActionGroup/__test__/index.test.js +40 -1
  5. package/src/commons/ActionTemplate/OnOffButtonAction.js +8 -2
  6. package/src/commons/ActionTemplate/OneButtonAction.js +5 -1
  7. package/src/configs/API.js +6 -0
  8. package/src/configs/AccessibilityLabel.js +7 -0
  9. package/src/configs/Constants.js +5 -0
  10. package/src/navigations/UnitStack.js +6 -0
  11. package/src/screens/Automate/AddNewAction/ChooseAction.js +1 -89
  12. package/src/screens/Automate/AddNewAction/NewActionWrapper.js +10 -2
  13. package/src/screens/Automate/AddNewAction/RenderActionItem.js +92 -0
  14. package/src/screens/Automate/AddNewAction/SetupConfigCondition.js +23 -11
  15. package/src/screens/Automate/AddNewAction/SetupScriptDelay.js +2 -2
  16. package/src/screens/Automate/AddNewAction/Styles/SetupSensorStyles.js +3 -3
  17. package/src/screens/Automate/AddNewAction/__test__/SetupConfigCondition.test.js +10 -17
  18. package/src/screens/Automate/EditActionsList/Styles/indexStyles.js +32 -6
  19. package/src/screens/Automate/EditActionsList/UpdateActionScript.js +141 -0
  20. package/src/screens/Automate/EditActionsList/UpdateDelayScript.js +94 -0
  21. package/src/screens/Automate/EditActionsList/UpdateNotifyScript.js +115 -0
  22. package/src/screens/Automate/EditActionsList/__tests__/UpdateActionScript.test.js +174 -0
  23. package/src/screens/Automate/EditActionsList/__tests__/UpdateDelayScript.test.js +119 -0
  24. package/src/screens/Automate/EditActionsList/__tests__/UpdateNotifyScript.test.js +138 -0
  25. package/src/screens/Automate/EditActionsList/__tests__/index.test.js +121 -50
  26. package/src/screens/Automate/EditActionsList/index.js +276 -167
  27. package/src/screens/Automate/ScriptDetail/index.js +11 -6
  28. package/src/screens/ChangePosition/index.js +1 -1
  29. package/src/screens/ChangePosition/styles.js +4 -0
  30. package/src/utils/I18n/translations/en.js +17 -4
  31. package/src/utils/I18n/translations/vi.js +17 -4
  32. package/src/utils/Route/index.js +2 -0
@@ -0,0 +1,119 @@
1
+ import React from 'react';
2
+ import renderer, { act } from 'react-test-renderer';
3
+ import MockAdapter from 'axios-mock-adapter';
4
+
5
+ import { SCProvider } from '../../../../context';
6
+ import { mockSCStore } from '../../../../context/mockStore';
7
+ import API from '../../../../configs/API';
8
+ import { AccessibilityLabel } from '../../../../configs/Constants';
9
+
10
+ import api from '../../../../utils/Apis/axios';
11
+ import _TextInput from '../../../../commons/Form/TextInput';
12
+ import BottomButtonView from '../../../../commons/BottomButtonView';
13
+ import { ToastBottomHelper } from '../../../../utils/Utils';
14
+ import UpdateDelayScript from '../UpdateDelayScript';
15
+
16
+ const mock = new MockAdapter(api.axiosInstance);
17
+ const mockedNavigate = jest.fn();
18
+ const mockedDispatch = jest.fn();
19
+ const mockedGoBack = jest.fn();
20
+ const mockerOnClosePopup = jest.fn();
21
+ const mockedSetActionList = jest.fn();
22
+ const mockedSetNeedRefresh = jest.fn();
23
+
24
+ jest.mock('@react-navigation/native', () => {
25
+ return {
26
+ ...jest.requireActual('@react-navigation/native'),
27
+ useNavigation: () => ({
28
+ navigate: mockedNavigate,
29
+ dispatch: mockedDispatch,
30
+ goBack: mockedGoBack,
31
+ }),
32
+ useRoute: jest.fn(),
33
+ };
34
+ });
35
+ let actionsList = [
36
+ {
37
+ id: 1,
38
+ action_script: { id: 1, sensor_name: 'abc', station_name: 'abc' },
39
+ notify_script: null,
40
+ delay_script: null,
41
+ order: 1,
42
+ },
43
+ {
44
+ id: 2,
45
+ action_script: null,
46
+ notify_script: { title: 'title', message: 'Contend' },
47
+ delay_script: null,
48
+ order: 2,
49
+ },
50
+ {
51
+ id: 3,
52
+ action_script: null,
53
+ notify_script: null,
54
+ delay_script: { delay: 10 },
55
+ order: 3,
56
+ },
57
+ ];
58
+ const wrapComponent = () => (
59
+ <SCProvider initState={mockSCStore({})}>
60
+ <UpdateDelayScript
61
+ automateId={1}
62
+ scriptItemId={1}
63
+ delay_script={{ delay: 10 }}
64
+ t={jest.fn()}
65
+ onClosePopup={mockerOnClosePopup}
66
+ actionsList={actionsList}
67
+ setActionList={mockedSetActionList}
68
+ updateIndex={2}
69
+ setNeedRefresh={mockedSetNeedRefresh}
70
+ />
71
+ </SCProvider>
72
+ );
73
+
74
+ describe('Test UpdateDelayScript', () => {
75
+ let tree;
76
+
77
+ beforeEach(() => {
78
+ mockedNavigate.mockClear();
79
+ });
80
+
81
+ it('test update delay', async () => {
82
+ mock.onPut(API.AUTOMATE.UPDATE_SCRIPT_DELAY(1)).reply(200);
83
+ const spyToast = jest.spyOn(ToastBottomHelper, 'success');
84
+ await act(async () => {
85
+ tree = await renderer.create(wrapComponent());
86
+ });
87
+ const instance = tree.root;
88
+ const title = instance.find(
89
+ (el) =>
90
+ el.props.accessibilityLabel ===
91
+ AccessibilityLabel.AUTOMATE_INPUT_DELAY && el.type === _TextInput
92
+ );
93
+ await act(async () => {
94
+ title.props.onChange('1');
95
+ });
96
+ const button = instance.findByType(BottomButtonView);
97
+ expect(button.props.typeMain).toEqual('primary');
98
+ await act(async () => {
99
+ button.props.onPressMain();
100
+ });
101
+ expect(spyToast).toBeCalled();
102
+ });
103
+ it('test can not update title and message', async () => {
104
+ await act(async () => {
105
+ tree = await renderer.create(wrapComponent());
106
+ });
107
+ const instance = tree.root;
108
+ const title = instance.find(
109
+ (el) =>
110
+ el.props.accessibilityLabel ===
111
+ AccessibilityLabel.AUTOMATE_INPUT_DELAY && el.type === _TextInput
112
+ );
113
+ await act(async () => {
114
+ title.props.onChange('10');
115
+ });
116
+ const button = instance.findByType(BottomButtonView);
117
+ expect(button.props.typeMain).toEqual('disabled');
118
+ });
119
+ });
@@ -0,0 +1,138 @@
1
+ import React from 'react';
2
+ import renderer, { act } from 'react-test-renderer';
3
+ import MockAdapter from 'axios-mock-adapter';
4
+
5
+ import { SCProvider } from '../../../../context';
6
+ import { mockSCStore } from '../../../../context/mockStore';
7
+ import API from '../../../../configs/API';
8
+ import { AccessibilityLabel } from '../../../../configs/Constants';
9
+
10
+ import api from '../../../../utils/Apis/axios';
11
+ import UpdateNotifyScript from '../UpdateNotifyScript';
12
+ import _TextInput from '../../../../commons/Form/TextInput';
13
+ import BottomButtonView from '../../../../commons/BottomButtonView';
14
+ import { ToastBottomHelper } from '../../../../utils/Utils';
15
+
16
+ const mock = new MockAdapter(api.axiosInstance);
17
+ const mockedNavigate = jest.fn();
18
+ const mockedDispatch = jest.fn();
19
+ const mockedGoBack = jest.fn();
20
+ const mockerOnClosePopup = jest.fn();
21
+ const mockedSetActionList = jest.fn();
22
+ const mockedSetNeedRefresh = jest.fn();
23
+
24
+ jest.mock('@react-navigation/native', () => {
25
+ return {
26
+ ...jest.requireActual('@react-navigation/native'),
27
+ useNavigation: () => ({
28
+ navigate: mockedNavigate,
29
+ dispatch: mockedDispatch,
30
+ goBack: mockedGoBack,
31
+ }),
32
+ useRoute: jest.fn(),
33
+ };
34
+ });
35
+ let actionsList = [
36
+ {
37
+ id: 1,
38
+ action_script: { id: 1, sensor_name: 'abc', station_name: 'abc' },
39
+ notify_script: null,
40
+ delay_script: null,
41
+ order: 1,
42
+ },
43
+ {
44
+ id: 2,
45
+ action_script: null,
46
+ notify_script: { title: 'title', message: 'Contend' },
47
+ delay_script: null,
48
+ order: 2,
49
+ },
50
+ {
51
+ id: 3,
52
+ action_script: null,
53
+ notify_script: null,
54
+ delay_script: { delay: 10 },
55
+ order: 3,
56
+ },
57
+ ];
58
+ const wrapComponent = () => (
59
+ <SCProvider initState={mockSCStore({})}>
60
+ <UpdateNotifyScript
61
+ automateId={1}
62
+ scriptItemId={1}
63
+ notify_script={{ title: 'title', message: 'Contend' }}
64
+ t={jest.fn()}
65
+ onClosePopup={mockerOnClosePopup}
66
+ actionsList={actionsList}
67
+ setActionList={mockedSetActionList}
68
+ updateIndex={1}
69
+ setNeedRefresh={mockedSetNeedRefresh}
70
+ />
71
+ </SCProvider>
72
+ );
73
+
74
+ describe('Test UpdateNotifyScript', () => {
75
+ let tree;
76
+
77
+ beforeEach(() => {
78
+ mockedNavigate.mockClear();
79
+ });
80
+
81
+ it('test update title and message', async () => {
82
+ mock.onPut(API.AUTOMATE.UPDATE_SCRIPT_NOTIFY(1)).reply(200);
83
+ const spyToast = jest.spyOn(ToastBottomHelper, 'success');
84
+ await act(async () => {
85
+ tree = await renderer.create(wrapComponent());
86
+ });
87
+ const instance = tree.root;
88
+ const title = instance.find(
89
+ (el) =>
90
+ el.props.accessibilityLabel ===
91
+ AccessibilityLabel.AUTOMATE_TITLE_NOTIFY && el.type === _TextInput
92
+ );
93
+ await act(async () => {
94
+ title.props.onChange('1');
95
+ });
96
+
97
+ const message = instance.find(
98
+ (el) =>
99
+ el.props.accessibilityLabel ===
100
+ AccessibilityLabel.AUTOMATE_MESSAGE_NOTIFY && el.type === _TextInput
101
+ );
102
+ await act(async () => {
103
+ message.props.onChange('2');
104
+ });
105
+ const button = instance.findByType(BottomButtonView);
106
+ expect(button.props.typeMain).toEqual('primary');
107
+ await act(async () => {
108
+ button.props.onPressMain();
109
+ });
110
+ expect(spyToast).toBeCalled();
111
+ // expect(mockedNavigate).toHaveBeenCalledWith('closeScreen');
112
+ });
113
+ it('test can not update title and message', async () => {
114
+ await act(async () => {
115
+ tree = await renderer.create(wrapComponent());
116
+ });
117
+ const instance = tree.root;
118
+ const title = instance.find(
119
+ (el) =>
120
+ el.props.accessibilityLabel ===
121
+ AccessibilityLabel.AUTOMATE_TITLE_NOTIFY && el.type === _TextInput
122
+ );
123
+ await act(async () => {
124
+ title.props.onChange('title');
125
+ });
126
+
127
+ const message = instance.find(
128
+ (el) =>
129
+ el.props.accessibilityLabel ===
130
+ AccessibilityLabel.AUTOMATE_MESSAGE_NOTIFY && el.type === _TextInput
131
+ );
132
+ await act(async () => {
133
+ message.props.onChange('Contend');
134
+ });
135
+ const button = instance.findByType(BottomButtonView);
136
+ expect(button.props.typeMain).toEqual('disabled');
137
+ });
138
+ });
@@ -10,8 +10,12 @@ import api from '../../../../utils/Apis/axios';
10
10
  import MockAdapter from 'axios-mock-adapter';
11
11
  import API from '../../../../configs/API';
12
12
 
13
- import { ModalBottom } from '../../../../commons/Modal';
13
+ import { ModalBottom, ModalCustom } from '../../../../commons/Modal';
14
14
  import { useNavigation, useRoute } from '@react-navigation/native';
15
+ import { HeaderCustom } from '../../../../commons';
16
+ import Routes from '../../../../utils/Route';
17
+ import UpdateNotifyScript from '../UpdateNotifyScript';
18
+ import UpdateDelayScript from '../UpdateDelayScript';
15
19
 
16
20
  const wrapComponent = () => (
17
21
  <SCProvider initState={mockSCStore({})}>
@@ -25,109 +29,176 @@ jest.mock('react-native-parsed-text', () => () => []);
25
29
  describe('EditActionsList', () => {
26
30
  let tree;
27
31
  const mockedNavigate = useNavigation().navigate;
32
+ let actionsList = [
33
+ {
34
+ id: 1,
35
+ action_script: {
36
+ id: 1,
37
+ sensor_name: 'abc',
38
+ station_name: 'abc',
39
+ end_device_id: 1,
40
+ },
41
+ notify_script: null,
42
+ delay_script: null,
43
+ order: 1,
44
+ },
45
+ {
46
+ id: 2,
47
+ action_script: null,
48
+ notify_script: { title: 'title', message: 'Contend' },
49
+ delay_script: null,
50
+ order: 2,
51
+ },
52
+ {
53
+ id: 3,
54
+ action_script: null,
55
+ notify_script: null,
56
+ delay_script: { delay: 10 },
57
+ order: 3,
58
+ },
59
+ ];
28
60
 
29
61
  beforeEach(() => {
30
62
  useRoute.mockReturnValue({
31
63
  params: {
32
- data: [
33
- {
34
- id: 1,
35
- action_script: { id: 1, sensor_name: 'abc', station_name: 'abc' },
36
- notify_script: null,
37
- delay_script: null,
38
- },
39
- {
40
- id: 2,
41
- action_script: null,
42
- notify_script: { title: 'title' },
43
- delay_script: null,
44
- },
45
- {
46
- id: 3,
47
- action_script: null,
48
- notify_script: null,
49
- delay_script: { delay: 10 },
50
- },
51
- ],
64
+ data: actionsList,
52
65
  id: 1,
53
66
  unit: { id: 1, name: 'unit' },
54
67
  },
55
68
  });
56
69
  mockedNavigate.mockClear();
57
70
  });
58
- it('render EditActionsList', async () => {
71
+
72
+ it('EditActionsList reorder actions', async () => {
73
+ mock.onPut(API.AUTOMATE.ORDER_SCRIPT_ITEMS(1)).reply(200);
59
74
  await act(async () => {
60
75
  tree = await create(wrapComponent());
61
76
  });
62
77
  const instance = tree.root;
63
78
  const draggableFlatList = instance.findAllByType(DraggableFlatList);
64
- const modalBottom = instance.findAllByType(ModalBottom);
65
- expect(draggableFlatList).toHaveLength(1);
66
- expect(modalBottom).toHaveLength(1);
79
+ expect(draggableFlatList.length).toBe(1);
80
+ await act(async () => {
81
+ draggableFlatList[0].props.onDragEnd({
82
+ data: actionsList,
83
+ from: 0,
84
+ to: 0,
85
+ });
86
+ });
87
+ expect(mock.history.put).toHaveLength(0);
88
+ await act(async () => {
89
+ draggableFlatList[0].props.onDragEnd({
90
+ data: actionsList,
91
+ from: 0,
92
+ to: 1,
93
+ });
94
+ });
95
+ expect(mock.history.put).toHaveLength(1);
96
+ const headerCustom = instance.findAllByType(HeaderCustom);
97
+ await act(async () => {
98
+ headerCustom[0].props.onGoBack();
99
+ });
100
+ expect(mockedNavigate).toHaveBeenCalled();
67
101
  });
68
- it('EditActionsList onPress cancel', async () => {
102
+
103
+ it('EditActionsList onPress remove action', async () => {
104
+ mock.onDelete(API.AUTOMATE.DELETE_SCRIPT_ITEM(1, 3)).reply(200);
69
105
  await act(async () => {
70
106
  tree = await create(wrapComponent());
71
107
  });
72
108
  const instance = tree.root;
73
- const buttonCancel = instance.find(
109
+ const buttonRemoves = instance.findAll(
74
110
  (el) =>
75
111
  el.props.accessibilityLabel ===
76
- AccessibilityLabel.BUTTON_CANCEL_EDIT_ACTION_LIST &&
112
+ AccessibilityLabel.BUTTON_REMOVE_EDIT_ACTION_LIST &&
77
113
  el.type === TouchableOpacity
78
114
  );
79
- expect(buttonCancel).toBeDefined();
115
+ expect(buttonRemoves).toHaveLength(3);
80
116
  await act(async () => {
81
- buttonCancel.props.onPress();
117
+ buttonRemoves[0].props.onPress(); // remove script action
118
+ buttonRemoves[1].props.onPress(); // remove script notify
119
+ buttonRemoves[2].props.onPress(); // remove script delay
82
120
  });
83
- expect(mockedNavigate).toHaveBeenCalled();
121
+ const modalBottom = instance.findByType(ModalBottom);
122
+ expect(modalBottom.props.isVisible).toBeTruthy();
123
+ await act(async () => {
124
+ modalBottom.props.onClose();
125
+ });
126
+ await act(async () => {
127
+ modalBottom.props.onRemove();
128
+ });
129
+ expect(mock.history.delete).toHaveLength(1);
84
130
  });
85
- it('EditActionsList onPress save', async () => {
86
- mock.onPut(API.AUTOMATE.ORDER_SCRIPT_ITEMS(1)).reply(200);
131
+
132
+ it('EditActionsList update script action', async () => {
87
133
  await act(async () => {
88
134
  tree = await create(wrapComponent());
89
135
  });
90
136
  const instance = tree.root;
91
- const buttonSave = instance.find(
137
+ const scriptItem = instance.findAll(
92
138
  (el) =>
93
- el.props.accessibilityLabel ===
94
- AccessibilityLabel.BUTTON_SAVE_EDIT_ACTION_LIST &&
139
+ el.props.accessibilityLabel === AccessibilityLabel.BUTTON_UPDATE &&
95
140
  el.type === TouchableOpacity
96
141
  );
97
- expect(buttonSave).toBeDefined();
98
-
142
+ expect(scriptItem).toHaveLength(3);
99
143
  await act(async () => {
100
- buttonSave.props.onPress();
144
+ scriptItem[0].props.onLongPress();
101
145
  });
102
146
 
103
- expect(mock.history.put).toHaveLength(1);
147
+ const modalCustom = instance.findAll(
148
+ (el) =>
149
+ el.props.accessibilityLabel === AccessibilityLabel.MODAL_CUSTOM &&
150
+ el.type === ModalCustom
151
+ );
152
+ await act(async () => {
153
+ modalCustom[0].props.onBackButtonPress();
154
+ });
155
+ expect(mockedNavigate).toHaveBeenCalledWith(Routes.UpdateActionScript, {
156
+ automateId: 1,
157
+ closeScreen: Routes.EditActionsList,
158
+ device: {
159
+ id: 1,
160
+ },
161
+ numberActionAdded: 3,
162
+ scriptItemId: 1,
163
+ unitId: undefined,
164
+ });
104
165
  });
105
166
 
106
- it('EditActionsList has remove button', async () => {
167
+ it('EditActionsList update script notify', async () => {
107
168
  await act(async () => {
108
169
  tree = await create(wrapComponent());
109
170
  });
110
171
  const instance = tree.root;
111
- const buttonRemoves = instance.findAll(
172
+ const scriptItem = instance.findAll(
112
173
  (el) =>
113
- el.props.accessibilityLabel ===
114
- AccessibilityLabel.BUTTON_REMOVE_EDIT_ACTION_LIST &&
174
+ el.props.accessibilityLabel === AccessibilityLabel.BUTTON_UPDATE &&
115
175
  el.type === TouchableOpacity
116
176
  );
117
- expect(buttonRemoves).toHaveLength(3);
177
+ expect(scriptItem).toHaveLength(3);
178
+ await act(async () => {
179
+ scriptItem[1].props.onLongPress();
180
+ });
181
+
182
+ const popUp = instance.findAllByType(UpdateNotifyScript);
183
+ expect(popUp).toHaveLength(1);
118
184
  });
119
185
 
120
- it('EditActionsList modal onPress remove', async () => {
186
+ it('EditActionsList update script delay', async () => {
121
187
  await act(async () => {
122
188
  tree = await create(wrapComponent());
123
189
  });
124
190
  const instance = tree.root;
125
- const modalBottom = instance.findAllByType(ModalBottom);
191
+ const scriptItem = instance.findAll(
192
+ (el) =>
193
+ el.props.accessibilityLabel === AccessibilityLabel.BUTTON_UPDATE &&
194
+ el.type === TouchableOpacity
195
+ );
196
+ expect(scriptItem).toHaveLength(3);
126
197
  await act(async () => {
127
- modalBottom[0].props.onRemove();
198
+ scriptItem[2].props.onLongPress();
128
199
  });
129
200
 
130
- mock.onDelete(API.AUTOMATE.DELETE_SCRIPT_ACTION(1, 1)).reply(200);
131
- expect(mock.history.delete).toHaveLength(1);
201
+ const popUp = instance.findAllByType(UpdateDelayScript);
202
+ expect(popUp).toHaveLength(1);
132
203
  });
133
204
  });