DeletePrefab_UnderNestedInstance.py 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  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_UnderNestedInstance():
  7. """
  8. Test description:
  9. - Focuses on the "First_Car" instance.
  10. - Deletes the "Tire_Prefab" instance of the "Front_Wheel" under "First_Car".
  11. - Checks that there are 2 "Tire_Prefab" and 2 "Tire_Entity" and the deleted
  12. instances are only in the "Front_Wheel" under both car instances.
  13. - Checks undo/redo correctness.
  14. - Checks that the deleted "Tire_Prefab" (and "Tire_Entity") should re-appear
  15. after focusing on its owning instance (i.e. "Front_Wheel") in "First_Car".
  16. Hierarchy:
  17. - Level
  18. - First_Car <-- focus on this prefab
  19. - Front_Wheel
  20. - Tire_Prefab <-- delete this instance as override
  21. - Tire_Entity
  22. - Back_Wheel
  23. - Tire_Prefab
  24. - Tire_Entity
  25. - Second_Car
  26. - Front_Wheel
  27. - Tire_Prefab <-- this should be deleted as well after propagation
  28. - Tire_Entity
  29. - Back_Wheel
  30. - Tire_Prefab
  31. - Tire_Entity
  32. """
  33. from editor_python_test_tools.editor_entity_utils import EditorEntity
  34. from editor_python_test_tools.prefab_utils import Prefab
  35. from editor_python_test_tools.wait_utils import PrefabWaiter
  36. import azlmbr.legacy.general as general
  37. import Prefab.tests.PrefabTestUtils as prefab_test_utils
  38. CAR_PREFAB_FILE_NAME = Path(__file__).stem + "_" + "car_prefab"
  39. WHEEL_PREFAB_FILE_NAME = Path(__file__).stem + "_" + "wheel_prefab"
  40. TIRE_PREFAB_FILE_NAME = Path(__file__).stem + "_" + "tire_prefab"
  41. FIRST_CAR_NAME = "First_Car"
  42. SECOND_CAR_NAME = "Second_Car"
  43. FRONT_WHEEL_NAME = "Front_Wheel"
  44. BACK_WHEEL_NAME = "Back_Wheel"
  45. TIRE_PREFAB_NAME = "Tire_Prefab"
  46. TIRE_ENTITY_NAME = "Tire_Entity"
  47. prefab_test_utils.open_base_tests_level()
  48. # Create a new entity at the root level.
  49. tire_entity = EditorEntity.create_editor_entity_at((100.0, 100.0, 100.0), TIRE_ENTITY_NAME)
  50. assert tire_entity.id.IsValid(), f"Failed to create new entity: {TIRE_ENTITY_NAME}."
  51. # Create a tire prefab from the tire entity.
  52. tire_prefab_entities = [tire_entity]
  53. tire_prefab, tire_instance = Prefab.create_prefab(tire_prefab_entities, TIRE_PREFAB_FILE_NAME, TIRE_PREFAB_NAME)
  54. assert tire_instance.is_valid(), f"Failed to instantiate instance: {TIRE_PREFAB_NAME}."
  55. # Create a wheel prefab and front wheel instance from the tire instance.
  56. wheel_prefab_entities = [tire_instance.container_entity]
  57. wheel_prefab, front_wheel_instance = Prefab.create_prefab(wheel_prefab_entities, WHEEL_PREFAB_FILE_NAME, \
  58. FRONT_WHEEL_NAME)
  59. assert front_wheel_instance.is_valid(), f"Failed to instantiate instance: {FRONT_WHEEL_NAME}."
  60. # Create a back wheel instance.
  61. back_wheel_instance = wheel_prefab.instantiate(name=BACK_WHEEL_NAME)
  62. assert back_wheel_instance.is_valid(), f"Failed to instantiate instance: {BACK_WHEEL_NAME}."
  63. # Create a car prefab and the first car instance from two wheels.
  64. car_prefab_entities = [front_wheel_instance.container_entity, back_wheel_instance.container_entity]
  65. car_prefab, car_instance_1 = Prefab.create_prefab(car_prefab_entities, CAR_PREFAB_FILE_NAME, FIRST_CAR_NAME)
  66. assert car_instance_1.is_valid(), f"Failed to instantiate instance: {FIRST_CAR_NAME}."
  67. # Create a second car instance.
  68. car_instance_2 = car_prefab.instantiate(name=SECOND_CAR_NAME)
  69. assert car_instance_2.is_valid(), f"Failed to instantiate instance: {SECOND_CAR_NAME}."
  70. # Focus on the first car instance.
  71. car_instance_1.container_entity.focus_on_owning_prefab()
  72. # Delete the tire instance in the front wheel instance in the first car instance.
  73. wheel_container_entities_in_car_instance_1 = car_instance_1.get_direct_child_entities()
  74. filtered_wheel_list = list(filter(lambda wheel_container_entity: \
  75. wheel_container_entity.get_name() == FRONT_WHEEL_NAME, \
  76. wheel_container_entities_in_car_instance_1))
  77. assert len(filtered_wheel_list) == 1, f"Found {len(filtered_wheel_list)} {FRONT_WHEEL_NAME}. " \
  78. f"Expected 1 {FRONT_WHEEL_NAME} in {FIRST_CAR_NAME} to delete."
  79. tire_container_entity_in_front_wheel_in_car_instance_1 = filtered_wheel_list[0].get_children()[0]
  80. tire_container_entity_in_front_wheel_in_car_instance_1.delete()
  81. # Wait till prefab propagation finishes before validating deletion.
  82. PrefabWaiter.wait_for_propagation()
  83. # Validate after instance deletion.
  84. prefab_test_utils.validate_count_for_named_editor_entity(TIRE_PREFAB_NAME, 2)
  85. prefab_test_utils.validate_count_for_named_editor_entity(TIRE_ENTITY_NAME, 2)
  86. prefab_test_utils.validate_child_count_for_named_editor_entity(FRONT_WHEEL_NAME, 0)
  87. prefab_test_utils.validate_child_count_for_named_editor_entity(BACK_WHEEL_NAME, 1)
  88. # Validate undo on instance deletion.
  89. general.undo()
  90. PrefabWaiter.wait_for_propagation()
  91. prefab_test_utils.validate_count_for_named_editor_entity(TIRE_PREFAB_NAME, 4)
  92. prefab_test_utils.validate_count_for_named_editor_entity(TIRE_ENTITY_NAME, 4)
  93. prefab_test_utils.validate_child_count_for_named_editor_entity(FRONT_WHEEL_NAME, 1)
  94. prefab_test_utils.validate_child_count_for_named_editor_entity(BACK_WHEEL_NAME, 1)
  95. # Validate redo on instance deletion.
  96. general.redo()
  97. PrefabWaiter.wait_for_propagation()
  98. prefab_test_utils.validate_count_for_named_editor_entity(TIRE_PREFAB_NAME, 2)
  99. prefab_test_utils.validate_count_for_named_editor_entity(TIRE_ENTITY_NAME, 2)
  100. prefab_test_utils.validate_child_count_for_named_editor_entity(FRONT_WHEEL_NAME, 0)
  101. prefab_test_utils.validate_child_count_for_named_editor_entity(BACK_WHEEL_NAME, 1)
  102. # Focus on first wheel instance in first car instance. Deleted tire instance should appear in Prefab Edit Mode.
  103. front_wheel_container_entities = EditorEntity.find_editor_entities([FRONT_WHEEL_NAME])
  104. filtered_front_wheel_list = list(filter(lambda front_wheel: \
  105. front_wheel.get_parent_id() == car_instance_1.container_entity.id, \
  106. front_wheel_container_entities))
  107. assert len(filtered_front_wheel_list) == 1, f"Found {len(filtered_front_wheel_list)} {FRONT_WHEEL_NAME}. " \
  108. f"Expected 1 {FRONT_WHEEL_NAME} in {FIRST_CAR_NAME} to focus on."
  109. front_wheel_in_car_instance_1 = filtered_front_wheel_list[0]
  110. front_wheel_in_car_instance_1.focus_on_owning_prefab()
  111. PrefabWaiter.wait_for_propagation() # propagate source template changes after focusing on
  112. prefab_test_utils.check_entity_children_count(front_wheel_in_car_instance_1.id, 1)
  113. # Note: This should be 3 because the tire instance inside the front wheel under the second car is still deleted.
  114. prefab_test_utils.validate_count_for_named_editor_entity(TIRE_PREFAB_NAME, 3)
  115. prefab_test_utils.validate_count_for_named_editor_entity(TIRE_ENTITY_NAME, 3)
  116. if __name__ == "__main__":
  117. from editor_python_test_tools.utils import Report
  118. Report.start_test(DeletePrefab_UnderNestedInstance)