#[test]
    fn property_block_promotion_is_direct_base_exact_slot_and_one_history_edit() {
        let root = promotion_test_root("success");
        let (mut app, entity, slot_id, selected_reference, block) = promotion_test_world(&root);
        let world = app.world_mut();
        let promotion =
            plan_property_block_promotion(world, entity, &selected_reference, &block, "Body")
                .unwrap();
        assert!(!promotion.destination_absolute.exists());
        assert_eq!(promotion.instance.base.0.asset_id, "material-id");
        assert_eq!(promotion.instance.overrides.values.len(), 2);

        let published = commit_property_block_promotion(world, &promotion).unwrap();

        assert_eq!(published, promotion.destination_path);
        assert!(promotion.destination_absolute.exists());
        assert!(world.get::<MaterialPropertyBlocks>(entity).is_none());
        assert_eq!(world.resource::<EditorHistory>().undo_depth(), 1);
        let renderer = world.get::<StaticMeshRenderer>(entity).unwrap();
        let assigned = renderer
            .materials
            .slot(&slot_id)
            .unwrap()
            .material
            .as_ref()
            .unwrap();
        assert_eq!(assigned.0.sub_asset_id, "material:instance");
        assert_eq!(
            assigned.0.source_path.as_deref(),
            Some(published.to_str().unwrap())
        );
        let authored =
            MaterialInstanceAsset::load_from_path(promotion.destination_absolute.to_str().unwrap())
                .unwrap();
        assert_eq!(authored.base.0.asset_id, "material-id");
        assert_eq!(authored.overrides, promotion.instance.overrides);
        assert!(world
            .resource::<AssetRegistry>()
            .records
            .iter()
            .any(|record| record.path == published.to_string_lossy()));

        apply_command_undo(world);
        let restored = world
            .get::<StaticMeshRenderer>(entity)
            .unwrap()
            .materials
            .slot(&slot_id)
            .unwrap()
            .material
            .as_ref()
            .unwrap();
        assert_eq!(restored, &selected_reference);
        std::fs::remove_dir_all(root).unwrap();
    }

    #[test]
    fn create_instance_and_assign_keeps_runtime_block_and_uses_one_scene_history_edit() {
        let root = promotion_test_root("create-instance");
        let (mut app, entity, slot_id, selected_reference, block) = promotion_test_world(&root);
        let empty = MaterialPropertyBlock {
            slot_id: slot_id.clone(),
            parameters: Vec::new(),
            textures: Vec::new(),
        };
        let world = app.world_mut();
        let transaction = plan_material_instance_assignment(
            world,
            entity,
            &selected_reference,
            &empty,
            "Body",
            false,
        )
        .unwrap();
        assert!(!transaction.clear_property_block);
        assert!(transaction.instance.label.ends_with("Body Instance"));
        assert_eq!(transaction.instance.overrides.values.len(), 1);

        let published = commit_property_block_promotion(world, &transaction).unwrap();

        assert!(transaction.destination_absolute.exists());
        assert_eq!(world.resource::<EditorHistory>().undo_depth(), 1);
        assert_eq!(
            world
                .get::<MaterialPropertyBlocks>(entity)
                .and_then(|blocks| blocks.slots.first()),
            Some(&block)
        );
        let assigned = world
            .get::<StaticMeshRenderer>(entity)
            .unwrap()
            .materials
            .slot(&slot_id)
            .unwrap()
            .material
            .as_ref()
            .unwrap();
        assert_eq!(assigned.0.source_path.as_deref(), published.to_str());
        std::fs::remove_dir_all(root).unwrap();
    }

    #[test]
    fn property_block_promotion_cancel_and_external_conflict_are_non_mutating() {
        let root = promotion_test_root("conflict");
        let (mut app, entity, slot_id, selected_reference, block) = promotion_test_world(&root);
        let world = app.world_mut();
        let promotion =
            plan_property_block_promotion(world, entity, &selected_reference, &block, "Body")
                .unwrap();

        assert_eq!(world.resource::<EditorHistory>().undo_depth(), 0);
        assert_eq!(world.resource::<AssetRegistry>().records.len(), 0);
        assert_eq!(
            world.get::<MaterialPropertyBlocks>(entity).unwrap().slots,
            vec![block.clone()]
        );
        assert_eq!(
            world
                .get::<StaticMeshRenderer>(entity)
                .unwrap()
                .materials
                .slot(&slot_id)
                .unwrap()
                .material
                .as_ref(),
            Some(&selected_reference)
        );

        std::fs::write(&promotion.destination_absolute, b"external owner").unwrap();
        let error = commit_property_block_promotion(world, &promotion).unwrap_err();
        assert!(error.contains("changed after the promotion review"));
        assert_eq!(
            std::fs::read(&promotion.destination_absolute).unwrap(),
            b"external owner"
        );
        assert_eq!(world.resource::<EditorHistory>().undo_depth(), 0);
        assert_eq!(world.resource::<AssetRegistry>().records.len(), 0);
        assert_eq!(
            world.get::<MaterialPropertyBlocks>(entity).unwrap().slots,
            vec![block]
        );
        assert_eq!(
            world
                .get::<StaticMeshRenderer>(entity)
                .unwrap()
                .materials
                .slot(&slot_id)
                .unwrap()
                .material
                .as_ref(),
            Some(&selected_reference)
        );
        std::fs::remove_dir_all(root).unwrap();
    }

    #[test]
    fn property_block_promotion_rejects_invalid_and_stale_runtime_inputs() {
        let root = promotion_test_root("invalid");
        let (mut app, entity, _slot_id, selected_reference, block) = promotion_test_world(&root);
        let world = app.world_mut();
        let mut invalid = block.clone();
        invalid.parameters.push(MaterialParameter {
            name: "undeclared_standard_property".into(),
            value: MaterialParameterValue::Float(0.5),
        });
        let error =
            plan_property_block_promotion(world, entity, &selected_reference, &invalid, "Body")
                .unwrap_err();
        assert!(error.contains("not supported by Standard materials"));
        assert_eq!(world.resource::<EditorHistory>().undo_depth(), 0);
        assert_eq!(world.resource::<AssetRegistry>().records.len(), 0);

        let promotion =
            plan_property_block_promotion(world, entity, &selected_reference, &block, "Body")
                .unwrap();
        std::fs::write(
            root.join("assets/materials/promotion_variant.material-instance.ron"),
            b"externally changed",
        )
        .unwrap();
        let error = commit_property_block_promotion(world, &promotion).unwrap_err();
        assert!(error.contains("changed after the promotion review"));
        assert!(!promotion.destination_absolute.exists());
        assert_eq!(world.resource::<EditorHistory>().undo_depth(), 0);
        assert_eq!(world.resource::<AssetRegistry>().records.len(), 0);
        assert_eq!(
            world.get::<MaterialPropertyBlocks>(entity).unwrap().slots,
            vec![block]
        );
        std::fs::remove_dir_all(root).unwrap();
    }

    #[test]
    fn property_block_promotion_rolls_back_file_and_catalog_when_scene_edit_fails() {
        let root = promotion_test_root("rollback");
        let (mut app, entity, slot_id, selected_reference, block) = promotion_test_world(&root);
        let world = app.world_mut();
        let promotion =
            plan_property_block_promotion(world, entity, &selected_reference, &block, "Body")
                .unwrap();
        world.entity_mut(entity).remove::<LevelObject>();

        let error = commit_property_block_promotion(world, &promotion).unwrap_err();

        assert!(error.contains("actor is not editable"));
        assert!(!promotion.destination_absolute.exists());
        assert!(!root.join(content_pipeline::REGISTRY_PATH).exists());
        assert!(!root.join(content_pipeline::RUNTIME_CATALOG_PATH).exists());
        assert_eq!(world.resource::<EditorHistory>().undo_depth(), 0);
        assert_eq!(world.resource::<AssetRegistry>().records.len(), 0);
        assert_eq!(
            world.get::<MaterialPropertyBlocks>(entity).unwrap().slots,
            vec![block]
        );
        assert_eq!(
            world
                .get::<StaticMeshRenderer>(entity)
                .unwrap()
                .materials
                .slot(&slot_id)
                .unwrap()
                .material
                .as_ref(),
            Some(&selected_reference)
        );
        std::fs::remove_dir_all(root).unwrap();
    }
