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
20 #include "core/components_ng/manager/drag_drop/drag_drop_func_wrapper.h"
21 #include "core/components_ng/manager/drag_drop/drag_drop_initiating/drag_drop_initiating_handler.h"
22 #include "core/components_ng/manager/drag_drop/drag_drop_initiating/drag_drop_initiating_state_press.h"
23 #include "core/event/touch_event.h"
24 #include "core/gestures/drag_event.h"
25
26 using namespace testing;
27 using namespace testing::ext;
28
29 namespace OHOS::Ace::NG {
30 struct DragDropInitiatingStatePressTestCase : public DragDropInitiatingStateTestCase {
31 bool isMenuShow = false;
32 bool isGatherWithNode = false;
33 bool hasGatherNode = false;
34 bool isDragNodeNeedClean = false;
35 PreDragStatus preDragStatus = PreDragStatus::ACTION_DETECTING_STATUS;
36 SourceType sourceType = SourceType::TOUCH;
DragDropInitiatingStatePressTestCaseOHOS::Ace::NG::DragDropInitiatingStatePressTestCase37 DragDropInitiatingStatePressTestCase(DragDropInitiatingReceivedInput receivedInput,
38 DragDropInitiatingStatus expectStatus, bool isMenuShow, bool isGatherWithNode, bool hasGatherNode,
39 bool isDragNodeNeedClean, PreDragStatus preDragStatus, SourceType sourceType)
40 : DragDropInitiatingStateTestCase(DragDropInitiatingStatus::PRESS, receivedInput, expectStatus),
41 isMenuShow(isMenuShow), isGatherWithNode(isGatherWithNode), hasGatherNode(hasGatherNode),
42 isDragNodeNeedClean(isDragNodeNeedClean), preDragStatus(preDragStatus), sourceType(sourceType)
43 {}
44 };
45
46 const std::vector<DragDropInitiatingStatePressTestCase> DRAG_DROP_INITIATING_STATE_PRESS_IMAGE_TEST_CASES = {
47 DragDropInitiatingStatePressTestCase(DragDropInitiatingReceivedInput::HandleHitTesting,
48 DragDropInitiatingStatus::PRESS, false, false, false, false, PreDragStatus::ACTION_DETECTING_STATUS,
49 SourceType::TOUCH),
50 DragDropInitiatingStatePressTestCase(DragDropInitiatingReceivedInput::HandleHitTesting,
51 DragDropInitiatingStatus::PRESS, false, false, false, false, PreDragStatus::ACTION_DETECTING_STATUS,
52 SourceType::TOUCH),
53 DragDropInitiatingStatePressTestCase(DragDropInitiatingReceivedInput::HandleHitTesting,
54 DragDropInitiatingStatus::PRESS, false, false, false, false, PreDragStatus::ACTION_DETECTING_STATUS,
55 SourceType::MOUSE),
56
57 DragDropInitiatingStatePressTestCase(DragDropInitiatingReceivedInput::HandlePreviewLongPressOnAction,
58 DragDropInitiatingStatus::LIFTING, true, true, false, true, PreDragStatus::ACTION_DETECTING_STATUS,
59 SourceType::TOUCH),
60
61 DragDropInitiatingStatePressTestCase(DragDropInitiatingReceivedInput::HandleSequenceOnActionCancel,
62 DragDropInitiatingStatus::IDLE, false, true, false, true, PreDragStatus::ACTION_DETECTING_STATUS,
63 SourceType::TOUCH),
64 DragDropInitiatingStatePressTestCase(DragDropInitiatingReceivedInput::HandleSequenceOnActionCancel,
65 DragDropInitiatingStatus::PRESS, true, true, false, true, PreDragStatus::ACTION_DETECTING_STATUS,
66 SourceType::TOUCH),
67
68 DragDropInitiatingStatePressTestCase(DragDropInitiatingReceivedInput::HandlePanOnActionStart,
69 DragDropInitiatingStatus::PRESS, false, false, false, false, PreDragStatus::ACTION_DETECTING_STATUS,
70 SourceType::TOUCH),
71 DragDropInitiatingStatePressTestCase(DragDropInitiatingReceivedInput::HandlePanOnActionStart,
72 DragDropInitiatingStatus::PRESS, false, false, false, true, PreDragStatus::ACTION_DETECTING_STATUS,
73 SourceType::TOUCH),
74 DragDropInitiatingStatePressTestCase(DragDropInitiatingReceivedInput::HandlePanOnActionStart,
75 DragDropInitiatingStatus::PRESS, false, false, false, false, PreDragStatus::ACTION_DETECTING_STATUS,
76 SourceType::MOUSE),
77 DragDropInitiatingStatePressTestCase(DragDropInitiatingReceivedInput::HandlePanOnActionStart,
78 DragDropInitiatingStatus::PRESS, false, false, false, true, PreDragStatus::ACTION_DETECTING_STATUS,
79 SourceType::MOUSE),
80
81 DragDropInitiatingStatePressTestCase(DragDropInitiatingReceivedInput::HandlePanOnReject,
82 DragDropInitiatingStatus::PRESS, false, false, false, false, PreDragStatus::ACTION_DETECTING_STATUS,
83 SourceType::TOUCH),
84 DragDropInitiatingStatePressTestCase(DragDropInitiatingReceivedInput::HandlePanOnReject,
85 DragDropInitiatingStatus::PRESS, false, false, true, false, PreDragStatus::ACTION_DETECTING_STATUS,
86 SourceType::TOUCH),
87 DragDropInitiatingStatePressTestCase(DragDropInitiatingReceivedInput::HandlePanOnReject,
88 DragDropInitiatingStatus::PRESS, false, true, false, false, PreDragStatus::ACTION_DETECTING_STATUS,
89 SourceType::TOUCH),
90 DragDropInitiatingStatePressTestCase(DragDropInitiatingReceivedInput::HandlePanOnReject,
91 DragDropInitiatingStatus::PRESS, false, true, true, false, PreDragStatus::ACTION_DETECTING_STATUS,
92 SourceType::TOUCH),
93 DragDropInitiatingStatePressTestCase(DragDropInitiatingReceivedInput::HandlePanOnReject,
94 DragDropInitiatingStatus::PRESS, false, false, true, false, PreDragStatus::READY_TO_TRIGGER_DRAG_ACTION,
95 SourceType::TOUCH),
96
97 DragDropInitiatingStatePressTestCase(DragDropInitiatingReceivedInput::HandleTouchEvent,
98 DragDropInitiatingStatus::PRESS, false, false, true, false, PreDragStatus::ACTION_DETECTING_STATUS,
99 SourceType::TOUCH),
100
101 DragDropInitiatingStatePressTestCase(DragDropInitiatingReceivedInput::HandlePanOnActionEnd,
102 DragDropInitiatingStatus::IDLE, true, false, false, false, PreDragStatus::ACTION_DETECTING_STATUS,
103 SourceType::TOUCH),
104 DragDropInitiatingStatePressTestCase(DragDropInitiatingReceivedInput::HandlePanOnActionEnd,
105 DragDropInitiatingStatus::IDLE, true, false, false, false, PreDragStatus::ACTION_DETECTING_STATUS,
106 SourceType::TOUCH),
107 DragDropInitiatingStatePressTestCase(DragDropInitiatingReceivedInput::HandlePullEvent,
108 DragDropInitiatingStatus::PRESS, true, true, false, true, PreDragStatus::ACTION_DETECTING_STATUS,
109 SourceType::TOUCH),
110 DragDropInitiatingStatePressTestCase(DragDropInitiatingReceivedInput::HandleReStartDrag,
111 DragDropInitiatingStatus::PRESS, true, true, false, true, PreDragStatus::ACTION_DETECTING_STATUS,
112 SourceType::TOUCH),
113 DragDropInitiatingStatePressTestCase(DragDropInitiatingReceivedInput::HandleDragStart,
114 DragDropInitiatingStatus::MOVING, true, true, false, true, PreDragStatus::ACTION_DETECTING_STATUS,
115 SourceType::TOUCH),
116 DragDropInitiatingStatePressTestCase(DragDropInitiatingReceivedInput::HandleDragEnd, DragDropInitiatingStatus::IDLE,
117 true, true, false, true, PreDragStatus::ACTION_DETECTING_STATUS, SourceType::TOUCH),
118 DragDropInitiatingStatePressTestCase(DragDropInitiatingReceivedInput::TransDragWindowToFwk,
119 DragDropInitiatingStatus::IDLE, true, true, false, true, PreDragStatus::ACTION_DETECTING_STATUS,
120 SourceType::TOUCH),
121 DragDropInitiatingStatePressTestCase(DragDropInitiatingReceivedInput::TransMenuShow,
122 DragDropInitiatingStatus::LIFTING, true, true, false, true, PreDragStatus::ACTION_DETECTING_STATUS,
123 SourceType::TOUCH),
124 DragDropInitiatingStatePressTestCase(DragDropInitiatingReceivedInput::TransMenuShow, DragDropInitiatingStatus::IDLE,
125 false, true, false, true, PreDragStatus::ACTION_DETECTING_STATUS, SourceType::TOUCH),
126 };
127
SetUpTestCase()128 void DragDropInitiatingStatePressTestNG::SetUpTestCase()
129 {
130 MockPipelineContext::SetUp();
131 MockContainer::SetUp();
132 }
133
TearDownTestCase()134 void DragDropInitiatingStatePressTestNG::TearDownTestCase()
135 {
136 MockPipelineContext::TearDown();
137 MockContainer::TearDown();
138 }
139
140 /**
141 * @tc.name: DragDropInitiatingStatePressTestNG001
142 * @tc.desc: Test CollectTouchTarget function when frameNode is image.
143 * @tc.type: FUNC
144 */
145 HWTEST_F(DragDropInitiatingStatePressTestNG, DragDropInitiatingStatePressTestNG001, TestSize.Level1)
146 {
147 int32_t caseNum = 0;
148 auto pipelineContext = MockPipelineContext::GetCurrentContext();
149 ASSERT_NE(pipelineContext, nullptr);
150 auto dragDropManager = pipelineContext->GetDragDropManager();
151 ASSERT_NE(dragDropManager, nullptr);
152 auto overlayManager = pipelineContext->GetOverlayManager();
153 ASSERT_NE(overlayManager, nullptr);
154 for (const auto& testCase : DRAG_DROP_INITIATING_STATE_PRESS_IMAGE_TEST_CASES) {
155 /**
156 * @tc.steps: step1. create DragDropEventActuator.
157 */
158 auto eventHub = AceType::MakeRefPtr<EventHub>();
159 ASSERT_NE(eventHub, nullptr);
160 auto gestureEventHub = AceType::MakeRefPtr<GestureEventHub>(AceType::WeakClaim(AceType::RawPtr(eventHub)));
161 ASSERT_NE(gestureEventHub, nullptr);
162 auto frameNode = FrameNode::GetOrCreateFrameNode(V2::IMAGE_ETS_TAG,
__anon1d53423b0102() 163 ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<ImagePattern>(); });
164 ASSERT_NE(frameNode, nullptr);
165 eventHub->host_ = AceType::WeakClaim(AceType::RawPtr(frameNode));
166 auto dragDropEventActuator =
167 AceType::MakeRefPtr<DragDropEventActuator>(AceType::WeakClaim(AceType::RawPtr(gestureEventHub)));
168 ASSERT_NE(dragDropEventActuator, nullptr);
169 auto handler = dragDropEventActuator->dragDropInitiatingHandler_;
170 ASSERT_NE(handler, nullptr);
171 auto machine = handler->initiatingFlow_;
172 ASSERT_NE(machine, nullptr);
173 machine->InitializeState();
174 machine->currentState_ = static_cast<int32_t>(testCase.originStatus);
175 overlayManager->SetIsGatherWithMenu(testCase.isGatherWithNode);
176 machine->dragDropInitiatingParams_.hasGatherNode = testCase.hasGatherNode;
177 dragDropManager->isDragNodeNeedClean_ = testCase.isDragNodeNeedClean;
178 DragDropGlobalController::GetInstance().UpdateMenuShowingStatus(testCase.isMenuShow);
179 DragDropGlobalController::GetInstance().SetPreDragStatus(testCase.preDragStatus);
180 if (((static_cast<int32_t>(testCase.receivedInput)) & DRAG_ACTION_NONE_ARGS) != 0) {
181 DragDropInitiatingStateTestNG::DoMachineAction(machine, testCase.receivedInput);
182 } else if (((static_cast<int32_t>(testCase.receivedInput)) & DRAG_ACTION_DRAG_POINTER_EVENT_ARGS) != 0) {
183 DragPointerEvent dragPointerEvent;
184 DragDropInitiatingStateTestNG::DoMachineAction(machine, testCase.receivedInput, dragPointerEvent);
185 } else if (((static_cast<int32_t>(testCase.receivedInput)) & DRAG_ACTION_TOUCH_EVENT_ARGS) != 0) {
186 TouchEvent touchEvent;
187 touchEvent.type = TouchType::MOVE;
188 touchEvent.sourceType = testCase.sourceType;
189 DragDropInitiatingStateTestNG::DoMachineAction(machine, testCase.receivedInput, touchEvent);
190 } else if (((static_cast<int32_t>(testCase.receivedInput)) & DRAG_ACTION_GESTURE_EVENT_ARGS) != 0) {
191 GestureEvent info;
192 info.SetSourceDevice(testCase.sourceType);
193 DragDropInitiatingStateTestNG::DoMachineAction(machine, testCase.receivedInput, info);
194 }
195 EXPECT_TRUE(DragDropInitiatingStateTestNG::CheckDragDropInitiatingStatus(
196 caseNum, static_cast<DragDropInitiatingStatus>(machine->currentState_), testCase.expectStatus));
197 caseNum++;
198 }
199 }
200
201 /**
202 * @tc.name: DragDropInitiatingStatePressTestNG002
203 * @tc.desc: Test GetThumbnailPixelMap is called when isThumbnailCallbackTriggered is false and text is not draggable.
204 * @tc.type: FUNC
205 */
206 HWTEST_F(DragDropInitiatingStatePressTestNG, DragDropInitiatingStatePressTestNG002, TestSize.Level1)
207 {
208 /**
209 * @tc.steps: step1. Get the current pipeline context and dragDropManager.
210 * @tc.expected: Both should be non-null.
211 */
212 auto pipelineContext = MockPipelineContext::GetCurrentContext();
213 ASSERT_NE(pipelineContext, nullptr);
214 auto dragDropManager = pipelineContext->GetDragDropManager();
215 ASSERT_NE(dragDropManager, nullptr);
216
217 /**
218 * @tc.steps: step2. Create a FrameNode of type IMAGE with a GestureEventHub, set text draggable to false.
219 */
220 auto frameNode = FrameNode::GetOrCreateFrameNode(V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
__anon1d53423b0202() 221 []() { return AceType::MakeRefPtr<ImagePattern>(); });
222 ASSERT_NE(frameNode, nullptr);
223 auto gestureHub = frameNode->GetOrCreateGestureEventHub();
224 ASSERT_NE(gestureHub, nullptr);
225 gestureHub->SetTextDraggable(false);
226
227 /**
228 * @tc.steps: step3. Assign a pixel map as preview to frameNode.
229 */
230 auto pixelMap = AceType::MakeRefPtr<MockPixelMap>();
231 DragDropInfo previewInfo;
232 previewInfo.pixelMap = pixelMap;
233 frameNode->SetDragPreview(previewInfo);
234
235 /**
236 * @tc.steps: step4. Call GetThumbnailPixelMap with a callback and expect it to be triggered.
237 * @tc.expected: callbackTriggered is true.
238 */
239 bool callbackTriggered = false;
240 DragDropFuncWrapper::GetThumbnailPixelMap(
__anon1d53423b0302(const RefPtr<PixelMap>&, bool) 241 gestureHub, [&callbackTriggered](const RefPtr<PixelMap>&, bool) { callbackTriggered = true; }, true);
242
243 /**
244 * @tc.steps: step5. Initialize the DragDrop state machine and set isThumbnailCallbackTriggered to false.
245 */
246 auto handler = AceType::MakeRefPtr<DragDropInitiatingHandler>(frameNode);
247 ASSERT_NE(handler, nullptr);
248 auto machine = handler->initiatingFlow_;
249 machine->InitializeState();
250 machine->dragDropInitiatingParams_.frameNode = frameNode;
251 machine->dragDropInitiatingParams_.isThumbnailCallbackTriggered = false;
252
253 /**
254 * @tc.steps: step6. Create and initialize DragDropInitiatingStatePress, triggering state logic.
255 * @tc.expected: The callback for GetThumbnailPixelMap is called.
256 */
257 auto pressState =
258 AceType::MakeRefPtr<DragDropInitiatingStatePress>(WeakPtr<DragDropInitiatingStateMachine>(machine));
259 ASSERT_NE(pressState, nullptr);
260 pressState->Init(static_cast<int32_t>(DragDropInitiatingStatus::PRESS));
261 EXPECT_TRUE(callbackTriggered);
262 }
263 } // namespace OHOS::Ace::NG