1 /*
2  * Copyright (c) 2023 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 <memory>
17 
18 #include "gtest/gtest.h"
19 
20 #include "base/json/json_util.h"
21 
22 #define protected public
23 #define private public
24 
25 #include "base/json/node_object.h"
26 #include "core/components_ng/base/distributed_ui.h"
27 #include "core/pipeline_ng/pipeline_context.h"
28 #include "test/mock/core/pipeline/mock_pipeline_context.h"
29 
30 using namespace testing;
31 using namespace testing::ext;
32 
33 namespace OHOS::Ace::NG {
34 namespace {
35 const char DISTRIBUTE_UI_ID[] = "$ID";
36 const char DISTRIBUTE_UI_DEPTH[] = "$depth";
37 const char DISTRIBUTE_UI_ATTRS[] = "$attrs";
38 } // namespace
39 class DistributedUiTestNg : public testing::Test {
40 public:
SetUpTestSuite()41     static void SetUpTestSuite()
42     {
43         MockPipelineContext::SetUp();
44     }
TearDownTestSuite()45     static void TearDownTestSuite()
46     {
47         MockPipelineContext::TearDown();
48     }
49 
50     void Init();
51 };
52 
Init()53 void DistributedUiTestNg::Init()
54 {
55     auto parentNode = FrameNode::CreateFrameNode(
56         V2::STAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>());
57     auto childNode = FrameNode::CreateFrameNode(
58         "child", ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>());
59     parentNode->AddChild(childNode);
60     auto stageManager = AceType::MakeRefPtr<StageManager>(parentNode);
61     MockPipelineContext::GetCurrent()->stageManager_ = stageManager;
62 }
63 
64 /**
65  * @tc.name: DistributedUiTestNg001
66  * @tc.desc: DistributedUi of tests
67  * @tc.type: FUNC
68  */
69 HWTEST_F(DistributedUiTestNg, DistributedUiTestNg001, TestSize.Level1)
70 {
71     auto parentNode = FrameNode::CreateFrameNode(
72         V2::STAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>());
73     auto childNode = FrameNode::CreateFrameNode(
74         "child", ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>());
75     parentNode->AddChild(childNode);
76     auto thirdGenerationNode = FrameNode::CreateFrameNode(
77         "thirdGenerationNode", ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>());
78     auto stageManager = AceType::MakeRefPtr<StageManager>(parentNode);
79     MockPipelineContext::GetCurrent()->stageManager_ = stageManager;
80 
81     /**
82      * @tc.steps: step1. creat distributedUI and creat parentNode add childNode
83      * @tc.expected: step1. call DumpUITree() return SerializeableObjectArray
84      */
85     DistributedUI distributedUI;
86     auto array = distributedUI.DumpUITree();
87     EXPECT_EQ(distributedUI.status_, DistributedUI::StateMachine::SOURCE_START);
88 
89     /**
90      * @tc.steps: step2. childNode add thirdGenerationNode
91      * @tc.expected: step2. call DumpUITree() return SerializeableObjectArray
92      */
93     childNode->AddChild(thirdGenerationNode);
94     array = distributedUI.DumpUITree();
95     EXPECT_EQ(distributedUI.status_, DistributedUI::StateMachine::SOURCE_START);
96     EXPECT_FALSE(array.empty());
97 
98     /**
99      * @tc.steps: step3. creat fun.
100      * @tc.expected: step3. distributedUI.onUpdateCb_ is not null
101      */
102 
__anone7a239e30202(int32_t num, SerializeableObjectArray& array) 103     std::function<void(int32_t, SerializeableObjectArray&)> fun = [](int32_t num, SerializeableObjectArray& array) {};
104 
105     distributedUI.SubscribeUpdate(fun);
106     EXPECT_TRUE(distributedUI.onUpdateCb_);
107     /**
108      * @tc.steps: step4. call UnSubscribeUpdate
109      * @tc.expected: step4. distributedUI.onUpdateCb_ is destroy.
110      */
111 
112     distributedUI.UnSubscribeUpdate();
113     EXPECT_FALSE(distributedUI.onUpdateCb_);
114     EXPECT_EQ(distributedUI.status_, DistributedUI::StateMachine::STOP);
115 }
116 
117 /**
118  * @tc.name: DistributedUiTestNg002
119  * @tc.desc: DistributedUi of tests
120  * @tc.type: FUNC
121  */
122 HWTEST_F(DistributedUiTestNg, DistributedUiTestNg002, TestSize.Level1)
123 {
124     Init();
125     /**
126      * @tc.steps: step1. creat distributedUI and creat parentNode add childNode
127      * @tc.expected: step1. call DumpUITree() return SerializeableObjectArray
128      */
129     DistributedUI distributedUI;
130     auto array = distributedUI.DumpUITree();
131     EXPECT_EQ(distributedUI.status_, DistributedUI::StateMachine::SOURCE_START);
132 
133     /**
134      * @tc.steps: step2. call AddNode
135      * @tc.expected: step2. DistributedUI::StateMachine state determines whether to add nodes
136      */
137     distributedUI.AddDeletedNode(0);
138     distributedUI.AddNewNode(0);
139     distributedUI.AddDirtyCustomNode(0);
140     distributedUI.AddDirtyRenderNode(0);
141     distributedUI.AddDirtyLayoutNode(0);
142     EXPECT_TRUE(distributedUI.deletedNodes_.empty());
143 
__anone7a239e30302(int32_t num, SerializeableObjectArray& array) 144     std::function<void(int32_t, SerializeableObjectArray&)> fun = [](int32_t num, SerializeableObjectArray& array) {};
145     distributedUI.SubscribeUpdate(fun);
146     EXPECT_TRUE(distributedUI.onUpdateCb_);
147     distributedUI.AddDeletedNode(0);
148     distributedUI.AddNewNode(0);
149     distributedUI.AddDirtyCustomNode(0);
150     distributedUI.AddDirtyRenderNode(0);
151     distributedUI.AddDirtyLayoutNode(0);
152     EXPECT_EQ(distributedUI.deletedNodes_.size(), 1);
153 }
154 
155 /**
156  * @tc.name: DistributedUiTestNg003
157  * @tc.desc: DistributedUi of tests
158  * @tc.type: FUNC
159  */
160 HWTEST_F(DistributedUiTestNg, DistributedUiTestNg003, TestSize.Level1)
161 {
162     Init();
163 
164     /**
165      * @tc.steps: step1. creat distributedUI and creat parentNode add childNode
166      * @tc.expected: step1. call DumpUITree() return SerializeableObjectArray
167      */
168     DistributedUI distributedUI;
169     auto array = distributedUI.DumpUITree();
170     EXPECT_EQ(distributedUI.status_, DistributedUI::StateMachine::SOURCE_START);
171 
172     /**
173      * @tc.steps: step2. call OnTreeUpdate.
174      * @tc.expected: step2. distributedUI.pageChangeFlag_ change.
175      */
176     distributedUI.OnTreeUpdate();
__anone7a239e30402(int32_t num, SerializeableObjectArray& array) 177     std::function<void(int32_t, SerializeableObjectArray&)> fun = [](int32_t num, SerializeableObjectArray& array) {};
178     distributedUI.SubscribeUpdate(fun);
179     EXPECT_TRUE(distributedUI.onUpdateCb_);
180     distributedUI.OnPageChanged(0);
181     EXPECT_TRUE(distributedUI.pageChangeFlag_);
182     distributedUI.OnTreeUpdate();
183     EXPECT_FALSE(distributedUI.pageChangeFlag_);
184     distributedUI.OnTreeUpdate();
185     EXPECT_TRUE(distributedUI.onUpdateCb_);
186 
187     distributedUI.status_ = DistributedUI::StateMachine::STOP;
188     distributedUI.OnPageChanged(distributedUI.GetCurrentPageId());
189     EXPECT_FALSE(distributedUI.pageChangeFlag_);
190 }
191 
192 /**
193  * @tc.name: DistributedUiTestNg004
194  * @tc.desc: DistributedUi of tests
195  * @tc.type: FUNC
196  */
197 HWTEST_F(DistributedUiTestNg, DistributedUiTestNg004, TestSize.Level1)
198 {
199     Init();
200     /**
201      * @tc.steps: step1. creat distributedUI and creat parentNode add childNode
202      * @tc.expected: step1. call DumpUITree() return SerializeableObjectArray
203      */
204     DistributedUI distributedUI;
205     auto array = distributedUI.DumpUITree();
206     EXPECT_EQ(distributedUI.status_, DistributedUI::StateMachine::SOURCE_START);
207 
208     /**
209      * @tc.steps: step2. call SubscribeInputEventProcess
210      * @tc.expected: step2. creat eventFun and eventFun destroy
211      */
__anone7a239e30502(SerializeableObjectArray& array) 212     std::function<void(SerializeableObjectArray&)> eventFun = [](SerializeableObjectArray& array) {};
213     distributedUI.SubscribeInputEventProcess(eventFun);
214     TouchEvent touchEvent;
215     distributedUI.BypassEvent(touchEvent, false);
216     distributedUI.status_ = DistributedUI::StateMachine::SINK_START;
217     EXPECT_TRUE(distributedUI.onEventCb_);
218     EXPECT_TRUE(distributedUI.IsSinkMode());
219     distributedUI.UnSubscribeInputEventProcess();
220     distributedUI.BypassEvent(touchEvent, false);
221     EXPECT_FALSE(distributedUI.onEventCb_);
222     EXPECT_FALSE(distributedUI.IsSinkMode());
223 }
224 
225 /**
226  * @tc.name: DistributedUiTestNg005
227  * @tc.desc: DistributedUi of tests
228  * @tc.type: FUNC
229  */
230 HWTEST_F(DistributedUiTestNg, DistributedUiTestNg005, TestSize.Level1)
231 {
232     auto parentNode = FrameNode::CreateFrameNode(
233         V2::STAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>());
234     auto childNode = FrameNode::CreateFrameNode(
235         "child", ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>());
236     parentNode->AddChild(childNode);
237     auto stageManager = AceType::MakeRefPtr<StageManager>(parentNode);
238     MockPipelineContext::GetCurrent()->stageManager_ = stageManager;
239     /**
240      * @tc.steps: step1. creat distributedUI and creat parentNode add childNode
241      * @tc.expected: step1. call DumpUITree() return SerializeableObjectArray
242      */
243     DistributedUI distributedUI;
244     auto array = distributedUI.DumpUITree();
245     EXPECT_EQ(distributedUI.status_, DistributedUI::StateMachine::SOURCE_START);
246 
247     /**
248      * @tc.steps: step2. call DumpUpdate().
249      * @tc.expected: step2. return SerializeableObjectArray is not empty.
250      */
__anone7a239e30602(int32_t num, SerializeableObjectArray& array) 251     std::function<void(int32_t, SerializeableObjectArray&)> fun = [](int32_t num, SerializeableObjectArray& array) {};
252     distributedUI.SubscribeUpdate(fun);
253     EXPECT_TRUE(distributedUI.onUpdateCb_);
254     distributedUI.AddDeletedNode(parentNode->GetId());
255     distributedUI.AddNewNode(parentNode->GetId());
256     distributedUI.AddDirtyCustomNode(parentNode->GetId());
257     distributedUI.AddDirtyRenderNode(parentNode->GetId());
258     distributedUI.AddDirtyLayoutNode(parentNode->GetId());
259     distributedUI.AddDeletedNode(100);
260     distributedUI.AddNewNode(100);
261     distributedUI.AddDirtyCustomNode(100);
262     distributedUI.AddDirtyRenderNode(100);
263     distributedUI.AddDirtyLayoutNode(100);
264     EXPECT_TRUE(distributedUI.IsNewNode(100));
265     auto newArray = distributedUI.DumpUpdate();
266     EXPECT_TRUE(!newArray.empty());
267     distributedUI.ResetDirtyNodes();
268     EXPECT_TRUE(distributedUI.newNodes_.empty());
269     EXPECT_FALSE(distributedUI.IsNewNode(100));
270 }
271 
272 /**
273  * @tc.name: DistributedUiTestNg006
274  * @tc.desc: DistributedUi of tests
275  * @tc.type: FUNC
276  */
277 HWTEST_F(DistributedUiTestNg, DistributedUiTestNg006, TestSize.Level1)
278 {
279     auto parentNode = FrameNode::CreateFrameNode(
280         V2::JS_SYNTAX_ITEM_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>());
281     auto childNode = FrameNode::CreateFrameNode(
282         "child", ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>());
283     parentNode->AddChild(childNode);
284     auto stageManager = AceType::MakeRefPtr<StageManager>(parentNode);
285     MockPipelineContext::GetCurrent()->stageManager_ = stageManager;
286     /**
287      * @tc.steps: step1. creat distributedUI and creat parentNode add childNode
288      * @tc.expected: step1. call DumpUITree() return SerializeableObjectArray
289      */
290     DistributedUI distributedUI;
291     auto array = distributedUI.DumpUITree();
292     EXPECT_EQ(distributedUI.status_, DistributedUI::StateMachine::SOURCE_START);
293 
294     /**
295      * @tc.steps: step2. call SetIdMapping
296      * @tc.expected: step2. nodeIdMapping_.size() > 0
297      */
298     int32_t srcNodeId = 0;
299     int32_t sinkNodeId = 0;
300     distributedUI.SetIdMapping(srcNodeId, sinkNodeId);
301     EXPECT_EQ(distributedUI.GetIdMapping(srcNodeId), sinkNodeId);
302     /**
303      * @tc.steps: step3. call SetIdMapping
304      * @tc.expected: step3. set same numerals fix value price
305      */
306     distributedUI.SetIdMapping(srcNodeId, sinkNodeId + 1);
307     EXPECT_EQ(distributedUI.nodeIdMapping_.size(), 1);
308     /**
309      * @tc.steps: step4. call GetIdMapping
310      * @tc.expected: step4. Enter a value that does not exist and return -1
311      */
312     EXPECT_EQ(distributedUI.GetIdMapping(10), -1);
313 
314     /**
315      * @tc.steps: step5. call IsRecordHash
316      * @tc.expected: step5. Returns false or true to determine whether a value already exists
317      */
318     distributedUI.AddNodeHash(0, 0);
319     EXPECT_FALSE(distributedUI.IsRecordHash(0, 0));
320     EXPECT_TRUE(distributedUI.IsRecordHash(10, 0));
321     EXPECT_TRUE(distributedUI.IsRecordHash(0, 10));
322     EXPECT_TRUE(distributedUI.IsRecordHash(10, 10));
323 
324     /**
325      * @tc.steps: step6. call IsInCurrentPage
326      * @tc.expected: step6. Returns false or true to determine whether a value already exists
327      */
328     EXPECT_TRUE(distributedUI.IsInCurrentPage(parentNode, 0));
329     EXPECT_TRUE(distributedUI.IsInCurrentPage(childNode, 0));
330     EXPECT_FALSE(distributedUI.IsInCurrentPage(childNode, 5));
331 }
332 
333 /**
334  * @tc.name: DistributedUiTestNg007
335  * @tc.desc: DistributedUi of tests
336  * @tc.type: FUNC
337  */
338 HWTEST_F(DistributedUiTestNg, DistributedUiTestNg007, TestSize.Level1)
339 {
340     auto parentNode = FrameNode::CreateFrameNode(
341         V2::JS_SYNTAX_ITEM_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>());
342     auto childNode = FrameNode::CreateFrameNode(
343         "child", ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>());
344     parentNode->AddChild(childNode);
345     auto stageManager = AceType::MakeRefPtr<StageManager>(parentNode);
346     MockPipelineContext::GetCurrent()->stageManager_ = stageManager;
347 
348     auto nodeObject = std::make_unique<OHOS::Ace::NodeObject>();
349     /**
350      * @tc.steps: step1. creat distributedUI and creat parentNode add childNode
351      * @tc.expected: step1. call AttachToTree() return SerializeableObjectArray
352      */
353     DistributedUI distributedUI;
354     distributedUI.AttachToTree(parentNode, childNode, nodeObject);
355     EXPECT_TRUE(distributedUI.IsInCurrentPage(parentNode, 0));
356 
357     nodeObject->Put(DISTRIBUTE_UI_DEPTH, 1);
358     distributedUI.AttachToTree(parentNode, childNode, nodeObject);
359     EXPECT_TRUE(distributedUI.IsInCurrentPage(parentNode, 0));
360 }
361 
362 /**
363  * @tc.name: DistributedUiTestNg008
364  * @tc.desc: DistributedUi of tests
365  * @tc.type: FUNC
366  */
367 HWTEST_F(DistributedUiTestNg, DistributedUiTestNg008, TestSize.Level1)
368 {
369     auto parentNodeId = ElementRegister::GetInstance()->MakeUniqueId();
370     auto parentNode =
371         FrameNode::CreateFrameNode(V2::JS_SYNTAX_ITEM_ETS_TAG, parentNodeId, AceType::MakeRefPtr<Pattern>());
372     auto childNodeId = ElementRegister::GetInstance()->MakeUniqueId();
373     auto childNode = FrameNode::CreateFrameNode("child", childNodeId, AceType::MakeRefPtr<Pattern>());
374     parentNode->AddChild(childNode);
375     auto stageManager = AceType::MakeRefPtr<StageManager>(parentNode);
376     MockPipelineContext::GetCurrent()->stageManager_ = stageManager;
377 
378     auto nodeObject = std::make_unique<OHOS::Ace::NodeObject>();
379     nodeObject->Put(DISTRIBUTE_UI_ID, childNodeId);
380     /**
381      * @tc.steps: step1. creat distributedUI and creat parentNode add childNode
382      * @tc.expected: step1. call AttachToTree() return SerializeableObjectArray
383      */
384     DistributedUI distributedUI;
385     distributedUI.DelNode(nodeObject);
386     EXPECT_FALSE(parentNode->GetChildren().empty());
387 
388     distributedUI.SetIdMapping(childNodeId, childNodeId);
389     distributedUI.DelNode(nodeObject);
390     EXPECT_TRUE(parentNode->GetChildren().empty());
391 
392     distributedUI.DelNode(nodeObject);
393     EXPECT_EQ(childNode->GetParent(), nullptr);
394 }
395 
396 /**
397  * @tc.name: DistributedUiTestNg009
398  * @tc.desc: DistributedUi of tests
399  * @tc.type: FUNC
400  */
401 HWTEST_F(DistributedUiTestNg, DistributedUiTestNg009, TestSize.Level1)
402 {
403     auto parentNodeId = ElementRegister::GetInstance()->MakeUniqueId();
404     auto parentNode =
405         FrameNode::CreateFrameNode(V2::JS_SYNTAX_ITEM_ETS_TAG, parentNodeId, AceType::MakeRefPtr<Pattern>());
406     auto childNodeId = ElementRegister::GetInstance()->MakeUniqueId();
407     auto childNode = FrameNode::CreateFrameNode("child", childNodeId, AceType::MakeRefPtr<Pattern>());
408     parentNode->AddChild(childNode);
409     auto stageManager = AceType::MakeRefPtr<StageManager>(parentNode);
410     MockPipelineContext::GetCurrent()->stageManager_ = stageManager;
411 
412     auto nodeObject = std::make_unique<OHOS::Ace::NodeObject>();
413     nodeObject->Put(DISTRIBUTE_UI_ID, childNodeId);
414 
415     auto attrValue = "{padding: 1px}";
416     nodeObject->Put(DISTRIBUTE_UI_ATTRS, OHOS::Ace::JsonUtil::ParseJsonString(attrValue));
417     /**
418      * @tc.steps: step1. creat distributedUI and creat parentNode add childNode
419      * @tc.expected: step1. call AttachToTree() return SerializeableObjectArray
420      */
421     DistributedUI distributedUI;
422     distributedUI.ModNode(nodeObject);
423     EXPECT_NE(childNode, nullptr);
424 
425     distributedUI.SetIdMapping(childNodeId, childNodeId);
426     distributedUI.ModNode(nodeObject);
427     EXPECT_NE(childNode->GetLayoutProperty()->GetPaddingProperty()->left->calcValue_, "0.0");
428 }
429 
430 /**
431  * @tc.name: DistributedUiTestNg010
432  * @tc.desc: DistributedUi UpdateUITree
433  * @tc.type: FUNC
434  */
435 HWTEST_F(DistributedUiTestNg, DistributedUiTestNg010, TestSize.Level1)
436 {
437     /**
438      * @tc.steps: step1. statement distributedUI and SerializeableObjectArray
439      */
440     SerializeableObjectArray array;
441     DistributedUI distributedUI;
442 
443     /**
444      * @tc.steps: step2. call UpdateUITree()
445      * @tc.expected: step2. call AttachToTree() and cover branch status_ is INIT
446      */
447     distributedUI.UpdateUITree(array);
448     EXPECT_EQ(distributedUI.status_, DistributedUI::StateMachine::INIT);
449 
450     /**
451      * @tc.steps: step3. call UpdateUITree()
452      * @tc.expected: step3. call AttachToTree() and cover branch status_ is not INIT
453      */
454     distributedUI.status_ = DistributedUI::StateMachine::SINK_START;
455     distributedUI.UpdateUITree(array);
456     EXPECT_NE(distributedUI.status_, DistributedUI::StateMachine::INIT);
457 }
458 
459 /**
460  * @tc.name: DistributedUiTestNg011
461  * @tc.desc: DistributedUi UpdateUITree
462  * @tc.type: FUNC
463  */
464 HWTEST_F(DistributedUiTestNg, DistributedUiTestNg011, TestSize.Level1)
465 {
466     /**
467      * @tc.steps: step1. statement distributedUI and SerializeableObjectArray
468      */
469     DistributedUI distributedUI;
470     distributedUI.ApplyOneUpdate();
471     EXPECT_EQ(distributedUI.pendingUpdates_.size() == 0, true);
472     SerializeableObjectArray array;
473     std::unique_ptr<SerializeableObject> value = std::make_unique<JsonValue>();
474     array.push_back(std::move(value));
475     distributedUI.RestoreUITree(array);
476     distributedUI.UpdateUITree(array);
477     EXPECT_EQ(distributedUI.pendingUpdates_.size() == 1, true);
478     distributedUI.ApplyOneUpdate();
479     EXPECT_EQ(distributedUI.pendingUpdates_.size() == 0, true);
480 }
481 } // namespace OHOS::Ace::NG