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