diff --git a/tests/components/camera/common.py b/tests/components/camera/common.py index 8c05295b5d1..93e2596e343 100644 --- a/tests/components/camera/common.py +++ b/tests/components/camera/common.py @@ -3,63 +3,13 @@ All containing methods are legacy helpers that should not be used by new components. Instead call the service directly. """ -from homeassistant.components.camera import ( - ATTR_FILENAME, - SERVICE_ENABLE_MOTION, - SERVICE_SNAPSHOT, -) -from homeassistant.components.camera.const import ( - DATA_CAMERA_PREFS, - DOMAIN, - PREF_PRELOAD_STREAM, -) -from homeassistant.const import ( - ATTR_ENTITY_ID, - ENTITY_MATCH_ALL, - SERVICE_TURN_OFF, - SERVICE_TURN_ON, -) -from homeassistant.core import callback -from homeassistant.loader import bind_hass +from homeassistant.components.camera.const import DATA_CAMERA_PREFS, PREF_PRELOAD_STREAM -@bind_hass -async def async_turn_off(hass, entity_id=ENTITY_MATCH_ALL): - """Turn off camera.""" - data = {ATTR_ENTITY_ID: entity_id} if entity_id else {} - await hass.services.async_call(DOMAIN, SERVICE_TURN_OFF, data) - - -@bind_hass -async def async_turn_on(hass, entity_id=ENTITY_MATCH_ALL): - """Turn on camera, and set operation mode.""" - data = {} - if entity_id is not None: - data[ATTR_ENTITY_ID] = entity_id - - await hass.services.async_call(DOMAIN, SERVICE_TURN_ON, data) - - -@bind_hass -def enable_motion_detection(hass, entity_id=ENTITY_MATCH_ALL): - """Enable Motion Detection.""" - data = {ATTR_ENTITY_ID: entity_id} if entity_id else None - hass.async_add_job(hass.services.async_call(DOMAIN, SERVICE_ENABLE_MOTION, data)) - - -@bind_hass -@callback -def async_snapshot(hass, filename, entity_id=ENTITY_MATCH_ALL): - """Make a snapshot from a camera.""" - data = {ATTR_ENTITY_ID: entity_id} if entity_id else {} - data[ATTR_FILENAME] = filename - - hass.async_add_job(hass.services.async_call(DOMAIN, SERVICE_SNAPSHOT, data)) - - -def mock_camera_prefs(hass, entity_id, prefs={}): +def mock_camera_prefs(hass, entity_id, prefs=None): """Fixture for cloud component.""" prefs_to_set = {PREF_PRELOAD_STREAM: True} - prefs_to_set.update(prefs) + if prefs is not None: + prefs_to_set.update(prefs) hass.data[DATA_CAMERA_PREFS]._prefs[entity_id] = prefs_to_set return prefs_to_set diff --git a/tests/components/camera/test_init.py b/tests/components/camera/test_init.py index 23c04fe347e..cb4201e2957 100644 --- a/tests/components/camera/test_init.py +++ b/tests/components/camera/test_init.py @@ -102,8 +102,15 @@ async def test_snapshot_service(hass, mock_camera): with patch( "homeassistant.components.camera.open", mopen, create=True ), patch.object(hass.config, "is_allowed_path", return_value=True): - common.async_snapshot(hass, "/test/snapshot.jpg") - await hass.async_block_till_done() + await hass.services.async_call( + camera.DOMAIN, + camera.SERVICE_SNAPSHOT, + { + ATTR_ENTITY_ID: "camera.demo_camera", + camera.ATTR_FILENAME: "/test/snapshot.jpg", + }, + blocking=True, + ) mock_write = mopen().write @@ -237,10 +244,6 @@ async def test_play_stream_service_no_source(hass, mock_camera, mock_stream): async def test_handle_play_stream_service(hass, mock_camera, mock_stream): """Test camera play_stream service.""" await async_setup_component(hass, "media_player", {}) - data = { - ATTR_ENTITY_ID: "camera.demo_camera", - camera.ATTR_MEDIA_PLAYER: "media_player.test", - } with patch( "homeassistant.components.camera.request_stream" ) as mock_request_stream, patch( @@ -249,7 +252,13 @@ async def test_handle_play_stream_service(hass, mock_camera, mock_stream): ): # Call service await hass.services.async_call( - camera.DOMAIN, camera.SERVICE_PLAY_STREAM, data, blocking=True + camera.DOMAIN, + camera.SERVICE_PLAY_STREAM, + { + ATTR_ENTITY_ID: "camera.demo_camera", + camera.ATTR_MEDIA_PLAYER: "media_player.test", + }, + blocking=True, ) # So long as we request the stream, the rest should be covered # by the play_media service tests. @@ -295,23 +304,23 @@ async def test_preload_stream(hass, mock_stream): async def test_record_service_invalid_path(hass, mock_camera): """Test record service with invalid path.""" - data = { - ATTR_ENTITY_ID: "camera.demo_camera", - camera.CONF_FILENAME: "/my/invalid/path", - } with patch.object( hass.config, "is_allowed_path", return_value=False ), pytest.raises(HomeAssistantError): # Call service await hass.services.async_call( - camera.DOMAIN, camera.SERVICE_RECORD, data, blocking=True + camera.DOMAIN, + camera.SERVICE_RECORD, + { + ATTR_ENTITY_ID: "camera.demo_camera", + camera.CONF_FILENAME: "/my/invalid/path", + }, + blocking=True, ) async def test_record_service(hass, mock_camera, mock_stream): """Test record service.""" - data = {ATTR_ENTITY_ID: "camera.demo_camera", camera.CONF_FILENAME: "/my/path"} - with patch( "homeassistant.components.demo.camera.DemoCamera.stream_source", return_value=mock_coro("http://example.com"), @@ -323,7 +332,10 @@ async def test_record_service(hass, mock_camera, mock_stream): ): # Call service await hass.services.async_call( - camera.DOMAIN, camera.SERVICE_RECORD, data, blocking=True + camera.DOMAIN, + camera.SERVICE_RECORD, + {ATTR_ENTITY_ID: "camera.demo_camera", camera.CONF_FILENAME: "/my/path"}, + blocking=True, ) # So long as we call stream.record, the rest should be covered # by those tests. diff --git a/tests/components/demo/test_camera.py b/tests/components/demo/test_camera.py index 286a1c8ca22..530cfef4cb6 100644 --- a/tests/components/demo/test_camera.py +++ b/tests/components/demo/test_camera.py @@ -3,30 +3,41 @@ from unittest.mock import mock_open, patch import pytest -from homeassistant.components import camera -from homeassistant.components.camera import STATE_IDLE, STATE_STREAMING +from homeassistant.components.camera import ( + DOMAIN as CAMERA_DOMAIN, + SERVICE_ENABLE_MOTION, + SERVICE_TURN_OFF, + SERVICE_TURN_ON, + STATE_IDLE, + STATE_STREAMING, + async_get_image, +) +from homeassistant.components.demo import DOMAIN +from homeassistant.const import ATTR_ENTITY_ID from homeassistant.exceptions import HomeAssistantError from homeassistant.setup import async_setup_component -from tests.components.camera import common +ENTITY_CAMERA = "camera.demo_camera" -@pytest.fixture +@pytest.fixture(autouse=True) def demo_camera(hass): """Initialize a demo camera platform.""" hass.loop.run_until_complete( - async_setup_component(hass, "camera", {camera.DOMAIN: {"platform": "demo"}}) + async_setup_component( + hass, CAMERA_DOMAIN, {CAMERA_DOMAIN: {"platform": DOMAIN}} + ) ) - return hass.data["camera"].get_entity("camera.demo_camera") -async def test_init_state_is_streaming(hass, demo_camera): +async def test_init_state_is_streaming(hass): """Demo camera initialize as streaming.""" - assert demo_camera.state == STATE_STREAMING + state = hass.states.get(ENTITY_CAMERA) + assert state.state == STATE_STREAMING mock_on_img = mock_open(read_data=b"ON") with patch("homeassistant.components.demo.camera.open", mock_on_img, create=True): - image = await camera.async_get_image(hass, demo_camera.entity_id) + image = await async_get_image(hass, ENTITY_CAMERA) assert mock_on_img.called assert mock_on_img.call_args_list[0][0][0][-6:] in [ "_0.jpg", @@ -37,52 +48,68 @@ async def test_init_state_is_streaming(hass, demo_camera): assert image.content == b"ON" -async def test_turn_on_state_back_to_streaming(hass, demo_camera): +async def test_turn_on_state_back_to_streaming(hass): """After turn on state back to streaming.""" - assert demo_camera.state == STATE_STREAMING - await common.async_turn_off(hass, demo_camera.entity_id) - await hass.async_block_till_done() + state = hass.states.get(ENTITY_CAMERA) + assert state.state == STATE_STREAMING - assert demo_camera.state == STATE_IDLE + await hass.services.async_call( + CAMERA_DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: ENTITY_CAMERA}, blocking=True + ) - await common.async_turn_on(hass, demo_camera.entity_id) - await hass.async_block_till_done() + state = hass.states.get(ENTITY_CAMERA) + assert state.state == STATE_IDLE - assert demo_camera.state == STATE_STREAMING + await hass.services.async_call( + CAMERA_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: ENTITY_CAMERA}, blocking=True + ) + + state = hass.states.get(ENTITY_CAMERA) + assert state.state == STATE_STREAMING -async def test_turn_off_image(hass, demo_camera): +async def test_turn_off_image(hass): """After turn off, Demo camera raise error.""" - await common.async_turn_off(hass, demo_camera.entity_id) - await hass.async_block_till_done() + await hass.services.async_call( + CAMERA_DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: ENTITY_CAMERA}, blocking=True + ) with pytest.raises(HomeAssistantError) as error: - await camera.async_get_image(hass, demo_camera.entity_id) + await async_get_image(hass, ENTITY_CAMERA) assert error.args[0] == "Camera is off" -async def test_turn_off_invalid_camera(hass, demo_camera): +async def test_turn_off_invalid_camera(hass): """Turn off non-exist camera should quietly fail.""" - assert demo_camera.state == STATE_STREAMING - await common.async_turn_off(hass, "camera.invalid_camera") - await hass.async_block_till_done() + state = hass.states.get(ENTITY_CAMERA) + assert state.state == STATE_STREAMING - assert demo_camera.state == STATE_STREAMING + await hass.services.async_call( + CAMERA_DOMAIN, + SERVICE_TURN_OFF, + {ATTR_ENTITY_ID: "camera.invalid_camera"}, + blocking=True, + ) + + state = hass.states.get(ENTITY_CAMERA) + assert state.state == STATE_STREAMING async def test_motion_detection(hass): """Test motion detection services.""" - # Setup platform - await async_setup_component(hass, "camera", {"camera": {"platform": "demo"}}) # Fetch state and check motion detection attribute - state = hass.states.get("camera.demo_camera") + state = hass.states.get(ENTITY_CAMERA) assert not state.attributes.get("motion_detection") # Call service to turn on motion detection - common.enable_motion_detection(hass, "camera.demo_camera") - await hass.async_block_till_done() + await hass.services.async_call( + CAMERA_DOMAIN, + SERVICE_ENABLE_MOTION, + {ATTR_ENTITY_ID: ENTITY_CAMERA}, + blocking=True, + ) # Check if state has been updated. - state = hass.states.get("camera.demo_camera") + state = hass.states.get(ENTITY_CAMERA) assert state.attributes.get("motion_detection")