1 /*
2  * Copyright (c) 2022 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 <clocale>
17 #include <cmath>
18 #include <cstdint>
19 #include <unistd.h>
20 
21 #include "gtest/gtest.h"
22 
23 #include "base/memory/ace_type.h"
24 #define private public
25 #define protected public
26 #include "core/components_ng/pattern/scroll/scroll_edge_effect.h"
27 #include "core/components_ng/base/frame_node.h"
28 #include "core/components_ng/event/event_hub.h"
29 #include "core/components_ng/event/scrollable_event.h"
30 #include "core/components_ng/pattern/pattern.h"
31 #include "core/components_v2/inspector/inspector_constants.h"
32 #include "test/mock/core/pipeline/mock_pipeline_context.h"
33 
34 using namespace testing;
35 using namespace testing::ext;
36 
37 namespace OHOS::Ace::NG {
38 namespace {
39 constexpr Axis SCROLLABLE_EVENT_AXIS = Axis::VERTICAL;
40 constexpr EdgeEffect SCROLLABLE_EVENT_EDGE_EFFECT = EdgeEffect::FADE;
41 constexpr uint32_t SCROLL_TEST_RESULT_SIZE_1 = 2;
42 constexpr uint32_t SCROLL_TEST_RESULT_SIZE = 0;
43 constexpr uint32_t SCROLL_EFFECTS_SIZE = 0;
44 constexpr uint32_t SCROLL_EFFECTS_SIZE_1 = 1;
45 const TouchRestrict SCROLL_RESTRICT = { TouchRestrict::LONG_PRESS };
46 constexpr uint32_t SCROLLABLE_EVENT_SIZE = 0;
47 constexpr uint32_t SCROLLABLE_EVENT_SIZE_1 = 1;
48 constexpr float WIDTH = 400.0f;
49 constexpr float HEIGHT = 400.0f;
50 const OffsetF COORDINATE_OFFSET(WIDTH, HEIGHT);
51 constexpr bool SCROLLABLE_EVENT_DISENABLED = false;
52 const PanDirection SCROLLABLE_EVENT_DIRECTION = { PanDirection::LEFT };
53 constexpr int32_t FINGERS_NUMBER = 2;
54 constexpr float DISTANCE = 10.5f;
55 const PointF LOCAL_POINT { 15.0f, 15.0f };
56 } // namespace
57 
58 class ScrollableEventTestNg : public testing::Test {
59 public:
60     static void SetUpTestSuite();
61     static void TearDownTestSuite();
62     void SetUp() override;
63     void TearDown() override;
64 };
65 
SetUpTestSuite()66 void ScrollableEventTestNg::SetUpTestSuite()
67 {
68     GTEST_LOG_(INFO) << "ScrollableEventTestNg SetUpTestCase";
69 }
70 
TearDownTestSuite()71 void ScrollableEventTestNg::TearDownTestSuite()
72 {
73     GTEST_LOG_(INFO) << "ScrollableEventTestNg TearDownTestCase";
74 }
75 
SetUp()76 void ScrollableEventTestNg::SetUp()
77 {
78     MockPipelineContext::SetUp();
79 }
80 
TearDown()81 void ScrollableEventTestNg::TearDown()
82 {
83     MockPipelineContext::TearDown();
84 }
85 
86 /**
87  * @tc.name: ScrollableEventAddScrollEdgeEffectTest001
88  * @tc.desc: Create ScrollableEvent and Add ScrollEdgeEffect.
89  * @tc.type: FUNC
90  */
91 HWTEST_F(ScrollableEventTestNg, ScrollableEventCreateTest001, TestSize.Level1)
92 {
93     /**
94      * @tc.steps: step1. Create ScrollableActuator.
95      */
96     auto eventHub = AceType::MakeRefPtr<EventHub>();
97     auto gestureEventHub = AceType::MakeRefPtr<GestureEventHub>(AceType::WeakClaim(AceType::RawPtr(eventHub)));
98     auto scrollableActuator =
99         AceType::MakeRefPtr<ScrollableActuator>((AceType::WeakClaim(AceType::RawPtr(gestureEventHub))));
100     EXPECT_NE(scrollableActuator, nullptr);
101 
102     /**
103      * @tc.steps: step2. Add ScrollEdgeEffect when ScrollEdgeEffect is nullptr.
104      * @tc.expected: AddScrollEdgeEffect function will return directly, and scrollEffects_ size is 0.
105      */
106     RefPtr<ScrollEdgeEffect> edgeEffect;
107     scrollableActuator->AddScrollEdgeEffect(SCROLLABLE_EVENT_AXIS, edgeEffect);
108     EXPECT_EQ(scrollableActuator->scrollEffects_.size(), SCROLL_EFFECTS_SIZE);
109 
110     /**
111      * @tc.steps: step3. Create ScrollEdgeEffect.
112      * @tc.expected: scrollEdgeEffect is not nullptr.
113      */
114     auto scrollEdgeEffect = AceType::MakeRefPtr<ScrollEdgeEffect>(SCROLLABLE_EVENT_EDGE_EFFECT);
115     EXPECT_NE(scrollEdgeEffect, nullptr);
116 
117     /**
118      * @tc.steps: step4. Add ScrollEdgeEffect when ScrollEdgeEffect is not nullptr.
119      * @tc.expected: Add ScrollEdgeEffect to scrollEffects_ which size will increased by one
120      */
121     auto scrollableEvent = AceType::MakeRefPtr<ScrollableEvent>(SCROLLABLE_EVENT_AXIS);
122     scrollableActuator->AddScrollableEvent(scrollableEvent);
123     scrollableActuator->AddScrollEdgeEffect(SCROLLABLE_EVENT_AXIS, scrollEdgeEffect);
124     EXPECT_EQ(scrollableActuator->scrollEffects_.size(), SCROLL_EFFECTS_SIZE_1);
125 }
126 
127 /**
128  * @tc.name: ScrollableEventRemoveScrollEdgeEffectTest002
129  * @tc.desc: Create ScrollableEvent and remove ScrollEdgeEffect.
130  * @tc.type: FUNC
131  */
132 HWTEST_F(ScrollableEventTestNg, ScrollableEventRemoveScrollEdgeEffectTest002, TestSize.Level1)
133 {
134     /**
135      * @tc.steps: step1. Create ScrollableActuator.
136      */
137     auto eventHub = AceType::MakeRefPtr<EventHub>();
138     auto gestureEventHub = AceType::MakeRefPtr<GestureEventHub>(AceType::WeakClaim(AceType::RawPtr(eventHub)));
139     auto scrollableActuator =
140         AceType::MakeRefPtr<ScrollableActuator>((AceType::WeakClaim(AceType::RawPtr(gestureEventHub))));
141     EXPECT_NE(scrollableActuator, nullptr);
142 
143     /**
144      * @tc.steps: step2. Remove ScrollEdgeEffect when ScrollEdgeEffect is nullptr.
145      * @tc.expected: RemoveScrollEdgeEffect function will return false directly.
146      */
147     EXPECT_FALSE(scrollableActuator->RemoveScrollEdgeEffect(nullptr));
148 
149     /**
150      * @tc.steps: step3. Create ScrollEdgeEffect.
151      * @tc.expected: scrollEdgeEffect is not nullptr.
152      */
153     auto scrollEdgeEffect = AceType::MakeRefPtr<ScrollEdgeEffect>(SCROLLABLE_EVENT_EDGE_EFFECT);
154     EXPECT_NE(scrollEdgeEffect, nullptr);
155 
156     /**
157      * @tc.steps: step4. Add ScrollEdgeEffect.
158      * @tc.expected: Add ScrollEdgeEffect to scrollEffects_ which size will not be empty.
159      */
160     auto scrollableEvent = AceType::MakeRefPtr<ScrollableEvent>(SCROLLABLE_EVENT_AXIS);
161     scrollableActuator->AddScrollableEvent(scrollableEvent);
162     scrollableActuator->AddScrollEdgeEffect(SCROLLABLE_EVENT_AXIS, scrollEdgeEffect);
163     EXPECT_EQ(scrollableActuator->scrollEffects_.size(), SCROLL_EFFECTS_SIZE_1);
164 
165     /**
166      * @tc.steps: step5. Remove ScrollEdgeEffect when ScrollEdgeEffect is not nullptr and can be found in
167      * scrollEffects_.
168      * @tc.expected: RemoveScrollEdgeEffect function will remove effect in scrollEffects_ and return true.
169      */
170     EXPECT_TRUE(scrollableActuator->RemoveScrollEdgeEffect(scrollEdgeEffect));
171     EXPECT_EQ(scrollableActuator->scrollEffects_.size(), SCROLL_EFFECTS_SIZE);
172 }
173 
174 /**
175  * @tc.name: ScrollableEventOnCollectTouchTargetTest003
176  * @tc.desc: Create ScrollableEvent and invoke OnCollectTouchTarget.
177  * @tc.type: FUNC
178  */
179 HWTEST_F(ScrollableEventTestNg, ScrollableEventOnCollectTouchTargetTest003, TestSize.Level1)
180 {
181     /**
182      * @tc.steps: step1. Create ScrollableActuator.
183      */
184     auto eventHub = AceType::MakeRefPtr<EventHub>();
185     auto gestureEventHub = AceType::MakeRefPtr<GestureEventHub>(AceType::WeakClaim(AceType::RawPtr(eventHub)));
186     auto scrollableActuator =
187         AceType::MakeRefPtr<ScrollableActuator>((AceType::WeakClaim(AceType::RawPtr(gestureEventHub))));
188     EXPECT_NE(scrollableActuator, nullptr);
189 
190     /**
191      * @tc.steps: step2. CollectTouchTarget when initialized_ is false.
192      * @tc.expected: Invoke InitializeScrollable. when scrollableEvents_ is empty return directly.
193      */
194     TouchTestResult result;
195     ResponseLinkResult responseLinkResult;
196     auto frameNode = AceType::MakeRefPtr<FrameNode>(V2::TEXT_ETS_TAG, -1, AceType::MakeRefPtr<Pattern>());
197     scrollableActuator->CollectTouchTarget(COORDINATE_OFFSET, SCROLL_RESTRICT, eventHub->CreateGetEventTargetImpl(),
198         result, LOCAL_POINT, frameNode, nullptr, responseLinkResult);
199     EXPECT_EQ(result.size(), SCROLL_TEST_RESULT_SIZE);
200     EXPECT_EQ(scrollableActuator->scrollableEvents_.size(), SCROLLABLE_EVENT_SIZE);
201 
202     /**
203      * @tc.steps: step3. Add ScrollableEvent.
204      * @tc.expected: scrollableEvent will be added in scrollableEvents_.
205      */
206     auto scrollableEvent = AceType::MakeRefPtr<ScrollableEvent>(SCROLLABLE_EVENT_AXIS);
207     auto scrollable = AceType::MakeRefPtr<Scrollable>();
208     auto panRecognizerNG = AceType::MakeRefPtr<PanRecognizer>(FINGERS_NUMBER, SCROLLABLE_EVENT_DIRECTION, DISTANCE);
209     scrollable->panRecognizerNG_ = panRecognizerNG;
210     scrollableEvent->SetScrollable(scrollable);
211     scrollableActuator->AddScrollableEvent(scrollableEvent);
212     EXPECT_EQ(scrollableActuator->scrollableEvents_.size(), SCROLLABLE_EVENT_SIZE_1);
213 
214     /**
215      * @tc.steps: step4. CollectTouchTarget when initialized_ is false and scrollableEvents_ is not empty.
216      * @tc.expected: gestureEventHub cannot GetFrameNode, InitializeScrollable fuction will return directly.
217      */
218     scrollableActuator->CollectTouchTarget(COORDINATE_OFFSET, SCROLL_RESTRICT, eventHub->CreateGetEventTargetImpl(),
219         result, LOCAL_POINT, frameNode, nullptr, responseLinkResult);
220     EXPECT_EQ(result.size(), SCROLL_TEST_RESULT_SIZE_1);
221     auto coordinateOffset = scrollableEvent->GetScrollable()->panRecognizerNG_->GetCoordinateOffset();
222     EXPECT_EQ(coordinateOffset, Offset(WIDTH, HEIGHT)) <<
223         "coordinateOffset: " << coordinateOffset.ToString() <<
224         "Offset(WIDTH, HEIGHT)" << Offset(WIDTH, HEIGHT).ToString();
225 
226     /**
227      * @tc.steps: step5. Add frameNode to gestureEventHub, and Add ScrollEdgeEffect whose axis is same with the
228      * scrollableEvent.
229      */
230     eventHub->AttachHost(frameNode);
231     auto scrollEdgeEffect = AceType::MakeRefPtr<ScrollEdgeEffect>(SCROLLABLE_EVENT_EDGE_EFFECT);
232     scrollableActuator->AddScrollEdgeEffect(SCROLLABLE_EVENT_AXIS, scrollEdgeEffect);
233     EXPECT_EQ(scrollableActuator->scrollEffects_.size(), SCROLL_EFFECTS_SIZE_1);
234 
235     /**
236      * @tc.steps: step6. CollectTouchTarget when initialized_ is false, scrollableEvents_ is not empty,
237      * gestureEventHub has frameNode and scrollEffects_ shares the same axis with scrollableEvent.
238      * @tc.expected: The loop will be continued when scrollableEvent is not enabled.
239      */
240     scrollableEvent->SetEnabled(SCROLLABLE_EVENT_DISENABLED);
241     scrollableActuator->CollectTouchTarget(COORDINATE_OFFSET, SCROLL_RESTRICT, eventHub->CreateGetEventTargetImpl(),
242         result, LOCAL_POINT, frameNode, nullptr, responseLinkResult);
243     EXPECT_EQ(result.size(), SCROLL_TEST_RESULT_SIZE_1);
244 }
245 } // namespace OHOS::Ace::NG
246