DeletePrefab_ContainingNestedEntitiesAndNestedPrefabs.py 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  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. SPDX-License-Identifier: Apache-2.0 OR MIT
  5. """
  6. def DeletePrefab_ContainingNestedEntitiesAndNestedPrefabs():
  7. """
  8. Test description:
  9. - Creates linear nested entities.
  10. - Creates linear nested prefabs based of an entity with a physx collider.
  11. - Creates a prefab from the nested entities and the nested prefabs.
  12. - Deletes the prefab.
  13. - Checks that the prefab is correctly destroyed.
  14. - Checks Undo/Redo operations.
  15. """
  16. from pathlib import Path
  17. import azlmbr.legacy.general as general
  18. from editor_python_test_tools.editor_entity_utils import EditorEntity
  19. from editor_python_test_tools.prefab_utils import Prefab, get_all_entity_ids
  20. from editor_python_test_tools.wait_utils import PrefabWaiter
  21. from consts.physics import PHYSX_PRIMITIVE_COLLIDER as PHYSX_PRIMITIVE_COLLIDER_NAME
  22. import Prefab.tests.PrefabTestUtils as prefab_test_utils
  23. NESTED_ENTITIES_PREFAB_FILE_NAME = Path(__file__).stem + '_' + 'nested_entities_prefab'
  24. NESTED_ENTITIES_NAME_PREFIX = 'Entity_'
  25. NESTED_PREFABS_FILE_NAME_PREFIX = Path(__file__).stem + '_' + 'nested_prefabs_'
  26. NESTED_PREFABS_NAME_PREFIX = 'NestedPrefabs_Prefab_'
  27. FILE_NAME_OF_PREFAB_WITH_NESTED_ENTITIES_AND_NESTED_PREFABS = Path(__file__).stem + '_' + 'new_prefab'
  28. NESTED_PREFABS_TEST_ENTITY_NAME = 'TestEntity'
  29. CREATION_POSITION = azlmbr.math.Vector3(100.0, 100.0, 100.0)
  30. NUM_NESTED_ENTITIES_LEVELS = 3
  31. NUM_NESTED_PREFABS_LEVELS = 3
  32. prefab_test_utils.open_base_tests_level()
  33. # Creates new nested entities at the root level
  34. # Asserts if creation didn't succeed
  35. nested_entities_root = prefab_test_utils.create_linear_nested_entities(
  36. NESTED_ENTITIES_NAME_PREFIX, NUM_NESTED_ENTITIES_LEVELS, CREATION_POSITION)
  37. nested_entities_root_parent = nested_entities_root.get_parent_id()
  38. prefab_test_utils.validate_linear_nested_entities(nested_entities_root, NUM_NESTED_ENTITIES_LEVELS, CREATION_POSITION)
  39. nested_entities_root_name = nested_entities_root.get_name()
  40. # Creates new nested prefabs at the root level
  41. # Asserts if creation didn't succeed
  42. entity_to_nest = EditorEntity.create_editor_entity_at(CREATION_POSITION, name=NESTED_PREFABS_TEST_ENTITY_NAME)
  43. assert entity_to_nest.id.IsValid(), "Couldn't create TestEntity"
  44. entity_to_nest.add_component(PHYSX_PRIMITIVE_COLLIDER_NAME)
  45. assert entity_to_nest.has_component(PHYSX_PRIMITIVE_COLLIDER_NAME), f"Failed to add a {PHYSX_PRIMITIVE_COLLIDER_NAME}"
  46. _, nested_prefab_instances = prefab_test_utils.create_linear_nested_prefabs(
  47. [entity_to_nest], NESTED_PREFABS_FILE_NAME_PREFIX, NESTED_PREFABS_NAME_PREFIX, NUM_NESTED_PREFABS_LEVELS)
  48. prefab_test_utils.validate_linear_nested_prefab_instances_hierarchy(nested_prefab_instances)
  49. # Creates a new prefab containing the nested entities and the nested prefab instances
  50. # Asserts if prefab creation doesn't succeed
  51. _, new_prefab = Prefab.create_prefab(
  52. [nested_entities_root, nested_prefab_instances[0].container_entity], FILE_NAME_OF_PREFAB_WITH_NESTED_ENTITIES_AND_NESTED_PREFABS)
  53. new_prefab_container_entity = new_prefab.container_entity
  54. nested_entities_root_on_instance = new_prefab.get_direct_child_entities()[0]
  55. nested_prefabs_root_container_entity_on_instance = new_prefab.get_direct_child_entities()[1]
  56. if new_prefab.get_direct_child_entities()[0].get_name() != nested_entities_root_name:
  57. nested_entities_root_on_instance, nested_prefabs_root_container_entity_on_instance = \
  58. nested_prefabs_root_container_entity_on_instance, nested_entities_root_on_instance
  59. assert nested_entities_root_on_instance.get_name() == nested_entities_root_name \
  60. and nested_entities_root_on_instance.get_parent_id() == new_prefab_container_entity.id, \
  61. f"The name of the first child entity of the new prefab '{new_prefab_container_entity.get_name()}' " \
  62. f"should be '{nested_entities_root_name}', " \
  63. f"not '{nested_entities_root_on_instance.get_name()}'"
  64. prefab_test_utils.validate_linear_nested_entities(nested_entities_root_on_instance, NUM_NESTED_ENTITIES_LEVELS, CREATION_POSITION)
  65. # Get parent entity and container id for verifying successful Undo/Redo operations
  66. instance_parent_entity = EditorEntity(new_prefab.container_entity.get_parent_id())
  67. instance_id = new_prefab.container_entity.id
  68. # Deletes the prefab instance and asserts if deletion doesn't succeed
  69. entity_ids_removed = Prefab.remove_prefabs([new_prefab])
  70. # Undo the prefab instance deletion
  71. general.undo()
  72. PrefabWaiter.wait_for_propagation()
  73. # Check that the prefab instance has been restored
  74. child_ids = instance_parent_entity.get_children_ids()
  75. assert instance_id in child_ids, \
  76. "Undo Failed: Failed to find restored prefab instance after Undo."
  77. # Verify the nested entities
  78. prefab_test_utils.validate_linear_nested_entities(nested_entities_root_on_instance, NUM_NESTED_ENTITIES_LEVELS, CREATION_POSITION)
  79. # Verify the nested instances
  80. parent_prefab_container_entity_on_instance = new_prefab_container_entity
  81. child_entity_on_inner_instance = nested_prefabs_root_container_entity_on_instance
  82. for current_level in range(0, NUM_NESTED_PREFABS_LEVELS):
  83. assert child_entity_on_inner_instance.get_name() == prefab_test_utils.get_linear_nested_items_name(NESTED_PREFABS_NAME_PREFIX, current_level), \
  84. f"The name of a prefab inside the nested prefabs should be " \
  85. f"'{prefab_test_utils.get_linear_nested_items_name(NESTED_PREFABS_NAME_PREFIX, current_level)}', " \
  86. f"not '{child_entity_on_inner_instance.get_name()}'"
  87. assert child_entity_on_inner_instance.get_parent_id() == parent_prefab_container_entity_on_instance.id, \
  88. f"Prefab '{child_entity_on_inner_instance.get_name()}' should be the direct inner prefab of " \
  89. f"prefab with id '{parent_prefab_container_entity_on_instance.id.ToString()}', " \
  90. f"not '{child_entity_on_inner_instance.get_parent_id()}'"
  91. parent_prefab_container_entity_on_instance = child_entity_on_inner_instance
  92. child_entity_on_inner_instance = child_entity_on_inner_instance.get_children()[0]
  93. assert child_entity_on_inner_instance.id.IsValid(), \
  94. f"Entity '{child_entity_on_inner_instance.get_name()}' is not valid"
  95. assert child_entity_on_inner_instance.get_name() == NESTED_PREFABS_TEST_ENTITY_NAME, \
  96. f"The name of the entity inside the nested prefabs should be '{NESTED_PREFABS_TEST_ENTITY_NAME}', " \
  97. f"not '{child_entity_on_inner_instance.get_name()}'"
  98. assert child_entity_on_inner_instance.has_component(PHYSX_PRIMITIVE_COLLIDER_NAME), \
  99. "Entity inside inner_prefab doesn't have the collider component it should"
  100. assert child_entity_on_inner_instance.get_parent_id() == parent_prefab_container_entity_on_instance.id, \
  101. f"Entity '{child_entity_on_inner_instance.get_name()}' should be under " \
  102. f"prefab with id '{parent_prefab_container_entity_on_instance.id.ToString()}', " \
  103. f"not '{child_entity_on_inner_instance.get_parent_id()}'"
  104. # Redo the prefab instance deletion
  105. general.redo()
  106. PrefabWaiter.wait_for_propagation()
  107. # Check that all entities and instances have been deleted
  108. entity_ids_after_delete = set(get_all_entity_ids())
  109. for entity_id_removed in entity_ids_removed:
  110. if entity_id_removed in entity_ids_after_delete:
  111. assert False, "Redo Failed: Not all entities and descendants in target prefabs are deleted."
  112. child_ids = instance_parent_entity.get_children_ids()
  113. assert not child_ids, \
  114. "Redo Failed: Instance was still found after redo of instance deletion."
  115. if __name__ == "__main__":
  116. from editor_python_test_tools.utils import Report
  117. Report.start_test(DeletePrefab_ContainingNestedEntitiesAndNestedPrefabs)