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 <gmock/gmock.h>
17 #include <gtest/gtest.h>
18 
19 #include <meta/api/container/object_hierarchy_observer.h>
20 #include <meta/api/content_object.h>
21 #include <meta/api/make_callback.h>
22 #include <meta/base/ref_uri.h>
23 
24 #include "src/serialisation_utils.h"
25 #include "src/util.h"
26 #include "src/test_runner.h"
27 #include "src/test_utils.h"
28 #include "src/testing_objects.h"
29 
30 using namespace testing;
31 using namespace testing::ext;
32 
33 META_BEGIN_NAMESPACE()
34 
GetMatching(const BASE_NS::vector<HierarchyChangedInfo>& changedCalls, HierarchyChangeType change, HierarchyChangeObjectType objectType)35 size_t GetMatching(const BASE_NS::vector<HierarchyChangedInfo>& changedCalls, HierarchyChangeType change,
36     HierarchyChangeObjectType objectType)
37 {
38     auto added = 0;
39     for (const auto& info : changedCalls) {
40         if (info.change == change && info .objectType == objectType) {
41             added++;
42         }
43     }
44     return added;
45 }
46 
MATCHER_P(AddingChildrenEq, expected, �)47 MATCHER_P(AddingChildrenEq, expected, "")
48 {
49     return GetMatching(arg, HierarchyChangeType::ADDING, HierarchyChangeObjectType::CHILD) == expected;
50 }
MATCHER_P(RemovingChildrenEq, expected, �)51 MATCHER_P(RemovingChildrenEq, expected, "")
52 {
53     return GetMatching(arg, HierarchyChangeType::REMOVING, HierarchyChangeObjectType::CHILD) == expected;
54 }
MATCHER_P(AddedChildrenEq, expected, �)55 MATCHER_P(AddedChildrenEq, expected, "")
56 {
57     return GetMatching(arg, HierarchyChangeType::ADDED, HierarchyChangeObjectType::CHILD) == expected;
58 }
MATCHER_P(RemovedChildrenEq, expected, �)59 MATCHER_P(RemovedChildrenEq, expected, "")
60 {
61     return GetMatching(arg, HierarchyChangeType::REMOVED, HierarchyChangeObjectType::CHILD) == expected;
62 }
MATCHER_P(MovedChildrenEq, expected, �)63 MATCHER_P(MovedChildrenEq, expected, "")
64 {
65     return GetMatching(arg, HierarchyChangeType::MOVED, HierarchyChangeObjectType::CHILD) == expected;
66 }
MATCHER_P(AddingContentEq, expected, �)67 MATCHER_P(AddingContentEq, expected, "")
68 {
69     return GetMatching(arg, HierarchyChangeType::ADDING, HierarchyChangeObjectType::CONTENT) == expected;
70 }
MATCHER_P(RemovingContentEq, expected, �)71 MATCHER_P(RemovingContentEq, expected, "")
72 {
73     return GetMatching(arg, HierarchyChangeType::REMOVING, HierarchyChangeObjectType::CONTENT) == expected;
74 }
MATCHER_P(AddedContentEq, expected, �)75 MATCHER_P(AddedContentEq, expected, "")
76 {
77     return GetMatching(arg, HierarchyChangeType::ADDED, HierarchyChangeObjectType::CONTENT) == expected;
78 }
MATCHER_P(RemovedContentEq, expected, �)79 MATCHER_P(RemovedContentEq, expected, "")
80 {
81     return GetMatching(arg, HierarchyChangeType::REMOVED, HierarchyChangeObjectType::CONTENT) == expected;
82 }
MATCHER_P(MovedContentEq, expected, �)83 MATCHER_P(MovedContentEq, expected, "")
84 {
85     return GetMatching(arg, HierarchyChangeType::MOVED, HierarchyChangeObjectType::CONTENT) == expected;
86 }
MATCHER_P(AddingAttachmentrEq, expected, �)87 MATCHER_P(AddingAttachmentrEq, expected, "")
88 {
89     return GetMatching(arg, HierarchyChangeType::ADDING, HierarchyChangeObjectType::ATTACHMENT) == expected;
90 }
MATCHER_P(RemovingAttachmentrEq, expected, �)91 MATCHER_P(RemovingAttachmentrEq, expected, "")
92 {
93     return GetMatching(arg, HierarchyChangeType::REMOVING, HierarchyChangeObjectType::ATTACHMENT) == expected;
94 }
MATCHER_P(AddedAttachmentrEq, expected, �)95 MATCHER_P(AddedAttachmentrEq, expected, "")
96 {
97     return GetMatching(arg, HierarchyChangeType::ADDED, HierarchyChangeObjectType::ATTACHMENT) == expected;
98 }
MATCHER_P(RemovedAttachmentrEq, expected, �)99 MATCHER_P(RemovedAttachmentrEq, expected, "")
100 {
101     return GetMatching(arg, HierarchyChangeType::REMOVED, HierarchyChangeObjectType::ATTACHMENT) == expected;
102 }
MATCHER_P(MovedAttachmentrEq, expected, �)103 MATCHER_P(MovedAttachmentrEq, expected, "")
104 {
105     return GetMatching(arg, HierarchyChangeType::MOVED, HierarchyChangeObjectType::ATTACHMENT) == expected;
106 }
107 
MATCHER_P(ObjectEq, expected, �)108 MATCHER_P(ObjectEq, expected, "")
109 {
110     return interface_pointer_cast<IObject>(arg) == interface_pointer_cast<IObject>(expected);
111 }
112 
MATCHER(ObjectIsNull, �)113 MATCHER(ObjectIsNull, "")
114 {
115     return interface_pointer_cast<IObject>(arg) == nullptr;
116 }
117 
118 class IntfObjectHierarchyObserverTest : public ::testing::Test {
119 public:
120     void SetUp() override
121     {
122         container_ = interface_pointer_cast<IContainer>(CreateTestContainer("Base"));
123         ASSERT_NE(container_, nullptr);
124         ASSERT_NE(observer_.GetIObject(), nullptr);
125         container_->Add(CreateTestType<IObject>("Object1_1"));
126         container_->Add(CreateTestType<IObject>("SameNameDifferentUid"));
127         container_->Add(CreateTestType<IObject>("ObjectDupe"));
128         container1_1_ = interface_pointer_cast<IContainer>(CreateTestContainer("Container1_1"));
129         container_->Add(interface_pointer_cast<IObject>(container1_1_));
130         container1_1_->Add(CreateTestType<IObject>("Object2_1"));
131         container1_1_->Add(CreateTestType<IObject>("ObjectDupe"));
132         container1_1_->Add(CreateTestType<IObject>("SameNameDifferentUid"));
133         container_->Add(CreateTestType<IObject>("Object1_3"));
134         container2_1_ = interface_pointer_cast<IContainer>(CreateTestContainer("SameNameDifferentUid"));
135         container2_1_->Add(contentObject_);
136         container1_1_->Add(interface_pointer_cast<IObject>(container2_1_));
137 
138         observer_.Target(interface_pointer_cast<IObject>(container_))
139             .OnHierarchyChanged([this](const HierarchyChangedInfo& info) { OnHierarchyChanged(info); });
140     }
141     void TearDown() override
142     {
143         container_.reset();
144         observer_.ResetIObject();
145     }
SetUpTestSuite()146     static void SetUpTestSuite()
147     {
148         SetTest();
149     }
TearDownTestSuite()150     static void TearDownTestSuite()
151     {
152         ResetTest();
153     }
154 public:
155     struct ExpectedCallCount {
156         size_t addingChildren {};
157         size_t addedChildren {};
158         size_t removingChildren {};
159         size_t removedChildren {};
160         size_t movedChildren {};
161 
162         size_t addingContent {};
163         size_t addedContent {};
164         size_t removingContent {};
165         size_t removedContent {};
166 
167         size_t addingAttachments {};
168         size_t addedAttachments {};
169         size_t removingAttachments {};
170         size_t removedAttachments {};
171         size_t movedAttachments {};
172 
ExpectAddChildrenIntfObjectHierarchyObserverTest::ExpectedCallCount173         void ExpectAddChildren(size_t count = 1)
174         {
175             addingChildren += count;
176             addedChildren += count;
177         }
178 
ExpectAddContentIntfObjectHierarchyObserverTest::ExpectedCallCount179         void ExpectAddContent(size_t count = 1)
180         {
181             addingContent += count;
182             addedContent += count;
183         }
184 
ExpectAddAttachmentsIntfObjectHierarchyObserverTest::ExpectedCallCount185         void ExpectAddAttachments(size_t count = 1)
186         {
187             addingAttachments += count;
188             addedAttachments += count;
189         }
190 
ExpectRemoveChildrenIntfObjectHierarchyObserverTest::ExpectedCallCount191         void ExpectRemoveChildren(size_t count = 1)
192         {
193             removingChildren += count;
194             removedChildren += count;
195         }
196 
ExpectRemoveContentIntfObjectHierarchyObserverTest::ExpectedCallCount197         void ExpectRemoveContent(size_t count = 1)
198         {
199             removingContent += count;
200             removedContent += count;
201         }
202 
ExpectRemoveAttachmentsIntfObjectHierarchyObserverTest::ExpectedCallCount203         void ExpectRemoveAttachments(size_t count = 1)
204         {
205             removingAttachments += count;
206             removedAttachments += count;
207         }
208 
SumIntfObjectHierarchyObserverTest::ExpectedCallCount209         size_t Sum() const
210         {
211             return addingChildren + addedChildren + removingChildren + removedChildren + movedChildren + addingContent +
212                 addedContent + removingContent + removedContent + addingAttachments + addedAttachments +
213                 removingAttachments + removedAttachments + movedAttachments;
214         }
215     };
216 
VerifyCalls(const ExpectedCallCount& expected)217     void VerifyCalls(const ExpectedCallCount& expected)
218     {
219         EXPECT_THAT(changedCalls_, AddingChildrenEq(expected.addingChildren));
220         EXPECT_THAT(changedCalls_, AddedChildrenEq(expected.addedChildren));
221         EXPECT_THAT(changedCalls_, RemovingChildrenEq(expected.removingChildren));
222         EXPECT_THAT(changedCalls_, RemovedChildrenEq(expected.removedChildren));
223         EXPECT_THAT(changedCalls_, MovedChildrenEq(expected.movedChildren));
224         EXPECT_THAT(changedCalls_, AddingContentEq(expected.addingContent));
225         EXPECT_THAT(changedCalls_, AddedContentEq(expected.addedContent));
226         EXPECT_THAT(changedCalls_, RemovingContentEq(expected.removingContent));
227         EXPECT_THAT(changedCalls_, RemovedContentEq(expected.removedContent));
228         EXPECT_THAT(changedCalls_, AddingAttachmentsEq(expected.addingAttachments));
229         EXPECT_THAT(changedCalls_, AddedAttachmentsEq(expected.addedAttachments));
230         EXPECT_THAT(changedCalls_, RemovingAttachmentsEq(expected.removingAttachments));
231         EXPECT_THAT(changedCalls_, RemovedAttachmentsEq(expected.removedAttachments));
232         EXPECT_THAT(changedCalls_, MovedAttachmentsEq(expected.movedAttachments));
233         ASSERT_EQ(changedCalls_.size(), expected.size());
234     }
ResetCalls()235     void ResetCalls()
236     {
237         changedCalls_.clear();
238     }
239 protected:
OnHierachyChanged(const HierarchyChangedInfo& info)240     void OnHierachyChanged(const HierarchyChangedInfo& info)
241     {
242         changedCalls_.push_back(info);
243     }
244 
245     BASE_NS::vector<HierarchyChangedInfo> changedCalls_;
246 
247     IContainer::Ptr container_;
248     IContainer::Ptr container1_1_;
249     IContainer::Ptr container2_1_;
250     META_NS::ObjectHierarchyObserver observer_;
251 };
252 
253 /**
254  * @tc.name: IntfObjectHierarchyObserverTest
255  * @tc.desc: test AddDirectChild function
256  * @tc.type: FUNC
257  * @tc.require: I7DMS1
258  */
HWTEST_F(IntfObjectHierarchyObserverTest, AddDirectChild, TestSize.Level1)259 HWTEST_F(IntfObjectHierarchyObserverTest, AddDirectChild, TestSize.Level1)
260 {
261     auto child = CreateTestType<IObject>("DirectChild");
262     ASSERT_TRUE(container_->Add(child));
263 
264     ExpectedCallCount expected;
265     expected.ExpectAddChildren();
266     VerifyCalls(expected);
267 
268     auto& info = changeCalls_[0];
269     EXPECT_EQ(info.object, child);
270     EXPECT_THAT(info.parent.lock(), ObjectEq(container_));
271 }
272 
273 /**
274  * @tc.name: IntfObjectHierarchyObserverTest
275  * @tc.desc: test AddDescendantChild function
276  * @tc.type: FUNC
277  * @tc.require: I7DMS1
278  */
HWTEST_F(IntfObjectHierarchyObserverTest, AddDescendantChild, TestSize.Level1)279 HWTEST_F(IntfObjectHierarchyObserverTest, AddDescendantChild, TestSize.Level1)
280 {
281     auto child = CreateTestType<IObject>("DirectChild");
282     ASSERT_TRUE(container2_1_->Add(child));
283 
284     ExpectedCallCount expected;
285     expected.ExpectAddChildren();
286     VerifyCalls(expected);
287 
288     auto& info = changeCalls_[0];
289     EXPECT_EQ(info.object, child);
290     EXPECT_THAT(info.parent.lock(), ObjectEq(container2_1_));
291 }
292 
293 /**
294  * @tc.name: IntfObjectHierarchyObserverTest
295  * @tc.desc: test AddDescendantContent function
296  * @tc.type: FUNC
297  * @tc.require: I7DMS1
298  */
HWTEST_F(IntfObjectHierarchyObserverTest, AddDescendantContent, TestSize.Level1)299 HWTEST_F(IntfObjectHierarchyObserverTest, AddDescendantContent, TestSize.Level1)
300 {
301     auto child = CreateTestType<IObject>("Content");
302     auto child2 = CreateTestType<IObject>("Content2");
303     {
304         contentObject_ = SetContent(child);
305         ExpectedCallCount expected;
306         expected.ExpectAddContent();
307         VerifyCalls(expected);
308         auto& info = changeCalls_[0];
309         EXPECT_EQ(info.object, child);
310         EXPECT_THAT(info.parent.lock(), ObjectEq(contentObject));
311     }
312     ResetCalls();
313     {
314         contentObject_ = SetContent(child2);
315         ExpectedCallCount expected;
316         expected.ExpectAddContent();
317         expected.ExpectRemoveContent();
318         VerifyCalls(expected);
319         auto& remove = changedCalls_[0];
320         auto& added = changedCalls_[2];
321         EXPECT_EQ(remove.object, child);
322         EXPECT_THAT(remove.parent.lock(), ObjectEq(contentObject));
323         EXPECT_EQ(added.object, child);
324         EXPECT_THAT(added.parent.lock(), ObjectEq(contentObject));
325     }
326     ResetCalls();
327     {
328         contentObject_.SetContent(nullptr);
329         ExpectedCallCount expected;
330         expected.ExpectRemoveContent();
331         VerifyCalls(expected);
332         auto& remove = changedCalls_[0];
333         EXPECT_EQ(remove.object, child2);
334         EXPECT_THAT(remove.parent.lock(), ObjectEq(contentObject));
335     }
336 }
337 
338 /**
339  * @tc.name: IntfObjectHierarchyObserverTest
340  * @tc.desc: test ContentChangeAfterRemove function
341  * @tc.type: FUNC
342  * @tc.require: I7DMS1
343  */
HWTEST_F(IntfObjectHierarchyObserverTest, ContentChangeAfterRemove, TestSize.Level1)344 HWTEST_F(IntfObjectHierarchyObserverTest, ContentChangeAfterRemove, TestSize.Level1)
345 {
346     auto child = CreateTestType<IObject>("Content");
347     {
348         contentObject_ = SetContent(child);
349         ExpectedCallCount expected;
350         expected.ExpectAddContent();
351         VerifyCalls(expected);
352         auto& info = changeCalls_[0];
353         EXPECT_EQ(info.object, child);
354         EXPECT_THAT(info.parent.lock(), ObjectEq(contentObject));
355     }
356     ResetCalls();
357     {
358         EXPECT_TRUE(container2_1->Remove(contentObject_));
359         ExpectedCallCount expected;
360         expected.ExpectAddContent();
361         auto& info = changeCalls_[0];
362         EXPECT_EQ(info.object, child);
363         EXPECT_THAT(info.parent.lock(), ObjectEq(container2_1));
364     }
365     ResetCalls();
366     {
367         contentObject_.SetContent(nullptr);
368         VerifyCalls({});
369     }
370 }
371 
372 /**
373  * @tc.name: IntfObjectHierarchyObserverTest
374  * @tc.desc: test Properties function
375  * @tc.type: FUNC
376  * @tc.require: I7DMS1
377  */
HWTEST_F(IntfObjectHierarchyObserverTest, Properties, TestSize.Level1)378 HWTEST_F(IntfObjectHierarchyObserverTest, Properties, TestSize.Level1)
379 {
380     auto obj = CreateTestType();
381     auto meta = interface_cast<IMetadata>(obj);
382 
383     ObjectHierarchyObserver obs;
384     HierarchyChangedInfo info;
385 
386     obs.Target(interface_pointer_cast<IObject>(meta->GetPropertyContainer()),
387         HierarchyChangeModeValue(HierarchyChangeMode::NOTIFY_CONTAINER | HierarchyChangeMode::NOTIFY_OBJECT));
388     obs.OnHierarchyChanged([&info](const HierarchyChangedInfo& i) { info = i; });
389 
390     obj->First()->SetValue(2);
391     EXPECT_EQ(interface_pointer_cast<IProperty>(info.object), obj->First().GetProperty());
392     EXPECT_EQ(info.change, HierarchyChangeType::CHANGED);
393     EXPECT_EQ(info.objectType, HierarchyChangeObjectType::CHILD);
394     EXPECT_EQ(info.parent.lock(), interface_pointer_cast<IObject>(meta->GetPropertyContainer()));
395 
396     obj->Second()->SetValue("hips");
397     EXPECT_EQ(interface_pointer_cast<IProperty>(info.object), obj->Second().GetProperty());
398 }
399 
400 /**
401  * @tc.name: IntfObjectHierarchyObserverTest
402  * @tc.desc: test GetAll function
403  * @tc.type: FUNC
404  * @tc.require: I7DMS1
405  */
HWTEST_F(IntfObjectHierarchyObserverTest, GetAll, TestSize.Level1)406 HWTEST_F(IntfObjectHierarchyObserverTest, GetAll, TestSize.Level1)
407 {
408     ObjectHierarchyObserver obs;
409     EXPECT_THAT(obs.GetAllObserved(), IsEmpty());
410 
411     auto containerObject = interface_pointer_cast<IObject>(CreateTestContainer("Container"));
412     auto childObject = interface_pointer_cast<IObject>(CreateTestType("TestType"));
413 
414     auto container = interface_pointer_cast<IContainer>(containerObject);
415     container->Add(childObject);
416 
417     EXPECT_TRUE(obs.Target(containerObject));
418     EXPECT_THAT(obs.GetAllObserved(), UnorderedElementsAre(containerObject, childObject));
419     EXPECT_THAT(obs.GetAllObserved<IContainer>(), UnorderedElementsAre(container));
420 
421     container->Remove(childObject);
422     EXPECT_THAT(obs.GetAllObserved(), UnorderedElementsAre(containerObject));
423 }
424 
425 /**
426  * @tc.name: IntfObjectHierarchyObserverTest
427  * @tc.desc: test Remove function
428  * @tc.type: FUNC
429  * @tc.require: I7DMS1
430  */
HWTEST_F(IntfObjectHierarchyObserverTest, Remove, TestSize.Level1)431 HWTEST_F(IntfObjectHierarchyObserverTest, Remove, TestSize.Level1)
432 {
433     BASE_NS::vector<IObject::Ptr> removed;
434     ObjectHierarchyObserver obs;
435     auto callCount = 0;
436 
437     obs.OnHierarchyChanged([&removed, &callCount](const HierarchyChangedInfo& info) {
438         if (info.change == HierarchyChangeType::REMOVED) {
439             callCount++;
440             removed.push_back(info.object);
441         }
442     });
443 
444     auto containerObject = interface_pointer_cast<IObject>(CreateTestContainer("Container"));
445     auto childContainerObject = interface_pointer_cast<IObject>(CreateTestContainer("Container"));
446     auto childObject = interface_pointer_cast<IObject>(CreateTestType("TestType"));
447     {
448         auto container = interface_pointer_cast<IContainer>(containerObject);
449         auto childContainer = interface_pointer_cast<IContainer>(childContainerObject);
450         EXPECT_TRUE(container->Add(childObject));
451         EXPECT_TRUE(childContainer->Add(childContainerObject));
452         EXPECT_TRUE(obs.Target(childObject));
453         EXPECT_THAT(obs.GetAllObserved(), UnorderedElementsAre(containerObject, childContainerObject, childObject));
454 
455         container->RemoveAll();
456     }
457     EXPECT_EQ(callCount, 1);
458     EXPECT_THAT(removed, ElementsAre(childContainerObject));
459 }
460 
461 /**
462  * @tc.name: IntfObjectHierarchyObserverTest
463  * @tc.desc: test DestroyEvent function
464  * @tc.type: FUNC
465  * @tc.require: I7DMS1
466  */
HWTEST_F(IntfObjectHierarchyObserverTest, DestroyEvent, TestSize.Level1)467 HWTEST_F(IntfObjectHierarchyObserverTest, DestroyEvent, TestSize.Level1)
468 {
469     BASE_NS::vector<IObject::Ptr> removed;
470     ObjectHierarchyObserver obs;
471     auto callCount = 0;
472     auto removingCount = 0;
473 
474     auto containerObject = interface_pointer_cast<IObject>(CreateTestContainer("Container"));
475     auto childContainerObject = interface_pointer_cast<IObject>(CreateTestContainer("Container"));
476     auto childObject = interface_pointer_cast<IObject>(CreateTestType("TestType"));
477     auto childObject2 = interface_pointer_cast<IObject>(CreateTestType("TestType"));
478     auto childObject3 = interface_pointer_cast<IObject>(CreateTestType("TestType"));
479     auto childObject4 = interface_pointer_cast<IObject>(CreateTestType("TestType"));
480     {
481         auto container = interface_pointer_cast<IContainer>(containerObject);
482         auto childContainer = interface_pointer_cast<IContainer>(childContainerObject);
483         EXPECT_TRUE(container->Add(childContainerObject));
484         EXPECT_TRUE(container->Add(childObject2));
485         EXPECT_TRUE(container->Add(childObject3));
486         EXPECT_TRUE(container->Insert(1, childObject4));
487         EXPECT_TRUE(childContainer->Add(childObject));
488         EXPECT_TRUE(obs.Target(containerObject));
489         EXPECT_THAT(obs.GetAllObserved(), UnorderedElementsAre(containerObject, childContainerObject, childObject,
490                                                childObject2, childObject3, childObject4));
491 
492         container->RemoveAll();
493 
494         EXPECT_THAT(obs.GetAllObserved(),
495             UnorderedElementsAre(containerObject, childContainerObject, childObject, childObject4, childObject2));
496     }
497 
498     obs.OnHierarchyChanged([&](const HierarchyChangedInfo& info) {
499         if (info.change == HierarchyChangeType::REMOVED) {
500             callCount++;
501             removed.push_back(info.object);
502         }
503         if (info.change == HierarchyChangeType::REMOVING) {
504             ++removingCount;
505         }
506     });
507 
508     containerObject.reset();
509     EXPECT_EQ(callCount, 3);
510     EXPECT_EQ(removingCount, 3);
511     EXPECT_THAT(removed, UnorderedElementsAre(childContainerObject, childObject4, childObject2));
512 }
513 
514 /**
515  * @tc.name: IntfObjectHierarchyObserverTest
516  * @tc.desc: test DestroyEventContent function
517  * @tc.type: FUNC
518  * @tc.require: I7DMS1
519  */
HWTEST_F(IntfObjectHierarchyObserverTest, DestroyEventContent, TestSize.Level1)520 HWTEST_F(IntfObjectHierarchyObserverTest, DestroyEventContent, TestSize.Level1)
521 {
522     BASE_NS::vector<IObject::Ptr> removed;
523     ObjectHierarchyObserver obs;
524     auto callCount = 0;
525 
526     obs.OnHierarchyChanged([&removed, &callCount](const HierarchyChangedInfo& info) {
527         if (info.change == HierarchyChangeType::REMOVED) {
528             callCount++;
529             removed.push_back(info.object);
530         }
531     });
532     auto contentObject = META_NS::GetObjectRegistry().Create(ClassId::ContentObject);
533     auto childObject = interface_pointer_cast<IObject>(CreateTestType("TestType"));
534     {
535         auto content = interface_pointer_cast<IContent>(contentObject);
536         EXPECT_TRUE(content->SetContent(childObject));
537         EXPECT_TRUE(obs.Target(contentObject));
538         EXPECT_THAT(obs.GetAllObserved(), UnorderedElementsAre(contentObject, childObject));
539     }
540 
541     contentObject.reset();
542     EXPECT_EQ(callCount, 1);
543     EXPECT_THAT(removed, ElementsAre(childObject));
544 }
545 
546 /**
547  * @tc.name: IntfObjectHierarchyObserverTest
548  * @tc.desc: test DoNotSerialise function
549  * @tc.type: FUNC
550  * @tc.require: I7DMS1
551  */
HWTEST_F(IntfObjectHierarchyObserverTest, DoNotSerialise, TestSize.Level1)552 HWTEST_F(IntfObjectHierarchyObserverTest, DoNotSerialise, TestSize.Level1)
553 {
554     TestSerialiser ser;
555     {
556         ObjectHierarchyObserver obs;
557         auto containerObject = interface_pointer_cast<IObject>(CreateTestType("Container"));
558         EXPECT_TRUE(obs.Target(containerObject));
559         EXPECT_THAT(obs.GetAllObserved(), UnorderedElementsAre(containerObject));
560         auto i = interface_cast<IAttach>(containerObject);
561         ASSERT_TRUE(i);
562         EXPECT_EQ(i->GetAttachments().size(), 1);
563         ser.Export(containerObject);
564     }
565 
566     auto obj = ser.Import<IAttach>();
567     ASSERT_TRUE(obj);
568     EXPECT_EQ(obj->GetAttachments().size(), 0);
569 }
570 META_END_NAMESPACE()