• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 = &times](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