PrefabDuplicateTests.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <AzToolsFramework/Entity/EditorEntityHelpers.h>
  9. #include <AzToolsFramework/ToolsComponents/TransformComponent.h>
  10. #include <Prefab/PrefabTestComponent.h>
  11. #include <Prefab/PrefabTestDomUtils.h>
  12. #include <Prefab/PrefabTestFixture.h>
  13. namespace UnitTest
  14. {
  15. using PrefabDuplicateTest = PrefabTestFixture;
  16. TEST_F(PrefabDuplicateTest, DuplicateSingleEntitySucceeds)
  17. {
  18. const AZStd::string entityName = "EntityToDuplicate";
  19. AZ::EntityId entityToDuplicateId = CreateEditorEntityUnderRoot(entityName);
  20. // Add PrefabTestComponent to the entity and make the change to template.
  21. AZ::Entity* entityToDuplicate = AzToolsFramework::GetEntityById(entityToDuplicateId);
  22. entityToDuplicate->Deactivate();
  23. entityToDuplicate->AddComponent(aznew PrefabTestComponent());
  24. entityToDuplicate->Activate();
  25. m_prefabPublicInterface->GenerateUndoNodesForEntityChangeAndUpdateCache(entityToDuplicateId, m_undoStack->GetTop());
  26. PropagateAllTemplateChanges();
  27. InstanceOptionalReference levelInstance = m_instanceEntityMapperInterface->FindOwningInstance(GetRootContainerEntityId());
  28. EXPECT_TRUE(levelInstance.has_value());
  29. // Validate there is one entity before duplicating.
  30. EXPECT_EQ(levelInstance->get().GetEntityAliasCount(), 1);
  31. // Duplicate the entity.
  32. DuplicatePrefabResult result = m_prefabPublicInterface->DuplicateEntitiesInInstance({ entityToDuplicateId });
  33. ASSERT_TRUE(result.IsSuccess());
  34. PropagateAllTemplateChanges();
  35. // Validate there are two entities with the same name and PrefabTestComponent.
  36. EXPECT_EQ(levelInstance->get().GetEntityAliasCount(), 2);
  37. levelInstance->get().GetConstEntities(
  38. [&](const AZ::Entity& entity)
  39. {
  40. EXPECT_EQ(entity.GetName(), entityName);
  41. EXPECT_TRUE(entity.FindComponent<PrefabTestComponent>());
  42. return true;
  43. });
  44. }
  45. TEST_F(PrefabDuplicateTest, DuplicateSingleInstanceSucceeds)
  46. {
  47. const AZStd::string prefabName = "PrefabToDuplicate";
  48. AZ::IO::Path engineRootPath;
  49. m_settingsRegistryInterface->Get(engineRootPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder);
  50. AZ::IO::Path prefabFilepath = engineRootPath / prefabName;
  51. AZ::EntityId entityUnderPrefabId = CreateEditorEntityUnderRoot("Entity");
  52. AZ::EntityId containerId = CreateEditorPrefab(prefabFilepath, { entityUnderPrefabId });
  53. InstanceOptionalReference levelInstance = m_instanceEntityMapperInterface->FindOwningInstance(GetRootContainerEntityId());
  54. EXPECT_TRUE(levelInstance.has_value());
  55. AZStd::vector<InstanceOptionalReference> nestedInstances;
  56. levelInstance->get().GetNestedInstances(
  57. [&nestedInstances](AZStd::unique_ptr<Instance>& nestedInstance)
  58. {
  59. nestedInstances.push_back(*(nestedInstance.get()));
  60. });
  61. // Validate there is one instance before duplicating.
  62. EXPECT_EQ(nestedInstances.size(), 1);
  63. // Duplicate the instance.
  64. DuplicatePrefabResult result = m_prefabPublicInterface->DuplicateEntitiesInInstance({ containerId });
  65. ASSERT_TRUE(result.IsSuccess());
  66. PropagateAllTemplateChanges();
  67. // Validate there are two prefab instances with the same name.
  68. nestedInstances.clear();
  69. levelInstance->get().GetNestedInstances(
  70. [&nestedInstances](AZStd::unique_ptr<Instance>& nestedInstance)
  71. {
  72. nestedInstances.push_back(*(nestedInstance.get()));
  73. });
  74. EXPECT_EQ(nestedInstances.size(), 2);
  75. for (InstanceOptionalReference nestedInstance : nestedInstances)
  76. {
  77. EntityOptionalReference nestedContainerEntity = nestedInstance->get().GetContainerEntity();
  78. EXPECT_TRUE(nestedContainerEntity.has_value());
  79. EXPECT_EQ(nestedContainerEntity->get().GetName(), prefabName);
  80. }
  81. }
  82. TEST_F(PrefabDuplicateTest, DuplicateMultipleEntitiesAndFixesReferences)
  83. {
  84. const AZStd::string parentEntityName = "Parent Entity";
  85. const AZStd::string childEntityName = "Child Entity";
  86. AZ::EntityId parentEntityId = CreateEditorEntityUnderRoot(parentEntityName);
  87. AZ::EntityId childEntityId = CreateEditorEntity(childEntityName, parentEntityId);
  88. // Add PrefabTestComponent to the child entity and make the change to template.
  89. AZ::Entity* childEntity = AzToolsFramework::GetEntityById(childEntityId);
  90. childEntity->Deactivate();
  91. PrefabTestComponent* testComponentInChild = aznew PrefabTestComponent();
  92. testComponentInChild->m_entityIdProperty = parentEntityId; // set the entity id reference to parent
  93. childEntity->AddComponent(testComponentInChild);
  94. childEntity->Activate();
  95. m_prefabPublicInterface->GenerateUndoNodesForEntityChangeAndUpdateCache(childEntityId, m_undoStack->GetTop());
  96. PropagateAllTemplateChanges();
  97. InstanceOptionalReference levelInstance = m_instanceEntityMapperInterface->FindOwningInstance(GetRootContainerEntityId());
  98. EXPECT_TRUE(levelInstance.has_value());
  99. // Validate there are two entities before duplicating.
  100. EXPECT_EQ(levelInstance->get().GetEntityAliasCount(), 2);
  101. // Duplicate the parent entity.
  102. DuplicatePrefabResult result = m_prefabPublicInterface->DuplicateEntitiesInInstance({ parentEntityId });
  103. ASSERT_TRUE(result.IsSuccess());
  104. PropagateAllTemplateChanges();
  105. // Validate there are four entities in total.
  106. EXPECT_EQ(levelInstance->get().GetEntityAliasCount(), 4);
  107. // Validate there are two parent entities.
  108. AzToolsFramework::EntityIdList parentEntityIds;
  109. levelInstance->get().GetConstEntities(
  110. [&](const AZ::Entity& entity)
  111. {
  112. if (entity.GetName() == parentEntityName)
  113. {
  114. parentEntityIds.push_back(entity.GetId());
  115. }
  116. return true;
  117. });
  118. EXPECT_EQ(parentEntityIds.size(), 2);
  119. // Validate there are two child entities and they have correct parent reference in PrefabTestComponent.
  120. AzToolsFramework::EntityIdList childEntityIds;
  121. levelInstance->get().GetConstEntities(
  122. [&](const AZ::Entity& entity)
  123. {
  124. if (entity.GetName() == childEntityName)
  125. {
  126. childEntityIds.push_back(entity.GetId());
  127. PrefabTestComponent* testComponent = entity.FindComponent<PrefabTestComponent>();
  128. if (testComponent)
  129. {
  130. auto it = AZStd::find(parentEntityIds.begin(), parentEntityIds.end(), testComponent->m_entityIdProperty);
  131. EXPECT_NE(it, parentEntityIds.end());
  132. // Erase when we find it so that the matches will be unique.
  133. parentEntityIds.erase(it);
  134. }
  135. }
  136. return true;
  137. });
  138. EXPECT_EQ(childEntityIds.size(), 2);
  139. // Verify we matched each of the parent entity ids.
  140. EXPECT_EQ(parentEntityIds.size(), 0);
  141. }
  142. }