1 /*
2  * Copyright (c) 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 <cstddef>
17 
18 #include "gtest/gtest.h"
19 
20 #include "core/interfaces/native/node/node_content_modifier.h"
21 #define private public
22 #include "interfaces/native/native_node.h"
23 #include "test/mock/core/pipeline/mock_pipeline_context.h"
24 
25 #include "base/memory/ace_type.h"
26 #include "core/components_ng/base/ui_node.h"
27 #include "core/components_ng/base/view_stack_processor.h"
28 #include "core/components_ng/syntax/content_slot_model_ng.h"
29 #include "core/components_ng/syntax/content_slot_node.h"
30 #include "core/components_ng/syntax/node_content.h"
31 
32 using namespace testing;
33 using namespace testing::ext;
34 
35 namespace OHOS::Ace::NG {
36 namespace {
37 constexpr int32_t NODE_CONTENT_INIT_STATUS = 1000;
38 constexpr int32_t NODE_CONTENT_ATTACH_TO_TREE = 1001;
39 constexpr int32_t NODE_CONTENT_DETACH_FROM_TREE = 1002;
40 constexpr uint32_t NUM_1 = 1;
41 constexpr uint32_t NUM_2 = 2;
42 } // namespace
43 
44 class ContentSlotSyntaxTestNg : public testing::Test {
45 public:
46     static void SetUpTestSuite();
47     static void TearDownTestSuite();
48     void SetUp() override;
49     void TearDown() override;
50 };
51 
SetUpTestSuite()52 void ContentSlotSyntaxTestNg::SetUpTestSuite()
53 {
54     GTEST_LOG_(INFO) << "ContentSlotSyntaxTestNg SetUpTestCase";
55 }
56 
TearDownTestSuite()57 void ContentSlotSyntaxTestNg::TearDownTestSuite()
58 {
59     GTEST_LOG_(INFO) << "ContentSlotSyntaxTestNg TearDownTestCase";
60 }
61 
SetUp()62 void ContentSlotSyntaxTestNg::SetUp()
63 {
64     MockPipelineContext::SetUp();
65 }
66 
TearDown()67 void ContentSlotSyntaxTestNg::TearDown()
68 {
69     MockPipelineContext::TearDown();
70 }
71 
72 /**
73  * @tc.name: ContentSlotSyntaxTest001
74  * @tc.desc: ContentSlot For CAPI 1
75  * @tc.type: FUNC
76  */
77 HWTEST_F(ContentSlotSyntaxTestNg, ContentSlotSyntaxTest001, TestSize.Level1)
78 {
79     /**
80      * @tc.steps: step1. Create contentSlotNode
81      * @tc.expected: contentSlotNode create successfully
82      */
83     auto nodeContentPtr = AceType::MakeRefPtr<NodeContent>();
84     NodeContent* nodeContent = AceType::RawPtr(nodeContentPtr);
85     ContentSlotModel::Create(nodeContent);
86     auto contentSlotNode = AceType::DynamicCast<ContentSlotNode>(ViewStackProcessor::GetInstance()->Finish());
87     EXPECT_TRUE(contentSlotNode != nullptr && contentSlotNode->GetTag() == V2::JS_NODE_SLOT_ETS_TAG);
88 
89     /**
90      * @tc.steps: step2. add/insert/remove child
91      * @tc.expected: add/insert/remove child successfully
92      */
93     const auto* contentModifier = NodeModifier::GetNodeContentModifier();
94     auto childFrameNode1 = FrameNode::CreateFrameNode("frameNode1", -1, AceType::MakeRefPtr<Pattern>());
95     contentModifier->addChild(reinterpret_cast<ArkUINodeContentHandle>(nodeContent),
96         reinterpret_cast<ArkUINodeHandle>(childFrameNode1.GetRawPtr()));
97     auto children = contentSlotNode->GetChildren();
98     EXPECT_TRUE(children.size() == NUM_1 && children.front()->GetTag() == "frameNode1");
99 
100     auto childFrameNode2 = FrameNode::CreateFrameNode("frameNode2", -1, AceType::MakeRefPtr<Pattern>());
101     contentModifier->insertChild(reinterpret_cast<ArkUINodeContentHandle>(nodeContent),
102         reinterpret_cast<ArkUINodeHandle>(childFrameNode2.GetRawPtr()), 0);
103     children = contentSlotNode->GetChildren();
104     EXPECT_TRUE(children.size() == NUM_2 && children.front()->GetTag() == "frameNode2");
105 
106     contentModifier->removeChild(reinterpret_cast<ArkUINodeContentHandle>(nodeContent),
107         reinterpret_cast<ArkUINodeHandle>(childFrameNode1.GetRawPtr()));
108     contentModifier->removeChild(reinterpret_cast<ArkUINodeContentHandle>(nodeContent),
109         reinterpret_cast<ArkUINodeHandle>(childFrameNode2.GetRawPtr()));
110     children = contentSlotNode->GetChildren();
111     EXPECT_TRUE(children.size() == 0);
112 }
113 
114 /**
115  * @tc.name: ContentSlotSyntaxTest002
116  * @tc.desc: ContentSlot For CAPI 2
117  * @tc.type: FUNC
118  */
119 HWTEST_F(ContentSlotSyntaxTestNg, ContentSlotSyntaxTest002, TestSize.Level1)
120 {
121     /**
122      * @tc.steps: step1. Create contentSlotNode
123      * @tc.expected: contentSlotNode create successfully
124      */
125     auto nodeContentPtr = AceType::MakeRefPtr<NodeContent>();
126     NodeContent* nodeContent = AceType::RawPtr(nodeContentPtr);
127     ContentSlotModel::Create(nodeContent);
128     auto contentSlotNode = AceType::DynamicCast<ContentSlotNode>(ViewStackProcessor::GetInstance()->Finish());
129     EXPECT_TRUE(contentSlotNode != nullptr && contentSlotNode->GetTag() == V2::JS_NODE_SLOT_ETS_TAG);
130 
131     /**
132      * @tc.steps: step2. releated to event
133      * @tc.expected: registerEvent, set/getUserData, getNodeContent successfully
134      */
135     const auto* contentModifier = NodeModifier::GetNodeContentModifier();
136     auto* userData = new int32_t(NODE_CONTENT_INIT_STATUS);
137     contentModifier->setUserData(reinterpret_cast<ArkUINodeContentHandle>(nodeContent), userData);
__anon694de3710202(ArkUINodeContentEvent* event) 138     auto callback = [](ArkUINodeContentEvent* event) {
139         auto* nodeContent = event->nodeContent;
140         const auto* contentModifier = NodeModifier::GetNodeContentModifier();
141         if (event->type == 0) {
142             int32_t* userData = reinterpret_cast<int32_t*>(
143                 contentModifier->getUserData(reinterpret_cast<ArkUINodeContentHandle>(nodeContent)));
144             EXPECT_EQ(*userData, NODE_CONTENT_INIT_STATUS);
145             delete userData;
146             userData = new int32_t(NODE_CONTENT_ATTACH_TO_TREE);
147             contentModifier->setUserData(reinterpret_cast<ArkUINodeContentHandle>(nodeContent), userData);
148         } else if (event->type == 1) {
149             int32_t* userData = reinterpret_cast<int32_t*>(
150                 contentModifier->getUserData(reinterpret_cast<ArkUINodeContentHandle>(nodeContent)));
151             EXPECT_EQ(*userData, NODE_CONTENT_ATTACH_TO_TREE);
152             delete userData;
153             userData = new int32_t(NODE_CONTENT_DETACH_FROM_TREE);
154             contentModifier->setUserData(reinterpret_cast<ArkUINodeContentHandle>(nodeContent), userData);
155         }
156     };
157     contentModifier->registerEvent(reinterpret_cast<ArkUINodeContentHandle>(nodeContent), nullptr, std::move(callback));
158     nodeContent->OnAttachToMainTree();
159     EXPECT_TRUE(nodeContent->onMainTree_);
160     nodeContent->OnDetachFromMainTree();
161     EXPECT_FALSE(nodeContent->onMainTree_);
162     userData =
163         reinterpret_cast<int32_t*>(contentModifier->getUserData(reinterpret_cast<ArkUINodeContentHandle>(nodeContent)));
164     EXPECT_EQ(*userData, NODE_CONTENT_DETACH_FROM_TREE);
165     delete userData;
166 }
167 } // namespace OHOS::Ace::NG