1 /*
2  * Copyright (c) 2022-2023 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 <cstddef>
17 #include <cstdint>
18 #include <unistd.h>
19 
20 #include "gtest/gtest.h"
21 
22 #define private public
23 #define protected public
24 
25 #include "core/components_ng/base/frame_node.h"
26 #include "core/components_ng/event/click_event.h"
27 #include "core/components_ng/event/event_hub.h"
28 #include "core/components_ng/pattern/pattern.h"
29 #include "core/components_v2/inspector/inspector_constants.h"
30 #include "test/mock/core/pipeline/mock_pipeline_context.h"
31 
32 using namespace testing;
33 using namespace testing::ext;
34 
35 namespace OHOS::Ace::NG {
36 namespace {
37 constexpr double GESTURE_EVENT_PROPERTY_VALUE = 10.0;
38 constexpr int32_t CLICK_TEST_RESULT_SIZE_1 = 1;
39 constexpr int32_t CLICK_TEST_RESULT_SIZE_2 = 2;
40 constexpr int32_t CLICK_TEST_RESULT_SIZE_3 = 3;
41 constexpr int32_t CLICK_TEST_RESULT_SIZE_0 = 0;
42 constexpr uint32_t CLICK_EVENTS_SIZE = 1;
43 constexpr uint32_t CLICK_EVENTS_SIZE_2 = 2;
44 const TouchRestrict CLICK_TOUCH_RESTRICT = { TouchRestrict::CLICK };
45 constexpr float WIDTH = 400.0f;
46 constexpr float HEIGHT = 400.0f;
47 const std::string RESULT_SUCCESS = "success";
48 const OffsetF COORDINATE_OFFSET(WIDTH, HEIGHT);
49 } // namespace
50 
51 class ClickEventTestNg : public testing::Test {
52 public:
53     static void SetUpTestSuite();
54     static void TearDownTestSuite();
55     void SetUp() override;
56     void TearDown() override;
57 };
58 
SetUpTestSuite()59 void ClickEventTestNg::SetUpTestSuite()
60 {
61     GTEST_LOG_(INFO) << "ClickEventTestNg SetUpTestCase";
62 }
63 
TearDownTestSuite()64 void ClickEventTestNg::TearDownTestSuite()
65 {
66     GTEST_LOG_(INFO) << "ClickEventTestNg TearDownTestCase";
67 }
68 
SetUp()69 void ClickEventTestNg::SetUp()
70 {
71     MockPipelineContext::SetUp();
72 }
73 
TearDown()74 void ClickEventTestNg::TearDown()
75 {
76     MockPipelineContext::TearDown();
77 }
78 
79 /**
80  * @tc.name: ClickEventTest001
81  * @tc.desc: Create ClickEvent and execute its functions.
82  * @tc.type: FUNC
83  */
84 HWTEST_F(ClickEventTestNg, ClickEventTest001, TestSize.Level1)
85 {
86     /**
87      * @tc.steps: step1. Create GestureEventFunc as the arguments of the construction of ClickEvent.
88      * @tc.expected: clickEvent is not nullptr.
89      */
90     double unknownPropertyValue = 0.0;
__anon2d438b710202(GestureEvent& info) 91     GestureEventFunc callback = [&unknownPropertyValue](GestureEvent& info) { unknownPropertyValue = info.GetScale(); };
92     auto clickEvent = AceType::MakeRefPtr<ClickEvent>(std::move(callback));
93     EXPECT_NE(clickEvent, nullptr);
94 
95     /**
96      * @tc.steps: step2. Get callback function and execute.
97      * @tc.expected: Execute ActionUpdateEvent which unknownPropertyValue is assigned in.
98      */
99     GestureEvent info = GestureEvent();
100     info.SetScale(GESTURE_EVENT_PROPERTY_VALUE);
101     clickEvent->GetGestureEventFunc()(info);
102     EXPECT_EQ(unknownPropertyValue, GESTURE_EVENT_PROPERTY_VALUE);
103 }
104 
105 /**
106  * @tc.name: ClickEventActuatorTest002
107  * @tc.desc: Create ClickEventActuator and replace, add and remove clickEvent.
108  * @tc.type: FUNC
109  */
110 HWTEST_F(ClickEventTestNg, ClickEventActuatorTest002, TestSize.Level1)
111 {
112     /**
113      * @tc.steps: step1. Create DragEventActuator.
114      */
115     auto eventHub = AceType::MakeRefPtr<EventHub>();
116     auto gestureEventHub = AceType::MakeRefPtr<GestureEventHub>(AceType::WeakClaim(AceType::RawPtr(eventHub)));
117     ClickEventActuator clickEventActuator = ClickEventActuator(AceType::WeakClaim(AceType::RawPtr(gestureEventHub)));
118 
119     /**
120      * @tc.steps: step2. Replace ClickEvent when userCallback_ is not nullptr.
121      * @tc.expected: userCallback_ will be reset and Make an new instance.
122      */
__anon2d438b710302(GestureEvent& info) 123     GestureEventFunc callback1 = [](GestureEvent& info) {};
124     auto clickEvent = AceType::MakeRefPtr<ClickEvent>(std::move(callback1));
125     clickEventActuator.userCallback_ = clickEvent;
__anon2d438b710402(GestureEvent& info) 126     GestureEventFunc callback2 = [](GestureEvent& info) {};
127     clickEventActuator.SetUserCallback(std::move(callback2));
128     EXPECT_NE(clickEventActuator.userCallback_, nullptr);
129 
130     /**
131      * @tc.steps: step3. Add click event when clickEvents_ is empty.
132      * @tc.expected: Add click event to the list of clickEvents.
133      */
134     clickEventActuator.AddClickEvent(clickEvent);
135     EXPECT_EQ(clickEventActuator.clickEvents_.size(), CLICK_EVENTS_SIZE);
136 
137     /**
138      * @tc.steps: step4. Add click event when clickEvents_ is not empty.
139      * @tc.expected: Add click event to the list of clickEvents when it is not found in the list.
140      */
__anon2d438b710502(GestureEvent& info) 141     GestureEventFunc callback3 = [](GestureEvent& info) {};
142     auto clickEvent2 = AceType::MakeRefPtr<ClickEvent>(std::move(callback3));
143     clickEventActuator.AddClickEvent(clickEvent2);
144     EXPECT_EQ(clickEventActuator.clickEvents_.size(), CLICK_EVENTS_SIZE_2);
145 
146     /**
147      * @tc.steps: step5. Remove click event.
148      * @tc.expected: The list of click event size will minus one.
149      */
150     clickEventActuator.RemoveClickEvent(clickEvent2);
151     EXPECT_EQ(clickEventActuator.clickEvents_.size(), CLICK_EVENTS_SIZE);
152 }
153 
154 /**
155  * @tc.name: ClickEventActuatorTest003
156  * @tc.desc: Create ClickEventActuator and invoke OnCollectTouchTarget.
157  * @tc.type: FUNC
158  */
159 HWTEST_F(ClickEventTestNg, ClickEventActuatorTest003, TestSize.Level1)
160 {
161     /**
162      * @tc.steps: step1. Create DragEventActuator.
163      */
164     auto eventHub = AceType::MakeRefPtr<EventHub>();
165     auto frameNode = AceType::MakeRefPtr<FrameNode>(V2::TEXT_ETS_TAG, -1, AceType::MakeRefPtr<Pattern>());
166     eventHub->AttachHost(frameNode);
167     auto gestureEventHub = AceType::MakeRefPtr<GestureEventHub>(AceType::WeakClaim(AceType::RawPtr(eventHub)));
168     ClickEventActuator clickEventActuator = ClickEventActuator(AceType::WeakClaim(AceType::RawPtr(gestureEventHub)));
169 
170     /**
171      * @tc.steps: step2. Invoke OnCollectTouchTarget when clickEvents_ is empty and userCallback_ is nullptr.
172      * @tc.expected: OnCollectTouchTarget will return directly and finalResult is empty.
173      */
174     auto getEventTargetImpl = eventHub->CreateGetEventTargetImpl();
175     EXPECT_NE(getEventTargetImpl, nullptr);
176     TouchTestResult finalResult;
177     ResponseLinkResult responseLinkResult;
178     clickEventActuator.OnCollectTouchTarget(
179         COORDINATE_OFFSET, CLICK_TOUCH_RESTRICT, getEventTargetImpl, finalResult, responseLinkResult);
180     EXPECT_TRUE(finalResult.empty());
181 
182     /**
183      * @tc.steps: step3. Invoke OnCollectTouchTarget when clickEvents_ is empty and userCallback_ and
184      * jsFrameNodeCallback_ are both nullptr.
185      * @tc.expected: OnCollectTouchTarget will return directly and finalResult is empty.
186      */
187 
188     clickEventActuator.jsFrameNodeCallback_ = nullptr;
189     clickEventActuator.OnCollectTouchTarget(
190         COORDINATE_OFFSET, CLICK_TOUCH_RESTRICT, getEventTargetImpl, finalResult, responseLinkResult);
191     EXPECT_TRUE(finalResult.empty());
192 
193     /**
194      * @tc.steps: step4. Invoke OnCollectTouchTarget when clickEvents_ is empty and userCallback_ is nullptr and
195      * jsFrameNodeCallback_ is not nullptr.
196      * @tc.expected: OnCollectTouchTarget can't return directly.
197      */
198     getEventTargetImpl = eventHub->CreateGetEventTargetImpl();
199     EXPECT_NE(getEventTargetImpl, nullptr);
__anon2d438b710602(GestureEvent& info) 200     GestureEventFunc callback = [](GestureEvent& info) {};
201     clickEventActuator.jsFrameNodeCallback_ = AceType::MakeRefPtr<ClickEvent>(std::move(callback));
202     clickEventActuator.OnCollectTouchTarget(
203         COORDINATE_OFFSET, CLICK_TOUCH_RESTRICT, getEventTargetImpl, finalResult, responseLinkResult);
204     EXPECT_FALSE(finalResult.empty());
205 
206     /**
207      * @tc.steps: step5. Invoke OnCollectTouchTarget when clickEvents_ is not empty but userCallback_ is nullptr.
208      * @tc.expected: Add clickRecognizer_ to finalResult, and it's size is equal 2.
209      */
210     auto clickEvent = AceType::MakeRefPtr<ClickEvent>(std::move(callback));
211     clickEventActuator.AddClickEvent(clickEvent);
212     clickEventActuator.AddClickEvent(nullptr);
213     clickEventActuator.OnCollectTouchTarget(
214         COORDINATE_OFFSET, CLICK_TOUCH_RESTRICT, getEventTargetImpl, finalResult, responseLinkResult);
215     EXPECT_EQ(finalResult.size(), CLICK_TEST_RESULT_SIZE_2);
216 
217     /**
218      * @tc.steps: step6. Execute onAction_ when clickEvents_ has nullptr and userCallback_ and
219      * onAccessibilityEventFunc_ are nullptr.
220      * @tc.expected: Add clickRecognizer_ to finalResult, and it's size is equal 1.
221      */
222     GestureEvent info = GestureEvent();
223     (*clickEventActuator.clickRecognizer_->onAction_)(info);
224 
225     /**
226      * @tc.steps: step7. Invoke OnCollectTouchTarget when userCallback_ and clickEvents_ is not empty but
227      * clickRecognizer_ is nullptr.
228      * @tc.expected: Add clickRecognizer_ to finalResult, and it's size is equal 3.
229      */
230     clickEventActuator.clickRecognizer_ = nullptr;
231     clickEventActuator.userCallback_ = clickEvent;
__anon2d438b710702(AccessibilityEventType type) 232     const OnAccessibilityEventFunc onAccessibility = [](AccessibilityEventType type) {};
233     clickEventActuator.SetOnAccessibility(onAccessibility);
234     clickEventActuator.OnCollectTouchTarget(
235         COORDINATE_OFFSET, CLICK_TOUCH_RESTRICT, getEventTargetImpl, finalResult, responseLinkResult);
236     EXPECT_EQ(finalResult.size(), CLICK_TEST_RESULT_SIZE_3);
237 
238     /**
239      * @tc.steps: step8. Execute onAction_ when clickEvents_ has nullptr and userCallback_ and
240      * onAccessibilityEventFunc_ are not nullptr.
241      */
242     (*clickEventActuator.clickRecognizer_->onAction_)(info);
243 }
244 
245 /**
246  * @tc.name: ClickEventActuatorTest004
247  * @tc.desc: test clear user callback.
248  * @tc.type: FUNC
249  */
250 HWTEST_F(ClickEventTestNg, ClickEventActuatorTest004, TestSize.Level1)
251 {
252     /**
253      * @tc.steps: step1. Create EventActuator.
254      */
255     auto eventHub = AceType::MakeRefPtr<EventHub>();
256     auto frameNode = AceType::MakeRefPtr<FrameNode>(V2::TEXT_ETS_TAG, -1, AceType::MakeRefPtr<Pattern>());
257     eventHub->AttachHost(frameNode);
258     auto gestureEventHub = AceType::MakeRefPtr<GestureEventHub>(AceType::WeakClaim(AceType::RawPtr(eventHub)));
259     ClickEventActuator clickEventActuator = ClickEventActuator(AceType::WeakClaim(AceType::RawPtr(gestureEventHub)));
260 
261     /**
262      * @tc.steps: step2. Invoke OnCollectTouchTarget when clickEvents_ is empty and userCallback_ is not nullptr.
263      * @tc.expected: OnCollectTouchTarget will return directly and finalResult is 1.
264      */
265     auto getEventTargetImpl = eventHub->CreateGetEventTargetImpl();
266     EXPECT_NE(getEventTargetImpl, nullptr);
267 
268     TouchTestResult finalResult;
269     ResponseLinkResult responseLinkResult;
270     std::string result;
__anon2d438b710802(GestureEvent& info) 271     GestureEventFunc callback = [&result](GestureEvent& info) { result = RESULT_SUCCESS; };
272 
273     clickEventActuator.SetUserCallback(std::move(callback));
274     clickEventActuator.OnCollectTouchTarget(
275         COORDINATE_OFFSET, CLICK_TOUCH_RESTRICT, getEventTargetImpl, finalResult, responseLinkResult);
276     EXPECT_NE(clickEventActuator.userCallback_->callback_, nullptr);
277 
278     GestureEvent info = GestureEvent();
279     clickEventActuator.userCallback_->callback_(info);
280     EXPECT_EQ(result, RESULT_SUCCESS);
281     EXPECT_EQ(finalResult.size(), CLICK_TEST_RESULT_SIZE_1);
282 
283     clickEventActuator.ClearUserCallback();
284     clickEventActuator.OnCollectTouchTarget(
285         COORDINATE_OFFSET, CLICK_TOUCH_RESTRICT, getEventTargetImpl, finalResult, responseLinkResult);
286     EXPECT_EQ(clickEventActuator.userCallback_, nullptr);
287     EXPECT_EQ(finalResult.size(), CLICK_TEST_RESULT_SIZE_1);
288 }
289 
290 /**
291  * @tc.name: ClickEventActuatorTest005
292  * @tc.desc: test user callback and clickevent are different.
293  * @tc.type: FUNC
294  */
295 HWTEST_F(ClickEventTestNg, ClickEventActuatorTest005, TestSize.Level1)
296 {
297     /**
298      * @tc.steps: step1. Create EventActuator.
299      */
300     auto eventHub = AceType::MakeRefPtr<EventHub>();
301     auto frameNode = AceType::MakeRefPtr<FrameNode>(V2::TEXT_ETS_TAG, -1, AceType::MakeRefPtr<Pattern>());
302     eventHub->AttachHost(frameNode);
303     auto gestureEventHub = AceType::MakeRefPtr<GestureEventHub>(AceType::WeakClaim(AceType::RawPtr(eventHub)));
304     ClickEventActuator clickEventActuator = ClickEventActuator(AceType::WeakClaim(AceType::RawPtr(gestureEventHub)));
305 
306     /**
307      * @tc.steps: step2. test clear callback and add event.
308      * @tc.expected: Add clickRecognizer_ to finalResult, and it's size is equal 1.
309      */
310     auto getEventTargetImpl = eventHub->CreateGetEventTargetImpl();
311     EXPECT_NE(getEventTargetImpl, nullptr);
312     clickEventActuator.ClearUserCallback();
313 
__anon2d438b710902(GestureEvent& info) 314     GestureEventFunc callback = [](GestureEvent& info) {};
315     auto clickEvent = AceType::MakeRefPtr<ClickEvent>(std::move(callback));
316     clickEventActuator.AddClickEvent(clickEvent);
317 
318     TouchTestResult finalResult;
319     ResponseLinkResult responseLinkResult;
320     clickEventActuator.OnCollectTouchTarget(
321         COORDINATE_OFFSET, CLICK_TOUCH_RESTRICT, getEventTargetImpl, finalResult, responseLinkResult);
322     EXPECT_EQ(finalResult.size(), CLICK_TEST_RESULT_SIZE_1);
323 
324     /**
325      * @tc.steps: step3. test clear callback again.
326      * @tc.expected: Add clickRecognizer_ to finalResult, and it's size is equal 1.
327      */
328     TouchTestResult finalResultAfterClear;
329     clickEventActuator.ClearUserCallback();
330     clickEventActuator.OnCollectTouchTarget(
331         COORDINATE_OFFSET, CLICK_TOUCH_RESTRICT, getEventTargetImpl, finalResultAfterClear, responseLinkResult);
332     EXPECT_EQ(finalResultAfterClear.size(), CLICK_TEST_RESULT_SIZE_1);
333 
334     /**
335      * @tc.steps: step4. test clear event again.
336      * @tc.expected: callback and event are null, and it's size is equal 0.
337      */
338     clickEventActuator.RemoveClickEvent(clickEvent);
339     TouchTestResult finalResultAfterClearEvent;
340     clickEventActuator.OnCollectTouchTarget(
341         COORDINATE_OFFSET, CLICK_TOUCH_RESTRICT, getEventTargetImpl, finalResultAfterClearEvent, responseLinkResult);
342     EXPECT_EQ(finalResultAfterClearEvent.size(), CLICK_TEST_RESULT_SIZE_0);
343 }
344 /**
345  * @tc.name: ClickEventActuatorTest006
346  * @tc.desc: test AddClickAfterEvent and ClearClickAfterEvent.
347  * @tc.type: FUNC
348  */
349 HWTEST_F(ClickEventTestNg, ClickEventActuatorTest006, TestSize.Level1)
350 {
351     /**
352      * @tc.steps: step1. Create DragEventActuator.
353      */
354     auto eventHub = AceType::MakeRefPtr<EventHub>();
355     auto gestureEventHub = AceType::MakeRefPtr<GestureEventHub>(AceType::WeakClaim(AceType::RawPtr(eventHub)));
356     ClickEventActuator clickEventActuator = ClickEventActuator(AceType::WeakClaim(AceType::RawPtr(gestureEventHub)));
357 
358     /**
359      * @tc.steps: step2. Replace ClickEvent when userCallback_ is not nullptr.
360      * @tc.expected: userCallback_ will be reset and Make an new instance.
361      */
__anon2d438b710a02(GestureEvent& info) 362     GestureEventFunc callback = [](GestureEvent& info) {};
363     auto clickEvent = AceType::MakeRefPtr<ClickEvent>(std::move(callback));
364     clickEventActuator.AddClickAfterEvent(clickEvent);
365     EXPECT_NE(clickEventActuator.clickAfterEvents_, nullptr);
366 
367     clickEventActuator.ClearClickAfterEvent();
368     EXPECT_EQ(clickEventActuator.clickAfterEvents_, nullptr);
369 }
370 } // namespace OHOS::Ace::NG
371