async def test_options_flow_filter_exclude(hass):
    config_entry = _mock_config_entry_with_options_populated(
        const.CONNECTION_TYPE_DIRECT)
    config_entry.add_to_hass(hass)

    hass.states.async_set('climate.old', 'off')
    await hass.async_block_till_done()

    with patch_yaml_files({YAML_CONFIG_FILE: ''}):
        result = await hass.config_entries.options.async_init(
            config_entry.entry_id)

        assert result['type'] == data_entry_flow.RESULT_TYPE_FORM
        assert result['step_id'] == 'include_domains'

        result = await hass.config_entries.options.async_configure(
            result['flow_id'],
            user_input={'domains': ['fan', 'vacuum', 'climate']})
        assert result['type'] == data_entry_flow.RESULT_TYPE_FORM
        assert result['step_id'] == 'include_exclude'

        result2 = await hass.config_entries.options.async_configure(
            result['flow_id'],
            user_input={
                'entities': ['climate.old'],
                'include_exclude_mode': 'exclude'
            })
        assert result2['type'] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
        assert config_entry.options == {
            'filter': {
                'exclude_entities': ['climate.old'],
                'include_domains': ['fan', 'vacuum', 'climate'],
                'include_entities': []
            },
        }
async def test_options_flow_with_yaml_filters_cloud(hass, hass_admin_user):
    config_entry = _mock_config_entry_with_options_populated(
        const.CONNECTION_TYPE_CLOUD)
    config_entry.add_to_hass(hass)

    with patch_yaml_files({
            YAML_CONFIG_FILE:
            """
yandex_smart_home:
  filter:
    include_domains:
      - script"""
    }):
        result = await hass.config_entries.options.async_init(
            config_entry.entry_id)
        assert result['type'] == data_entry_flow.RESULT_TYPE_FORM
        assert result['step_id'] == 'include_domains_yaml'

        result2 = await hass.config_entries.options.async_configure(
            result['flow_id'], user_input={})
        assert result2['type'] == data_entry_flow.RESULT_TYPE_FORM
        assert result2['step_id'] == 'cloud_settings'

        result3 = await hass.config_entries.options.async_configure(
            result2['flow_id'], user_input={'user_id': hass_admin_user.id})
        assert result3['type'] == data_entry_flow.RESULT_TYPE_FORM
        assert result3['step_id'] == 'cloud_info'

        result4 = await hass.config_entries.options.async_configure(
            result3['flow_id'], user_input={})
        assert result4['type'] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
        assert config_entry.options['user_id'] == hass_admin_user.id
async def test_step_user_with_yaml_filters(hass):
    with patch_yaml_files({
            YAML_CONFIG_FILE:
            """
yandex_smart_home:
  filter:
    include_domains:
      - script"""
    }):
        result = await hass.config_entries.flow.async_init(
            DOMAIN, context={'source': config_entries.SOURCE_USER})
        assert result['type'] == 'form'
        assert result['step_id'] == 'connection_type'
        assert result['errors'] == {}

        with patch(f'{COMPONENT_PATH}.async_setup',
                   return_value=True) as mock_setup, patch(
                       f'{COMPONENT_PATH}.async_setup_entry',
                       return_value=True) as mock_setup_entry:
            result2 = await hass.config_entries.flow.async_configure(
                result['flow_id'],
                {const.CONF_CONNECTION_TYPE: const.CONNECTION_TYPE_DIRECT})
            assert result2['type'] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
            mock_setup.assert_called_once()
            mock_setup_entry.assert_called_once()

        result = await hass.config_entries.flow.async_init(
            DOMAIN, context={'source': config_entries.SOURCE_USER})
        assert result['type'] == 'abort'
        assert result['reason'] == 'single_instance_allowed'
async def test_notifier_check_for_devices_discovered(
        hass_platform_cloud_connection, caplog):
    hass = hass_platform_cloud_connection
    assert len(hass.data[DOMAIN][NOTIFIERS]) == 1
    notifier = hass.data[DOMAIN][NOTIFIERS][0]

    with patch(
            'custom_components.yandex_smart_home.notifier.YandexNotifier._async_send_callback'
    ) as mock_send_cb:
        await notifier.async_send_discovery(None)
        mock_send_cb.assert_not_called()

    with patch_yaml_files({YAML_CONFIG_FILE: ''}), patch(
            'custom_components.yandex_smart_home.cloud.CloudManager.connect',
            return_value=None):
        await async_devices(hass,
                            RequestData(hass.data[DOMAIN][CONFIG], None, None),
                            {})
        await hass.async_block_till_done()

    assert len(hass.data[DOMAIN][NOTIFIERS]) == 1
    notifier = hass.data[DOMAIN][NOTIFIERS][0]
    with patch(
            'custom_components.yandex_smart_home.notifier.YandexNotifier._async_send_callback'
    ) as mock_send_cb:
        await notifier.async_send_discovery(None)
        mock_send_cb.assert_called_once()
