Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor config flow tests in generic camera #134385

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Code review: Further rationalise tests
  • Loading branch information
davet2001 committed Jan 9, 2025
commit 50c884a1a39f9452adc321e0809e3d3168286035
23 changes: 11 additions & 12 deletions tests/components/generic/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ def fakeimg_gif(fakeimgbytes_gif: bytes) -> Generator[None]:
respx.pop("fake_img")


@pytest.fixture
def mock_create_stream(hass: HomeAssistant) -> _patch[MagicMock]:
@pytest.fixture(name="mock_create_stream")
def mock_create_stream_fixture(hass: HomeAssistant) -> _patch[MagicMock]:
"""Mock create stream."""
mock_stream = MagicMock()
mock_stream.hass = hass
Expand All @@ -93,6 +93,15 @@ def mock_create_stream(hass: HomeAssistant) -> _patch[MagicMock]:
)


@pytest.fixture(name="mock_setup_entry")
def mock_async_setup_entry_fixture() -> _patch:
"""Mock setup entry."""
return patch(
"homeassistant.components.generic.async_setup_entry",
return_value=True,
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A common fixture for this is

@pytest.fixture
def mock_setup_entry() -> Generator[AsyncMock]:
    """Override async_setup_entry."""
    with patch(
        "homeassistant.components.airgradient.async_setup_entry",
        return_value=True,
    ) as mock_setup_entry:
        yield mock_setup_entry

This way you only need to load the fixture and its already patch. With the current solution, you would need to always do with mock_setup_entry (and I personally try to avoid them if possible)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok thanks! Yes that makes sense. Will update tonight and check it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It works well, thanks!

Note: That has reduced the code but resulted in a lot of outdenting in facfe9e, so the diff looks a lot bigger. I suggest reviewing with whitespace ignored:
facfe9e?w=1



@pytest.fixture(name="user_flow")
async def user_flow_fixture(hass: HomeAssistant) -> ConfigFlowResult:
"""Initiate a user flow."""
Expand Down Expand Up @@ -128,13 +137,3 @@ def config_entry_fixture(hass: HomeAssistant) -> MockConfigEntry:
)
entry.add_to_hass(hass)
return entry


@pytest.fixture(name="setup_entry")
async def setup_entry_fixture(
hass: HomeAssistant, config_entry: MockConfigEntry
) -> MockConfigEntry:
"""Set up a config entry ready to be used in tests."""
await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()
return config_entry
62 changes: 29 additions & 33 deletions tests/components/generic/test_config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,12 @@ async def test_form(
hass_client: ClientSessionGenerator,
user_flow: ConfigFlowResult,
mock_create_stream: _patch[MagicMock],
mock_setup_entry: _patch[MagicMock],
hass_ws_client: WebSocketGenerator,
) -> None:
"""Test the form with a normal set of settings."""

