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