async def test_options_flow_filter_exclude2(hass):
    config_entry = MockConfigEntry(
        domain=DOMAIN,
        data={'connection_type': 'direct'},
        options={
            'filter': {
                'include_domains': [
                    'fan',
                    'humidifier',
                    'vacuum',
                    'media_player',
                    'climate',
                ],
                'exclude_entities': ['climate.front_gate'],
                'include_entities': []
            },
        },
    )
    config_entry.add_to_hass(hass)

    hass.states.async_set('climate.old', 'off')
    hass.states.async_set('climate.new', 'off')

    await hass.async_block_till_done()

    with patch_yaml_files({YAML_CONFIG_FILE: ''}):
        result = await hass.config_entries.options.async_init(
            config_entry.entry_id)

        assert result['type'] == data_entry_flow.RESULT_TYPE_FORM
        assert result['step_id'] == 'include_domains'

        result = await hass.config_entries.options.async_configure(
            result['flow_id'],
            user_input={'domains': ['fan', 'vacuum', 'climate']})

        assert result['type'] == data_entry_flow.RESULT_TYPE_FORM
        assert result['step_id'] == 'include_exclude'

        result2 = await hass.config_entries.options.async_configure(
            result['flow_id'],
            user_input={
                'entities': ['climate.new'],
                'include_exclude_mode': 'include'
            })
        assert result2['type'] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
        assert config_entry.options == {
            'filter': {
                'exclude_entities': [],
                'include_domains': ['fan', 'vacuum'],
                'include_entities': ['climate.new'],
            }
        }
async def test_options_flow_with_non_existant_entity(hass):
    config_entry = MockConfigEntry(
        domain=DOMAIN,
        data={'connection_type': 'direct'},
        options={
            'filter': {
                'include_domains': [],
                'include_entities':
                ['climate.not_exist', 'climate.front_gate'],
            },
        },
    )
    config_entry.add_to_hass(hass)
    hass.states.async_set('climate.front_gate', 'off')
    hass.states.async_set('climate.new', 'off')

    await hass.async_block_till_done()

    with patch_yaml_files({YAML_CONFIG_FILE: ''}):
        result = await hass.config_entries.options.async_init(
            config_entry.entry_id)

        assert result['type'] == data_entry_flow.RESULT_TYPE_FORM
        assert result['step_id'] == 'include_domains'

        result2 = await hass.config_entries.options.async_configure(
            result['flow_id'],
            user_input={'domains': ['fan', 'vacuum', 'climate']})

        assert result2['type'] == data_entry_flow.RESULT_TYPE_FORM
        assert result2['step_id'] == 'include_exclude'
        entities = result2['data_schema']({
            'include_exclude_mode': 'include'
        })['entities']

        print(entities)
        assert 'climate.not_exist' not in entities

        result3 = await hass.config_entries.options.async_configure(
            result2['flow_id'],
            user_input={
                'entities': ['climate.new', 'climate.front_gate'],
                'include_exclude_mode': 'include',
            })
        assert result3['type'] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
        assert config_entry.options == {
            'filter': {
                'exclude_entities': [],
                'include_domains': ['fan', 'vacuum'],
                'include_entities': ['climate.new', 'climate.front_gate'],
            },
        }
示例#7
0
def hass_platform_cloud_connection(loop, hass, config_entry_cloud_connection):
    demo_sensor = DemoSensor(
        unique_id='outside_temp',
        name='Outside Temperature',
        state=15.6,
        device_class=DEVICE_CLASS_TEMPERATURE,
        state_class=STATE_CLASS_MEASUREMENT,
        unit_of_measurement=TEMP_CELSIUS,
        battery=None
    )
    demo_sensor.hass = hass
    demo_sensor.entity_id = 'sensor.outside_temp'

    demo_light = DemoLight(
        unique_id='light_kitchen',
        name='Kitchen Light',
        available=True,
        state=True,
    )
    demo_light.hass = hass
    demo_light.entity_id = 'light.kitchen'

    loop.run_until_complete(
        demo_sensor.async_update_ha_state()
    )
    loop.run_until_complete(
        demo_light.async_update_ha_state()
    )

    loop.run_until_complete(
        async_setup_component(hass, http.DOMAIN, {http.DOMAIN: {}})
    )
    loop.run_until_complete(
        hass.async_block_till_done()
    )

    with patch.object(hass.config_entries.flow, 'async_init', return_value=None), patch_yaml_files({
        YAML_CONFIG_FILE: 'yandex_smart_home:'
    }):
        config_entry_cloud_connection.add_to_hass(hass)
        loop.run_until_complete(async_setup(hass, {DOMAIN: {}}))
        with patch('custom_components.yandex_smart_home.cloud.CloudManager.connect', return_value=None):
            loop.run_until_complete(async_setup_entry(hass, config_entry_cloud_connection))

    return hass