with (
mock_create_stream as mock_setup,
):
with mock_create_stream, mock_setup_entry:
result1 = await hass.config_entries.flow.async_configure(
user_flow["flow_id"],
TESTDATA,
Expand Down Expand Up @@ -126,18 +125,19 @@ async def test_form(
# Check that the preview image is disabled after.
resp = await client.get(still_preview_url)
assert resp.status == HTTPStatus.NOT_FOUND
assert len(mock_setup.mock_calls) == 1


@respx.mock
@pytest.mark.usefixtures("fakeimg_png")
async def test_form_only_stillimage(
hass: HomeAssistant, user_flow: ConfigFlowResult
hass: HomeAssistant,
user_flow: ConfigFlowResult,
mock_setup_entry: _patch[MagicMock],
) -> None:
"""Test we complete ok if the user wants still images only."""
data = TESTDATA.copy()
data.pop(CONF_STREAM_SOURCE)
with patch("homeassistant.components.generic.async_setup_entry", return_value=True):
with mock_setup_entry:
result1 = await hass.config_entries.flow.async_configure(
user_flow["flow_id"],
data,
Expand Down Expand Up @@ -233,12 +233,14 @@ async def test_form_still_preview_cam_off(
@respx.mock
@pytest.mark.usefixtures("fakeimg_gif")
async def test_form_only_stillimage_gif(
hass: HomeAssistant, user_flow: ConfigFlowResult
hass: HomeAssistant,
user_flow: ConfigFlowResult,
mock_setup_entry: _patch[MagicMock],
) -> None:
"""Test we complete ok if the user wants a gif."""
data = TESTDATA.copy()
data.pop(CONF_STREAM_SOURCE)
with patch("homeassistant.components.generic.async_setup_entry", return_value=True):
with mock_setup_entry:
result1 = await hass.config_entries.flow.async_configure(
user_flow["flow_id"],
data,
Expand All @@ -256,14 +258,17 @@ async def test_form_only_stillimage_gif(

@respx.mock
async def test_form_only_svg_whitespace(
hass: HomeAssistant, fakeimgbytes_svg: bytes, user_flow: ConfigFlowResult
hass: HomeAssistant,
fakeimgbytes_svg: bytes,
user_flow: ConfigFlowResult,
mock_setup_entry: _patch[MagicMock],
) -> None:
"""Test we complete ok if svg starts with whitespace, issue #68889."""
fakeimgbytes_wspace_svg = bytes(" \n ", encoding="utf-8") + fakeimgbytes_svg
respx.get("http://127.0.0.1/testurl/1").respond(stream=fakeimgbytes_wspace_svg)
data = TESTDATA.copy()
data.pop(CONF_STREAM_SOURCE)
with patch("homeassistant.components.generic.async_setup_entry", return_value=True):
with mock_setup_entry:
result1 = await hass.config_entries.flow.async_configure(
user_flow["flow_id"],
data,
Expand Down Expand Up @@ -383,15 +388,13 @@ async def test_form_rtsp_mode(
hass: HomeAssistant,
user_flow: ConfigFlowResult,
mock_create_stream: _patch[MagicMock],
mock_setup_entry: _patch[MagicMock],
) -> None:
"""Test we complete ok if the user enters a stream url."""
data = TESTDATA.copy()
data[CONF_RTSP_TRANSPORT] = "tcp"
data[CONF_STREAM_SOURCE] = "rtsp://127.0.0.1/testurl/2"
with (
mock_create_stream as mock_setup,
patch("homeassistant.components.generic.async_setup_entry", return_value=True),
):
with mock_create_stream, mock_setup_entry:
result1 = await hass.config_entries.flow.async_configure(
user_flow["flow_id"], data
)
Expand All @@ -415,8 +418,6 @@ async def test_form_rtsp_mode(
CONF_VERIFY_SSL: False,
}

assert len(mock_setup.mock_calls) == 1


async def test_form_only_stream(
hass: HomeAssistant,
Expand Down Expand Up @@ -583,12 +584,12 @@ async def test_form_stream_invalidimage3(
@respx.mock
@pytest.mark.usefixtures("fakeimg_png")
async def test_form_stream_timeout(
hass: HomeAssistant, user_flow: ConfigFlowResult
hass: HomeAssistant,
user_flow: ConfigFlowResult,
mock_create_stream: _patch[MagicMock],
) -> None:
"""Test we handle invalid auth."""
with patch(
"homeassistant.components.generic.config_flow.create_stream"
) as create_stream:
with mock_create_stream as create_stream:
create_stream.return_value.start = AsyncMock()
create_stream.return_value.stop = AsyncMock()
create_stream.return_value.hass = hass
Expand Down Expand Up @@ -720,10 +721,10 @@ async def test_form_oserror(hass: HomeAssistant, user_flow: ConfigFlowResult) ->
async def test_options_template_error(
hass: HomeAssistant,
mock_create_stream: _patch[MagicMock],
setup_entry: MockConfigEntry,
config_entry: MockConfigEntry,
) -> None:
"""Test the options flow with a template error."""
result = await hass.config_entries.options.async_init(setup_entry.entry_id)
result = await hass.config_entries.options.async_init(config_entry.entry_id)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "init"

Expand All @@ -743,7 +744,7 @@ async def test_options_template_error(
)
assert result2a["type"] is FlowResultType.CREATE_ENTRY

result3 = await hass.config_entries.options.async_init(setup_entry.entry_id)
result3 = await hass.config_entries.options.async_init(config_entry.entry_id)
assert result3["type"] is FlowResultType.FORM
assert result3["step_id"] == "init"

Expand Down Expand Up @@ -930,19 +931,17 @@ async def test_options_use_wallclock_as_timestamps(
hass_client: ClientSessionGenerator,
hass_ws_client: WebSocketGenerator,
fakeimgbytes_png: bytes,
setup_entry: MockConfigEntry,
config_entry: MockConfigEntry,
mock_setup_entry: _patch[MagicMock],
) -> None:
"""Test the use_wallclock_as_timestamps option flow."""

result = await hass.config_entries.options.async_init(
setup_entry.entry_id, context={"show_advanced_options": True}
config_entry.entry_id, context={"show_advanced_options": True}
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "init"
with (
patch("homeassistant.components.generic.async_setup_entry", return_value=True),
mock_create_stream,
):
with mock_setup_entry, mock_create_stream:
result2 = await hass.config_entries.options.async_configure(
result["flow_id"],
user_input={CONF_USE_WALLCLOCK_AS_TIMESTAMPS: True, **TESTDATA},
Expand Down Expand Up @@ -973,10 +972,7 @@ async def test_options_use_wallclock_as_timestamps(
)
assert result3["type"] is FlowResultType.FORM
assert result3["step_id"] == "init"
with (
patch("homeassistant.components.generic.async_setup_entry", return_value=True),
mock_create_stream,
):
with mock_setup_entry, mock_create_stream:
result4 = await hass.config_entries.options.async_configure(
result3["flow_id"],
user_input={CONF_USE_WALLCLOCK_AS_TIMESTAMPS: True, **TESTDATA},
Expand Down