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 #include "gtest/gtest.h"
16
17 #define private public
18 #define protected public
19 #include "test/mock/core/common/mock_resource_adapter.h"
20 #include "test/mock/core/common/mock_theme_manager.h"
21 #include "test/mock/core/pipeline/mock_pipeline_context.h"
22 #include "test/mock/core/render/mock_render_context.h"
23 #include "test/unittest/core/pattern/test_ng.h"
24
25 #include "base/log/log_wrapper.h"
26 #include "core/components/container_modal/container_modal_constants.h"
27 #include "core/components/theme/theme_constants.h"
28 #include "core/components_ng/base/ui_node.h"
29 #include "core/components_ng/base/view_stack_processor.h"
30 #include "core/components_ng/pattern/button/button_pattern.h"
31 #include "core/components_ng/pattern/container_modal/container_modal_pattern.h"
32 #include "core/components_ng/pattern/container_modal/container_modal_theme.h"
33 #include "core/components_ng/pattern/container_modal/container_modal_view.h"
34 #include "core/components_ng/pattern/image/image_layout_property.h"
35 #include "core/components_ng/pattern/image/image_pattern.h"
36 #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h"
37 #include "core/components_ng/pattern/pattern.h"
38 #include "core/components_ng/pattern/stack/stack_pattern.h"
39 #include "core/components_ng/pattern/text/text_pattern.h"
40 #include "core/components_ng/pattern/text_picker/textpicker_column_pattern.h"
41 #include "core/pipeline_ng/pipeline_context.h"
42 #include "test/unittest/core/event/focus_core/focus_window_test.h"
43 #include "core/components_ng/pattern/root/root_pattern.h"
44
45 using namespace testing;
46 using namespace testing::ext;
47 namespace OHOS::Ace::NG {
48
49 struct WindowFocusCase {
50 bool isBLastFocusView;
51 // 0 for null, 1 for root, 2 for B, 3 for C
52 int32_t isNodeCurrentFocus;
53 bool isBDependenceSelf;
54 bool isBFocusable;
55 bool isCFocusable;
56 std::string expectResults;
WindowFocusCaseOHOS::Ace::NG::WindowFocusCase57 WindowFocusCase(
58 bool isBLastFocusView, int32_t isNodeCurrentFocus, bool isBDependenceSelf, bool isBFocusable,
59 bool isCFocusable, const std::string& expectResults) : isBLastFocusView(isBLastFocusView),
60 isNodeCurrentFocus(isNodeCurrentFocus), isBDependenceSelf(isBDependenceSelf),
61 isBFocusable(isBFocusable), isCFocusable(isCFocusable), expectResults(expectResults) {}
62 };
63
64 const std::vector<WindowFocusCase>
65 WINDOW_FOCUS_CASES = {};
66
SetUpTestSuite()67 void FocusWindowTestNG::SetUpTestSuite()
68 {
69 MockPipelineContext::SetUp();
70 GTEST_LOG_(INFO) << "FocusWindowTestNG SetUpTestCase";
71 }
72
TearDownTestSuite()73 void FocusWindowTestNG::TearDownTestSuite()
74 {
75 MockPipelineContext::TearDown();
76 GTEST_LOG_(INFO) << "FocusWindowTestNG TearDownTestCase";
77 }
78
IsWindowFocusStateEqual(int32_t caseNum,std::string & expectState)79 testing::AssertionResult FocusWindowTestNG::IsWindowFocusStateEqual(int32_t caseNum,
80 std::string& expectState)
81 {
82 if (!focusManager_) {
83 return testing::AssertionFailure() << "TestCaseNum: " << caseNum <<
84 "focusManager is null";
85 }
86 auto focusNode = focusManager_->switchingFocus_;
87 if (!focusNode) {
88 return testing::AssertionFailure() << "TestCaseNum: " << caseNum <<
89 "focus node is null";
90 }
91 auto actualState = focusNode->GetFrameNode()->GetInspectorId().value_or("NULL");
92 if (actualState != expectState) {
93 return testing::AssertionFailure() << "TestCaseNum: " << caseNum <<
94 ", actual state: " << actualState << ", expect state: " << expectState;
95 }
96 return testing::AssertionSuccess();
97 }
98
99 /**
100 * @tc.name: FocusWindowTestNG001
101 * @tc.desc: FocusWindowTestNG
102 * @tc.type: FUNC
103 */
104 HWTEST_F(FocusWindowTestNG, FocusWindowTestNG001, TestSize.Level1)
105 {
106 int32_t caseNum = 1;
107 bool initResult = InitFocusTestBaseNG();
108 EXPECT_TRUE(initResult);
109 for (const auto& testCase : WINDOW_FOCUS_CASES) {
110
111 /**
112 * @tc.steps: step1. Create rootNode and focusHub.
113 * @tc.expected: rootNode and focusHub not null.
114 */
115 auto rootNode = CreateRootNode();
116 EXPECT_NE(rootNode, nullptr);
117 auto rootNodeFocusHub = rootNode->GetOrCreateFocusHub();
118 EXPECT_NE(rootNodeFocusHub, nullptr);
119 rootNode->UpdateInspectorId("ROOTNODE");
120
121 /**
122 * @tc.steps: step2. Create FocusView nodeB.
123 * @tc.expected: nodeB and focusHubB not null.
124 */
125 std::list<int32_t> emptyList;
126 auto nodeB = CreateFocusViewWithFocusPattern("nodeB", emptyList, FocusType::SCOPE, testCase.isBFocusable);
127 EXPECT_NE(nodeB, nullptr);
128 nodeB->UpdateInspectorId("NODEB");
129 auto focusHubB = nodeB->GetOrCreateFocusHub();
130 EXPECT_NE(focusHubB, nullptr);
131 auto focusViewB = nodeB->GetPattern<FocusView>();
132 EXPECT_NE(focusViewB, nullptr);
133
134 /**
135 * @tc.steps: step3. Create nodeC.
136 * @tc.expected: nodeC and focusHubC not null.
137 */
138 auto nodeC = CreateNodeWithFocusPattern("nodeC", FocusType::NODE, testCase.isCFocusable);
139 EXPECT_NE(nodeC, nullptr);
140 nodeC->UpdateInspectorId("NODEC");
141 auto focusHubC = nodeC->GetOrCreateFocusHub();
142 EXPECT_NE(focusHubC, nullptr);
143
144 /**
145 * @tc.steps: step4. Add nodeB as child of rootNode, add nodeC as child of nodeB.
146 */
147 rootNode->AddChild(nodeB);
148 nodeB->AddChild(nodeC);
149
150 /**
151 * @tc.steps: step4. Set lastFocusView to nodeB or null.
152 */
153 if (testCase.isBLastFocusView) {
154 focusManager_->lastFocusView_ = AceType::WeakClaim(AceType::RawPtr(focusViewB));
155 } else {
156 focusManager_->lastFocusView_ = nullptr;
157 }
158
159 /**
160 * @tc.steps: step4. Set FocusDependence::SELF to nodeB and rootNode by input.
161 */
162 if (testCase.isNodeCurrentFocus == 1) {
163 rootNodeFocusHub->SetFocusDependence(FocusDependence::SELF);
164 rootNodeFocusHub->RequestFocusImmediatelyInner();
165 } else if (testCase.isNodeCurrentFocus == 2) {
166 focusHubB->SetFocusDependence(FocusDependence::SELF);
167 focusHubB->RequestFocusImmediatelyInner();
168 } else if (testCase.isNodeCurrentFocus == 3) {
169 focusHubC->RequestFocusImmediatelyInner();
170 }
171
172 /**
173 * @tc.steps: step5. Set FocusDependence::SELF to nodeB by input.
174 */
175 if (testCase.isBDependenceSelf) {
176 focusHubB->SetFocusDependence(FocusDependence::SELF);
177 }
178
179 /**
180 * @tc.steps: step6. Set Window Focus.
181 * @tc.expected: results are same as expectResults.
182 */
183 auto context = PipelineContext::GetCurrentContext();
184 EXPECT_NE(context, nullptr);
185 context->WindowFocus(true);
186 auto expectResults = testCase.expectResults;
187 EXPECT_TRUE(IsWindowFocusStateEqual(caseNum, expectResults));
188 ++caseNum;
189 }
190 }
191 } // namespace OHOS::Ace::NG
192