async def test_options_flow_with_yaml_filters_direct(hass):
    config_entry = _mock_config_entry_with_options_populated(
        const.CONNECTION_TYPE_DIRECT)
    config_entry.add_to_hass(hass)

    with patch_yaml_files({
            YAML_CONFIG_FILE:
            """
yandex_smart_home:
  filter:
    include_domains:
      - script"""
    }):
        result = await hass.config_entries.options.async_init(
            config_entry.entry_id)
        assert result['type'] == data_entry_flow.RESULT_TYPE_FORM
        assert result['step_id'] == 'include_domains_yaml'

        result2 = await hass.config_entries.options.async_configure(
            result['flow_id'], user_input={})
        assert result2['type'] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
async def test_step_user_direct(hass):
    with patch_yaml_files({YAML_CONFIG_FILE: ''}):
        result = await hass.config_entries.flow.async_init(
            DOMAIN, context={'source': config_entries.SOURCE_USER})
        assert result['type'] == 'form'
        assert result['step_id'] == 'include_domains'
        assert result['errors'] is None

        result2 = await hass.config_entries.flow.async_configure(
            result['flow_id'], {'include_domains': ['light']})
        assert result2['type'] == 'form'
        assert result2['step_id'] == 'connection_type'
        assert result2['errors'] == {}

        with patch(f'{COMPONENT_PATH}.async_setup',
                   return_value=True) as mock_setup, patch(
                       f'{COMPONENT_PATH}.async_setup_entry',
                       return_value=True) as mock_setup_entry:
            result3 = await hass.config_entries.flow.async_configure(
                result['flow_id'],
                {const.CONF_CONNECTION_TYPE: const.CONNECTION_TYPE_DIRECT})
            await hass.async_block_till_done()

            assert result3['type'] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
            assert result3['data'] == {
                'connection_type': 'direct',
                'devices_discovered': False,
                'filter': {
                    'exclude_entities': [],
                    'include_domains': ['light'],
                    'include_entities': []
                },
            }

            mock_setup.assert_called_once()
            mock_setup_entry.assert_called_once()
async def test_step_user_cloud(hass, aioclient_mock):
    with patch_yaml_files({YAML_CONFIG_FILE: ''}):
        result = await hass.config_entries.flow.async_init(
            DOMAIN, context={'source': config_entries.SOURCE_USER})
        assert result['type'] == 'form'
        assert result['step_id'] == 'include_domains'
        assert result['errors'] is None

        result2 = await hass.config_entries.flow.async_configure(
            result['flow_id'], {'include_domains': ['light']})
        assert result2['type'] == 'form'
        assert result2['step_id'] == 'connection_type'
        assert result2['errors'] == {}

        aioclient_mock.post(f'{cloud.BASE_API_URL}/instance/register',
                            status=500)
        result3 = await hass.config_entries.flow.async_configure(
            result2['flow_id'],
            {const.CONF_CONNECTION_TYPE: const.CONNECTION_TYPE_CLOUD})
        assert result3['type'] == 'form'
        assert result3['step_id'] == 'connection_type'
        assert result3['errors']['base'] == 'cannot_connect'

        aioclient_mock.post(f'{cloud.BASE_API_URL}/instance/register',
                            side_effect=Exception())
        result4 = await hass.config_entries.flow.async_configure(
            result3['flow_id'],
            {const.CONF_CONNECTION_TYPE: const.CONNECTION_TYPE_CLOUD})
        assert result4['type'] == 'form'
        assert result4['step_id'] == 'connection_type'
        assert result4['errors']['base'] == 'cannot_connect'

        aioclient_mock.clear_requests()
        aioclient_mock.post(
            f'{cloud.BASE_API_URL}/instance/register',
            status=202,
            json={
                'id': 'test',
                'password': '******',
                'connection_token': 'foo'
            },
        )
        result5 = await hass.config_entries.flow.async_configure(
            result4['flow_id'],
            {const.CONF_CONNECTION_TYPE: const.CONNECTION_TYPE_CLOUD})
        assert result5['type'] == 'form'
        assert result5['step_id'] == 'cloud_info'
        assert result5['errors'] is None

        with patch(f'{COMPONENT_PATH}.async_setup',
                   return_value=True) as mock_setup, patch(
                       f'{COMPONENT_PATH}.async_setup_entry',
                       return_value=True) as mock_setup_entry:
            result6 = await hass.config_entries.flow.async_configure(
                result5['flow_id'], {})
            await hass.async_block_till_done()

            assert result6['type'] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
            assert result6['data'] == {
                'connection_type': 'cloud',
                'devices_discovered': False,
                'cloud_instance': {
                    'id': 'test',
                    'password': '******',
                    'token': 'foo'
                },
                'filter': {
                    'exclude_entities': [],
                    'include_domains': ['light'],
                    'include_entities': []
                },
            }

            mock_setup.assert_called_once()
            mock_setup_entry.assert_called_once()