1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "test/unittest/core/manager/drag_drop/drag_drop_initiating_test_ng.h"
17
18 #define private public
19 #define protected public
20
21 #include "test/mock/base/mock_task_executor.h"
22
23 #include "core/components_ng/manager/drag_drop/drag_drop_initiating/drag_drop_initiating_handler.h"
24 #include "core/components_ng/manager/drag_drop/drag_drop_initiating/drag_drop_initiating_state_ready.h"
25 #include "core/event/touch_event.h"
26 #include "core/gestures/drag_event.h"
27
28 using namespace testing;
29 using namespace testing::ext;
30
31 namespace OHOS::Ace::NG {
32 struct DragDropInitiatingStateReadyTestCase : public DragDropInitiatingStateTestCase {
33 bool isDragging = false;
34 bool isDragNodeNeedClean = false;
35 bool isGatherWithMenu = false;
36 bool isBindContextMenu = false;
37 int32_t dragPointerId = 0;
38 SourceType sourceType = SourceType::TOUCH;
DragDropInitiatingStateReadyTestCaseOHOS::Ace::NG::DragDropInitiatingStateReadyTestCase39 DragDropInitiatingStateReadyTestCase(DragDropInitiatingReceivedInput receivedInput,
40 DragDropInitiatingStatus expectStatus, bool isDragging, bool isDragNodeNeedClean, bool isGatherWithMenu,
41 bool isBindContextMenu, int32_t dragPointerId, SourceType sourceType)
42 : DragDropInitiatingStateTestCase(DragDropInitiatingStatus::READY, receivedInput, expectStatus),
43 isDragging(isDragging), isDragNodeNeedClean(isDragNodeNeedClean), isGatherWithMenu(isGatherWithMenu),
44 isBindContextMenu(isBindContextMenu), dragPointerId(dragPointerId), sourceType(sourceType)
45 {}
46 };
47
48 struct DragDropInitiatingStateReadyTouchTestCase : public DragDropInitiatingStateReadyTestCase {
49 TouchType touchType = TouchType::DOWN;
50 bool isMenuShow = false;
51 int32_t idleFingerId = -1;
DragDropInitiatingStateReadyTouchTestCaseOHOS::Ace::NG::DragDropInitiatingStateReadyTouchTestCase52 DragDropInitiatingStateReadyTouchTestCase(DragDropInitiatingReceivedInput receivedInput,
53 DragDropInitiatingStatus expectStatus, SourceType sourceType, TouchType touchType, bool isMenuShow,
54 int32_t idleFingerId)
55 : DragDropInitiatingStateReadyTestCase(receivedInput, expectStatus, false, true, false, false, 0, sourceType),
56 touchType(touchType), isMenuShow(isMenuShow), idleFingerId(idleFingerId)
57 {}
58 };
59
60 const std::vector<DragDropInitiatingStateReadyTestCase> DRAG_DROP_INITIATING_STATE_READY_IMAGE_TEST_CASES = {
61 DragDropInitiatingStateReadyTestCase(DragDropInitiatingReceivedInput::HandleLongPressOnAction,
62 DragDropInitiatingStatus::PRESS, false, false, false, false, 0, SourceType::TOUCH),
63 DragDropInitiatingStateReadyTestCase(DragDropInitiatingReceivedInput::HandleLongPressOnAction,
64 DragDropInitiatingStatus::PRESS, false, false, false, true, 0, SourceType::TOUCH),
65
66 DragDropInitiatingStateReadyTestCase(DragDropInitiatingReceivedInput::HandlePanOnActionStart,
67 DragDropInitiatingStatus::READY, false, false, false, false, 0, SourceType::TOUCH),
68 DragDropInitiatingStateReadyTestCase(DragDropInitiatingReceivedInput::HandlePanOnActionStart,
69 DragDropInitiatingStatus::READY, true, false, false, false, 0, SourceType::TOUCH),
70 DragDropInitiatingStateReadyTestCase(DragDropInitiatingReceivedInput::HandlePanOnActionStart,
71 DragDropInitiatingStatus::READY, false, false, false, false, 0, SourceType::MOUSE),
72 DragDropInitiatingStateReadyTestCase(DragDropInitiatingReceivedInput::HandlePanOnActionStart,
73 DragDropInitiatingStatus::READY, true, false, false, false, 0, SourceType::MOUSE),
74
75 DragDropInitiatingStateReadyTestCase(DragDropInitiatingReceivedInput::HandlePanOnReject,
76 DragDropInitiatingStatus::READY, false, false, false, false, 0, SourceType::TOUCH),
77 DragDropInitiatingStateReadyTestCase(DragDropInitiatingReceivedInput::HandlePanOnReject,
78 DragDropInitiatingStatus::READY, false, false, true, false, 0, SourceType::TOUCH),
79 DragDropInitiatingStateReadyTestCase(DragDropInitiatingReceivedInput::HandlePanOnReject,
80 DragDropInitiatingStatus::READY, false, false, false, false, 0, SourceType::MOUSE),
81 DragDropInitiatingStateReadyTestCase(DragDropInitiatingReceivedInput::HandlePanOnReject,
82 DragDropInitiatingStatus::READY, false, false, true, false, 0, SourceType::MOUSE),
83
84 DragDropInitiatingStateReadyTestCase(DragDropInitiatingReceivedInput::HandleSequenceOnActionCancel,
85 DragDropInitiatingStatus::IDLE, true, true, false, false, 0, SourceType::TOUCH),
86 DragDropInitiatingStateReadyTestCase(DragDropInitiatingReceivedInput::HandleSequenceOnActionCancel,
87 DragDropInitiatingStatus::IDLE, true, true, false, false, 0, SourceType::MOUSE),
88
89 DragDropInitiatingStateReadyTestCase(DragDropInitiatingReceivedInput::HandleTouchEvent,
90 DragDropInitiatingStatus::READY, true, true, false, false, 0, SourceType::TOUCH),
91
92 DragDropInitiatingStateReadyTestCase(DragDropInitiatingReceivedInput::HandlePanOnActionEnd,
93 DragDropInitiatingStatus::IDLE, true, false, false, false, 0, SourceType::TOUCH),
94 DragDropInitiatingStateReadyTestCase(DragDropInitiatingReceivedInput::HandlePanOnActionEnd,
95 DragDropInitiatingStatus::IDLE, false, false, false, false, 0, SourceType::TOUCH),
96 DragDropInitiatingStateReadyTestCase(DragDropInitiatingReceivedInput::HandlePanOnActionEnd,
97 DragDropInitiatingStatus::IDLE, true, false, false, false, 0, SourceType::MOUSE),
98 DragDropInitiatingStateReadyTestCase(DragDropInitiatingReceivedInput::HandlePanOnActionEnd,
99 DragDropInitiatingStatus::IDLE, false, false, false, false, 0, SourceType::MOUSE),
100 DragDropInitiatingStateReadyTestCase(DragDropInitiatingReceivedInput::HandlePullEvent,
101 DragDropInitiatingStatus::READY, false, false, false, false, 0, SourceType::MOUSE),
102 DragDropInitiatingStateReadyTestCase(DragDropInitiatingReceivedInput::HandleReStartDrag,
103 DragDropInitiatingStatus::READY, false, false, false, false, 0, SourceType::MOUSE),
104 DragDropInitiatingStateReadyTestCase(DragDropInitiatingReceivedInput::HandleDragStart,
105 DragDropInitiatingStatus::MOVING, false, false, false, false, 0, SourceType::MOUSE),
106 DragDropInitiatingStateReadyTestCase(DragDropInitiatingReceivedInput::HandleDragEnd, DragDropInitiatingStatus::IDLE,
107 false, false, false, false, 0, SourceType::MOUSE),
108 DragDropInitiatingStateReadyTestCase(DragDropInitiatingReceivedInput::TransDragWindowToFwk,
109 DragDropInitiatingStatus::IDLE, false, false, false, false, 0, SourceType::MOUSE),
110 DragDropInitiatingStateReadyTestCase(DragDropInitiatingReceivedInput::TransMenuShow, DragDropInitiatingStatus::IDLE,
111 false, false, false, false, 0, SourceType::MOUSE),
112 };
113
114 const std::vector<DragDropInitiatingStateReadyTouchTestCase> DRAG_DROP_INITIATING_STATE_READY_TOUCH_TEST_CASES = {
115 DragDropInitiatingStateReadyTouchTestCase(DragDropInitiatingReceivedInput::HandleTouchEvent,
116 DragDropInitiatingStatus::READY, SourceType::TOUCH, TouchType::MOVE, false, -1),
117 DragDropInitiatingStateReadyTouchTestCase(DragDropInitiatingReceivedInput::HandleTouchEvent,
118 DragDropInitiatingStatus::READY, SourceType::TOUCH, TouchType::UP, false, -1),
119 DragDropInitiatingStateReadyTouchTestCase(DragDropInitiatingReceivedInput::HandleTouchEvent,
120 DragDropInitiatingStatus::READY, SourceType::TOUCH, TouchType::UP, true, 0),
121 DragDropInitiatingStateReadyTouchTestCase(DragDropInitiatingReceivedInput::HandleTouchEvent,
122 DragDropInitiatingStatus::IDLE, SourceType::TOUCH, TouchType::UP, false, 0),
123 };
124
SetUpTestCase()125 void DragDropInitiatingStateReadyTestNG::SetUpTestCase()
126 {
127 MockPipelineContext::SetUp();
128 MockContainer::SetUp();
129 }
130
TearDownTestCase()131 void DragDropInitiatingStateReadyTestNG::TearDownTestCase()
132 {
133 MockPipelineContext::TearDown();
134 MockContainer::TearDown();
135 }
136
137 /**
138 * @tc.name: DragDropInitiatingStateReadyTestNG001
139 * @tc.desc: Test DragDropInitiatingStateReady class when frameNode is image.
140 * @tc.type: FUNC
141 */
142 HWTEST_F(DragDropInitiatingStateReadyTestNG, DragDropInitiatingStateReadyTestNG001, TestSize.Level1)
143 {
144 auto pipelineContext = MockPipelineContext::GetCurrentContext();
145 ASSERT_NE(pipelineContext, nullptr);
146 auto dragDropManager = AceType::MakeRefPtr<DragDropManager>();
147 pipelineContext->dragDropManager_ = dragDropManager;
148 RefPtr<UINode> rootNode = AceType::MakeRefPtr<FrameNode>("root_node", -1, AceType::MakeRefPtr<Pattern>());
149 ASSERT_NE(rootNode, nullptr);
150 auto overlayManager = AceType::MakeRefPtr<OverlayManager>(AceType::DynamicCast<FrameNode>(rootNode));
151 pipelineContext->overlayManager_ = overlayManager;
152 int32_t caseNum = 0;
153 for (const auto& testCase : DRAG_DROP_INITIATING_STATE_READY_IMAGE_TEST_CASES) {
154 /**
155 * @tc.steps: step1. create DragDropEventActuator.
156 */
157 auto eventHub = AceType::MakeRefPtr<EventHub>();
158 ASSERT_NE(eventHub, nullptr);
159 auto gestureEventHub = AceType::MakeRefPtr<GestureEventHub>(AceType::WeakClaim(AceType::RawPtr(eventHub)));
160 ASSERT_NE(gestureEventHub, nullptr);
161 auto frameNode = FrameNode::GetOrCreateFrameNode(V2::IMAGE_ETS_TAG,
__anon7aad3b630102() 162 ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<ImagePattern>(); });
163 ASSERT_NE(frameNode, nullptr);
164 eventHub->host_ = AceType::WeakClaim(AceType::RawPtr(frameNode));
165 auto dragDropEventActuator =
166 AceType::MakeRefPtr<DragDropEventActuator>(AceType::WeakClaim(AceType::RawPtr(gestureEventHub)));
167 ASSERT_NE(dragDropEventActuator, nullptr);
168 auto handler = dragDropEventActuator->dragDropInitiatingHandler_;
169 ASSERT_NE(handler, nullptr);
170 auto machine = handler->initiatingFlow_;
171 ASSERT_NE(machine, nullptr);
172 machine->InitializeState();
173 dragDropManager->ResetDragging(testCase.isDragging ? DragDropMgrState::DRAGGING : DragDropMgrState::IDLE);
174 dragDropManager->SetIsDragNodeNeedClean(testCase.isDragNodeNeedClean);
175 overlayManager->SetIsGatherWithMenu(testCase.isGatherWithMenu);
176 if (testCase.isBindContextMenu) {
177 auto focusHub = frameNode->GetOrCreateFocusHub();
__anon7aad3b630202(const KeyEvent& event) 178 focusHub->SetOnKeyEventInternal([](const KeyEvent& event) { return true; }, OnKeyEventType::CONTEXT_MENU);
179 }
180 machine->currentState_ = static_cast<int32_t>(testCase.originStatus);
181 if (((static_cast<int32_t>(testCase.receivedInput)) & DRAG_ACTION_NONE_ARGS) != 0) {
182 DragDropInitiatingStateTestNG::DoMachineAction(machine, testCase.receivedInput);
183 } else if (((static_cast<int32_t>(testCase.receivedInput)) & DRAG_ACTION_DRAG_POINTER_EVENT_ARGS) != 0) {
184 DragPointerEvent dragPointerEvent;
185 dragPointerEvent.pointerId = testCase.dragPointerId;
186 DragDropInitiatingStateTestNG::DoMachineAction(machine, testCase.receivedInput, dragPointerEvent);
187 } else if (((static_cast<int32_t>(testCase.receivedInput)) & DRAG_ACTION_TOUCH_EVENT_ARGS) != 0) {
188 TouchEvent touchEvent;
189 touchEvent.id = testCase.dragPointerId;
190 touchEvent.type = TouchType::MOVE;
191 touchEvent.sourceType = testCase.sourceType;
192 DragDropInitiatingStateTestNG::DoMachineAction(machine, testCase.receivedInput, touchEvent);
193 } else if (((static_cast<int32_t>(testCase.receivedInput)) & DRAG_ACTION_GESTURE_EVENT_ARGS) != 0) {
194 GestureEvent info;
195 info.SetPointerId(testCase.dragPointerId);
196 info.SetSourceDevice(testCase.sourceType);
197 DragDropInitiatingStateTestNG::DoMachineAction(machine, testCase.receivedInput, info);
198 }
199 EXPECT_TRUE(DragDropInitiatingStateTestNG::CheckDragDropInitiatingStatus(
200 caseNum, static_cast<DragDropInitiatingStatus>(machine->currentState_), testCase.expectStatus));
201 caseNum++;
202 }
203 }
204
205 /**
206 * @tc.name: DragDropInitiatingStateReadyTestNG002
207 * @tc.desc: Test HandleTouchEvent.
208 * @tc.type: FUNC
209 */
210 HWTEST_F(DragDropInitiatingStateReadyTestNG, DragDropInitiatingStateReadyTestNG002, TestSize.Level1)
211 {
212 auto pipelineContext = MockPipelineContext::GetCurrentContext();
213 ASSERT_NE(pipelineContext, nullptr);
214 auto mockTaskExecutor = AceType::MakeRefPtr<MockTaskExecutor>();
215 pipelineContext->taskExecutor_ = mockTaskExecutor;
216 auto dragDropManager = AceType::MakeRefPtr<DragDropManager>();
217 pipelineContext->dragDropManager_ = dragDropManager;
218 RefPtr<UINode> rootNode = AceType::MakeRefPtr<FrameNode>("root_node", -1, AceType::MakeRefPtr<Pattern>());
219 ASSERT_NE(rootNode, nullptr);
220 auto overlayManager = AceType::MakeRefPtr<OverlayManager>(AceType::DynamicCast<FrameNode>(rootNode));
221 pipelineContext->overlayManager_ = overlayManager;
222 int32_t caseNum = 0;
223 for (const auto& testCase : DRAG_DROP_INITIATING_STATE_READY_TOUCH_TEST_CASES) {
224 /**
225 * @tc.steps: step1. create DragDropEventActuator.
226 */
227 auto eventHub = AceType::MakeRefPtr<EventHub>();
228 ASSERT_NE(eventHub, nullptr);
229 auto gestureEventHub = AceType::MakeRefPtr<GestureEventHub>(AceType::WeakClaim(AceType::RawPtr(eventHub)));
230 ASSERT_NE(gestureEventHub, nullptr);
231 auto frameNode = FrameNode::GetOrCreateFrameNode(V2::IMAGE_ETS_TAG,
__anon7aad3b630302() 232 ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<ImagePattern>(); });
233 ASSERT_NE(frameNode, nullptr);
234 eventHub->host_ = AceType::WeakClaim(AceType::RawPtr(frameNode));
235 auto dragDropEventActuator =
236 AceType::MakeRefPtr<DragDropEventActuator>(AceType::WeakClaim(AceType::RawPtr(gestureEventHub)));
237 ASSERT_NE(dragDropEventActuator, nullptr);
238 auto handler = dragDropEventActuator->dragDropInitiatingHandler_;
239 ASSERT_NE(handler, nullptr);
240 auto machine = handler->initiatingFlow_;
241 ASSERT_NE(machine, nullptr);
242 machine->InitializeState();
243 DragDropGlobalController::GetInstance().UpdateMenuShowingStatus(testCase.isMenuShow);
244 auto& params = machine->GetDragDropInitiatingParams();
245 params.idleFingerId = testCase.idleFingerId;
246 dragDropManager->ResetDragging(testCase.isDragging ? DragDropMgrState::DRAGGING : DragDropMgrState::IDLE);
247 dragDropManager->SetIsDragNodeNeedClean(testCase.isDragNodeNeedClean);
248 overlayManager->SetIsGatherWithMenu(testCase.isGatherWithMenu);
249 if (testCase.isBindContextMenu) {
250 auto focusHub = frameNode->GetOrCreateFocusHub();
__anon7aad3b630402(const KeyEvent& event) 251 focusHub->SetOnKeyEventInternal([](const KeyEvent& event) { return true; }, OnKeyEventType::CONTEXT_MENU);
252 }
253 machine->currentState_ = static_cast<int32_t>(testCase.originStatus);
254 if (((static_cast<int32_t>(testCase.receivedInput)) & DRAG_ACTION_TOUCH_EVENT_ARGS) != 0) {
255 TouchEvent touchEvent;
256 touchEvent.id = testCase.dragPointerId;
257 touchEvent.type = testCase.touchType;
258 touchEvent.sourceType = testCase.sourceType;
259 DragDropInitiatingStateTestNG::DoMachineAction(machine, testCase.receivedInput, touchEvent);
260 }
261 EXPECT_TRUE(DragDropInitiatingStateTestNG::CheckDragDropInitiatingStatus(
262 caseNum, static_cast<DragDropInitiatingStatus>(machine->currentState_), testCase.expectStatus));
263 caseNum++;
264 }
265 }
266
267 /**
268 * @tc.name: DragDropInitiatingStateReadyTestNG003
269 * @tc.desc: Test HandlePanOnActionCancel.
270 * @tc.type: FUNC
271 */
272 HWTEST_F(DragDropInitiatingStateReadyTestNG, DragDropInitiatingStateReadyTestNG003, TestSize.Level1)
273 {
274 auto pipelineContext = MockPipelineContext::GetCurrentContext();
275 ASSERT_NE(pipelineContext, nullptr);
276 auto dragDropManager = AceType::MakeRefPtr<DragDropManager>();
277 pipelineContext->dragDropManager_ = dragDropManager;
278 RefPtr<UINode> rootNode = AceType::MakeRefPtr<FrameNode>("root_node", -1, AceType::MakeRefPtr<Pattern>());
279 ASSERT_NE(rootNode, nullptr);
280 auto overlayManager = AceType::MakeRefPtr<OverlayManager>(AceType::DynamicCast<FrameNode>(rootNode));
281 pipelineContext->overlayManager_ = overlayManager;
282 /**
283 * @tc.steps: step1. create DragDropEventActuator.
284 */
285 auto eventHub = AceType::MakeRefPtr<EventHub>();
286 ASSERT_NE(eventHub, nullptr);
287 auto gestureEventHub = AceType::MakeRefPtr<GestureEventHub>(AceType::WeakClaim(AceType::RawPtr(eventHub)));
288 ASSERT_NE(gestureEventHub, nullptr);
289 auto frameNode = FrameNode::GetOrCreateFrameNode(V2::IMAGE_ETS_TAG,
__anon7aad3b630502() 290 ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<ImagePattern>(); });
291 ASSERT_NE(frameNode, nullptr);
292 eventHub->host_ = AceType::WeakClaim(AceType::RawPtr(frameNode));
293 auto dragDropEventActuator =
294 AceType::MakeRefPtr<DragDropEventActuator>(AceType::WeakClaim(AceType::RawPtr(gestureEventHub)));
295 ASSERT_NE(dragDropEventActuator, nullptr);
296 auto handler = dragDropEventActuator->dragDropInitiatingHandler_;
297 ASSERT_NE(handler, nullptr);
298 auto machine = handler->initiatingFlow_;
299 ASSERT_NE(machine, nullptr);
300 machine->InitializeState();
301 GestureEvent info;
302 dragDropManager->ResetDragging(DragDropMgrState::IDLE);
303 machine->currentState_ = static_cast<int32_t>(DragDropInitiatingStatus::READY);
304 machine->HandlePanOnActionCancel(info);
305 EXPECT_EQ(machine->currentState_, static_cast<int32_t>(DragDropMgrState::IDLE));
306
307 dragDropManager->ResetDragging(DragDropMgrState::ABOUT_TO_PREVIEW);
308 machine->currentState_ = static_cast<int32_t>(DragDropInitiatingStatus::READY);
309 machine->HandlePanOnActionCancel(info);
310 EXPECT_EQ(machine->currentState_, static_cast<int32_t>(DragDropMgrState::IDLE));
311 }
312 } // namespace OHOS::Ace::NG