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 "gmock/gmock.h"
17 #include "gtest/gtest.h"
18
19 #define private public
20 #define protected public
21
22 #include "adapter/ohos/entrance/ace_container.h"
23 #include "base/log/dump_log.h"
24 #include "core/components_ng/pattern/pattern.h"
25 #include "frameworks/core/accessibility/utils/accessibility_action_function_utils.h"
26 #include "interfaces/inner_api/ace_kit/src/view/ui_context_impl.h"
27
28
29 using namespace OHOS::Accessibility;
30 using namespace testing;
31 using namespace testing::ext;
32
33 namespace OHOS::Ace {
34 } // namespace OHOS::Ace
35
36 namespace OHOS::Ace::NG {
37 namespace {
38 } // namespace
39
40
41 class AccessibilityActionFunctionUtilsTest : public testing::Test {
42 public:
43 static void SetUpTestCase();
44 static void TearDownTestCase();
45
46 bool processFlag1_ = false;
47 bool processFlag2_ = false;
48 bool processFlag3_ = false;
49
50 int32_t processType1_ = -1;
51 int32_t processType2_ = -1;
52 };
53
SetUpTestCase()54 void AccessibilityActionFunctionUtilsTest::SetUpTestCase()
55 {
56 std::unique_ptr<std::ostream> ostream = std::make_unique<std::ostringstream>();
57 ASSERT_NE(ostream, nullptr);
58 DumpLog::GetInstance().SetDumpFile(std::move(ostream));
59 }
60
TearDownTestCase()61 void AccessibilityActionFunctionUtilsTest::TearDownTestCase()
62 {
63 }
64
65 /**
66 * @tc.name: AccessibilityActionFunctionUtilsTest001
67 * @tc.desc: AddMultipleNodes
68 * @tc.type: FUNC
69 */
70 HWTEST_F(AccessibilityActionFunctionUtilsTest, AccessibilityActionFunctionUtilsTest001, TestSize.Level1)
71 {
72 /**
73 * @tc.steps: step1. construct framenodes
74 */
75 auto frameNode1 = FrameNode::CreateFrameNode("framenode", 1, AceType::MakeRefPtr<Pattern>(), false);
76 CHECK_NULL_VOID(frameNode1);
77 auto frameNode2 = FrameNode::CreateFrameNode("framenode", 2, AceType::MakeRefPtr<Pattern>(), false);
78 CHECK_NULL_VOID(frameNode2);
79 frameNode2->MountToParent(frameNode1);
80 frameNode1->AddChild(frameNode2);
81 auto frameNode3 = FrameNode::CreateFrameNode("framenode", 3, AceType::MakeRefPtr<Pattern>(), false);
82 CHECK_NULL_VOID(frameNode3);
83 frameNode3->MountToParent(frameNode2);
84 frameNode2->AddChild(frameNode3);
85
86 /**
87 * @tc.steps: step2. framenode2 set callback.
88 * @tc.expected: callback can be handled, when framenode3 HandleNotifyChildAction.
89 */
90 processFlag1_ = false;
91 processFlag2_ = false;
92 processType1_ = -1;
93 processType2_ = -1;
94 auto accessibilityProperty2 = frameNode2->GetAccessibilityProperty<NG::AccessibilityProperty>();
95 CHECK_NULL_VOID(accessibilityProperty2);
96 accessibilityProperty2->SetNotifyChildAction([this] (const RefPtr<FrameNode>& node,
__anon9e2d7cf40202(const RefPtr<FrameNode>& node, NotifyChildActionType childActionType) 97 NotifyChildActionType childActionType) {
98 this->processFlag1_ = true;
99 this->processType1_ = static_cast<int32_t>(childActionType);
100 return AccessibilityActionResult::ACTION_OK;
101 }
102 );
103
104 auto result = AccessibilityFunctionUtils::HandleNotifyChildAction(frameNode3, NotifyChildActionType::ACTION_CLICK);
105 EXPECT_TRUE(processFlag1_);
106 EXPECT_EQ(processType1_, static_cast<int32_t>(NotifyChildActionType::ACTION_CLICK));
107 }
108
109 /**
110 * @tc.name: AccessibilityActionFunctionUtilsTest002
111 * @tc.desc: AddMultipleNodes
112 * @tc.type: FUNC
113 */
114 HWTEST_F(AccessibilityActionFunctionUtilsTest, AccessibilityActionFunctionUtilsTest002, TestSize.Level1)
115 {
116 /**
117 * @tc.steps: step1. construct framenodes
118 */
119 auto frameNode0 = FrameNode::CreateFrameNode("framenode", 1, AceType::MakeRefPtr<Pattern>(), false);
120 CHECK_NULL_VOID(frameNode0);
121 auto frameNode1 = FrameNode::CreateFrameNode("framenode", 1, AceType::MakeRefPtr<Pattern>(), false);
122 CHECK_NULL_VOID(frameNode1);
123 frameNode1->MountToParent(frameNode0);
124 frameNode0->AddChild(frameNode1);
125 auto frameNode2 = FrameNode::CreateFrameNode("framenode", 2, AceType::MakeRefPtr<Pattern>(), false);
126 CHECK_NULL_VOID(frameNode2);
127 frameNode2->MountToParent(frameNode1);
128 frameNode1->AddChild(frameNode2);
129 auto frameNode3 = FrameNode::CreateFrameNode("framenode", 3, AceType::MakeRefPtr<Pattern>(), false);
130 CHECK_NULL_VOID(frameNode3);
131 frameNode3->MountToParent(frameNode2);
132 frameNode2->AddChild(frameNode3);
133
134 /**
135 * @tc.steps: step2. framenode0 framenode2 set callback. framenode2 need to bubble up
136 * @tc.expected: callback of framenode0 and framenode2 can be handled, when framenode3 HandleNotifyChildAction.
137 */
138 processFlag1_ = false;
139 processFlag2_ = false;
140 processType1_ = -1;
141 processType2_ = -1;
142 auto accessibilityProperty2 = frameNode2->GetAccessibilityProperty<NG::AccessibilityProperty>();
143 CHECK_NULL_VOID(accessibilityProperty2);
144 accessibilityProperty2->SetNotifyChildAction([this] (const RefPtr<FrameNode>& node,
__anon9e2d7cf40302(const RefPtr<FrameNode>& node, NotifyChildActionType childActionType) 145 NotifyChildActionType childActionType) {
146 this->processFlag1_ = true;
147 this->processType1_ = static_cast<int32_t>(childActionType);
148 return AccessibilityActionResult::ACTION_RISE;
149 }
150 );
151
152 auto accessibilityProperty0 = frameNode0->GetAccessibilityProperty<NG::AccessibilityProperty>();
153 CHECK_NULL_VOID(accessibilityProperty0);
154 accessibilityProperty0->SetNotifyChildAction([this] (const RefPtr<FrameNode>& node,
__anon9e2d7cf40402(const RefPtr<FrameNode>& node, NotifyChildActionType childActionType) 155 NotifyChildActionType childActionType) {
156 this->processFlag2_ = true;
157 this->processType2_ = static_cast<int32_t>(childActionType);
158 return AccessibilityActionResult::ACTION_OK;
159 }
160 );
161
162 auto result = AccessibilityFunctionUtils::HandleNotifyChildAction(frameNode3, NotifyChildActionType::ACTION_CLICK);
163 EXPECT_TRUE(processFlag1_);
164 EXPECT_TRUE(processFlag2_);
165 EXPECT_EQ(processType1_, static_cast<int32_t>(NotifyChildActionType::ACTION_CLICK));
166 EXPECT_EQ(processType2_, static_cast<int32_t>(NotifyChildActionType::ACTION_CLICK));
167 }
168
169 /**
170 * @tc.name: AccessibilityActionFunctionUtilsTest003
171 * @tc.desc: AddMultipleNodes
172 * @tc.type: FUNC
173 */
174 HWTEST_F(AccessibilityActionFunctionUtilsTest, AccessibilityActionFunctionUtilsTest003, TestSize.Level1)
175 {
176 /**
177 * @tc.steps: step1. construct framenodes
178 */
179 auto frameNode1 = FrameNode::CreateFrameNode("framenode", 1, AceType::MakeRefPtr<Pattern>(), false);
180 CHECK_NULL_VOID(frameNode1);
181 auto frameNode2 = FrameNode::CreateFrameNode("framenode", 2, AceType::MakeRefPtr<Pattern>(), false);
182 CHECK_NULL_VOID(frameNode2);
183 frameNode2->MountToParent(frameNode1);
184 frameNode1->AddChild(frameNode2);
185 auto frameNode3 = FrameNode::CreateFrameNode("framenode", 3, AceType::MakeRefPtr<Pattern>(), false);
186 CHECK_NULL_VOID(frameNode3);
187 frameNode3->MountToParent(frameNode2);
188 frameNode2->AddChild(frameNode3);
189
190 /**
191 * @tc.steps: step2. framenode1 framenode2 set callback.
192 * @tc.expected: callback of framenode0 framenode1 framenode2 framenode3 can be handled,
193 * when no callcack is setted in framenode3.
194 */
195
196 processFlag1_ = false;
197 processFlag2_ = false;
198 processFlag3_ = false;
199
200 auto accessibilityProperty1 = frameNode1->GetAccessibilityProperty<NG::AccessibilityProperty>();
201 CHECK_NULL_VOID(accessibilityProperty1);
202 accessibilityProperty1->SetAccessibilityActionIntercept(
__anon9e2d7cf40502(AccessibilityInterfaceAction accessibilityInterfaceAction) 203 [this] (AccessibilityInterfaceAction accessibilityInterfaceAction) {
204 this->processFlag1_ = true;
205 return AccessibilityActionInterceptResult::ACTION_CONTINUE;
206 }
207 );
208
209 auto accessibilityProperty2 = frameNode2->GetAccessibilityProperty<NG::AccessibilityProperty>();
210 CHECK_NULL_VOID(accessibilityProperty2);
211 accessibilityProperty2->SetAccessibilityActionIntercept(
__anon9e2d7cf40602(AccessibilityInterfaceAction accessibilityInterfaceAction) 212 [this] (AccessibilityInterfaceAction accessibilityInterfaceAction) {
213 this->processFlag2_ = true;
214 return AccessibilityActionInterceptResult::ACTION_INTERCEPT;
215 }
216 );
217
218 auto result = AccessibilityFunctionUtils::HandleAccessibilityActionIntercept(frameNode3,
219 AccessibilityInterfaceAction::ACCESSIBILITY_CLICK);
220 EXPECT_FALSE(processFlag3_);
221 EXPECT_FALSE(processFlag2_);
222 EXPECT_FALSE(processFlag1_);
223 }
224
225 /**
226 * @tc.name: AccessibilityActionFunctionUtilsTest004
227 * @tc.desc: AddMultipleNodes
228 * @tc.type: FUNC
229 */
230 HWTEST_F(AccessibilityActionFunctionUtilsTest, AccessibilityActionFunctionUtilsTest004, TestSize.Level1)
231 {
232 /**
233 * @tc.steps: step1. construct framenodes
234 */
235 auto frameNode1 = FrameNode::CreateFrameNode("framenode", 1, AceType::MakeRefPtr<Pattern>(), false);
236 CHECK_NULL_VOID(frameNode1);
237 auto frameNode2 = FrameNode::CreateFrameNode("framenode", 2, AceType::MakeRefPtr<Pattern>(), false);
238 CHECK_NULL_VOID(frameNode2);
239 frameNode2->MountToParent(frameNode1);
240 frameNode1->AddChild(frameNode2);
241 auto frameNode3 = FrameNode::CreateFrameNode("framenode", 3, AceType::MakeRefPtr<Pattern>(), false);
242 CHECK_NULL_VOID(frameNode3);
243 frameNode3->MountToParent(frameNode2);
244 frameNode2->AddChild(frameNode3);
245
246 /**
247 * @tc.steps: step2. framenode0 framenode1 framenode2 framenode3 set callback. framenode3 need to bubble up
248 * @tc.expected: callback of framenode1 can be handled, when framenode3 HandleAccessibilityActionIntercept.
249 */
250
251 processFlag1_ = false;
252 processFlag2_ = false;
253 processFlag3_ = false;
254
255 auto accessibilityProperty1 = frameNode1->GetAccessibilityProperty<NG::AccessibilityProperty>();
256 CHECK_NULL_VOID(accessibilityProperty1);
257 accessibilityProperty1->SetAccessibilityActionIntercept(
__anon9e2d7cf40702(AccessibilityInterfaceAction accessibilityInterfaceAction) 258 [this] (AccessibilityInterfaceAction accessibilityInterfaceAction) {
259 this->processFlag1_ = true;
260 return AccessibilityActionInterceptResult::ACTION_CONTINUE;
261 }
262 );
263
264 auto accessibilityProperty3 = frameNode3->GetAccessibilityProperty<NG::AccessibilityProperty>();
265 CHECK_NULL_VOID(accessibilityProperty3);
266 accessibilityProperty3->SetAccessibilityActionIntercept(
__anon9e2d7cf40802(AccessibilityInterfaceAction accessibilityInterfaceAction) 267 [this] (AccessibilityInterfaceAction accessibilityInterfaceAction) {
268 this->processFlag3_ = true;
269 return AccessibilityActionInterceptResult::ACTION_RISE;
270 }
271 );
272 auto result = AccessibilityFunctionUtils::HandleAccessibilityActionIntercept(frameNode3,
273 AccessibilityInterfaceAction::ACCESSIBILITY_CLICK);
274 EXPECT_TRUE(processFlag3_);
275 EXPECT_TRUE(processFlag1_);
276 }
277 } // namespace OHOS::Ace::NG