async def test_updates_from_connection_event(hass, config_entry, config, controller, input_sources, caplog): """Tests player updates from connection event after connection failure.""" # Connected await setup_platform(hass, config_entry, config) player = controller.players[1] player.available = True player.heos.dispatcher.send(const.SIGNAL_HEOS_EVENT, const.EVENT_CONNECTED) await hass.async_block_till_done() state = hass.states.get('media_player.test_player') assert state.state == STATE_IDLE assert player.refresh.call_count == 1 # Connected handles refresh failure player.reset_mock() player.refresh.side_effect = CommandError(None, "Failure", 1) player.heos.dispatcher.send(const.SIGNAL_HEOS_EVENT, const.EVENT_CONNECTED) await hass.async_block_till_done() state = hass.states.get('media_player.test_player') assert player.refresh.call_count == 1 assert "Unable to refresh player" in caplog.text # Disconnected player.reset_mock() player.available = False player.heos.dispatcher.send(const.SIGNAL_HEOS_EVENT, const.EVENT_DISCONNECTED) await hass.async_block_till_done() state = hass.states.get('media_player.test_player') assert state.state == STATE_UNAVAILABLE assert player.refresh.call_count == 0
async def test_select_input_command_error( hass, config_entry, config, controller, caplog, input_sources): """Tests selecting an unknown input.""" await setup_platform(hass, config_entry, config) player = controller.players[1] input_source = input_sources[0] player.play_input_source.side_effect = CommandError(None, "Failure", 1) await hass.services.async_call( MEDIA_PLAYER_DOMAIN, SERVICE_SELECT_SOURCE, {ATTR_ENTITY_ID: 'media_player.test_player', ATTR_INPUT_SOURCE: input_source.name}, blocking=True) player.play_input_source.assert_called_once_with(input_source) assert "Unable to select source: Failure (1)" in caplog.text
async def test_stop(hass, config_entry, config, controller, caplog): """Test the stop service.""" await setup_platform(hass, config_entry, config) player = controller.players[1] # First pass completes successfully, second pass raises command error for _ in range(2): await hass.services.async_call( MEDIA_PLAYER_DOMAIN, SERVICE_MEDIA_STOP, {ATTR_ENTITY_ID: 'media_player.test_player'}, blocking=True) assert player.stop.call_count == 1 player.stop.reset_mock() player.stop.side_effect = CommandError(None, "Failure", 1) assert "Unable to stop: Failure (1)" in caplog.text
async def test_select_radio_favorite_command_error( hass, config_entry, config, controller, favorites, caplog): """Tests command error loged when playing favorite.""" await setup_platform(hass, config_entry, config) player = controller.players[1] # Test set radio preset favorite = favorites[2] player.play_favorite.side_effect = CommandError(None, "Failure", 1) await hass.services.async_call( MEDIA_PLAYER_DOMAIN, SERVICE_SELECT_SOURCE, {ATTR_ENTITY_ID: 'media_player.test_player', ATTR_INPUT_SOURCE: favorite.name}, blocking=True) player.play_favorite.assert_called_once_with(2) assert "Unable to select source: Failure (1)" in caplog.text
async def test_volume_set(hass, config_entry, config, controller, caplog): """Test the volume set service.""" await setup_platform(hass, config_entry, config) player = controller.players[1] # First pass completes successfully, second pass raises command error for _ in range(2): await hass.services.async_call( MEDIA_PLAYER_DOMAIN, SERVICE_VOLUME_SET, {ATTR_ENTITY_ID: 'media_player.test_player', ATTR_MEDIA_VOLUME_LEVEL: 1}, blocking=True) player.set_volume.assert_called_once_with(100) player.set_volume.reset_mock() player.set_volume.side_effect = CommandError(None, "Failure", 1) assert "Unable to set volume level: Failure (1)" in caplog.text
async def test_sign_in_failed(hass, config_entry, controller, caplog): """Test sign-in service logs error when not connected.""" await setup_component(hass, config_entry) controller.sign_in.side_effect = CommandError("", "Invalid credentials", 6) await hass.services.async_call( DOMAIN, SERVICE_SIGN_IN, {ATTR_USERNAME: "******", ATTR_PASSWORD: "******"}, blocking=True, ) controller.sign_in.assert_called_once_with("*****@*****.**", "password") assert "Sign in failed: Invalid credentials (6)" in caplog.text
async def test_next_track(hass, config_entry, config, controller, caplog): """Test the next track service.""" await setup_platform(hass, config_entry, config) player = controller.players[1] # First pass completes successfully, second pass raises command error for _ in range(2): await hass.services.async_call( MEDIA_PLAYER_DOMAIN, SERVICE_MEDIA_NEXT_TRACK, {ATTR_ENTITY_ID: "media_player.test_player"}, blocking=True, ) assert player.play_next.call_count == 1 player.play_next.reset_mock() player.play_next.side_effect = CommandError(None, "Failure", 1) assert "Unable to move to next track: Failure (1)" in caplog.text
async def test_clear_playlist(hass, config_entry, config, controller, caplog): """Test the clear playlist service.""" await setup_platform(hass, config_entry, config) player = controller.players[1] # First pass completes successfully, second pass raises command error for _ in range(2): await hass.services.async_call( MEDIA_PLAYER_DOMAIN, SERVICE_CLEAR_PLAYLIST, {ATTR_ENTITY_ID: "media_player.test_player"}, blocking=True, ) assert player.clear_queue.call_count == 1 player.clear_queue.reset_mock() player.clear_queue.side_effect = CommandError(None, "Failure", 1) assert "Unable to clear playlist: Failure (1)" in caplog.text
async def test_update_sources_retry(hass, config_entry, config, controller, caplog): """Test update sources retries on failures to max attempts.""" config_entry.add_to_hass(hass) assert await async_setup_component(hass, DOMAIN, config) controller.get_favorites.reset_mock() controller.get_input_sources.reset_mock() source_manager = hass.data[DOMAIN][DATA_SOURCE_MANAGER] source_manager.retry_delay = 0 source_manager.max_retry_attempts = 1 controller.get_favorites.side_effect = CommandError("Test", "test", 0) controller.dispatcher.send(const.SIGNAL_CONTROLLER_EVENT, const.EVENT_SOURCES_CHANGED, {}) # Wait until it's finished while "Unable to update sources" not in caplog.text: await asyncio.sleep(0.1) assert controller.get_favorites.call_count == 2
async def test_updates_from_connection_event(hass, config_entry, config, controller, caplog): """Tests player updates from connection event after connection failure.""" await setup_platform(hass, config_entry, config) player = controller.players[1] event = asyncio.Event() async def set_signal(): event.set() hass.helpers.dispatcher.async_dispatcher_connect(SIGNAL_HEOS_UPDATED, set_signal) # Connected player.available = True player.heos.dispatcher.send(const.SIGNAL_HEOS_EVENT, const.EVENT_CONNECTED) await event.wait() state = hass.states.get("media_player.test_player") assert state.state == STATE_IDLE assert controller.load_players.call_count == 1 # Disconnected event.clear() player.reset_mock() controller.load_players.reset_mock() player.available = False player.heos.dispatcher.send(const.SIGNAL_HEOS_EVENT, const.EVENT_DISCONNECTED) await event.wait() state = hass.states.get("media_player.test_player") assert state.state == STATE_UNAVAILABLE assert controller.load_players.call_count == 0 # Connected handles refresh failure event.clear() player.reset_mock() controller.load_players.reset_mock() controller.load_players.side_effect = CommandError(None, "Failure", 1) player.available = True player.heos.dispatcher.send(const.SIGNAL_HEOS_EVENT, const.EVENT_CONNECTED) await event.wait() state = hass.states.get("media_player.test_player") assert state.state == STATE_IDLE assert controller.load_players.call_count == 1 assert "Unable to refresh players" in caplog.text
async def test_shuffle_set(hass, config_entry, config, controller, caplog): """Test the shuffle set service.""" await setup_platform(hass, config_entry, config) player = controller.players[1] # First pass completes successfully, second pass raises command error for _ in range(2): await hass.services.async_call( MEDIA_PLAYER_DOMAIN, SERVICE_SHUFFLE_SET, { ATTR_ENTITY_ID: "media_player.test_player", ATTR_MEDIA_SHUFFLE: True }, blocking=True, ) player.set_play_mode.assert_called_once_with(player.repeat, True) player.set_play_mode.reset_mock() player.set_play_mode.side_effect = CommandError(None, "Failure", 1) assert "Unable to set shuffle: Failure (1)" in caplog.text
async def test_volume_mute(hass, config_entry, config, controller, caplog): """Test the volume mute service.""" await setup_platform(hass, config_entry, config) player = controller.players[1] # First pass completes successfully, second pass raises command error for _ in range(2): await hass.services.async_call( MEDIA_PLAYER_DOMAIN, SERVICE_VOLUME_MUTE, { ATTR_ENTITY_ID: "media_player.test_player", ATTR_MEDIA_VOLUME_MUTED: True }, blocking=True, ) assert player.set_mute.call_count == 1 player.set_mute.reset_mock() player.set_mute.side_effect = CommandError(None, "Failure", 1) assert "Unable to set mute: Failure (1)" in caplog.text
async def test_play_media_url(hass, config_entry, config, controller, caplog): """Test the play media service with type url.""" await setup_platform(hass, config_entry, config) player = controller.players[1] url = "http://news/podcast.mp3" # First pass completes successfully, second pass raises command error for _ in range(2): await hass.services.async_call( MEDIA_PLAYER_DOMAIN, SERVICE_PLAY_MEDIA, { ATTR_ENTITY_ID: 'media_player.test_player', ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_URL, ATTR_MEDIA_CONTENT_ID: url }, blocking=True) player.play_url.assert_called_once_with(url) player.play_url.reset_mock() player.play_url.side_effect = CommandError(None, "Failure", 1) assert "Unable to play media: Failure (1)" in caplog.text