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 <gtest/gtest.h>
17 
18 #include <meta/api/object.h>
19 #include <meta/base/ref_uri.h>
20 #include <meta/interface/intf_metadata.h>
21 
22 #include "src/test_runner.h"
23 #include "src/util.h"
24 #include "src/testing_objects.h"
25 
26 using namespace testing::ext;
27 
28 META_BEGIN_NAMESPACE()
29 
30 class RefUriTest : public testing::Test {
31 public:
SetUpTestSuite()32     static void SetUpTestSuite()
33     {
34         SetTest();
35     }
TearDownTestSuite()36     static void TearDownTestSuite()
37     {
38         ResetTest();
39     }
40     void SetUp() override {}
41     void TearDown() override {}
42 };
43 
44 /**
45  * @tc.name: RefUriTest
46  * @tc.desc: test DefaultAndUidConstruction function
47  * @tc.type: FUNC
48  * @tc.require: I7DMS1
49  */
HWTEST_F(RefUriTest, DefaultAndUidConstruction, TestSize.Level1)50 HWTEST_F(RefUriTest, DefaultAndUidConstruction, TestSize.Level1)
51 {
52     RefUri empty;
53     EXPECT_TRUE(empty.IsEmpty());
54     EXPECT_TRUE(empty.IsValid());
55     EXPECT_TRUE(!empty.ReferencesProperty());
56     EXPECT_TRUE(empty.ReferencesObject());
57     EXPECT_EQ(empty.BaseObjectUid(), BASE_NS::Uid {});
58     EXPECT_TRUE(!empty.StartsFromRoot());
59     EXPECT_EQ(empty.RelativeUri(), empty);
60     EXPECT_EQ(empty.ReferencedName(), "");
61     EXPECT_EQ(empty.ToString(), "ref:/");
62 
63     BASE_NS::Uid uid { "f80a3984-7ac7-4400-8e17-13937cc11d39" };
64     RefUri u1 { uid };
65     EXPECT_TRUE(!u1.IsEmpty());
66     EXPECT_TRUE(u1.IsValid());
67     EXPECT_TRUE(!u1.ReferencesProperty());
68     EXPECT_TRUE(u1.ReferencesObject());
69     EXPECT_EQ(u1.BaseObjectUid(), uid);
70     EXPECT_TRUE(!u1.StartsFromRoot());
71     EXPECT_EQ(u1.RelativeUri(), empty);
72     EXPECT_EQ(u1.ReferencedName(), "");
73     EXPECT_EQ(u1.ToString(), "ref:f80a3984-7ac7-4400-8e17-13937cc11d39/");
74 
75     RefUri u2 { uid, "/test/path" };
76     EXPECT_TRUE(!u2.IsEmpty());
77     EXPECT_TRUE(u2.IsValid());
78     EXPECT_TRUE(!u2.ReferencesProperty());
79     EXPECT_TRUE(u2.ReferencesObject());
80     EXPECT_EQ(u2.BaseObjectUid(), uid);
81     EXPECT_TRUE(!u2.StartsFromRoot());
82     EXPECT_EQ(u2.RelativeUri(), RefUri { "ref:/test/path" });
83     EXPECT_EQ(u2.ReferencedName(), "path");
84     EXPECT_EQ(u2.ToString(), "ref:f80a3984-7ac7-4400-8e17-13937cc11d39/test/path");
85     EXPECT_EQ(u2.TakeFirstNode().name, "test");
86     EXPECT_EQ(u2.TakeFirstNode().name, "path");
87     EXPECT_EQ(u2, u1);
88 
89     RefUri u3 { uid, "//test/path" };
90     EXPECT_TRUE(u3.StartsFromRoot());
91     EXPECT_EQ(u3.ToString(), "ref:f80a3984-7ac7-4400-8e17-13937cc11d39//test/path");
92     u3.SetStartsFromRoot(false);
93     EXPECT_EQ(u3, RefUri(uid, "/test/path"));
94 }
95 
96 /**
97  * @tc.name: RefUriTest
98  * @tc.desc: test StringConstruction function
99  * @tc.type: FUNC
100  * @tc.require: I7DMS1
101  */
HWTEST_F(RefUriTest, StringConstruction, TestSize.Level1)102 HWTEST_F(RefUriTest, StringConstruction, TestSize.Level1)
103 {
104     EXPECT_EQ(RefUri { "ref:/" }, RefUri {});
105     EXPECT_FALSE(RefUri("").IsValid());
106     EXPECT_FALSE(RefUri("/some/path").IsValid());
107     EXPECT_FALSE(RefUri("ref:///").IsValid());
108     EXPECT_EQ(RefUri("ref:/.."), RefUri::ParentUri());
109     EXPECT_FALSE(RefUri("ref:7ac7-4400-8e17-13937cc11d39").IsValid());
110     EXPECT_FALSE(RefUri("ref:f80a3984-7ac7-4400-8e17-13937cc11d39///").IsValid());
111     {
112         RefUri u { "ref://" };
113         EXPECT_TRUE(u.IsValid());
114         EXPECT_TRUE(!u.IsEmpty());
115         EXPECT_EQ(u.ToString(), "ref://");
116         EXPECT_TRUE(u.StartsFromRoot());
117     }
118     {
119         RefUri u { "ref://this/and/$that" };
120         EXPECT_TRUE(u.IsValid());
121         EXPECT_TRUE(!u.IsEmpty());
122         EXPECT_EQ(u.ToString(), "ref://this/and/$that");
123         EXPECT_TRUE(u.StartsFromRoot());
124         EXPECT_TRUE(u.ReferencesProperty());
125         EXPECT_TRUE(!u.ReferencesObject());
126         EXPECT_EQ(u.ReferencedName(), "that");
127         EXPECT_EQ(u.TakeFirstNode().name, "this");
128         {
129             auto n = u.TakeFirstNode();
130             EXPECT_EQ(n.name, "and");
131             EXPECT_EQ(n.type, RefUri::Node::OBJECT);
132         }
133         {
134             auto n = u.TakeFirstNode();
135             EXPECT_EQ(n.name, "that");
136             EXPECT_EQ(n.type, RefUri::Node::PROPERTY);
137         }
138     }
139     {
140         RefUri u { "ref:f80a3984-7ac7-4400-8e17-13937cc11d39/hips/$hops/haps" };
141         EXPECT_TRUE(u.IsValid());
142         EXPECT_TRUE(!u.IsEmpty());
143         EXPECT_EQ(u.BaseObjectUid(), BASE_NS::Uid { "f80a3984-7ac7-4400-8e17-13937cc11d39" });
144         EXPECT_EQ(u.ToString(), "ref:f80a3984-7ac7-4400-8e17-13937cc11d39/hips/$hops/haps");
145         EXPECT_TRUE(!u.StartsFromRoot());
146         EXPECT_TRUE(!u.ReferencesProperty());
147         EXPECT_TRUE(u.ReferencesObject());
148         EXPECT_EQ(u.ReferencedName(), "haps");
149         EXPECT_EQ(u.TakeFirstNode().name, "hips");
150         {
151             auto n = u.TakeFirstNode();
152             EXPECT_EQ(n.name, "hops");
153             EXPECT_EQ(n.type, RefUri::Node::PROPERTY);
154         }
155         {
156             auto n = u.TakeFirstNode();
157             EXPECT_EQ(n.name, "haps");
158             EXPECT_EQ(n.type, RefUri::Node::OBJECT);
159         }
160     }
161 }
162 
163 /**
164  * @tc.name: RefUriTest
165  * @tc.desc: test Setters function
166  * @tc.type: FUNC
167  * @tc.require: I7DMS1
168  */
HWTEST_F(RefUriTest, Setters, TestSize.Level1)169 HWTEST_F(RefUriTest, Setters, TestSize.Level1)
170 {
171     {
172         RefUri u { "ref:f80a3984-7ac7-4400-8e17-13937cc11d39/hips/$hops/haps" };
173         EXPECT_TRUE(u.IsValid());
174         BASE_NS::Uid uid { "1ae79e0c-2701-4f19-8553-fb2dd22f6eba" };
175         u.SetBaseObjectUid(uid);
176         EXPECT_EQ(u.ToString(), "ref:1ae79e0c-2701-4f19-8553-fb2dd22f6eba/hips/$hops/haps");
177         u.SetStartsFromRoot(true);
178         EXPECT_EQ(u.ToString(), "ref:1ae79e0c-2701-4f19-8553-fb2dd22f6eba//hips/$hops/haps");
179     }
180     {
181         RefUri u;
182         u.PushPropertySegment("test");
183         u.PushObjectSegment("other");
184         u.PushPropertySegment("some");
185         u.PushObjectSegment("path");
186         EXPECT_EQ(u.ToString(), "ref:/path/$some/other/$test");
187     }
188 }
189 
190 /**
191  * @tc.name: RefUriTest
192  * @tc.desc: test Escaping function
193  * @tc.type: FUNC
194  * @tc.require: I7DMS1
195  */
HWTEST_F(RefUriTest, Escaping, TestSize.Level1)196 HWTEST_F(RefUriTest, Escaping, TestSize.Level1)
197 {
198     {
199         RefUri u(R"--(ref:/\/123\$456\@dd\\77)--");
200         EXPECT_EQ(u.ToString(), R"--(ref:/\/123\$456\@dd\\77)--");
201         EXPECT_EQ(u.TakeFirstNode().name, R"--(/123$456@dd\77)--");
202     }
203     {
204         RefUri u(R"--(ref:/\\\\\\\\\\\\\/)--");
205         EXPECT_EQ(u.ToString(), R"--(ref:/\\\\\\\\\\\\\/)--");
206         EXPECT_EQ(u.TakeFirstNode().name, R"--(\\\\\\/)--");
207     }
208     {
209         RefUri u;
210         u.PushObjectSegment(R"--($/\gg@/)--");
211         EXPECT_EQ(u.ToString(), R"--(ref:/\$\/\\gg\@\/)--");
212     }
213 }
214 
215 /**
216  * @tc.name: RefUriTest
217  * @tc.desc: test Context function
218  * @tc.type: FUNC
219  * @tc.require: I7DMS1
220  */
HWTEST_F(RefUriTest, Context, TestSize.Level1)221 HWTEST_F(RefUriTest, Context, TestSize.Level1)
222 {
223     {
224         RefUri u { "ref:/@Context" };
225         EXPECT_TRUE(u.IsValid());
226         EXPECT_TRUE(!u.IsEmpty());
227         EXPECT_EQ(u.ToString(), "ref:/@Context");
228         EXPECT_TRUE(!u.StartsFromRoot());
229         EXPECT_TRUE(!u.ReferencesProperty());
230         EXPECT_TRUE(u.ReferencesObject());
231         EXPECT_EQ(u.ReferencedName(), "@Context");
232         {
233             auto n = u.TakeFirstNode();
234             EXPECT_EQ(n.name, "@Context");
235             EXPECT_EQ(n.type, RefUri::Node::SPECIAL);
236         }
237     }
238     {
239         EXPECT_EQ(RefUri::ContextUri(), RefUri("ref:/@Context"));
240         RefUri u;
241         u.PushObjectContextSegment();
242         EXPECT_EQ(u, RefUri::ContextUri());
243     }
244     {
245         RefUri u { "ref:1ae79e0c-2701-4f19-8553-fb2dd22f6eba/@Context/$Theme/$Prop" };
246         EXPECT_EQ(u.ToString(), "ref:1ae79e0c-2701-4f19-8553-fb2dd22f6eba/@Context/$Theme/$Prop");
247     }
248 }
249 
250 /**
251  * @tc.name: RefUriTest
252  * @tc.desc: test Context function
253  * @tc.type: FUNC
254  * @tc.require: I7DMS1
255  */
HWTEST_F(RefUriTest, Canonicalization, TestSize.Level1)256 HWTEST_F(RefUriTest, Canonicalization, TestSize.Level1)
257 {
258     EXPECT_EQ(RefUri("ref:/.").ToString(), "ref:/");
259     EXPECT_EQ(RefUri("ref:/..").ToString(), "ref:/..");
260     EXPECT_EQ(RefUri("ref://.").ToString(), "ref://");
261     EXPECT_EQ(RefUri("ref:/some/.").ToString(), "ref:/some");
262     EXPECT_EQ(RefUri("ref:/some/..").ToString(), "ref:/");
263     EXPECT_EQ(RefUri("ref:/some/other/..").ToString(), "ref:/some");
264     EXPECT_EQ(RefUri("ref:/1/2/../../3/../4/././5/../6/.").ToString(), "ref:/4/6");
265     EXPECT_EQ(RefUri("ref:/@Theme").ToString(), "ref:/@Context/$Theme");
266     EXPECT_EQ(RefUri("ref:/@Theme/./..").ToString(), "ref:/@Context");
267     EXPECT_EQ(RefUri("ref:/../@Theme").ToString(), "ref:/../@Context/$Theme");
268     EXPECT_EQ(RefUri("ref:/@Context/..").ToString(), "ref:/");
269 }
270 
271 /**
272  * @tc.name: RefUriTest
273  * @tc.desc: test ObjectHierarchyTraversal function
274  * @tc.type: FUNC
275  * @tc.require: I7DMS1
276  */
HWTEST_F(RefUriTest, ObjectHierarchyTraversal, TestSize.Level1)277 HWTEST_F(RefUriTest, ObjectHierarchyTraversal, TestSize.Level1)
278 {
279     auto r1 = CreateTestType();
280     r1->SetName("r1");
281     auto r2 = CreateTestType();
282     r2->SetName("r2");
283     auto c1 = CreateTestContainer();
284     c1->SetName("c1");
285     auto c2 = CreateTestContainer();
286     c2->SetName("c2");
287     auto c3 = CreateTestContainer();
288     c3->SetName("c3");
289 
290     interface_pointer_cast<IContainer>(c1)->Add(interface_pointer_cast<IObject>(r1));
291     interface_pointer_cast<IContainer>(c2)->Add(interface_pointer_cast<IObject>(r2));
292     interface_pointer_cast<IContainer>(c2)->Add(interface_pointer_cast<IObject>(c1));
293     interface_pointer_cast<IContainer>(c3)->Add(interface_pointer_cast<IObject>(c2));
294 
295     auto o1 = interface_pointer_cast<IObjectInstance>(r1)->Resolve<IObjectInstance>(RefUri::ParentUri());
296     ASSERT_TRUE(o1);
297     EXPECT_EQ(o1->GetInstanceId(), interface_pointer_cast<IObjectInstance>(c1)->GetInstanceId());
298 
299     auto o2 = interface_pointer_cast<IObjectInstance>(c3)->Resolve<IObjectInstance>(RefUri("ref:/"));
300     ASSERT_TRUE(o2);
301     EXPECT_EQ(o2->GetInstanceId(), interface_pointer_cast<IObjectInstance>(c3)->GetInstanceId());
302 
303     auto o3 = interface_pointer_cast<IObjectInstance>(c3)->Resolve<IObjectInstance>(RefUri("ref:/c2/c1/r1"));
304     ASSERT_TRUE(o3);
305     EXPECT_EQ(o3->GetInstanceId(), interface_pointer_cast<IObjectInstance>(r1)->GetInstanceId());
306 
307     auto o4 = interface_pointer_cast<IObjectInstance>(r1)->Resolve<IObjectInstance>(RefUri("ref://"));
308     ASSERT_TRUE(o4);
309     EXPECT_EQ(o4->GetInstanceId(), interface_pointer_cast<IObjectInstance>(c3)->GetInstanceId());
310 
311     auto o5 = interface_pointer_cast<IObjectInstance>(r1)->Resolve<IObjectInstance>(RefUri("ref://c2/r2"));
312     ASSERT_TRUE(o5);
313     EXPECT_EQ(o5->GetInstanceId(), interface_pointer_cast<IObjectInstance>(r2)->GetInstanceId());
314 }
315 
316 /**
317  * @tc.name: RefUriTest
318  * @tc.desc: test ObjectHierarchyTraversalWithProperty function
319  * @tc.type: FUNC
320  * @tc.require: I7DMS1
321  */
HWTEST_F(RefUriTest, ObjectHierarchyTraversalWithProperty, TestSize.Level1)322 HWTEST_F(RefUriTest, ObjectHierarchyTraversalWithProperty, TestSize.Level1)
323 {
324     auto p = CreateProperty<IObject::Ptr>("prop", 0);
325 
326     auto r = CreateTestType();
327     r->SetName("r");
328     auto c1 = CreateTestContainer();
329     c1->SetName("c1");
330     auto c2 = CreateTestContainer();
331     c2->SetName("c2");
332     auto c3 = CreateTestContainer();
333     c3->SetName("c3");
334 
335     interface_pointer_cast<IContainer>(c1)->Add(interface_pointer_cast<IObject>(r));
336     p->SetValue(interface_pointer_cast<IObject>(c1));
337     interface_pointer_cast<IMetadata>(c2)->AddProperty(p);
338     interface_pointer_cast<IContainer>(c3)->Add(interface_pointer_cast<IObject>(c2));
339 
340     auto o = interface_cast<IObjectInstance>(c3)->Resolve<IObjectInstance>(RefUri("ref:/c2/$prop/r"));
341     ASSERT_TRUE(o);
342     EXPECT_EQ(o->GetInstanceId(), interface_cast<IObjectInstance>(r)->GetInstanceId());
343 }
344 
345 /**
346  * @tc.name: RefUriTest
347  * @tc.desc: test ResolveWithProperties function
348  * @tc.type: FUNC
349  * @tc.require: I7DMS1
350  */
HWTEST_F(RefUriTest, ResolveWithProperties, TestSize.Level1)351 HWTEST_F(RefUriTest, ResolveWithProperties, TestSize.Level1)
352 {
353     {
354         Object obj;
355         obj.AddProperty(CreateProperty<int>("prop", 0));
356         EXPECT_FALSE(obj.GetInterface<IObjectInstance>()->Resolve(RefUri("ref:/$prop")));
357         RefUri abs("ref:/$prop");
358         abs.SetAbsoluteInterpretation(true);
359         EXPECT_TRUE(obj.GetInterface<IObjectInstance>()->Resolve(abs));
360     }
361     {
362         Object obj;
363         obj.AddProperty(CreateProperty<IObject::Ptr>("prop", nullptr));
364         EXPECT_FALSE(obj.GetInterface<IObjectInstance>()->Resolve(RefUri("ref:/$prop")));
365     }
366     {
367         Object obj;
368         Object obj2;
369         auto prop = CreateProperty<IObject::Ptr>("prop", obj2.GetIObject());
370         obj.AddProperty(prop);
371         EXPECT_EQ(obj.GetInterface<IObjectInstance>()->Resolve(RefUri("ref:/$prop")), obj2.GetInterfacePtr<IObject>());
372         RefUri abs("ref:/$prop");
373         abs.SetAbsoluteInterpretation(true);
374         EXPECT_EQ(obj.GetInterface<IObjectInstance>()->Resolve(abs), interface_pointer_cast<IObject>(prop));
375     }
376     {
377         Object obj;
378         Object obj2;
379         obj.AddProperty(CreateProperty<IObject::Ptr>("prop", obj2.GetIObject()));
380         obj2.AddProperty(CreateProperty<IObject::Ptr>("prop", nullptr));
381         EXPECT_EQ(obj.GetInterface<IObjectInstance>()->Resolve(RefUri("ref:/$prop")),
382             obj2.GetInterfacePtr<IObjectInstance>());
383         EXPECT_FALSE(obj.GetInterface<IObjectInstance>()->Resolve(RefUri("ref:/$prop/$prop")));
384     }
385     {
386         Object obj;
387         Object obj2;
388         Object obj3;
389         obj.AddProperty(CreateProperty<IObject::Ptr>("prop", obj2.GetIObject()));
390         obj2.AddProperty(CreateProperty<IObject::Ptr>("prop", obj3.GetIObject()));
391         EXPECT_EQ(obj.GetInterface<IObjectInstance>()->Resolve(RefUri("ref:/$prop")),
392             obj2.GetInterfacePtr<IObjectInstance>());
393         EXPECT_EQ(obj.GetInterface<IObjectInstance>()->Resolve(RefUri("ref:/$prop/$prop")),
394             obj3.GetInterfacePtr<IObjectInstance>());
395     }
396 }
397 
398 /**
399  * @tc.name: RefUriTest
400  * @tc.desc: test IObjectResolveAndSelf function
401  * @tc.type: FUNC
402  * @tc.require: I7DMS1
403  */
HWTEST_F(RefUriTest, IObjectResolveAndSelf, TestSize.Level1)404 HWTEST_F(RefUriTest, IObjectResolveAndSelf, TestSize.Level1)
405 {
406     Object obj;
407     Object obj2;
408     obj.AddProperty(CreateProperty<IObject::Ptr>("prop", obj2.GetIObject()));
409     EXPECT_EQ(obj.GetIObject()->Resolve(RefUri("ref:/$prop")), obj2.GetIObject());
410     EXPECT_EQ(obj.GetIObject()->GetSelf(), obj.GetIObject());
411     EXPECT_EQ(Resolve(obj.GetIObject(), RefUri("ref:/$prop")), obj2.GetIObject());
412     EXPECT_EQ(GetSelf(obj.GetIObject()), obj.GetIObject());
413 }
414 META_END_NAMESPACE()