1 /*
2 * Copyright (c) 2022-2024 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 #include "mock_navigation_route.h"
20 #include "mock_navigation_stack.h"
21
22 #define protected public
23 #define private public
24 #include "test/mock/base/mock_task_executor.h"
25 #include "core/components/button/button_theme.h"
26 #include "core/components_ng/base/frame_node.h"
27 #include "core/components_ng/base/ui_node.h"
28 #include "core/components_ng/pattern/button/button_pattern.h"
29 #include "core/components_ng/pattern/navigation/navigation_content_layout_algorithm.h"
30 #include "core/components_ng/pattern/navigation/navigation_layout_property.h"
31 #include "core/components_ng/pattern/navigation/navigation_model_ng.h"
32 #include "core/components_ng/pattern/navigation/navigation_pattern.h"
33 #include "core/components_ng/pattern/navigation/title_bar_pattern.h"
34 #include "core/components_ng/pattern/scroll/scroll_pattern.h"
35 #include "core/components_ng/pattern/text/text_pattern.h"
36 #include "test/mock/core/common/mock_theme_manager.h"
37 #include "test/mock/core/pipeline/mock_pipeline_context.h"
38 #include "test/mock/core/common/mock_container.h"
39
40 using namespace testing;
41 using namespace testing::ext;
42 namespace OHOS::Ace::NG {
43 namespace {
44 const InspectorFilter filter;
45 const std::string NAVIGATION_TITLE = "NavigationTestNg";
46 const std::string TEST_TAG = "test";
47 constexpr float DEFAULT_ROOT_HEIGHT = 800.f;
48 constexpr float DEFAULT_ROOT_WIDTH = 480.f;
49 } // namespace
50
51 class NavigationTestNg : public testing::Test {
52 public:
53 static void SetUpTestSuite();
54 static void TearDownTestSuite();
55 void MockPipelineContextGetTheme();
56 static void RunMeasureAndLayout(RefPtr<LayoutWrapperNode>& layoutWrapper, float width = DEFAULT_ROOT_WIDTH);
57 static RefPtr<NavDestinationGroupNode> CreateDestination(const std::string name);
58 };
59
SetUpTestSuite()60 void NavigationTestNg::SetUpTestSuite()
61 {
62 MockPipelineContext::SetUp();
63 MockContainer::SetUp();
64 MockContainer::Current()->SetNavigationRoute(AceType::MakeRefPtr<MockNavigationRoute>(""));
65 auto context = MockPipelineContext::GetCurrent();
66 if (context) {
67 context->stageManager_ = nullptr;
68 }
69 }
70
TearDownTestSuite()71 void NavigationTestNg::TearDownTestSuite()
72 {
73 MockPipelineContext::TearDown();
74 MockContainer::TearDown();
75 }
76
RunMeasureAndLayout(RefPtr<LayoutWrapperNode> & layoutWrapper,float width)77 void NavigationTestNg::RunMeasureAndLayout(RefPtr<LayoutWrapperNode>& layoutWrapper, float width)
78 {
79 layoutWrapper->SetActive();
80 layoutWrapper->SetRootMeasureNode();
81 LayoutConstraintF LayoutConstraint;
82 LayoutConstraint.parentIdealSize = { width, DEFAULT_ROOT_HEIGHT };
83 LayoutConstraint.percentReference = { width, DEFAULT_ROOT_HEIGHT };
84 LayoutConstraint.selfIdealSize = { width, DEFAULT_ROOT_HEIGHT };
85 LayoutConstraint.maxSize = { width, DEFAULT_ROOT_HEIGHT };
86 layoutWrapper->Measure(LayoutConstraint);
87 layoutWrapper->Layout();
88 layoutWrapper->MountToHostOnMainThread();
89 }
90
MockPipelineContextGetTheme()91 void NavigationTestNg::MockPipelineContextGetTheme()
92 {
93 auto themeManager = AceType::MakeRefPtr<MockThemeManager>();
94 MockPipelineContext::GetCurrent()->SetThemeManager(themeManager);
95 EXPECT_CALL(*themeManager, GetTheme(_)).WillRepeatedly(Return(AceType::MakeRefPtr<NavigationBarTheme>()));
96 EXPECT_CALL(*themeManager, GetTheme(_, _)).WillRepeatedly(Return(AceType::MakeRefPtr<NavigationBarTheme>()));
97 }
98
CreateDestination(const std::string name)99 RefPtr<NavDestinationGroupNode> NavigationTestNg::CreateDestination(const std::string name)
100 {
101 auto* stack = ViewStackProcessor::GetInstance();
102 // navDestination node
103 int32_t nodeId = stack->ClaimNodeId();
104 ACE_LAYOUT_SCOPED_TRACE("Create[%s][self:%d]", V2::NAVDESTINATION_VIEW_ETS_TAG, nodeId);
105 auto frameNode = NavDestinationGroupNode::GetOrCreateGroupNode(
106 V2::NAVDESTINATION_VIEW_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<NavDestinationPattern>(); });
107 EXPECT_NE(frameNode, nullptr);
108 auto pattern = AceType::DynamicCast<NavDestinationPattern>(frameNode->GetPattern());
109 EXPECT_NE(pattern, nullptr);
110 pattern->SetName(name);
111 auto context = AceType::MakeRefPtr<NavDestinationContext>();
112 auto pathInfo = AceType::MakeRefPtr<NavPathInfo>();
113 pathInfo->name_ = name;
114 context->SetNavPathInfo(pathInfo);
115 return frameNode;
116 }
117
118 struct TestProperty {
119 std::optional<bool> isOn = std::nullopt;
120 std::optional<Color> selectedColor = std::nullopt;
121 std::optional<Color> backgroundColor = std::nullopt;
122 };
123
124 /**
125 * @tc.name: NavigationModelTest004
126 * @tc.desc: Test NavigationModel SetTitle & SetSubTitle.
127 * @tc.type: FUNC
128 */
129 HWTEST_F(NavigationTestNg, NavigationModelTest004, TestSize.Level1)
130 {
131 MockPipelineContextGetTheme();
132 NavigationModelNG navigationModel;
133 navigationModel.Create();
134 navigationModel.SetNavigationStack();
135 navigationModel.SetTitle("navigationView", true);
136 navigationModel.SetSubtitle("subtitle");
137 auto frameNode = AceType::Claim(ViewStackProcessor::GetInstance()->GetMainFrameNode());
138 ASSERT_NE(frameNode, nullptr);
139 auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
140 ASSERT_NE(navigationGroupNode, nullptr);
141 auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
142 ASSERT_NE(navBarNode, nullptr);
143 }
144
145 /**
146 * @tc.name: NavigationModelTest003
147 * @tc.desc: Test NavigationModel SetHideToolBar false.
148 * @tc.type: FUNC
149 */
150 HWTEST_F(NavigationTestNg, NavigationModelTest003, TestSize.Level1)
151 {
152 NavigationModelNG navigationModel;
153 navigationModel.Create();
154 navigationModel.SetNavigationStack();
155 navigationModel.SetTitle("navigationModel", false);
156 auto frameNode = AceType::Claim(ViewStackProcessor::GetInstance()->GetMainFrameNode());
157 EXPECT_NE(frameNode, nullptr);
158 auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
159 EXPECT_NE(navigationGroupNode, nullptr);
160 auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
161 EXPECT_NE(navBarNode, nullptr);
162 auto navBarLayoutProperty = navBarNode->GetLayoutProperty<NavBarLayoutProperty>();
163 EXPECT_NE(navBarLayoutProperty, nullptr);
164 navigationModel.SetHideToolBar(false);
165 EXPECT_EQ(navBarLayoutProperty->GetHideToolBar().value_or(false), false);
166 }
167
168 /**
169 * @tc.name: NavigationModelNG007
170 * @tc.desc: Test NavigationPattern::CheckTopNavPathChange
171 * @tc.type: FUNC
172 */
173 HWTEST_F(NavigationTestNg, NavigationModelNG007, TestSize.Level1)
174 {
175 /**
176 * @tc.steps: step1. create navigation.
177 */
178 NavigationModelNG model;
179 model.Create();
180 model.SetNavigationStack();
181 auto navigation = AceType::DynamicCast<NavigationGroupNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
182 ASSERT_NE(navigation, nullptr);
183 auto navigationPattern = navigation->GetPattern<NavigationPattern>();
184 ASSERT_NE(navigationPattern, nullptr);
185 auto narBarNode = AceType::DynamicCast<NavBarNode>(navigation->GetNavBarNode());
186 ASSERT_NE(narBarNode, nullptr);
187 /**
188 * @tc.steps: step2. construct correct arguments of navigationPattern->CheckTopNavPathChange then call it.
189 * @tc.expected: check whether the properties is correct.
190 */
191 auto preTopNavDestination = NavDestinationGroupNode::GetOrCreateGroupNode(
__anoncc4618fd0302() 192 V2::NAVDESTINATION_VIEW_ETS_TAG, 100, []() { return AceType::MakeRefPtr<NavDestinationPattern>(); });
193 auto newTopNavDestination = NavDestinationGroupNode::GetOrCreateGroupNode(
__anoncc4618fd0402() 194 V2::NAVDESTINATION_VIEW_ETS_TAG, 101, []() { return AceType::MakeRefPtr<NavDestinationPattern>(); });
195
196 auto titleBarNode = TitleBarNode::GetOrCreateTitleBarNode(
__anoncc4618fd0502() 197 "titleBarNode", 102, []() { return AceType::MakeRefPtr<TitleBarPattern>(); });
198 ASSERT_NE(titleBarNode, nullptr);
199 narBarNode->titleBarNode_ = titleBarNode;
200 preTopNavDestination->titleBarNode_ = titleBarNode;
201 newTopNavDestination->titleBarNode_ = titleBarNode;
202 navigationPattern->SetNavigationMode(NavigationMode::STACK);
203 navigationPattern->TransitionWithAnimation(nullptr, nullptr, false);
204 navigationPattern->TransitionWithAnimation(preTopNavDestination, nullptr, false);
205 ASSERT_EQ(preTopNavDestination->transitionType_, PageTransitionType::EXIT_POP);
206 navigationPattern->TransitionWithAnimation(preTopNavDestination, newTopNavDestination, false);
207 ASSERT_EQ(newTopNavDestination->transitionType_, PageTransitionType::ENTER_PUSH);
208 navigationPattern->TransitionWithAnimation(preTopNavDestination, newTopNavDestination, true);
209 ASSERT_EQ(preTopNavDestination->transitionType_, PageTransitionType::EXIT_POP);
210 }
211
212 /**
213 * @tc.name: NavigationModelNG008
214 * @tc.desc: Test NavigationPattern::OnNavBarStateChange
215 * @tc.type: FUNC
216 */
217 HWTEST_F(NavigationTestNg, NavigationModelNG008, TestSize.Level1)
218 {
219 /**
220 * @tc.steps: step1. create navigation.
221 */
222 NavigationModelNG model;
223 model.Create();
224 model.SetNavigationStack();
225 auto navigation = AceType::DynamicCast<NavigationGroupNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
226 ASSERT_NE(navigation, nullptr);
227 auto navigationPattern = navigation->GetPattern<NavigationPattern>();
228 ASSERT_NE(navigationPattern, nullptr);
229 ASSERT_NE(AceType::DynamicCast<NavBarNode>(navigation->GetNavBarNode()), nullptr);
230
231 /**
232 * @tc.steps: step2. construct correct condition of navigationPattern->OnNavBarStateChange then call it.
233 * @tc.expected: check whether the properties is correct.
234 */
235 navigationPattern->navigationMode_ = NavigationMode::SPLIT;
236 navigationPattern->GetLayoutProperty<NavigationLayoutProperty>()->propHideNavBar_ = false;
237 navigationPattern->OnNavBarStateChange(true);
238 ASSERT_FALSE(navigationPattern->GetLayoutProperty<NavigationLayoutProperty>()->propHideNavBar_.value());
239
240 navigationPattern->navigationMode_ = NavigationMode::STACK;
241 navigationPattern->GetLayoutProperty<NavigationLayoutProperty>()->propHideNavBar_ = false;
242 auto preTopNavDestination = NavDestinationGroupNode::GetOrCreateGroupNode(
__anoncc4618fd0602() 243 V2::NAVDESTINATION_VIEW_ETS_TAG, 100, []() { return AceType::MakeRefPtr<NavDestinationPattern>(); });
244 navigationPattern->navigationStack_->Add("preTopNavDestination", preTopNavDestination);
245 navigationPattern->OnNavBarStateChange(true);
246 ASSERT_FALSE(navigationPattern->navigationStack_->Empty());
247
248 navigationPattern->navBarVisibilityChange_ = false;
249 navigationPattern->OnNavBarStateChange(false);
250
251 navigationPattern->navBarVisibilityChange_ = true;
252 navigationPattern->navigationMode_ = NavigationMode::STACK;
253 navigationPattern->OnNavBarStateChange(false);
254
255 navigationPattern->navBarVisibilityChange_ = true;
256 navigationPattern->navigationMode_ = NavigationMode::SPLIT;
257 navigationPattern->OnNavBarStateChange(false);
258 ASSERT_FALSE(navigationPattern->navBarVisibilityChange_);
259
260 navigationPattern->navBarVisibilityChange_ = true;
261 navigationPattern->navigationMode_ = NavigationMode::SPLIT;
262 navigationPattern->GetLayoutProperty<NavigationLayoutProperty>()->propHideNavBar_ = true;
263 navigationPattern->OnNavBarStateChange(false);
264 ASSERT_FALSE(navigationPattern->navBarVisibilityChange_);
265 }
266
267 /**
268 * @tc.name: NavigationModelNG0011
269 * @tc.desc: Test NavigationModelNG::SetCustomToolBar && SetToolBarItems
270 * @tc.type: FUNC
271 */
272 HWTEST_F(NavigationTestNg, NavigationModelNG0011, TestSize.Level1)
273 {
274 /**
275 * @tc.steps: step1. create navigation.
276 */
277 NavigationModelNG model;
278 model.Create();
279 model.SetNavigationStack();
280 auto navigation =
281 AceType::DynamicCast<NavigationGroupNode>(ViewStackProcessor::GetInstance()->GetMainElementNode());
282 ASSERT_NE(navigation, nullptr);
283 auto navigationPattern = navigation->GetPattern<NavigationPattern>();
284 ASSERT_NE(navigationPattern, nullptr);
285 auto navBarNode = AceType::DynamicCast<NavBarNode>(navigation->GetNavBarNode());
286 ASSERT_NE(navBarNode, nullptr);
287
288 auto customNode = FrameNode::CreateFrameNode("text", 113, AceType::MakeRefPtr<TextPattern>());
289 model.SetCustomToolBar(customNode);
290 ASSERT_EQ(navBarNode->GetToolBarNodeOperationValue(), ChildNodeOperation::REPLACE);
291
292 navBarNode->propPrevToolBarIsCustom_ = true;
293 model.SetCustomToolBar(customNode);
294 ASSERT_EQ(navBarNode->GetToolBarNodeOperationValue(), ChildNodeOperation::REPLACE);
295
296 customNode =
297 FrameNode::CreateFrameNode("text", navBarNode->GetToolBarNode()->GetId(), AceType::MakeRefPtr<TextPattern>());
298 model.SetCustomToolBar(customNode);
299 ASSERT_EQ(navBarNode->GetToolBarNodeOperationValue(), ChildNodeOperation::NONE);
300
301 std::vector<NG::BarItem> toolBarItems;
302 model.SetToolBarItems(std::move(toolBarItems));
303 ASSERT_EQ(navBarNode->GetToolBarNodeOperationValue(), ChildNodeOperation::REPLACE);
304
305 navBarNode->preToolBarNode_ = nullptr;
306 model.SetToolBarItems(std::move(toolBarItems));
307 ASSERT_EQ(navBarNode->GetToolBarNodeOperationValue(), ChildNodeOperation::REPLACE);
308 }
309
310 /**
311 * @tc.name: NavigationModelNG0012
312 * @tc.desc: Test NavigationModelNG::SetToolbarConfiguration
313 * @tc.type: FUNC
314 */
315 HWTEST_F(NavigationTestNg, NavigationModelNG0012, TestSize.Level1)
316 {
317 /**
318 * @tc.steps: step1. create navigation.
319 */
320 NavigationModelNG model;
321 model.Create();
322 model.SetNavigationStack();
323 auto navigation =
324 AceType::DynamicCast<NavigationGroupNode>(ViewStackProcessor::GetInstance()->GetMainElementNode());
325 ASSERT_NE(navigation, nullptr);
326 auto navigationPattern = navigation->GetPattern<NavigationPattern>();
327 ASSERT_NE(navigationPattern, nullptr);
328 auto navBarNode = AceType::DynamicCast<NavBarNode>(navigation->GetNavBarNode());
329 ASSERT_NE(navBarNode, nullptr);
330
331 navBarNode->propPrevToolBarIsCustom_ = true;
332 std::vector<NG::BarItem> toolBarItems;
333 model.SetToolbarConfiguration(std::move(toolBarItems));
334 ASSERT_EQ(navBarNode->GetToolBarNodeOperationValue(), ChildNodeOperation::REPLACE);
335 }
336
337 /**
338 * @tc.name: NavigationModelNG0013
339 * @tc.desc: Test NavigationContentLayoutAlgorithm::Measure
340 * @tc.type: FUNC
341 */
342 HWTEST_F(NavigationTestNg, NavigationModelNG0013, TestSize.Level1)
343 {
344 /**
345 * @tc.steps: step1. create navigation.
346 */
347 auto navigation = NavigationGroupNode::GetOrCreateGroupNode(
__anoncc4618fd0702() 348 "navigation", 120, []() { return AceType::MakeRefPtr<NavigationPattern>(); });
349 auto navigationStack = AceType::MakeRefPtr<NavigationStack>();
350 navigation->GetPattern<NavigationPattern>()->SetNavigationStack(std::move(navigationStack));
351 auto layoutWrapper = navigation->CreateLayoutWrapper();
352
353 auto navDestination = NavDestinationGroupNode::GetOrCreateGroupNode(
__anoncc4618fd0802() 354 "navDestination", 121, []() { return AceType::MakeRefPtr<NavDestinationPattern>(); });
355 auto navDestinationWrapper1 = navDestination->CreateLayoutWrapper();
356
357 ASSERT_EQ(layoutWrapper->GetTotalChildCount(), 0);
358 ASSERT_NE(layoutWrapper->GetLayoutProperty(), nullptr);
359 ASSERT_NE(navDestinationWrapper1->GetLayoutAlgorithm(), nullptr);
360 ASSERT_NE(navDestinationWrapper1->GetLayoutAlgorithm()->GetLayoutAlgorithm(), nullptr);
361
362 auto temp1 = AceType::MakeRefPtr<NavDestinationLayoutAlgorithm>();
363 navDestinationWrapper1->layoutAlgorithm_->layoutAlgorithm_ = temp1;
364
365 layoutWrapper->AppendChild(navDestinationWrapper1);
366
367 NavigationContentLayoutAlgorithm algorithm;
368 algorithm.Measure(AceType::RawPtr(layoutWrapper));
369
370 auto navDestination2 = NavDestinationGroupNode::GetOrCreateGroupNode(
__anoncc4618fd0902() 371 "navDestination", 121, []() { return AceType::MakeRefPtr<NavDestinationPattern>(); });
372 auto navDestinationWrapper2 = navDestination2->CreateLayoutWrapper();
373 auto temp2 = AceType::MakeRefPtr<NavDestinationLayoutAlgorithm>();
374 temp2->isShown_ = true;
375 navDestinationWrapper2->layoutAlgorithm_->layoutAlgorithm_ = temp2;
376 layoutWrapper->AppendChild(navDestinationWrapper2);
377 algorithm.Measure(AceType::RawPtr(layoutWrapper));
378 ASSERT_TRUE(temp2->isShown_);
379 temp1->isShown_ = true;
380 algorithm.Measure(AceType::RawPtr(layoutWrapper));
381 ASSERT_TRUE(temp1->isShown_);
382 }
383
384 /**
385 * @tc.name: NavigationModelNG0015
386 * @tc.desc: Test NavigationModelNG::UpdateNavDestinationNodeWithoutMarkDirty
387 * @tc.type: FUNC
388 */
389 HWTEST_F(NavigationTestNg, NavigationModelNG0015, TestSize.Level1)
390 {
391 /**
392 * @tc.steps: step1. create navigation.
393 */
394 NavigationModelNG model;
395 model.Create();
396 model.SetNavigationStack();
397 auto navigation =
398 AceType::DynamicCast<NavigationGroupNode>(ViewStackProcessor::GetInstance()->GetMainElementNode());
399 ASSERT_NE(navigation, nullptr);
400 auto navigationPattern = navigation->GetPattern<NavigationPattern>();
401 ASSERT_NE(navigationPattern, nullptr);
402
403 auto navigationContentNode =
404 FrameNode::CreateFrameNode("navigationContent", 123, AceType::MakeRefPtr<ButtonPattern>());
405 navigation->contentNode_ = navigationContentNode;
406 ASSERT_NE(navigationPattern->navigationStack_, nullptr);
407 /**
408 * @tc.steps: step2. create navDestination.
409 */
410 auto navDestination1 = NavDestinationGroupNode::GetOrCreateGroupNode(
__anoncc4618fd0a02() 411 "NavDestination", 124, []() { return AceType::MakeRefPtr<NavDestinationPattern>(); });
412 auto navDestination2 = NavDestinationGroupNode::GetOrCreateGroupNode(
__anoncc4618fd0b02() 413 "NavDestination", 125, []() { return AceType::MakeRefPtr<NavDestinationPattern>(); });
414 auto navDestination3 = NavDestinationGroupNode::GetOrCreateGroupNode(
__anoncc4618fd0c02() 415 "NavDestination", 126, []() { return AceType::MakeRefPtr<NavDestinationPattern>(); });
416 auto navDestination4 = NavDestinationGroupNode::GetOrCreateGroupNode(
__anoncc4618fd0d02() 417 "NavDestination", 127, []() { return AceType::MakeRefPtr<NavDestinationPattern>(); });
418 auto navDestination5 = NavDestinationGroupNode::GetOrCreateGroupNode(
__anoncc4618fd0e02() 419 "NavDestination", 129, []() { return AceType::MakeRefPtr<NavDestinationPattern>(); });
420 auto navDestination6 = NavDestinationGroupNode::GetOrCreateGroupNode(
__anoncc4618fd0f02() 421 "NavDestination", 130, []() { return AceType::MakeRefPtr<NavDestinationPattern>(); });
422 auto navDestination7 = NavDestinationGroupNode::GetOrCreateGroupNode(
__anoncc4618fd1002() 423 "NavDestination", 131, []() { return AceType::MakeRefPtr<NavDestinationPattern>(); });
424 auto child8 = FrameNode::CreateFrameNode("NavDestination", 132, AceType::MakeRefPtr<ButtonPattern>());
425
426 auto temp = NavDestinationGroupNode::GetOrCreateGroupNode(
__anoncc4618fd1102() 427 "NavDestination", 133, []() { return AceType::MakeRefPtr<NavDestinationPattern>(); });
428 /**
429 * @tc.steps: step3. add element to navigationPattern->navigationStack_.
430 */
431 navigationPattern->navigationStack_->Add("navDestination1", navDestination1);
432 navigationPattern->navigationStack_->Add("navDestination2", navDestination2);
433 navigationPattern->navigationStack_->Add("navDestination3", navDestination3);
434
435 auto pattern5 = navDestination5->GetPattern<NavDestinationPattern>();
436 pattern5->customNode_ = AceType::RawPtr(navDestination5);
437
438 pattern5->shallowBuilder_ = AceType::MakeRefPtr<ShallowBuilder>(
__anoncc4618fd1202() 439 []() { return FrameNode::CreateFrameNode("temp", 234, AceType::MakeRefPtr<ButtonPattern>()); });
440 navDestination5->contentNode_ = FrameNode::CreateFrameNode("temp", 235, AceType::MakeRefPtr<ButtonPattern>());
441
442 auto pattern6 = navDestination6->GetPattern<NavDestinationPattern>();
443 pattern6->customNode_ = AceType::RawPtr(navDestination6);
444
445 auto pattern7 = navDestination7->GetPattern<NavDestinationPattern>();
446 pattern7->customNode_ = AceType::RawPtr(navDestination7);
447
448 ASSERT_NE(navDestination7->GetPattern<NavDestinationPattern>()->GetCustomNode(), nullptr);
449 /**
450 * @tc.steps: step4. add element to navigationContentNode->children_.
451 */
452 navigationContentNode->children_.push_back(navDestination1);
453 navigationContentNode->children_.push_back(navDestination4);
454 navigationContentNode->children_.push_back(navDestination2);
455 navigationContentNode->children_.push_back(navDestination5);
456 navigationContentNode->children_.push_back(navDestination6);
457 navigationContentNode->children_.push_back(navDestination7);
458 navigationContentNode->children_.push_back(child8);
459
460 navigation->UpdateNavDestinationNodeWithoutMarkDirty(temp);
461 }
462
463 /**
464 * @tc.name: NavigationModelNG0016
465 * @tc.desc: Test NavigationModelNG::GetNavDestinationNode
466 * @tc.type: FUNC
467 */
468 HWTEST_F(NavigationTestNg, NavigationModelNG0016, TestSize.Level1)
469 {
470 /**
471 * @tc.steps: step1. create navigation.
472 */
473 NavigationModelNG model;
474 model.Create();
475 model.SetNavigationStack();
476 auto navigation =
477 AceType::DynamicCast<NavigationGroupNode>(ViewStackProcessor::GetInstance()->GetMainElementNode());
478 ASSERT_NE(navigation, nullptr);
479 auto navigationPattern = navigation->GetPattern<NavigationPattern>();
480 ASSERT_NE(navigationPattern, nullptr);
481
482 auto navigationContentNode =
483 FrameNode::CreateFrameNode("navigationContent", 123, AceType::MakeRefPtr<ButtonPattern>());
484 navigation->contentNode_ = navigationContentNode;
485
486 auto result = navigation->GetNavDestinationNode(navigationContentNode);
487 ASSERT_EQ(result, nullptr);
488 }
489
490 /**
491 * @tc.name: NavigationModelNG0017
492 * @tc.desc: Test NavigationModelNG::CheckCanHandleBack
493 * @tc.type: FUNC
494 */
495 HWTEST_F(NavigationTestNg, NavigationModelNG0017, TestSize.Level1)
496 {
497 /**
498 * @tc.steps: step1. create navigation.
499 */
500 NavigationModelNG model;
501 model.Create();
502 model.SetNavigationStack();
503 auto navigation =
504 AceType::DynamicCast<NavigationGroupNode>(ViewStackProcessor::GetInstance()->GetMainElementNode());
505 ASSERT_NE(navigation, nullptr);
506 auto navigationPattern = navigation->GetPattern<NavigationPattern>();
507 ASSERT_NE(navigationPattern, nullptr);
508
509 auto navigationContentNode =
510 FrameNode::CreateFrameNode("navigationContent", 123, AceType::MakeRefPtr<ButtonPattern>());
511 navigation->contentNode_ = navigationContentNode;
512
513 auto child = FrameNode::CreateFrameNode("navigationContent", 345, AceType::MakeRefPtr<ButtonPattern>());
514 navigationContentNode->children_.push_back(child);
515
516 bool isEntry = false;
517 navigation->CheckCanHandleBack(isEntry);
518 ASSERT_EQ(navigationPattern->navigationMode_, NavigationMode::AUTO);
519 navigationPattern->navigationMode_ = NavigationMode::SPLIT;
520 navigation->CheckCanHandleBack(isEntry);
521 ASSERT_EQ(navigationPattern->navigationMode_, NavigationMode::SPLIT);
522 auto child2 = FrameNode::CreateFrameNode("navigationContent", 346, AceType::MakeRefPtr<ButtonPattern>());
523 navigationContentNode->children_.push_back(child2);
524 navigationPattern->navigationMode_ = NavigationMode::SPLIT;
525 navigation->CheckCanHandleBack(isEntry);
526 ASSERT_EQ(navigationPattern->navigationMode_, NavigationMode::SPLIT);
527 }
528
529 /**
530 * @tc.name: NavigationModelNG0018
531 * @tc.desc: Test NavigationModelNG::UpdateNavDestinationNodeWithoutMarkDirty
532 * @tc.type: FUNC
533 */
534 HWTEST_F(NavigationTestNg, NavigationModelNG0018, TestSize.Level1)
535 {
536 /**
537 * @tc.steps: step1. create navigation.
538 */
539 NavigationModelNG model;
540 model.Create();
541 model.SetNavigationStack();
542 auto navigation =
543 AceType::DynamicCast<NavigationGroupNode>(ViewStackProcessor::GetInstance()->GetMainElementNode());
544 ASSERT_NE(navigation, nullptr);
545 auto navigationPattern = navigation->GetPattern<NavigationPattern>();
546 ASSERT_NE(navigationPattern, nullptr);
547
548 auto navigationContentNode =
549 FrameNode::CreateFrameNode("navigationContent", 123, AceType::MakeRefPtr<ButtonPattern>());
550 navigation->contentNode_ = navigationContentNode;
551 ASSERT_NE(navigationPattern->navigationStack_, nullptr);
552 /**
553 * @tc.steps: step2. create navDestination.
554 */
555 auto navDestination1 = NavDestinationGroupNode::GetOrCreateGroupNode(
__anoncc4618fd1302() 556 "NavDestination", 154, []() { return AceType::MakeRefPtr<NavDestinationPattern>(); });
557 auto navDestination2 = NavDestinationGroupNode::GetOrCreateGroupNode(
__anoncc4618fd1402() 558 "NavDestination", 155, []() { return AceType::MakeRefPtr<NavDestinationPattern>(); });
559 auto navDestination3 = NavDestinationGroupNode::GetOrCreateGroupNode(
__anoncc4618fd1502() 560 "NavDestination", 156, []() { return AceType::MakeRefPtr<NavDestinationPattern>(); });
561 auto navDestination4 = NavDestinationGroupNode::GetOrCreateGroupNode(
__anoncc4618fd1602() 562 "NavDestination", 157, []() { return AceType::MakeRefPtr<NavDestinationPattern>(); });
563 auto navDestination5 = NavDestinationGroupNode::GetOrCreateGroupNode(
__anoncc4618fd1702() 564 "NavDestination", 159, []() { return AceType::MakeRefPtr<NavDestinationPattern>(); });
565 auto navDestination6 = NavDestinationGroupNode::GetOrCreateGroupNode(
__anoncc4618fd1802() 566 "NavDestination", 160, []() { return AceType::MakeRefPtr<NavDestinationPattern>(); });
567 auto navDestination7 = NavDestinationGroupNode::GetOrCreateGroupNode(
__anoncc4618fd1902() 568 "NavDestination", 161, []() { return AceType::MakeRefPtr<NavDestinationPattern>(); });
569 auto child8 = FrameNode::CreateFrameNode("NavDestination", 132, AceType::MakeRefPtr<ButtonPattern>());
570
571 auto temp = NavDestinationGroupNode::GetOrCreateGroupNode(
__anoncc4618fd1a02() 572 "NavDestination", 163, []() { return AceType::MakeRefPtr<NavDestinationPattern>(); });
573
574 auto pattern5 = navDestination5->GetPattern<NavDestinationPattern>();
575 pattern5->customNode_ = AceType::RawPtr(navDestination5);
576
577 pattern5->shallowBuilder_ = AceType::MakeRefPtr<ShallowBuilder>(
__anoncc4618fd1b02() 578 []() { return FrameNode::CreateFrameNode("temp", 236, AceType::MakeRefPtr<ButtonPattern>()); });
579 navDestination5->contentNode_ = FrameNode::CreateFrameNode("temp", 245, AceType::MakeRefPtr<ButtonPattern>());
580
581 auto pattern6 = navDestination6->GetPattern<NavDestinationPattern>();
582 pattern6->customNode_ = AceType::RawPtr(navDestination6);
583
584 auto pattern7 = navDestination7->GetPattern<NavDestinationPattern>();
585 pattern7->customNode_ = AceType::RawPtr(temp);
586
587 ASSERT_NE(navDestination7->GetPattern<NavDestinationPattern>()->GetCustomNode(), nullptr);
588 /**
589 * @tc.steps: step4. add element to navigationContentNode->children_.
590 */
591 navigationContentNode->children_.push_back(navDestination1);
592 navigationContentNode->children_.push_back(navDestination4);
593 navigationContentNode->children_.push_back(navDestination2);
594 navigationContentNode->children_.push_back(navDestination5);
595 navigationContentNode->children_.push_back(navDestination6);
596 navigationContentNode->children_.push_back(navDestination7);
597 navigationContentNode->children_.push_back(child8);
598
599 navigation->UpdateNavDestinationNodeWithoutMarkDirty(temp);
600 }
601
602 /**
603 * @tc.name: NavigationModelNG0019
604 * @tc.desc: Test NavigationLayoutAlgorithm::IsAutoHeight
605 * @tc.type: FUNC
606 */
607 HWTEST_F(NavigationTestNg, NavigationModelNG0019, TestSize.Level1)
608 {
609 /**
610 * @tc.steps: step1. create navigation.
611 */
612 NavigationModelNG model;
613 model.Create();
614 model.SetNavigationStack();
615 auto navigation =
616 AceType::DynamicCast<NavigationGroupNode>(ViewStackProcessor::GetInstance()->GetMainElementNode());
617 ASSERT_NE(navigation, nullptr);
618
619 auto property = AceType::MakeRefPtr<LayoutProperty>();
620 std::unique_ptr<MeasureProperty> calcLayoutConstraint = std::make_unique<MeasureProperty>();
621 std::optional<CalcLength> len = CalcLength("auto");
622 calcLayoutConstraint->selfIdealSize = CalcSize(std::nullopt, len);
623 property->calcLayoutConstraint_ = std::move(calcLayoutConstraint);
624
625 auto& test = property->GetCalcLayoutConstraint();
626 ASSERT_NE(test, nullptr);
627 ASSERT_TRUE(test->selfIdealSize.has_value());
628 ASSERT_TRUE(test->selfIdealSize->Height().has_value());
629 ASSERT_NE(test->selfIdealSize->Height().value().ToString().find("auto"), std::string::npos);
630
631 NavigationLayoutAlgorithm algorithm;
632 auto result = algorithm.IsAutoHeight(property);
633 ASSERT_TRUE(result);
634
635 len = CalcLength("");
636 property->calcLayoutConstraint_->selfIdealSize = CalcSize(std::nullopt, len);
637 result = algorithm.IsAutoHeight(property);
638 ASSERT_FALSE(result);
639
640 property->calcLayoutConstraint_->selfIdealSize = CalcSize(std::nullopt, std::nullopt);
641 result = algorithm.IsAutoHeight(property);
642 ASSERT_FALSE(result);
643
644 property->calcLayoutConstraint_->selfIdealSize = std::nullopt;
645 result = algorithm.IsAutoHeight(property);
646 ASSERT_FALSE(result);
647
648 property->calcLayoutConstraint_ = nullptr;
649 result = algorithm.IsAutoHeight(property);
650 ASSERT_FALSE(result);
651 }
652
653 /**
654 * @tc.name: NavigationModelNG0020
655 * @tc.desc: Test NavigationLayoutAlgorithm::SizeCalculationSplit
656 * @tc.type: FUNC
657 */
658 HWTEST_F(NavigationTestNg, NavigationModelNG0020, TestSize.Level1)
659 {
660 /**
661 * @tc.steps: step1. create navigation.
662 */
663 NavigationModelNG model;
664 model.Create();
665 model.SetNavigationStack();
666 auto navigation =
667 AceType::DynamicCast<NavigationGroupNode>(ViewStackProcessor::GetInstance()->GetMainElementNode());
668 ASSERT_NE(navigation, nullptr);
669
670 auto algorithm = AceType::MakeRefPtr<NavigationLayoutAlgorithm>();
671 auto property = AceType::MakeRefPtr<NavigationLayoutProperty>();
672 property->propHideNavBar_ = true;
673 property->layoutConstraint_ = LayoutConstraintF();
674
675 algorithm->SizeCalculationSplit(navigation, property, SizeF());
676 property->propHideNavBar_ = false;
677 algorithm->realNavBarWidth_ = -1.0f;
678 algorithm->SizeCalculationSplit(navigation, property, SizeF(0.0f, 0.0f));
679 }
680
681 /**
682 * @tc.name: NavigationModelNG0021
683 * @tc.desc: Test NavigationLayoutAlgorithm::CheckSizeInSplit
684 * @tc.type: FUNC
685 */
686 HWTEST_F(NavigationTestNg, NavigationModelNG0021, TestSize.Level1)
687 {
688 /**
689 * @tc.steps: step1. create navigation.
690 */
691 NavigationModelNG model;
692 model.Create();
693 model.SetNavigationStack();
694 auto navigation =
695 AceType::DynamicCast<NavigationGroupNode>(ViewStackProcessor::GetInstance()->GetMainElementNode());
696 ASSERT_NE(navigation, nullptr);
697
698 auto algorithm = AceType::MakeRefPtr<NavigationLayoutAlgorithm>();
699 auto property = AceType::MakeRefPtr<NavigationLayoutProperty>();
700 property->propHideNavBar_ = true;
701 property->layoutConstraint_ = LayoutConstraintF();
702
703 algorithm->userSetMinContentFlag_ = true;
704 algorithm->userSetNavBarRangeFlag_ = false;
705 algorithm->CheckSizeInSplit(0, 0, 0, 0);
706 ASSERT_EQ(algorithm->realNavBarWidth_, 0.0f);
707
708 algorithm->CheckSizeInSplit(50, 0, 0, 0);
709 algorithm->realNavBarWidth_ = 60;
710 algorithm->CheckSizeInSplit(50, 0, 0, 0);
711 ASSERT_FALSE(algorithm->userSetNavBarRangeFlag_);
712
713 algorithm->userSetMinContentFlag_ = false;
714 algorithm->userSetNavBarRangeFlag_ = false;
715 algorithm->userSetNavBarWidthFlag_ = true;
716 algorithm->CheckSizeInSplit(50, 0, 0, 0);
717 ASSERT_FALSE(algorithm->userSetMinContentFlag_);
718
719 algorithm->userSetNavBarWidthFlag_ = false;
720 algorithm->realNavBarWidth_ = 0;
721 algorithm->CheckSizeInSplit(50, 0, 0, 0);
722 ASSERT_FALSE(algorithm->userSetNavBarWidthFlag_);
723
724 algorithm->realNavBarWidth_ = 60;
725 algorithm->userSetNavBarWidthFlag_ = false;
726 algorithm->CheckSizeInSplit(100, 0, 0, 50);
727 ASSERT_FALSE(algorithm->userSetNavBarWidthFlag_);
728
729 algorithm->userSetMinContentFlag_ = true;
730 algorithm->userSetNavBarRangeFlag_ = true;
731 algorithm->realNavBarWidth_ = 40;
732 algorithm->userSetNavBarWidthFlag_ = false;
733 algorithm->CheckSizeInSplit(100, 0, 60, 50);
734 ASSERT_TRUE(algorithm->userSetMinContentFlag_);
735 }
736
737 /**
738 * @tc.name: NavigationModelNG0022
739 * @tc.desc: Test NavigationLayoutAlgorithm::MeasureContentChild
740 * @tc.type: FUNC
741 */
742 HWTEST_F(NavigationTestNg, NavigationModelNG0022, TestSize.Level1)
743 {
744 /**
745 * @tc.steps: step1. create navigation.
746 */
747 NavigationModelNG model;
748 model.Create();
749 model.SetNavigationStack();
750 auto navigation =
751 AceType::DynamicCast<NavigationGroupNode>(ViewStackProcessor::GetInstance()->GetMainElementNode());
752 ASSERT_NE(navigation, nullptr);
753 auto navigationPattern = navigation->GetPattern<NavigationPattern>();
754 ASSERT_NE(navigationPattern, nullptr);
755 auto contentNode = FrameNode::CreateFrameNode("content", 454, AceType::MakeRefPtr<ButtonPattern>());
756 navigation->contentNode_ = contentNode;
757 navigation->children_.push_back(contentNode);
758
759 auto layoutWrapper = navigation->CreateLayoutWrapper();
760 auto navigationLayoutProperty = AceType::MakeRefPtr<NavigationLayoutProperty>();
761
762 layoutWrapper->layoutProperty_ = navigationLayoutProperty;
763 auto contentWrapper = contentNode->CreateLayoutWrapper();
764 layoutWrapper->AppendChild(contentWrapper);
765 contentNode->children_.push_back(FrameNode::CreateFrameNode("content", 456, AceType::MakeRefPtr<ButtonPattern>()));
766
767 auto algorithm = AceType::MakeRefPtr<NavigationLayoutAlgorithm>();
768 algorithm->MeasureContentChild(AceType::RawPtr(layoutWrapper), navigation, navigationLayoutProperty, SizeF());
769 ASSERT_FALSE(contentNode->children_.empty());
770
771 std::unique_ptr<MeasureProperty> calcLayoutConstraint = std::make_unique<MeasureProperty>();
772 std::optional<CalcLength> len = CalcLength(200);
773 calcLayoutConstraint->selfIdealSize = CalcSize(std::nullopt, len);
774 navigationLayoutProperty->calcLayoutConstraint_ = std::move(calcLayoutConstraint);
775 algorithm->MeasureContentChild(AceType::RawPtr(layoutWrapper), navigation, navigationLayoutProperty, SizeF());
776 algorithm->MeasureNavBar(AceType::RawPtr(layoutWrapper), navigation, navigationLayoutProperty, SizeF());
777 LayoutConstraintF constraint;
778 constraint.selfIdealSize = OptionalSizeF(20, 20);
779 navigationLayoutProperty->layoutConstraint_ = LayoutConstraintF();
780 algorithm->Measure(AceType::RawPtr(layoutWrapper));
781 ASSERT_FALSE(contentNode->children_.empty());
782 }
783
784 /**
785 * @tc.name: NavigationModelNG0023
786 * @tc.desc: Test NavigationLayoutAlgorithm::SetNavigationHeight
787 * @tc.type: FUNC
788 */
789 HWTEST_F(NavigationTestNg, NavigationModelNG0023, TestSize.Level1)
790 {
791 /**
792 * @tc.steps: step1. create navigation.
793 */
794 NavigationModelNG model;
795 model.Create();
796 model.SetNavigationStack();
797 auto navigation =
798 AceType::DynamicCast<NavigationGroupNode>(ViewStackProcessor::GetInstance()->GetMainElementNode());
799 ASSERT_NE(navigation, nullptr);
800 auto navigationPattern = navigation->GetPattern<NavigationPattern>();
801 ASSERT_NE(navigationPattern, nullptr);
802 auto contentNode = FrameNode::CreateFrameNode("content", 454, AceType::MakeRefPtr<ButtonPattern>());
803
804 auto layoutWrapper = navigation->CreateLayoutWrapper();
805
806 auto algorithm = AceType::MakeRefPtr<NavigationLayoutAlgorithm>();
807 SizeF size;
808 algorithm->SetNavigationHeight(AceType::RawPtr(layoutWrapper), size);
809
810 navigationPattern->navigationStack_->Add("11", contentNode);
811 algorithm->SetNavigationHeight(AceType::RawPtr(layoutWrapper), size);
812 ASSERT_EQ(navigationPattern->navigationMode_, NavigationMode::AUTO);
813
814 navigationPattern->navigationMode_ = NavigationMode::STACK;
815 algorithm->SetNavigationHeight(AceType::RawPtr(layoutWrapper), size);
816 ASSERT_EQ(navigationPattern->navigationMode_, NavigationMode::STACK);
817
818 navigationPattern->navigationMode_ = NavigationMode::SPLIT;
819 algorithm->SetNavigationHeight(AceType::RawPtr(layoutWrapper), size);
820 ASSERT_EQ(navigationPattern->navigationMode_, NavigationMode::SPLIT);
821 }
822
823 /**
824 * @tc.name: NavigationModelNG0025
825 * @tc.desc: Test NavBarPattern::OnWindowSizeChanged
826 * @tc.type: FUNC
827 */
828 HWTEST_F(NavigationTestNg, NavigationModelNG0025, TestSize.Level1)
829 {
830 /**
831 * @tc.steps: step1. create navigation.
832 */
833 NavigationModelNG model;
834 model.Create();
835 model.SetNavigationStack();
836 auto navigation =
837 AceType::DynamicCast<NavigationGroupNode>(ViewStackProcessor::GetInstance()->GetMainElementNode());
838 ASSERT_NE(navigation, nullptr);
839 auto navigationPattern = navigation->GetPattern<NavigationPattern>();
840 ASSERT_NE(navigationPattern, nullptr);
841 auto contentNode = FrameNode::CreateFrameNode("content", 454, AceType::MakeRefPtr<ButtonPattern>());
842
843 auto navBar =
__anoncc4618fd1c02() 844 NavBarNode::GetOrCreateNavBarNode("navBar", 300, []() { return AceType::MakeRefPtr<NavBarPattern>(); });
845 ASSERT_NE(navBar, nullptr);
846 auto navBarPattern = navBar->GetPattern<NavBarPattern>();
847 ASSERT_NE(navBarPattern, nullptr);
848 navBarPattern->OnWindowSizeChanged(20, 20, WindowSizeChangeReason::RESIZE);
849 auto titleBarNode = TitleBarNode::GetOrCreateTitleBarNode(
__anoncc4618fd1d02() 850 "titleBarNode", 301, []() { return AceType::MakeRefPtr<TitleBarPattern>(); });
851 ASSERT_EQ(titleBarNode->menu_, nullptr);
852 navBar->titleBarNode_ = titleBarNode;
853 navBarPattern->OnWindowSizeChanged(20, 20, WindowSizeChangeReason::RESIZE);
854 auto menu = FrameNode::CreateFrameNode("menu", 302, AceType::MakeRefPtr<ButtonPattern>());
855 auto barItem = BarItemNode::GetOrCreateBarItemNode(
__anoncc4618fd1e02() 856 V2::BAR_ITEM_ETS_TAG, 303, []() { return AceType::MakeRefPtr<Pattern>(); });
857 menu->children_.push_back(barItem);
858 titleBarNode->menu_ = menu;
859 barItem->isMoreItemNode_ = true;
860 navBarPattern->OnWindowSizeChanged(20, 20, WindowSizeChangeReason::RECOVER);
861 ASSERT_TRUE(barItem->isMoreItemNode_);
862 barItem->isMoreItemNode_ = false;
863 navBarPattern->OnWindowSizeChanged(20, 20, WindowSizeChangeReason::RECOVER);
864 ASSERT_FALSE(barItem->isMoreItemNode_);
865 }
866
867 HWTEST_F(NavigationTestNg, NavigationStackTest001, TestSize.Level1)
868 {
869 /**
870 * @tc.steps: step1.create navigation, and set the navigation stack
871 */
872 auto context = MockPipelineContext::GetCurrent();
873 ASSERT_NE(context, nullptr);
874 NavigationModelNG navigationModel;
875 navigationModel.Create();
876 navigationModel.SetNavigationStack();
877 navigationModel.SetTitle("navigationModel", false);
878 RefPtr<NavigationGroupNode> navigationNode =
879 AceType::DynamicCast<NavigationGroupNode>(ViewStackProcessor::GetInstance()->Finish());
880 ASSERT_NE(navigationNode, nullptr);
881 navigationNode->AttachToMainTree(false, AceType::RawPtr(context));
882
883 /**
884 * @tc.steps: step2.add page A
885 */
886 auto* viewStack = ViewStackProcessor::GetInstance();
887 // navDestination node
888 int32_t nodeId = viewStack->ClaimNodeId();
889 auto frameNode = NavDestinationGroupNode::GetOrCreateGroupNode(
__anoncc4618fd1f02() 890 V2::NAVDESTINATION_VIEW_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<NavDestinationPattern>(); });
891 auto pattern = AceType::DynamicCast<NavigationPattern>(navigationNode->GetPattern());
892 auto stack = pattern->GetNavigationStack();
893 stack->Add("A", frameNode);
894 auto navigationPattern = AceType::DynamicCast<NavigationPattern>(navigationNode->GetPattern());
895 navigationPattern->OnModifyDone();
896 navigationPattern->MarkNeedSyncWithJsStack();
897 navigationPattern->SyncWithJsStackIfNeeded();
898 auto targetNode = navigationPattern->GetNavigationStack()->Get();
899 ASSERT_EQ(frameNode, targetNode);
900
901 /**
902 * @tc.steps: step3. replace pageA
903 */
904 nodeId = viewStack->ClaimNodeId();
905 auto replaceNode = NavDestinationGroupNode::GetOrCreateGroupNode(
__anoncc4618fd2002() 906 V2::NAVDESTINATION_VIEW_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<NavDestinationPattern>(); });
907 stack->Pop();
908 stack->Add("C", replaceNode);
909 navigationPattern->OnModifyDone();
910 navigationPattern->MarkNeedSyncWithJsStack();
911 navigationPattern->SyncWithJsStackIfNeeded();
912 ASSERT_EQ(replaceNode, stack->Get());
913 }
914
915 HWTEST_F(NavigationTestNg, NavigationStackTest002, TestSize.Level1)
916 {
917 /**
918 * @tc.steps: step1.create navigation, and set the navigation stack
919 */
920 NavigationModelNG navigationModel;
921 navigationModel.Create();
922 navigationModel.SetTitle("navigationModel", false);
923 RefPtr<NavigationGroupNode> navigationNode =
924 AceType::DynamicCast<NavigationGroupNode>(ViewStackProcessor::GetInstance()->Finish());
925 ASSERT_NE(navigationNode, nullptr);
926 auto pattern = navigationNode->GetPattern<NavigationPattern>();
927 ASSERT_NE(pattern, nullptr);
928 pattern->SetNavigationStack(AceType::MakeRefPtr<MockNavigationStack>());
929 /**
930 * @tc.steps: step2.add page A
931 */
932 RefPtr<FrameNode> frameNode = FrameNode::CreateFrameNode("temp", 245, AceType::MakeRefPtr<NavDestinationPattern>());
933 auto stack = pattern->GetNavigationStack();
934 stack->Add("A", frameNode);
935 auto navigationPattern = AceType::DynamicCast<NavigationPattern>(navigationNode->GetPattern());
936 navigationPattern->OnModifyDone();
937 navigationPattern->MarkNeedSyncWithJsStack();
938 navigationPattern->SyncWithJsStackIfNeeded();
939 ASSERT_EQ(stack->Size(), 1);
940
941 /**
942 * @tc.steps: step3. replace pageA
943 */
944 RefPtr<FrameNode> replaceNode = FrameNode::CreateFrameNode("temp", 245,
945 AceType::MakeRefPtr<NavDestinationPattern>());
946 stack->Remove();
947 stack->Add("B", replaceNode);
948 navigationPattern->OnModifyDone();
949 navigationPattern->MarkNeedSyncWithJsStack();
950 navigationPattern->SyncWithJsStackIfNeeded();
951 ASSERT_EQ(stack->Size(), 1);
952
953 /**
954 * @tc.steps: step4. push pageC
955 */
956 stack->Add("C", frameNode);
957 navigationPattern->OnModifyDone();
958 navigationPattern->MarkNeedSyncWithJsStack();
959 navigationPattern->SyncWithJsStackIfNeeded();
960 ASSERT_EQ(stack->Size(), 2);
961 }
962
963 HWTEST_F(NavigationTestNg, NavigationReplaceTest001, TestSize.Level1)
964 {
965 /**
966 * @tc.steps: step1.create navigation, and set the navigation stack
967 */
968 NavigationModelNG navigationModel;
969 navigationModel.Create();
970 auto navigationStack = AceType::MakeRefPtr<MockNavigationStack>();
971 navigationModel.SetNavigationStack(navigationStack);
972 navigationModel.SetTitle("navigationModel", false);
973 RefPtr<NavigationGroupNode> navigationNode =
974 AceType::DynamicCast<NavigationGroupNode>(ViewStackProcessor::GetInstance()->Finish());
975 ASSERT_NE(navigationNode, nullptr);
976 auto pattern = navigationNode->GetPattern<NavigationPattern>();
977 auto stack = pattern->GetNavigationStack();
978 ASSERT_EQ(stack->GetReplaceValue(), 0);
979
980 /**
981 * @tc.steps: step2.add page A to stack
982 */
983 RefPtr<FrameNode> frameNode = FrameNode::CreateFrameNode("temp", 245, AceType::MakeRefPtr<ButtonPattern>());
984 stack->Add("A", frameNode);
985 auto navigationPattern = AceType::DynamicCast<NavigationPattern>(navigationNode->GetPattern());
986 navigationPattern->SetNavigationMode(NavigationMode::STACK);
987 navigationPattern->OnModifyDone();
988 navigationPattern->MarkNeedSyncWithJsStack();
989 navigationPattern->SyncWithJsStackIfNeeded();
990 ASSERT_EQ(stack->GetReplaceValue(), 0);
991
992 /**
993 * @tc.steps: step2.replace page A in stack
994 */
995 RefPtr<FrameNode> replaceNode = FrameNode::CreateFrameNode("temp", 245, AceType::MakeRefPtr<ButtonPattern>());
996 stack->Remove();
997 stack->Add("B", replaceNode);
998 stack->UpdateReplaceValue(1);
999 ASSERT_EQ(stack->GetReplaceValue(), 1);
1000 navigationPattern->OnModifyDone();
1001 navigationPattern->MarkNeedSyncWithJsStack();
1002 navigationPattern->SyncWithJsStackIfNeeded();
1003 ASSERT_EQ(stack->GetReplaceValue(), 0);
1004
1005 /**
1006 * @tc.steps: step2.push A
1007 */
1008 stack->Add("C", frameNode);
1009 navigationPattern->OnModifyDone();
1010 navigationPattern->MarkNeedSyncWithJsStack();
1011 navigationPattern->SyncWithJsStackIfNeeded();
1012 ASSERT_EQ(stack->GetReplaceValue(), 0);
1013 }
1014
1015 HWTEST_F(NavigationTestNg, NavigationReplaceTest002, TestSize.Level1)
1016 {
1017 /**
1018 * @tc.steps: step1.create navigation, and set the navigation stack
1019 */
1020 NavigationModelNG navigationModel;
1021 navigationModel.Create();
1022 auto navigationStack = AceType::MakeRefPtr<MockNavigationStack>();
1023 navigationModel.SetNavigationStack(navigationStack);
1024 navigationModel.SetTitle("navigationModel", false);
1025 RefPtr<NavigationGroupNode> navigationNode =
1026 AceType::DynamicCast<NavigationGroupNode>(ViewStackProcessor::GetInstance()->Finish());
1027 ASSERT_NE(navigationNode, nullptr);
1028 auto pattern = navigationNode->GetPattern<NavigationPattern>();
1029 auto stack = pattern->GetNavigationStack();
1030 ASSERT_EQ(stack->GetReplaceValue(), 0);
1031
1032 /**
1033 * @tc.steps: step2.add page A to stack
1034 */
1035 RefPtr<FrameNode> frameNode = FrameNode::CreateFrameNode("temp", 245, AceType::MakeRefPtr<ButtonPattern>());
1036 stack->Add("A", frameNode);
1037 stack->Add("A", frameNode);
1038 auto navigationPattern = AceType::DynamicCast<NavigationPattern>(navigationNode->GetPattern());
1039 navigationPattern->SetNavigationMode(NavigationMode::STACK);
1040 navigationPattern->OnModifyDone();
1041 navigationPattern->MarkNeedSyncWithJsStack();
1042 navigationPattern->SyncWithJsStackIfNeeded();
1043 ASSERT_EQ(stack->GetReplaceValue(), 0);
1044
1045 /**
1046 * @tc.steps: step2.replace page A in stack
1047 */
1048 RefPtr<FrameNode> replaceNode = FrameNode::CreateFrameNode("temp", 245, AceType::MakeRefPtr<ButtonPattern>());
1049 stack->Remove();
1050 stack->Add("B", replaceNode);
1051 stack->UpdateReplaceValue(1);
1052 ASSERT_EQ(stack->GetReplaceValue(), 1);
1053 navigationPattern->OnModifyDone();
1054 navigationPattern->MarkNeedSyncWithJsStack();
1055 navigationPattern->SyncWithJsStackIfNeeded();
1056 ASSERT_EQ(stack->GetReplaceValue(), 0);
1057
1058 /**
1059 * @tc.steps: step3.pop page B
1060 */
1061 stack->Remove();
1062 navigationPattern->OnModifyDone();
1063 navigationPattern->MarkNeedSyncWithJsStack();
1064 navigationPattern->SyncWithJsStackIfNeeded();
1065 ASSERT_EQ(stack->GetReplaceValue(), 0);
1066 }
1067
1068 HWTEST_F(NavigationTestNg, NavigationReplaceTest003, TestSize.Level1)
1069 {
1070 /**
1071 * @tc.steps: step1.create navigation, and set the navigation stack
1072 */
1073 NavigationModelNG navigationModel;
1074 navigationModel.Create();
1075 auto navigationStack = AceType::MakeRefPtr<MockNavigationStack>();
1076 navigationModel.SetNavigationStack(navigationStack);
1077 navigationModel.SetTitle("navigationModel", false);
1078 RefPtr<NavigationGroupNode> navigationNode =
1079 AceType::DynamicCast<NavigationGroupNode>(ViewStackProcessor::GetInstance()->Finish());
1080 ASSERT_NE(navigationNode, nullptr);
1081 auto pattern = navigationNode->GetPattern<NavigationPattern>();
1082 auto stack = pattern->GetNavigationStack();
1083 ASSERT_EQ(stack->GetReplaceValue(), 0);
1084
1085 /**
1086 * @tc.steps: step2.add page A to stack
1087 */
1088 RefPtr<FrameNode> frameNode = FrameNode::CreateFrameNode("temp", 245, AceType::MakeRefPtr<ButtonPattern>());
1089 stack->Add("A", frameNode);
1090 stack->Add("A", frameNode);
1091 auto navigationPattern = AceType::DynamicCast<NavigationPattern>(navigationNode->GetPattern());
1092 navigationPattern->SetNavigationMode(NavigationMode::STACK);
1093 navigationPattern->OnModifyDone();
1094 navigationPattern->MarkNeedSyncWithJsStack();
1095 navigationPattern->SyncWithJsStackIfNeeded();
1096 ASSERT_EQ(stack->GetReplaceValue(), 0);
1097
1098 /**
1099 * @tc.steps: step2.replace page A in stack
1100 */
1101 RefPtr<FrameNode> replaceNode = FrameNode::CreateFrameNode("temp", 245, AceType::MakeRefPtr<ButtonPattern>());
1102 stack->Remove();
1103 stack->Add("B", replaceNode);
1104 stack->UpdateReplaceValue(1);
1105 ASSERT_EQ(stack->GetReplaceValue(), 1);
1106 navigationPattern->OnModifyDone();
1107 navigationPattern->MarkNeedSyncWithJsStack();
1108 navigationPattern->SyncWithJsStackIfNeeded();
1109 ASSERT_EQ(stack->GetReplaceValue(), 0);
1110
1111 /**
1112 * @tc.steps: step3.pop page B
1113 */
1114 stack->Clear();
1115 navigationPattern->OnModifyDone();
1116 navigationPattern->MarkNeedSyncWithJsStack();
1117 navigationPattern->SyncWithJsStackIfNeeded();
1118 ASSERT_EQ(stack->GetReplaceValue(), 0);
1119 }
1120
1121 /**
1122 * @tc.name: NavDestinationTest001
1123 * @tc.desc: Test Dialog page visibility
1124 * @tc.type: FUNC
1125 */
1126 HWTEST_F(NavigationTestNg, NavDestinationDialogTest001, TestSize.Level1)
1127 {
1128 /**
1129 * @tc.steps: step1. create navigation stack
1130 */
1131 NavigationModelNG navigationModel;
1132 navigationModel.Create();
1133 auto navigationStack = AceType::MakeRefPtr<MockNavigationStack>();
1134 navigationModel.SetNavigationStack(navigationStack);
1135 RefPtr<NavigationGroupNode> navigationNode =
1136 AceType::DynamicCast<NavigationGroupNode>(ViewStackProcessor::GetInstance()->Finish());
1137 ASSERT_NE(navigationNode, nullptr);
1138
1139 /**
1140 * @tc.steps: step2.push page A to navDestination
1141 * @tc.expected: navbar is visible,page is visible
1142 */
1143 auto navDestination = NavDestinationGroupNode::GetOrCreateGroupNode(V2::NAVDESTINATION_VIEW_ETS_TAG,
__anoncc4618fd2102() 1144 ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<NavDestinationPattern>(); });
1145 navDestination->SetNavDestinationMode(NavDestinationMode::DIALOG);
1146 navigationStack->Add("A", navDestination);
1147 auto pattern = AceType::DynamicCast<NavigationPattern>(navigationNode->GetPattern());
1148 EXPECT_NE(pattern, nullptr);
1149 pattern->SetNavigationMode(NavigationMode::STACK);
1150 pattern->OnModifyDone();
1151 pattern->MarkNeedSyncWithJsStack();
1152 pattern->SyncWithJsStackIfNeeded();
1153 PipelineContext::GetCurrentContext()->FlushBuildFinishCallbacks();
1154 auto destinationProperty = AceType::DynamicCast<NavDestinationLayoutProperty>(navDestination->GetLayoutProperty());
1155 EXPECT_TRUE(destinationProperty != nullptr);
1156 destinationProperty->UpdateHideTitleBar(true);
1157 EXPECT_EQ(destinationProperty->GetVisibilityValue(VisibleType::VISIBLE), VisibleType::VISIBLE);
1158 auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationNode->GetNavBarNode());
1159 EXPECT_NE(navBarNode, nullptr);
1160 auto navBarProperty = navBarNode->GetLayoutProperty();
1161 EXPECT_EQ(navBarProperty->GetVisibilityValue(VisibleType::VISIBLE), VisibleType::VISIBLE);
1162
1163 /**
1164 * @tc.steps: step2. push navdestination page B
1165 * @tc.expected: page A is visible, page B is visible
1166 */
1167 auto navDestinationB = NavDestinationGroupNode::GetOrCreateGroupNode(V2::NAVDESTINATION_VIEW_ETS_TAG,
__anoncc4618fd2202() 1168 ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<NavDestinationPattern>(); });
1169 navDestinationB->SetNavDestinationMode(NavDestinationMode::DIALOG);
1170 auto navDestinationBPattern = navDestinationB->GetPattern<NavDestinationPattern>();
1171 EXPECT_NE(navDestinationBPattern, nullptr);
1172 navDestinationBPattern->SetNavigationNode(navigationNode);
1173 navigationStack->Add("B", navDestinationB);
1174 pattern->OnModifyDone();
1175 pattern->MarkNeedSyncWithJsStack();
1176 pattern->SyncWithJsStackIfNeeded();
1177 auto layoutPropertyB = AceType::DynamicCast<NavDestinationLayoutProperty>(navDestinationB->GetLayoutProperty());
1178 EXPECT_NE(layoutPropertyB, nullptr);
1179 layoutPropertyB->UpdateHideTitleBar(true);
1180 PipelineContext::GetCurrentContext()->FlushBuildFinishCallbacks();
1181 EXPECT_EQ(layoutPropertyB->GetVisibilityValue(VisibleType::VISIBLE), VisibleType::VISIBLE);
1182 EXPECT_EQ(destinationProperty->GetVisibilityValue(VisibleType::VISIBLE), VisibleType::VISIBLE);
1183
1184 /**
1185 * @tc.steps: step3. push standard page C
1186 * @tc.expected: page A is invisible, pageB is invisible, navBar is invisible, pageC is visible
1187 */
1188 auto navDestinationC = NavDestinationGroupNode::GetOrCreateGroupNode(V2::NAVDESTINATION_VIEW_ETS_TAG,
__anoncc4618fd2302() 1189 ElementRegister::GetInstance()->MakeUniqueId(), []() {
1190 return AceType::MakeRefPtr<NavDestinationPattern>();
1191 });
1192 auto navDestinationCPattern = navDestinationC->GetPattern<NavDestinationPattern>();
1193 EXPECT_NE(navDestinationBPattern, nullptr);
1194 navDestinationCPattern->SetNavigationNode(navigationNode);
1195 auto layoutPropertyC = AceType::DynamicCast<NavDestinationLayoutProperty>(navDestinationC->GetLayoutProperty());
1196 EXPECT_NE(layoutPropertyC, nullptr);
1197 layoutPropertyC->UpdateHideTitleBar(true);
1198 navigationStack->Add("C", navDestinationC);
1199 pattern->OnModifyDone();
1200 pattern->MarkNeedSyncWithJsStack();
1201 pattern->SyncWithJsStackIfNeeded();
1202 navigationNode->hideNodes_.emplace_back(std::make_pair(navDestination, false));
1203 PipelineContext::GetCurrentContext()->FlushBuildFinishCallbacks();
1204 EXPECT_EQ(layoutPropertyB->GetVisibilityValue(VisibleType::VISIBLE), VisibleType::INVISIBLE);
1205 EXPECT_EQ(destinationProperty->GetVisibilityValue(VisibleType::VISIBLE), VisibleType::INVISIBLE);
1206 EXPECT_EQ(layoutPropertyC->GetVisibilityValue(VisibleType::VISIBLE), VisibleType::VISIBLE);
1207 }
1208
1209 /**
1210 * @tc.name: NavDestinationDialogTest003
1211 * @tc.desc: Test window lifecycle event
1212 * @tc.type: FUNC
1213 */
1214 HWTEST_F(NavigationTestNg, NavDestinationDialogTest003, TestSize.Level1)
1215 {
1216 /**
1217 * @tc.steps: step1.create navigation stack
1218 */
1219 NavigationModelNG navigationModel;
1220 navigationModel.Create();
1221 auto navigationStack = AceType::MakeRefPtr<MockNavigationStack>();
1222 navigationModel.SetNavigationStack(navigationStack);
1223 RefPtr<NavigationGroupNode> navigationNode =
1224 AceType::DynamicCast<NavigationGroupNode>(ViewStackProcessor::GetInstance()->Finish());
1225 ASSERT_NE(navigationNode, nullptr);
1226 auto navigationPattern = AceType::DynamicCast<NavigationPattern>(navigationNode->GetPattern());
1227 ASSERT_NE(navigationPattern, nullptr);
1228
1229 /**
1230 * @tc.steps: step2. push standard page C
1231 */
1232 auto navDestinationC = NavDestinationGroupNode::GetOrCreateGroupNode(V2::NAVDESTINATION_VIEW_ETS_TAG,
__anoncc4618fd2402() 1233 ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<NavDestinationPattern>(); });
1234 navigationStack->Add("C", navDestinationC);
1235 RefPtr<GeometryNode> geometryNode = AceType::MakeRefPtr<GeometryNode>();
1236 ASSERT_NE(geometryNode, nullptr);
1237 auto layoutWrapper =
1238 AceType::MakeRefPtr<LayoutWrapperNode>(navigationNode, geometryNode, navigationNode->GetLayoutProperty());
1239 ASSERT_NE(layoutWrapper, nullptr);
1240 DirtySwapConfig config;
1241 config.skipMeasure = true;
1242 config.skipLayout = true;
1243 navigationPattern->OnDirtyLayoutWrapperSwap(layoutWrapper, config);
1244 auto layoutPropertyC = navDestinationC->GetLayoutProperty();
1245 EXPECT_NE(layoutPropertyC, nullptr);
1246 EXPECT_EQ(layoutPropertyC->GetVisibilityValue(VisibleType::VISIBLE), VisibleType::VISIBLE);
1247 }
1248
1249 /**
1250 * @tc.name: NavigationSetStackTest001
1251 * @tc.desc: Test setting of NavigationStack
1252 * @tc.type: FUNC
1253 */
1254 HWTEST_F(NavigationTestNg, NavigationSetStackTest001, TestSize.Level1)
1255 {
1256 /**
1257 * @tc.steps: step1. create navigation
1258 */
1259 NavigationModelNG navigationModel;
1260 navigationModel.Create();
1261
1262 int numOfCreatorCall = 0;
1263 int numOfUpdaterCall = 0;
1264 RefPtr<MockNavigationStack> stack;
__anoncc4618fd2502() 1265 auto stackCreator = [&numOfCreatorCall, &stack]() -> RefPtr<MockNavigationStack> {
1266 numOfCreatorCall++;
1267 stack = AceType::MakeRefPtr<MockNavigationStack>();
1268 return stack;
1269 };
__anoncc4618fd2602(RefPtr<NG::NavigationStack> stack) 1270 auto stackUpdater = [&numOfUpdaterCall, &navigationModel](RefPtr<NG::NavigationStack> stack) {
1271 numOfUpdaterCall++;
1272 auto mockStack = AceType::DynamicCast<MockNavigationStack>(stack);
1273 ASSERT_NE(mockStack, nullptr);
1274 };
1275
1276 /**
1277 * @tc.steps: step1. set stack's creator and updater
1278 * @tc.expected: check number of function calls
1279 */
1280 navigationModel.SetNavigationStackWithCreatorAndUpdater(stackCreator, stackUpdater);
1281 navigationModel.SetNavigationStackWithCreatorAndUpdater(stackCreator, stackUpdater);
1282 navigationModel.SetNavigationStackWithCreatorAndUpdater(stackCreator, stackUpdater);
1283 ASSERT_NE(stack, nullptr);
1284 ASSERT_NE(stack->GetOnStateChangedCallback(), nullptr);
1285 EXPECT_EQ(numOfCreatorCall, 1);
1286 EXPECT_EQ(numOfUpdaterCall, 3);
1287 }
1288
1289 /**
1290 * @tc.name: NavigationNewStackTest001
1291 * @tc.desc: Test stack operation of Navigation
1292 * @tc.type: FUNC
1293 */
1294 HWTEST_F(NavigationTestNg, NavigationNewStackTest001, TestSize.Level1)
1295 {
1296 /**
1297 * @tc.steps: step1. create navigation, set NavigationStack
1298 */
1299 NavigationModelNG navigationModel;
1300 navigationModel.Create();
__anoncc4618fd2702() 1301 auto stackCreator = []() -> RefPtr<MockNavigationStack> {
1302 return AceType::MakeRefPtr<MockNavigationStack>();
1303 };
__anoncc4618fd2802(RefPtr<NG::NavigationStack> stack) 1304 auto stackUpdater = [&navigationModel](RefPtr<NG::NavigationStack> stack) {
1305 navigationModel.SetNavigationStackProvided(false);
1306 auto mockStack = AceType::DynamicCast<MockNavigationStack>(stack);
1307 ASSERT_NE(mockStack, nullptr);
1308 };
1309 navigationModel.SetNavigationStackWithCreatorAndUpdater(stackCreator, stackUpdater);
1310
1311 /**
1312 * @tc.steps: step2. get onStateChangedCallback
1313 * @tc.expected: check if callback has been setted.
1314 */
1315 RefPtr<NavigationGroupNode> navigationNode =
1316 AceType::DynamicCast<NavigationGroupNode>(ViewStackProcessor::GetInstance()->Finish());
1317 ASSERT_NE(navigationNode, nullptr);
1318 auto navigationPattern = AceType::DynamicCast<NavigationPattern>(navigationNode->GetPattern());
1319 ASSERT_NE(navigationPattern, nullptr);
1320 EXPECT_FALSE(navigationPattern->GetNavigationStackProvided());
1321 auto stack = navigationPattern->GetNavigationStack();
1322 auto mockStack = AceType::DynamicCast<MockNavigationStack>(stack);
1323 ASSERT_NE(mockStack, nullptr);
1324 auto stateChangedCallback = mockStack->GetOnStateChangedCallback();
1325 ASSERT_NE(stateChangedCallback, nullptr);
1326
1327 /**
1328 * @tc.steps: step2.add page A
1329 */
1330 RefPtr<FrameNode> frameNode = FrameNode::CreateFrameNode("temp", 245, AceType::MakeRefPtr<ButtonPattern>());
1331 mockStack->Add("A", frameNode);
1332 ASSERT_FALSE(navigationPattern->NeedSyncWithJsStackMarked());
1333 stateChangedCallback();
1334 ASSERT_TRUE(navigationPattern->NeedSyncWithJsStackMarked());
1335 MockPipelineContext::GetCurrent()->FlushBuildFinishCallbacks();
1336 ASSERT_FALSE(navigationPattern->NeedSyncWithJsStackMarked());
1337 ASSERT_EQ(mockStack->Size(), 1);
1338
1339 /**
1340 * @tc.steps: step3. replace pageA
1341 */
1342 RefPtr<FrameNode> replaceNode = FrameNode::CreateFrameNode("temp", 245, AceType::MakeRefPtr<ButtonPattern>());
1343 mockStack->Remove();
1344 mockStack->Add("B", replaceNode);
1345 ASSERT_FALSE(navigationPattern->NeedSyncWithJsStackMarked());
1346 stateChangedCallback();
1347 ASSERT_TRUE(navigationPattern->NeedSyncWithJsStackMarked());
1348 MockPipelineContext::GetCurrent()->FlushBuildFinishCallbacks();
1349 ASSERT_FALSE(navigationPattern->NeedSyncWithJsStackMarked());
1350 ASSERT_EQ(mockStack->Size(), 1);
1351
1352 /**
1353 * @tc.steps: step4. push pageC
1354 */
1355 mockStack->Add("C", frameNode);
1356 ASSERT_FALSE(navigationPattern->NeedSyncWithJsStackMarked());
1357 stateChangedCallback();
1358 ASSERT_TRUE(navigationPattern->NeedSyncWithJsStackMarked());
1359 MockPipelineContext::GetCurrent()->FlushBuildFinishCallbacks();
1360 ASSERT_FALSE(navigationPattern->NeedSyncWithJsStackMarked());
1361 ASSERT_EQ(mockStack->Size(), 2);
1362 }
1363
1364 /**
1365 * @tc.name: NestedNavigationTest001
1366 * @tc.desc: Test case of nested Navigation
1367 * @tc.type: FUNC
1368 */
1369 HWTEST_F(NavigationTestNg, NestedNavigationTest001, TestSize.Level1)
1370 {
1371 /**
1372 * @tc.steps: step1. create NavigationStack, setup mock function
1373 */
1374
1375 auto context = MockPipelineContext::GetCurrent();
1376 ASSERT_NE(context, nullptr);
1377 ScopedViewStackProcessor scopedViewStackProcessor;
1378 auto outerStack = AceType::MakeRefPtr<MockNavigationStack>();
1379 auto innerStack = AceType::MakeRefPtr<MockNavigationStack>();
1380 EXPECT_CALL(*outerStack, OnAttachToParent(_)).Times(0);
1381 EXPECT_CALL(*innerStack, OnAttachToParent(_)).Times(1);
1382
1383 /**
1384 * @tc.steps: step1. create outer navigation and set stack
1385 */
1386 NavigationModelNG navigationModel;
1387 navigationModel.Create();
1388 navigationModel.SetNavigationStackWithCreatorAndUpdater(
__anoncc4618fd2902() 1389 [&outerStack]() -> RefPtr<MockNavigationStack> {
1390 return outerStack;
1391 }, [](RefPtr<NG::NavigationStack> stack) {
1392 auto mockStack = AceType::DynamicCast<MockNavigationStack>(stack);
1393 ASSERT_NE(mockStack, nullptr);
1394 });
1395 auto groupNode = AceType::DynamicCast<NavigationGroupNode>(
1396 ViewStackProcessor::GetInstance()->GetMainElementNode());
1397 ASSERT_NE(groupNode, nullptr);
1398 groupNode->AttachToMainTree(true, AceType::RawPtr(context));
1399
1400 /**
1401 * @tc.steps: step2. create inner navigation and set stack
1402 */
1403 navigationModel.Create();
1404 navigationModel.SetNavigationStackWithCreatorAndUpdater(
__anoncc4618fd2b02() 1405 [&innerStack]() -> RefPtr<MockNavigationStack> {
1406 return innerStack;
1407 }, [](RefPtr<NG::NavigationStack> stack) {
1408 auto mockStack = AceType::DynamicCast<MockNavigationStack>(stack);
1409 ASSERT_NE(mockStack, nullptr);
1410 });
1411
1412 /**
1413 * @tc.steps: step3. attach navigation to main tree
1414 * @tc.expected: check number of NavigationStack's OnAttachToParent function calls
1415 */
1416 ViewStackProcessor::GetInstance()->Pop();
1417 }
1418
1419 /*
1420 * @tc.name: NavigationInterceptionTest001
1421 * @tc.desc: Test navigation interception
1422 * @tc.type: FUNC
1423 */
1424 HWTEST_F(NavigationTestNg, NavigationInterceptionTest001, TestSize.Level1)
1425 {
1426 /**
1427 * @tc.steps: step1. create navigation, set NavigationStack
1428 */
1429 NavigationModelNG navigationModel;
1430 navigationModel.Create();
__anoncc4618fd2d02() 1431 auto stackCreator = []() -> RefPtr<MockNavigationStack> {
1432 return AceType::MakeRefPtr<MockNavigationStack>();
1433 };
__anoncc4618fd2e02(RefPtr<NG::NavigationStack> stack) 1434 auto stackUpdater = [&navigationModel](RefPtr<NG::NavigationStack> stack) {
1435 navigationModel.SetNavigationStackProvided(false);
1436 auto mockStack = AceType::DynamicCast<MockNavigationStack>(stack);
1437 ASSERT_NE(mockStack, nullptr);
1438 };
1439 navigationModel.SetNavigationStackWithCreatorAndUpdater(stackCreator, stackUpdater);
1440
1441 /**
1442 * @tc.steps: step2.set navigation before and after interception during destination transition
1443 */
1444 auto navigationNode = AceType::DynamicCast<NavigationGroupNode>(
1445 ViewStackProcessor::GetInstance()->GetMainElementNode());
1446 auto navigationPattern = AceType::DynamicCast<NavigationPattern>(navigationNode->GetPattern());
1447 EXPECT_NE(navigationPattern, nullptr);
1448 auto mockStack = AceType::DynamicCast<MockNavigationStack>(navigationPattern->GetNavigationStack());
1449 EXPECT_NE(mockStack, nullptr);
1450 mockStack->SetInterceptionBeforeCallback([stack = WeakPtr<MockNavigationStack>(mockStack)]
1451 (const RefPtr<NavDestinationContext>& from,
__anoncc4618fd2f02(const RefPtr<NavDestinationContext>& from, const RefPtr<NavDestinationContext>& to, NavigationOperation operation, bool isAnimated) 1452 const RefPtr<NavDestinationContext>& to, NavigationOperation operation, bool isAnimated) {
1453 ASSERT_EQ(from, nullptr);
1454 ASSERT_NE(to, nullptr);
1455 auto info = to->GetNavPathInfo();
1456 ASSERT_NE(info, nullptr);
1457 ASSERT_EQ(info->GetName(), "A");
1458 ASSERT_EQ(operation, NavigationOperation::PUSH);
1459 ASSERT_EQ(isAnimated, true);
1460 auto navigationStack = stack.Upgrade();
1461 ASSERT_NE(navigationStack, nullptr);
1462 navigationStack->Remove();
1463 RefPtr<FrameNode> frameNode = NavigationTestNg::CreateDestination("B");
1464 navigationStack->Add("B", frameNode);
1465 navigationStack->UpdateReplaceValue(true);
1466 navigationStack->UpdateAnimatedValue(true);
1467 });
1468
1469 mockStack->SetInterceptionAfterCallback([](const RefPtr<NavDestinationContext>& from,
__anoncc4618fd3002(const RefPtr<NavDestinationContext>& from, const RefPtr<NavDestinationContext>& to, NavigationOperation operation, bool isAnimated) 1470 const RefPtr<NavDestinationContext>& to, NavigationOperation operation, bool isAnimated) {
1471 EXPECT_EQ(from, nullptr);
1472 EXPECT_NE(to, nullptr);
1473 auto info = to->GetNavPathInfo();
1474 ASSERT_NE(info->GetName(), "B");
1475 ASSERT_EQ(operation, NavigationOperation::REPLACE);
1476 ASSERT_EQ(isAnimated, false);
1477 });
1478
1479 /**
1480 * @tc.steps: step3. sync navigation stack
1481 * @tc.expected: step3. trigger navigation interception before and after callback
1482 */
1483 auto frameNode = NavigationTestNg::CreateDestination("A");
1484 mockStack->Add("A", frameNode);
1485 navigationPattern->MarkNeedSyncWithJsStack();
1486 MockPipelineContext::GetCurrent()->GetNavigationManager()->FireNavigationUpdateCallback();
1487 }
1488
1489 /**
1490 * @tc.name: NavigationInterceptionTest002
1491 * @tc.desc: Test navigation interception
1492 * @tc.type: FUNC
1493 */
1494 HWTEST_F(NavigationTestNg, NavigationInterceptionTest002, TestSize.Level1)
1495 {
1496 /**
1497 * @tc.steps: step1. create navigation, set NavigationStack
1498 */
1499 NavigationModelNG navigationModel;
1500 navigationModel.Create();
__anoncc4618fd3102() 1501 auto stackCreator = []() -> RefPtr<MockNavigationStack> {
1502 return AceType::MakeRefPtr<MockNavigationStack>();
1503 };
__anoncc4618fd3202(RefPtr<NG::NavigationStack> stack) 1504 auto stackUpdater = [&navigationModel](RefPtr<NG::NavigationStack> stack) {
1505 navigationModel.SetNavigationStackProvided(false);
1506 auto mockStack = AceType::DynamicCast<MockNavigationStack>(stack);
1507 ASSERT_NE(mockStack, nullptr);
1508 };
1509 navigationModel.SetNavigationStackWithCreatorAndUpdater(stackCreator, stackUpdater);
1510
1511 /**
1512 * @tc.steps: step2. push A to navigation stack
1513 */
1514 auto navigationNode = AceType::DynamicCast<NavigationGroupNode>(
1515 ViewStackProcessor::GetInstance()->GetMainElementNode());
1516 auto navigationPattern = AceType::DynamicCast<NavigationPattern>(navigationNode->GetPattern());
1517 EXPECT_NE(navigationPattern, nullptr);
1518 auto mockStack = AceType::DynamicCast<MockNavigationStack>(navigationPattern->GetNavigationStack());
1519 EXPECT_NE(mockStack, nullptr);
1520 auto frameNode = NavigationTestNg::CreateDestination("A");
1521 mockStack->Add("A", frameNode);
1522 navigationPattern->MarkNeedSyncWithJsStack();
1523 MockPipelineContext::GetCurrent()->GetNavigationManager()->FireNavigationUpdateCallback();
1524
1525 /**
1526 * @tc.steps: step2.set navigation before and after interception during destination transition
1527 */
1528 mockStack->SetInterceptionBeforeCallback([stack = WeakPtr<NavigationStack>(mockStack)](
1529 const RefPtr<NavDestinationContext>& from,
__anoncc4618fd3302( const RefPtr<NavDestinationContext>& from, const RefPtr<NavDestinationContext>& to, NavigationOperation operation, bool isAnimated) 1530 const RefPtr<NavDestinationContext>& to, NavigationOperation operation, bool isAnimated) {
1531 ASSERT_EQ(to, nullptr);
1532 ASSERT_NE(from, nullptr);
1533 auto info = from->GetNavPathInfo();
1534 ASSERT_EQ(info->name_, "A");
1535 ASSERT_EQ(operation, NavigationOperation::POP);
1536 ASSERT_EQ(isAnimated, true);
1537 auto navigationStack = stack.Upgrade();
1538 ASSERT_NE(navigationStack, nullptr);
1539 auto frameNode = NavigationTestNg::CreateDestination("B");
1540 ASSERT_NE(frameNode, nullptr);
1541 navigationStack->Add("B", frameNode);
1542 });
1543
1544 mockStack->SetInterceptionAfterCallback([](const RefPtr<NavDestinationContext>& from,
__anoncc4618fd3402(const RefPtr<NavDestinationContext>& from, const RefPtr<NavDestinationContext>& to, NavigationOperation operation, bool isAnimated) 1545 const RefPtr<NavDestinationContext>& to, NavigationOperation operation, bool isAnimated) {
1546 EXPECT_NE(from, nullptr);
1547 EXPECT_NE(to, nullptr);
1548 auto fromInfo = from->GetNavPathInfo();
1549 ASSERT_NE(fromInfo, nullptr);
1550 ASSERT_EQ(fromInfo->GetName(), "A");
1551 auto toInfo = to->GetNavPathInfo();
1552 ASSERT_NE(toInfo, nullptr);
1553 ASSERT_EQ(toInfo->name_, "A");
1554 ASSERT_EQ(operation, NavigationOperation::PUSH);
1555 ASSERT_EQ(isAnimated, false);
1556 });
1557
1558 /**
1559 * @tc.steps: step3. sync navigation stack
1560 * @tc.expected: step3. trigger navigation interception before and after callback
1561 */
1562 mockStack->Remove();
1563 navigationPattern->MarkNeedSyncWithJsStack();
1564 MockPipelineContext::GetCurrent()->GetNavigationManager()->FireNavigationUpdateCallback();
1565 }
1566
1567 /**
1568 * @tc.name: NavigationInterceptionTest003
1569 * @tc.desc: Test navigation interception
1570 * @tc.type: FUNC
1571 */
1572 HWTEST_F(NavigationTestNg, NavigationInterceptionTest003, TestSize.Level1)
1573 {
1574 /**
1575 * @tc.steps: step1. create navigation, set NavigationStack
1576 */
1577 NavigationModelNG navigationModel;
1578 navigationModel.Create();
__anoncc4618fd3502() 1579 auto stackCreator = []() -> RefPtr<MockNavigationStack> {
1580 return AceType::MakeRefPtr<MockNavigationStack>();
1581 };
__anoncc4618fd3602(RefPtr<NG::NavigationStack> stack) 1582 auto stackUpdater = [&navigationModel](RefPtr<NG::NavigationStack> stack) {
1583 navigationModel.SetNavigationStackProvided(false);
1584 auto mockStack = AceType::DynamicCast<MockNavigationStack>(stack);
1585 ASSERT_NE(mockStack, nullptr);
1586 };
1587 navigationModel.SetNavigationStackWithCreatorAndUpdater(stackCreator, stackUpdater);
1588
1589 /**
1590 * @tc.steps: step2. push A to navigation stack
1591 */
1592 auto navigationNode = AceType::DynamicCast<NavigationGroupNode>(
1593 ViewStackProcessor::GetInstance()->GetMainElementNode());
1594 auto navigationPattern = AceType::DynamicCast<NavigationPattern>(navigationNode->GetPattern());
1595 EXPECT_NE(navigationPattern, nullptr);
1596 auto mockStack = AceType::DynamicCast<MockNavigationStack>(navigationPattern->GetNavigationStack());
1597 EXPECT_NE(mockStack, nullptr);
1598 auto frameNode = NavigationTestNg::CreateDestination("A");
1599 mockStack->Add("A", frameNode);
1600 mockStack->UpdateReplaceValue(true);
1601
1602 /**
1603 * @tc.steps: step2.set navigation before and after interception during destination transition
1604 */
1605 mockStack->SetInterceptionBeforeCallback([](const RefPtr<NavDestinationContext>& from,
__anoncc4618fd3702(const RefPtr<NavDestinationContext>& from, const RefPtr<NavDestinationContext>& to, NavigationOperation operation, bool isAnimated) 1606 const RefPtr<NavDestinationContext>& to, NavigationOperation operation, bool isAnimated) {
1607 ASSERT_EQ(to, nullptr);
1608 ASSERT_NE(from, nullptr);
1609 auto info = from->GetNavPathInfo();
1610 ASSERT_EQ(info->name_, "A");
1611 ASSERT_EQ(operation, NavigationOperation::REPLACE);
1612 ASSERT_EQ(isAnimated, true);
1613 });
1614
1615 mockStack->SetInterceptionAfterCallback([](const RefPtr<NavDestinationContext>& from,
__anoncc4618fd3802(const RefPtr<NavDestinationContext>& from, const RefPtr<NavDestinationContext>& to, NavigationOperation operation, bool isAnimated) 1616 const RefPtr<NavDestinationContext>& to, NavigationOperation operation, bool isAnimated) {
1617 ASSERT_EQ(to, nullptr);
1618 ASSERT_NE(from, nullptr);
1619 auto info = from->GetNavPathInfo();
1620 ASSERT_EQ(info->name_, "A");
1621 ASSERT_EQ(operation, NavigationOperation::REPLACE);
1622 ASSERT_EQ(isAnimated, true);
1623 });
1624
1625 /**
1626 * @tc.steps: step3. sync navigation stack.
1627 * @tc.expected: step3. trigger navigation before and after callback.
1628 */
1629 navigationPattern->MarkNeedSyncWithJsStack();
1630 MockPipelineContext::GetCurrent()->GetNavigationManager()->FireNavigationUpdateCallback();
1631 }
1632
1633 /**
1634 * @tc.name: NavigationInterceptionTest004
1635 * @tc.desc: Test navigation interception
1636 * @tc.type: FUNC
1637 */
1638 HWTEST_F(NavigationTestNg, NavigationInterceptionTest004, TestSize.Level1)
1639 {
1640 /**
1641 * @tc.steps: step1. create navigation, set NavigationStack
1642 */
1643 NavigationModelNG navigationModel;
1644 navigationModel.Create();
__anoncc4618fd3902() 1645 auto stackCreator = []() -> RefPtr<MockNavigationStack> {
1646 return AceType::MakeRefPtr<MockNavigationStack>();
1647 };
__anoncc4618fd3a02(RefPtr<NG::NavigationStack> stack) 1648 auto stackUpdater = [&navigationModel](RefPtr<NG::NavigationStack> stack) {
1649 navigationModel.SetNavigationStackProvided(false);
1650 auto mockStack = AceType::DynamicCast<MockNavigationStack>(stack);
1651 ASSERT_NE(mockStack, nullptr);
1652 };
1653 navigationModel.SetNavigationStackWithCreatorAndUpdater(stackCreator, stackUpdater);
1654
1655 /**
1656 * @tc.steps: step2.set navigation before and after interception during destination transition.
1657 * Remove top Destination during interception before callback.
1658 * @tc.expected: trigger before interception and not trigger after interception.
1659 */
1660 auto navigationNode = AceType::DynamicCast<NavigationGroupNode>(
1661 ViewStackProcessor::GetInstance()->GetMainElementNode());
1662 auto navigationPattern = AceType::DynamicCast<NavigationPattern>(navigationNode->GetPattern());
1663 EXPECT_NE(navigationPattern, nullptr);
1664 auto mockStack = AceType::DynamicCast<MockNavigationStack>(navigationPattern->GetNavigationStack());
1665 EXPECT_NE(mockStack, nullptr);
1666 mockStack->SetInterceptionBeforeCallback([stack = WeakPtr<NavigationStack>(mockStack)]
1667 (const RefPtr<NavDestinationContext>& from,
__anoncc4618fd3b02(const RefPtr<NavDestinationContext>& from, const RefPtr<NavDestinationContext>& to, NavigationOperation operation, bool isAnimated) 1668 const RefPtr<NavDestinationContext>& to, NavigationOperation operation, bool isAnimated) {
1669 ASSERT_EQ(to, nullptr);
1670 ASSERT_NE(from, nullptr);
1671 auto info = from->GetNavPathInfo();
1672 ASSERT_EQ(info->name_, "A");
1673 ASSERT_EQ(operation, NavigationOperation::REPLACE);
1674 ASSERT_EQ(isAnimated, true);
1675 auto navigationStack = stack.Upgrade();
1676 EXPECT_NE(navigationStack, nullptr);
1677 navigationStack->Remove();
1678 });
1679
1680 uint32_t times = 0;
1681 mockStack->SetInterceptionAfterCallback([time = ×](const RefPtr<NavDestinationContext>& from,
__anoncc4618fd3c02(const RefPtr<NavDestinationContext>& from, const RefPtr<NavDestinationContext>& to, NavigationOperation operation, bool isAnimated) 1682 const RefPtr<NavDestinationContext>& to, NavigationOperation operation, bool isAnimated) {
1683 (*time)++;
1684 });
1685
1686 /**
1687 * @tc.steps: step3. push destination A and sync navigation stack.
1688 * @tc.expected: step3. don't trigger interception after callback.times is 0.
1689 */
1690 auto frameNode = NavigationTestNg::CreateDestination("A");
1691 mockStack->Add("A", frameNode);
1692 navigationPattern->MarkNeedSyncWithJsStack();
1693 MockPipelineContext::GetCurrent()->GetNavigationManager()->FireNavigationUpdateCallback();
1694 EXPECT_EQ(times, 0);
1695 }
1696 } // namespace OHOS::Ace::NG
1697