Repository: home-assistant/core
File: tests/components/frontend/test_pr_download.py (Python)

Code before:

        pr_response = AsyncMock()
        pr_response.data = {
            "head": {"sha": "abc123def456"},
            "base": {"sha": "base789abc012"},
        }
        mock_client.generic.return_value = pr_response

        config = {
            DOMAIN: {
                "development_pr": 12345,
                "github_token": "test_token",
            }
        }

        assert await async_setup_component(hass, DOMAIN, config)
        await hass.async_block_till_done()

        assert "Using cached PR #12345" in caplog.text

        calls = list(mock_client.generic.call_args_list)
        assert len(calls) == 1  # Only PR check
        assert "pulls" in str(calls[0])


async def test_pr_download_cache_invalidated_head_changed(
    hass: HomeAssistant,
    tmp_path: Path,
    mock_github_api,
    aioclient_mock: AiohttpClientMocker,
    mock_zipfile,
) -> None:
    """Test that cache is invalidated when head commit changes."""
    hass.config.config_dir = str(tmp_path)

    pr_cache_dir = tmp_path / ".cache" / "frontend" / "development_artifacts"
    frontend_dir = pr_cache_dir / "hass_frontend"
    frontend_dir.mkdir(parents=True)
    (frontend_dir / "index.html").write_text("test")
    (pr_cache_dir / ".sha").write_text("old_head_sha:base789abc012")

    aioclient_mock.get(
        "https://api.github.com/artifact/download",
        content=b"fake zip data",
    )

    config = {
        DOMAIN: {
            "development_pr": 12345,
            "github_token": "test_token",
        }

Review comment (performance):
Don't duplicate the test. Instead, use `pytest.mark.parametrize` to inject the stored cache key and the new head+base hashes.

Code after:

        pr_response = AsyncMock()
        pr_response.data = {
            "head": {"sha": "abc123def456"},
            "base": {"sha": "base789abc012"},
        }
        mock_client.generic.return_value = pr_response

        config = {
            DOMAIN: {
                "development_pr": 12345,
                "github_token": "test_token",
            }
        }

        assert await async_setup_component(hass, DOMAIN, config)
        await hass.async_block_till_done()

        assert "Using cached PR #12345" in caplog.text

        calls = list(mock_client.generic.call_args_list)
        assert len(calls) == 1  # Only PR check
        assert "pulls" in str(calls[0])


@pytest.mark.parametrize(
    ("cache_key"),
    [
        ("old_head_sha:base789abc012"),
        ("abc123def456:old_base_sha"),
    ],
)
async def test_pr_download_cache_invalidated(
    hass: HomeAssistant,
    tmp_path: Path,
    mock_github_api,
    aioclient_mock: AiohttpClientMocker,
    mock_zipfile,
    cache_key: str,
) -> None:
    """Test that cache is invalidated when head commit changes."""
    hass.config.config_dir = str(tmp_path)

    pr_cache_dir = tmp_path / ".cache" / "frontend" / "development_artifacts"
    frontend_dir = pr_cache_dir / "hass_frontend"
    frontend_dir.mkdir(parents=True)
    (frontend_dir / "index.html").write_text("test")
    (pr_cache_dir / ".sha").write_text(cache_key)

    aioclient_mock.get(
        "https://api.github.com/artifact/download",