• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <optional>
17 
18 #include "gtest/gtest.h"
19 
20 #define private public
21 #define protected public
22 
23 #include "core/components_ng/manager/avoid_info/avoid_info_manager.h"
24 #include "test/mock/core/pipeline/mock_pipeline_context.h"
25 #include "test/mock/core/common/mock_container.h"
26 #include "test/mock/core/common/mock_theme_manager.h"
27 #include "test/mock/core/render/mock_render_context.h"
28 
29 using namespace testing;
30 using namespace testing::ext;
31 
32 namespace OHOS::Ace::NG {
operator ==(const ContainerModalAvoidInfo & a,const ContainerModalAvoidInfo & b)33 bool operator==(const ContainerModalAvoidInfo& a, const ContainerModalAvoidInfo& b)
34 {
35     return a.needAvoid == b.needAvoid &&
36            a.titleHeight == b.titleHeight &&
37            a.controlBottonsRect == b.controlBottonsRect;
38 }
39 
operator !=(const ContainerModalAvoidInfo & a,const ContainerModalAvoidInfo & b)40 bool operator!=(const ContainerModalAvoidInfo& a, const ContainerModalAvoidInfo& b)
41 {
42     return !(a == b);
43 }
44 
45 namespace {
46 class MockAvoidInfoListener : public IAvoidInfoListener {
47     DECLARE_ACE_TYPE(MockAvoidInfoListener, IAvoidInfoListener);
48 public:
49     MockAvoidInfoListener() = default;
50     ~MockAvoidInfoListener() = default;
51 
52     MOCK_METHOD1(OnAvoidInfoChange, void(const ContainerModalAvoidInfo& info));
53 };
54 
GetAvoidInfoManager()55 RefPtr<AvoidInfoManager> GetAvoidInfoManager()
56 {
57     auto pipeline = MockPipelineContext::GetCurrent();
58     return pipeline != nullptr ? pipeline->GetAvoidInfoManager() : nullptr;
59 }
60 } // namespace
61 
62 class AvoidInfoManagerTestNg : public testing::Test {
63 public:
64     static void SetUpTestSuite();
65     static void TearDownTestSuite();
66     void SetUp();
TearDown()67     void TearDown() {}
68 };
69 
SetUpTestSuite()70 void AvoidInfoManagerTestNg::SetUpTestSuite()
71 {
72     MockPipelineContext::SetUp();
73     MockContainer::SetUp();
74 }
75 
TearDownTestSuite()76 void AvoidInfoManagerTestNg::TearDownTestSuite()
77 {
78     MockPipelineContext::TearDown();
79     MockContainer::TearDown();
80 }
81 
SetUp()82 void AvoidInfoManagerTestNg::SetUp()
83 {
84     auto pipeline = MockPipelineContext::GetCurrent();
85     ASSERT_NE(pipeline, nullptr);
86     auto mgr = AceType::MakeRefPtr<AvoidInfoManager>();
87     ASSERT_NE(mgr, nullptr);
88     mgr->SetPipelineContext(WeakPtr(pipeline));
89     mgr->SetInstanceId(pipeline->GetInstanceId());
90     pipeline->avoidInfoMgr_ = mgr;
91 }
92 
93 /**
94  * @tc.name: OnAvoidInfoChange001
95  * @tc.desc: Test basic logic of OnAvoidInfoChange
96  * @tc.type: FUNC
97  * @tc.author:
98  */
99 HWTEST_F(AvoidInfoManagerTestNg, OnAvoidInfoChange001, TestSize.Level1)
100 {
101     /**
102      * @tc.steps: step1. Get AvoidInfoManager.
103      */
104     auto manager = GetAvoidInfoManager();
105     ASSERT_NE(manager, nullptr);
106     ASSERT_TRUE(manager->listeners_.empty());
107 
108     /**
109      * @tc.steps: step2. Create one listener, set expected input param and callTimes.
110      */
111     ContainerModalAvoidInfo info;
112     info.needAvoid = true;
113     info.titleHeight = 32;
114     auto listener = AceType::MakeRefPtr<MockAvoidInfoListener>();
115     ASSERT_NE(listener, nullptr);
116     EXPECT_CALL(*listener, OnAvoidInfoChange(info)).Times(1);
117 
118     /**
119      * @tc.steps: step3. Add listener to AvoidInfoManager, and invoke OnAvoidInfoChange with specified Param.
120      * @tc.expected: Manager's input param equals to Listener input param.
121      */
122     manager->listeners_.emplace(listener);
123     ASSERT_EQ(manager->listeners_.size(), 1);
124     manager->OnAvoidInfoChange(info);
125 }
126 
127 /**
128  * @tc.name: AddAvoidInfoListener001
129  * @tc.desc: Test basic logic of AddAvoidInfoListener&RemoveAvoidInfoListener
130  * @tc.type: FUNC
131  * @tc.author:
132  */
133 HWTEST_F(AvoidInfoManagerTestNg, AddAvoidInfoListener001, TestSize.Level1)
134 {
135     /**
136      * @tc.steps: step1. Get AvoidInfoManager.
137      */
138     auto manager = GetAvoidInfoManager();
139     ASSERT_NE(manager, nullptr);
140     ASSERT_TRUE(manager->listeners_.empty());
141 
142     /**
143      * @tc.steps: step2. Create three listeners.
144      */
145     auto listener1 = AceType::MakeRefPtr<MockAvoidInfoListener>();
146     ASSERT_NE(listener1, nullptr);
147     auto listener2 = AceType::MakeRefPtr<MockAvoidInfoListener>();
148     ASSERT_NE(listener2, nullptr);
149     auto listener3 = AceType::MakeRefPtr<MockAvoidInfoListener>();
150     ASSERT_NE(listener3, nullptr);
151 
152     /**
153      * @tc.steps: step2. Add listeners and check result.
154      */
155     manager->AddAvoidInfoListener(listener1);
156     ASSERT_EQ(manager->listeners_.size(), 1);
157     // add same listener again.
158     manager->AddAvoidInfoListener(listener1);
159     ASSERT_EQ(manager->listeners_.size(), 1);
160     manager->AddAvoidInfoListener(listener2);
161     manager->AddAvoidInfoListener(listener3);
162     ASSERT_EQ(manager->listeners_.size(), 3);
163 
164     /**
165      * @tc.steps: step2. Remove listeners and check result.
166      */
167     manager->RemoveAvoidInfoListener(listener1);
168     manager->RemoveAvoidInfoListener(listener2);
169     ASSERT_EQ(manager->listeners_.size(), 1);
170     auto it = manager->listeners_.find(listener3);
171     ASSERT_TRUE(it != manager->listeners_.end());
172 }
173 
174 /**
175  * @tc.name: GetContainerModalTitleHeight001
176  * @tc.desc: Test basic logic of GetContainerModalTitleHeight
177  * @tc.type: FUNC
178  * @tc.author:
179  */
180 HWTEST_F(AvoidInfoManagerTestNg, GetContainerModalTitleHeight001, TestSize.Level1)
181 {
182     /**
183      * @tc.steps: step1. Get AvoidInfoManager, Set AvoidInfo for normal scenario and UEC scenario.
184      */
185     auto container = MockContainer::Current();
186     ASSERT_NE(container, nullptr);
187     auto manager = GetAvoidInfoManager();
188     ASSERT_NE(manager, nullptr);
189     ContainerModalAvoidInfo info;
190     info.titleHeight = 32;
191     ContainerModalAvoidInfo uecInfo;
192     uecInfo.titleHeight = 64;
193     manager->SetAvoidInfo(info);
194     manager->SetAvoidInfoForUEC(uecInfo);
195 
196     /**
197      * @tc.steps: step2. Set current Container is UEC Container.
198      * @tc.desc: Branch: if (container->IsUIExtensionWindow()) { => true
199      */
200     container->SetIsUIExtensionWindow(true);
201     int32_t height = manager->GetContainerModalTitleHeight();
202     ASSERT_EQ(height, 64);
203 
204     /**
205      * @tc.steps: step2. Set current Container is regular Container.
206      * @tc.desc: Branch: if (container->IsUIExtensionWindow()) { => false
207      */
208     container->SetIsUIExtensionWindow(false);
209     height = manager->GetContainerModalTitleHeight();
210     ASSERT_EQ(height, 32);
211 }
212 
213 /**
214  * @tc.name: GetContainerModalButtonsRect001
215  * @tc.desc: Test basic logic of GetContainerModalButtonsRect
216  * @tc.type: FUNC
217  * @tc.author:
218  */
219 HWTEST_F(AvoidInfoManagerTestNg, GetContainerModalButtonsRect001, TestSize.Level1)
220 {
221     /**
222      * @tc.steps: step1. Get AvoidInfoManager, Set AvoidInfo for normal scenario and UEC scenario.
223      */
224     auto container = MockContainer::Current();
225     ASSERT_NE(container, nullptr);
226     auto manager = GetAvoidInfoManager();
227     ASSERT_NE(manager, nullptr);
228     ContainerModalAvoidInfo info;
229     info.controlBottonsRect = RectF(0.0f, 0.0f, 300.0f, 400.f);
230     ContainerModalAvoidInfo uecInfo;
231     uecInfo.controlBottonsRect = RectF(50.0f, 60.0f, 300.0f, 400.f);
232     manager->SetAvoidInfo(info);
233     manager->SetAvoidInfoForUEC(uecInfo);
234 
235     /**
236      * @tc.steps: step2. Set current Container is UEC Container.
237      * @tc.desc: Branch: if (container->IsUIExtensionWindow()) { => true
238      */
239     container->SetIsUIExtensionWindow(true);
240     RectF containerRect;
241     RectF buttonsRect;
242     ASSERT_TRUE(manager->GetContainerModalButtonsRect(containerRect, buttonsRect));
243     ASSERT_EQ(buttonsRect, uecInfo.controlBottonsRect);
244 
245     /**
246      * @tc.steps: step2. Set current Container is regular Container.
247      * @tc.desc: Branch: if (container->IsUIExtensionWindow()) { => false
248      */
249     container->SetIsUIExtensionWindow(false);
250     ASSERT_TRUE(manager->GetContainerModalButtonsRect(containerRect, buttonsRect));
251     ASSERT_EQ(buttonsRect, info.controlBottonsRect);
252 }
253 
254 /**
255  * @tc.name: NeedAvoidContainerModal001
256  * @tc.desc: Test basic logic of NeedAvoidContainerModal
257  * @tc.type: FUNC
258  * @tc.author:
259  */
260 HWTEST_F(AvoidInfoManagerTestNg, NeedAvoidContainerModal001, TestSize.Level1)
261 {
262     /**
263      * @tc.steps: step1. Get AvoidInfoManager, Set AvoidInfo for normal scenario and UEC scenario.
264      */
265     auto container = MockContainer::Current();
266     ASSERT_NE(container, nullptr);
267     auto manager = GetAvoidInfoManager();
268     ASSERT_NE(manager, nullptr);
269     ContainerModalAvoidInfo info;
270     info.needAvoid = true;
271     ContainerModalAvoidInfo uecInfo;
272     uecInfo.needAvoid = false;
273     manager->SetAvoidInfo(info);
274     manager->SetAvoidInfoForUEC(uecInfo);
275 
276     /**
277      * @tc.steps: step2. Set current Container is UEC Container.
278      * @tc.desc: Branch: if (container->IsUIExtensionWindow()) { => true
279      */
280     container->SetIsUIExtensionWindow(true);
281     ASSERT_FALSE(manager->NeedAvoidContainerModal());
282 
283     /**
284      * @tc.steps: step2. Set current Container is regular Container.
285      * @tc.desc: Branch: if (container->IsUIExtensionWindow()) { => false
286      */
287     container->SetIsUIExtensionWindow(false);
288     ASSERT_TRUE(manager->NeedAvoidContainerModal());
289 }
290 
291 /**
292  * @tc.name: RegisterListenerIfNeeded001
293  * @tc.desc: Test basic logic of RegisterListenerIfNeeded
294  * @tc.type: FUNC
295  * @tc.author:
296  */
297 HWTEST_F(AvoidInfoManagerTestNg, RegisterListenerIfNeeded001, TestSize.Level1)
298 {
299     /**
300      * @tc.steps: step1. Get AvoidInfoManager.
301      */
302     auto container = MockContainer::Current();
303     ASSERT_NE(container, nullptr);
304     auto manager = GetAvoidInfoManager();
305     ASSERT_NE(manager, nullptr);
306     manager->hasRegisterListener_ = false;
307 
308     /**
309      * @tc.steps: step2. Set current Container is regular Container.
310      * @tc.desc: Branch: if (!container->IsUIExtensionWindow()) { => true
311      */
312     container->SetIsUIExtensionWindow(false);
313     manager->RegisterListenerIfNeeded();
314     ASSERT_TRUE(manager->hasRegisterListener_);
315 
316     /**
317      * @tc.steps: step2. Keep the callbacks of AvoidInfoManager in an unset state,
318      *                   Set current Container is UEC Container.
319      * @tc.desc: Branch: if (!registerUECConsumerCallback_ || !requestAvoidInfoCallback_) { => true
320      */
321     manager->hasRegisterListener_ = false;
322     container->SetIsUIExtensionWindow(true);
323     manager->RegisterListenerIfNeeded();
324     ASSERT_FALSE(manager->hasRegisterListener_);
325 
326     /**
327      * @tc.steps: step2. Set callbacks to AvoidInfoManager, set current Container is UEC Container.
328      * @tc.desc: Branch: if (!registerUECConsumerCallback_ || !requestAvoidInfoCallback_) { => false
329      */
330     bool callRegisterFunc = false;
__anon14ccbd050202(UECAvoidInfoConsumer&& consumer) 331     auto registerCallback = [&callRegisterFunc](UECAvoidInfoConsumer&& consumer) {
332         callRegisterFunc = true;
333     };
334     bool callRequestFunc = false;
__anon14ccbd050302() 335     auto requestCallback = [&callRequestFunc]() {
336         callRequestFunc = true;
337     };
338     manager->SetRegisterUECAvoidInfoConsumerCallback(std::move(registerCallback));;
339     manager->SetRequestAvoidInfoCallback(std::move(requestCallback));
340     manager->RegisterListenerIfNeeded();
341     ASSERT_TRUE(manager->hasRegisterListener_);
342     ASSERT_TRUE(callRegisterFunc);
343     ASSERT_TRUE(callRequestFunc);
344 }
345 
346 /**
347  * @tc.name: UnregisterListenerIfNeeded001
348  * @tc.desc: Test basic logic of UnregisterListenerIfNeeded
349  * @tc.type: FUNC
350  * @tc.author:
351  */
352 HWTEST_F(AvoidInfoManagerTestNg, UnregisterListenerIfNeeded001, TestSize.Level1)
353 {
354     /**
355      * @tc.steps: step1. Get AvoidInfoManager.
356      */
357     auto container = MockContainer::Current();
358     ASSERT_NE(container, nullptr);
359     auto manager = GetAvoidInfoManager();
360     ASSERT_NE(manager, nullptr);
361     manager->hasRegisterListener_ = true;
362 
363     /**
364      * @tc.steps: step2. Set current Container is UEC Container.
365      * @tc.desc: Branch: if (container->IsUIExtensionWindow()) { => true
366      */
367     container->SetIsUIExtensionWindow(true);
368     manager->UnregisterListenerIfNeeded();
369     ASSERT_FALSE(manager->hasRegisterListener_);
370 
371     /**
372      * @tc.steps: step2. Set current Container is regular Container.
373      * @tc.desc: Branch: if (container->IsUIExtensionWindow()) { => false
374      */
375     manager->hasRegisterListener_ = true;
376     container->SetIsUIExtensionWindow(false);
377     manager->UnregisterListenerIfNeeded();
378     ASSERT_FALSE(manager->hasRegisterListener_);
379 }
380 
381 /**
382  * @tc.name: GetContainerModalAvoidInfoForUEC001
383  * @tc.desc: Branch: if (context->GetContainerCustomTitleVisible() ||
384  *                       !context->GetContainerControlButtonVisible()) { => false
385  *                   if (!context->GetContainerModalButtonsRect(containerModal, buttonsRect)) { => false
386  *                   if (height <= 0) { => false
387  *                   if (!uecRect.IsIntersectWith(buttonsRect)) { => true
388  * @tc.type: FUNC
389  * @tc.author:
390  */
391 HWTEST_F(AvoidInfoManagerTestNg, GetContainerModalAvoidInfoForUEC001, TestSize.Level1)
392 {
393     auto container = MockContainer::Current();
394     ASSERT_NE(container, nullptr);
395     auto pipeline = MockPipelineContext::GetCurrent();
396     ASSERT_NE(pipeline, nullptr);
397     auto manager = GetAvoidInfoManager();
398     ASSERT_NE(manager, nullptr);
399 
400     bool preTitleVisible = pipeline->GetContainerCustomTitleVisible();
401     bool preBtnVisible = pipeline->GetContainerControlButtonVisible();
402     int32_t preHeight = pipeline->GetContainerModalTitleHeight();
403 
404     pipeline->SetContainerCustomTitleVisible(false);
405     pipeline->SetContainerControlButtonVisible(true);
406     pipeline->SetContainerModalButtonsRect(true);
407     RectF btnRct{200.0f, 0.0f, 200.0f, 100.0f};
408     pipeline->SetContainerModalButtonsRect(btnRct);
409     pipeline->SetContainerModalTitleHeight(80);
410 
411     auto uecNode = FrameNode::CreateFrameNode(V2::UI_EXTENSION_COMPONENT_ETS_TAG,
412         ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>());
413     ASSERT_NE(uecNode, nullptr);
414     auto geometryNode = uecNode->GetGeometryNode();
415     ASSERT_NE(geometryNode, nullptr);
416     geometryNode->SetFrameOffset(OffsetF(100.0f, 0.0f));
417     geometryNode->SetFrameSize(SizeF(200.0f, 200.0f));
418 
419     auto renderContext = AceType::MakeRefPtr<MockRenderContext>();
420     ASSERT_NE(geometryNode, nullptr);
421     renderContext->UpdatePaintRect(RectF(100.0f, 120.0f, 200.0f, 200.0f));
422     uecNode->renderContext_ = renderContext;
423 
424     ContainerModalAvoidInfo info;
425     info.needAvoid = true;
426     manager->GetContainerModalAvoidInfoForUEC(uecNode, info);
427     EXPECT_FALSE(info.needAvoid);
428 
429     pipeline->SetContainerCustomTitleVisible(preTitleVisible);
430     pipeline->SetContainerControlButtonVisible(preBtnVisible);
431     pipeline->SetContainerModalTitleHeight(preHeight);
432 }
433 } // namespace OHOS::Ace::NG
434