1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "gtest/gtest.h"
17
18 #define private public
19 #define protected public
20 #include "test/mock/core/common/mock_resource_adapter.h"
21 #include "test/mock/core/common/mock_theme_manager.h"
22 #include "test/mock/core/pipeline/mock_pipeline_context.h"
23 #include "test/mock/core/render/mock_render_context.h"
24 #include "test/unittest/core/event/focus_core/lost_focus_to_view_root_test.h"
25 #include "test/unittest/core/pattern/test_ng.h"
26
27 #include "base/log/log_wrapper.h"
28 #include "core/components/container_modal/container_modal_constants.h"
29 #include "core/components/theme/theme_constants.h"
30 #include "core/components_ng/base/ui_node.h"
31 #include "core/components_ng/base/view_stack_processor.h"
32 #include "core/components_ng/pattern/button/button_pattern.h"
33 #include "core/components_ng/pattern/container_modal/container_modal_pattern.h"
34 #include "core/components_ng/pattern/container_modal/container_modal_theme.h"
35 #include "core/components_ng/pattern/container_modal/container_modal_view.h"
36 #include "core/components_ng/pattern/image/image_layout_property.h"
37 #include "core/components_ng/pattern/image/image_pattern.h"
38 #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h"
39 #include "core/components_ng/pattern/pattern.h"
40 #include "core/components_ng/pattern/root/root_pattern.h"
41 #include "core/components_ng/pattern/stack/stack_pattern.h"
42 #include "core/components_ng/pattern/text/text_pattern.h"
43 #include "core/components_ng/pattern/text_picker/textpicker_column_pattern.h"
44 #include "core/pipeline_ng/pipeline_context.h"
45
46 using namespace testing;
47 using namespace testing::ext;
48 namespace OHOS::Ace::NG {
49
50 struct LostFocusToViewRootCase {
51 std::string checkPoint; // not report A or null
52 std::string getFocusNode; // A B or null
53 std::string expectResults;
LostFocusToViewRootCaseOHOS::Ace::NG::LostFocusToViewRootCase54 LostFocusToViewRootCase(
55 const std::string& checkPoint, const std::string& getFocusNode, const std::string& expectResults)
56 : checkPoint(checkPoint), getFocusNode(getFocusNode), expectResults(expectResults)
57 {}
58 };
59
60 const std::vector<LostFocusToViewRootCase> LOST_FOCUS_TO_VIEW_ROOT_CASES = { LostFocusToViewRootCase(
61 "不上报", "A", "A") };
62
SetUpTestSuite()63 void LostFocusToViewRootTestNG::SetUpTestSuite()
64 {
65 MockPipelineContext::SetUp();
66 GTEST_LOG_(INFO) << "LostFocusToViewRootTestNG SetUpTestCase";
67 }
68
TearDownTestSuite()69 void LostFocusToViewRootTestNG::TearDownTestSuite()
70 {
71 MockPipelineContext::TearDown();
72 GTEST_LOG_(INFO) << "LostFocusToViewRootTestNG TearDownTestCase";
73 }
74
75 HWTEST_F(LostFocusToViewRootTestNG, LostFocusToViewRootTestNG001, TestSize.Level1)
76 {
77 int32_t caseNum = 1;
78 bool initResult = InitFocusTestBaseNG();
79 EXPECT_TRUE(initResult);
80 for (const auto& testCase : LOST_FOCUS_TO_VIEW_ROOT_CASES) {
81 // create root node
82 auto rootNode = CreateRootNode();
83 CHECK_NULL_VOID(rootNode);
84 auto rootNodeFocusHub = rootNode->GetOrCreateFocusHub();
85 EXPECT_NE(rootNodeFocusHub, nullptr);
86 CHECK_NULL_VOID(rootNodeFocusHub);
87
88 // create node A
89 auto nodeA = CreateNodeWithFocusPattern("nodeA", FocusType::NODE, true);
90 CHECK_NULL_VOID(nodeA);
91 nodeA->UpdateInspectorId("A");
92 auto nodeAFocusHub = nodeA->GetOrCreateFocusHub();
93 CHECK_NULL_VOID(nodeAFocusHub);
94
95 // create node B
96 auto nodeB = CreateNodeWithFocusPattern("nodeB", FocusType::NODE, true);
97 CHECK_NULL_VOID(nodeB);
98 nodeB->UpdateInspectorId("B");
99 auto nodeBFocusHub = nodeB->GetOrCreateFocusHub();
100 CHECK_NULL_VOID(nodeBFocusHub);
101
102 // create node tree
103 rootNode->AddChild(nodeA);
104 nodeA->AddChild(nodeB);
105
106 // Request focus according to the test case
107 if (testCase.getFocusNode == "A") {
108 if (nodeAFocusHub) {
109 nodeAFocusHub->RequestFocusImmediately();
110 }
111 } else if (testCase.getFocusNode == "B") {
112 if (nodeBFocusHub) {
113 nodeBFocusHub->RequestFocusImmediately();
114 }
115 }
116
117 // Simulate losing focus to the view root node
118 if (rootNodeFocusHub) {
119 rootNodeFocusHub->LostFocusToViewRoot();
120 }
121
122 // get current focus node
123 std::string actualState = "NULL";
124 if (focusManager_) {
125 auto currentFocusNode = focusManager_->GetCurrentFocus();
126 if (currentFocusNode) {
127 auto inspectorId = currentFocusNode->GetFrameNode()->GetInspectorId();
128 actualState = inspectorId.has_value() ? inspectorId.value() : "NULL";
129 }
130 }
131
132 // Verify result
133 EXPECT_EQ(actualState, testCase.expectResults)
134 << "TestCaseNum: " << caseNum << ", actual state: " << actualState
135 << ", expect state: " << testCase.expectResults;
136
137 ++caseNum;
138 }
139 }
140 } // namespace OHOS::Ace::NG
141