Repository: apache/airflow
File: airflow-core/tests/unit/api_fastapi/core_api/services/ui/test_grid.py (Python)

Code before:

        This is the main regression test for issue #61208.
        Old version has task with children=None, new version has TaskGroup with children=[...].
        """
        # Old version: task_a is a simple task
        current = [{"id": "task_a", "label": "Task A", "children": None}]

        # New version: task_a is now a TaskGroup with children
        new = [
            {
                "id": "task_a",
                "label": "Task A",
                "children": [
                    {"id": "task_a.subtask1", "label": "Subtask 1", "children": None},
                    {"id": "task_a.subtask2", "label": "Subtask 2", "children": None},
                ],
            }
        ]

        # Should not raise TypeError: 'NoneType' object is not iterable
        _merge_node_dicts(current, new)

        # Current should now have the new structure (TaskGroup)
        assert len(current) == 1
        assert current[0]["id"] == "task_a"
        # The old node with children=None is kept (not merged into children)

    def test_merge_taskgroup_to_task_conversion(self):
        """Test merging when a TaskGroup is converted to a simple task."""
        # Old version: task_a is a TaskGroup
        current = [
            {
                "id": "task_a",
                "label": "Task A",
                "children": [
                    {"id": "task_a.subtask1", "label": "Subtask 1", "children": None},
                ],
            }
        ]

        # New version: task_a is now a simple task
        new = [{"id": "task_a", "label": "Task A", "children": None}]

        # Should not crash
        _merge_node_dicts(current, new)

        assert len(current) == 1
        assert current[0]["id"] == "task_a"

    def test_merge_nested_children(self):
        """Test merging nodes with nested children."""

Review comment (suggestion):
There are a lot of auto generated code comments that aren't helpful. Those just describe the code and I would remove them.

Code after:
    _merge_node_dicts(current, new)

    # Current structure (TaskGroup) is preserved
    assert len(current) == 1
    assert current[0]["id"] == "task_a"
    assert current[0]["children"] is not None
    assert len(current[0]["children"]) == 1


def test_merge_node_dicts_merges_nested_children():
    """Test merging nodes with nested children."""
    current = [
        {
            "id": "group1",
            "label": "Group 1",
            "children": [
                {"id": "group1.task1", "label": "Task 1"},
            ],
        }
    ]
    new = [
        {
            "id": "group1",
            "label": "Group 1",
            "children": [
                {"id": "group1.task1", "label": "Task 1"},
                {"id": "group1.task2", "label": "Task 2"},
            ],
        }
    ]

    _merge_node_dicts(current, new)

    assert len(current) == 1
    assert current[0]["id"] == "group1"
    assert len(current[0]["children"]) == 2


def test_merge_node_dicts_merges_children_and_appends_new_nodes():
    current = [
        {
            "id": "group",
            "label": "group",
            "children": [{"id": "group.task_a", "label": "task_a"}],
        },
        {"id": "task", "label": "task"},
    ]
    new = [
        {
            "id": "group",
            "label": "group",