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 = ×](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