async def test_import_already_configured(hass):
    """Test importing a device from .homekit that is already a ConfigEntry."""
    discovery_info = {
        'host': '127.0.0.1',
        'port': 8080,
        'properties': {
            'md': 'TestDevice',
            'id': '00:00:00:00:00:00',
            'c#': 1,
            'sf': 1,
        }
    }

    import_info = {
        'AccessoryPairingID': '00:00:00:00:00:00',
    }

    config_entry = MockConfigEntry(domain='homekit_controller',
                                   data=import_info)
    config_entry.add_to_hass(hass)

    flow = config_flow.HomekitControllerFlowHandler()
    flow.hass = hass

    result = await flow.async_import_legacy_pairing(
        discovery_info['properties'], import_info)
    assert result['type'] == 'abort'
    assert result['reason'] == 'already_configured'
async def test_user_works(hass):
    """Test user initiated disovers devices."""
    discovery_info = {
        'host': '127.0.0.1',
        'port': 8080,
        'properties': {
            'md': 'TestDevice',
            'id': '00:00:00:00:00:00',
            'c#': 1,
            'sf': 1,
        }
    }

    pairing = mock.Mock(pairing_data={
        'AccessoryPairingID': '00:00:00:00:00:00',
    })
    pairing.list_accessories_and_characteristics.return_value = [{
        "aid":
        1,
        "services": [{
            "characteristics": [{
                "type": "23",
                "value": "Koogeek-LS1-20833F"
            }],
            "type":
            "3e",
        }]
    }]

    controller = mock.Mock()
    controller.pairings = {
        '00:00:00:00:00:00': pairing,
    }
    controller.discover.return_value = [
        discovery_info,
    ]

    flow = config_flow.HomekitControllerFlowHandler()
    flow.hass = hass

    with mock.patch('homekit.Controller') as controller_cls:
        controller_cls.return_value = controller
        result = await flow.async_step_user()
    assert result['type'] == 'form'
    assert result['step_id'] == 'user'

    result = await flow.async_step_user({
        'device': '00:00:00:00:00:00',
    })
    assert result['type'] == 'form'
    assert result['step_id'] == 'pair'

    with mock.patch('homekit.Controller') as controller_cls:
        controller_cls.return_value = controller
        result = await flow.async_step_pair({
            'pairing_code': '111-22-33',
        })
    assert result['type'] == 'create_entry'
    assert result['title'] == 'Koogeek-LS1-20833F'
    assert result['data'] == pairing.pairing_data
async def test_pair_already_paired(hass):
    """Device is already paired."""
    discovery_info = {
        'host': '127.0.0.1',
        'port': 8080,
        'properties': {
            'md': 'TestDevice',
            'id': '00:00:00:00:00:00',
            'c#': 1,
            'sf': 1,
        }
    }

    flow = config_flow.HomekitControllerFlowHandler()
    flow.hass = hass

    result = await flow.async_step_discovery(discovery_info)
    assert result['type'] == 'form'
    assert result['step_id'] == 'pair'

    controller = mock.Mock()
    controller.pairings = {}

    with mock.patch('homekit.Controller') as controller_cls:
        controller_cls.return_value = controller
        exc = homekit.UnavailableError('Unavailable error')
        controller.perform_pairing.side_effect = exc
        result = await flow.async_step_pair({
            'pairing_code': '111-22-33',
        })

    assert result['type'] == 'abort'
    assert result['reason'] == 'already_paired'
示例#4
0
async def device_config_changed(hass, accessories):
    """Discover new devices added to Home Assistant at runtime."""
    # Update the accessories our FakePairing knows about
    controller = hass.data[CONTROLLER]
    pairing = controller.pairings["00:00:00:00:00:00"]

    accessories_obj = Accessories()
    for accessory in accessories:
        accessories_obj.add_accessory(accessory)
    pairing.accessories = accessories_obj

    discovery_info = {
        "name": "TestDevice",
        "host": "127.0.0.1",
        "port": 8080,
        "properties": {
            "md": "TestDevice",
            "id": "00:00:00:00:00:00",
            "c#": "2",
            "sf": "0",
        },
    }

    # Config Flow will abort and notify us if the discovery event is of
    # interest - in this case c# has incremented
    flow = config_flow.HomekitControllerFlowHandler()
    flow.hass = hass
    flow.context = {}
    result = await flow.async_step_zeroconf(discovery_info)
    assert result["type"] == "abort"
    assert result["reason"] == "already_configured"

    # Wait for services to reconfigure
    await hass.async_block_till_done()
    await hass.async_block_till_done()
async def test_pair_unable_to_pair(hass):
    """Pairing completed without exception, but didn't create a pairing."""
    discovery_info = {
        'host': '127.0.0.1',
        'port': 8080,
        'properties': {
            'md': 'TestDevice',
            'id': '00:00:00:00:00:00',
            'c#': 1,
            'sf': 1,
        }
    }

    flow = config_flow.HomekitControllerFlowHandler()
    flow.hass = hass

    result = await flow.async_step_discovery(discovery_info)
    assert result['type'] == 'form'
    assert result['step_id'] == 'pair'

    controller = mock.Mock()
    controller.pairings = {}

    with mock.patch('homekit.Controller') as controller_cls:
        controller_cls.return_value = controller
        result = await flow.async_step_pair({
            'pairing_code': '111-22-33',
        })

    assert result['type'] == 'form'
    assert result['errors']['pairing_code'] == 'unable_to_pair'
async def test_pair_authentication_error(hass):
    """Pairing code is incorrect."""
    discovery_info = {
        'host': '127.0.0.1',
        'port': 8080,
        'properties': {
            'md': 'TestDevice',
            'id': '00:00:00:00:00:00',
            'c#': 1,
            'sf': 1,
        }
    }

    flow = config_flow.HomekitControllerFlowHandler()
    flow.hass = hass

    result = await flow.async_step_discovery(discovery_info)
    assert result['type'] == 'form'
    assert result['step_id'] == 'pair'

    controller = mock.Mock()
    controller.pairings = {}

    with mock.patch('homekit.Controller') as controller_cls:
        controller_cls.return_value = controller
        exc = homekit.AuthenticationError('Invalid pairing code')
        controller.perform_pairing.side_effect = exc
        result = await flow.async_step_pair({
            'pairing_code': '111-22-33',
        })

    assert result['type'] == 'form'
    assert result['errors']['pairing_code'] == 'authentication_error'
async def test_discovery_already_configured_config_change(hass):
    """Already configured."""
    discovery_info = {
        'host': '127.0.0.1',
        'port': 8080,
        'properties': {
            'md': 'TestDevice',
            'id': '00:00:00:00:00:00',
            'c#': 2,
            'sf': 0,
        }
    }

    await setup_platform(hass)

    conn = mock.Mock()
    conn.config_num = 1
    hass.data[KNOWN_DEVICES]['00:00:00:00:00:00'] = conn

    flow = config_flow.HomekitControllerFlowHandler()
    flow.hass = hass

    result = await flow.async_step_discovery(discovery_info)
    assert result['type'] == 'abort'
    assert result['reason'] == 'already_configured'

    assert conn.async_config_num_changed.call_args == mock.call(2)
async def test_discovery_invalid_config_entry(hass):
    """There is already a config entry for the pairing id but its invalid."""
    MockConfigEntry(domain='homekit_controller',
                    data={
                        'AccessoryPairingID': '00:00:00:00:00:00'
                    }).add_to_hass(hass)

    # We just added a mock config entry so it must be visible in hass
    assert len(hass.config_entries.async_entries()) == 1

    discovery_info = {
        'host': '127.0.0.1',
        'port': 8080,
        'properties': {
            'md': 'TestDevice',
            'id': '00:00:00:00:00:00',
            'c#': 1,
            'sf': 1,
        }
    }

    flow = config_flow.HomekitControllerFlowHandler()
    flow.hass = hass

    result = await flow.async_step_discovery(discovery_info)
    assert result['type'] == 'form'
    assert result['step_id'] == 'pair'

    # Discovery of a HKID that is in a pairable state but for which there is
    # already a config entry - in that case the stale config entry is
    # automatically removed.
    config_entry_count = len(hass.config_entries.async_entries())
    assert config_entry_count == 0
示例#9
0
async def device_config_changed(hass, accessories):
    """Discover new devices added to HomeAssistant at runtime."""
    # Update the accessories our FakePairing knows about
    controller = hass.data[CONTROLLER]
    pairing = controller.pairings['00:00:00:00:00:00']
    pairing.accessories = accessories

    discovery_info = {
        'name': 'TestDevice',
        'host': '127.0.0.1',
        'port': 8080,
        'properties': {
            'md': 'TestDevice',
            'id': '00:00:00:00:00:00',
            'c#': '2',
            'sf': '0',
        }
    }

    # Config Flow will abort and notify us if the discovery event is of
    # interest - in this case c# has incremented
    flow = config_flow.HomekitControllerFlowHandler()
    flow.hass = hass
    flow.context = {}
    result = await flow.async_step_discovery(discovery_info)
    assert result['type'] == 'abort'
    assert result['reason'] == 'already_configured'

    # Wait for services to reconfigure
    await hass.async_block_till_done()
    await hass.async_block_till_done()
def _setup_flow_handler(hass):
    flow = config_flow.HomekitControllerFlowHandler()
    flow.hass = hass
    flow.context = {}

    flow.controller = mock.Mock()
    flow.controller.pairings = {}

    return flow
示例#11
0
async def test_user_no_devices(hass):
    """Test user initiated pairing where no devices discovered."""
    flow = config_flow.HomekitControllerFlowHandler()
    flow.hass = hass

    with mock.patch('homekit.Controller') as controller_cls:
        controller_cls.return_value.discover.return_value = []
        result = await flow.async_step_user()

    assert result['type'] == 'abort'
    assert result['reason'] == 'no_devices'
示例#12
0
async def test_parse_old_homekit_json(hass):
    """Test migrating original .homekit/hk-00:00:00:00:00:00 files."""
    service = FakeService('public.hap.service.lightbulb')
    on_char = service.add_characteristic('on')
    on_char.value = 1

    accessory = Accessory('TestDevice', 'example.com', 'Test', '0001', '0.1')
    accessory.services.append(service)

    fake_controller = await setup_platform(hass)
    pairing = fake_controller.add([accessory])
    pairing.pairing_data = {
        'AccessoryPairingID': '00:00:00:00:00:00',
    }

    mock_path = mock.Mock()
    mock_path.exists.side_effect = [False, True]

    mock_listdir = mock.Mock()
    mock_listdir.return_value = ['hk-00:00:00:00:00:00', 'pairings.json']

    read_data = {
        'AccessoryPairingID': '00:00:00:00:00:00',
    }
    mock_open = mock.mock_open(read_data=json.dumps(read_data))

    discovery_info = {
        'host': '127.0.0.1',
        'port': 8080,
        'properties': {
            'md': 'TestDevice',
            'id': '00:00:00:00:00:00',
            'c#': 1,
            'sf': 0,
        }
    }

    flow = config_flow.HomekitControllerFlowHandler()
    flow.hass = hass

    pairing_cls_imp = "homekit.controller.ip_implementation.IpPairing"

    with mock.patch(pairing_cls_imp) as pairing_cls:
        pairing_cls.return_value = pairing
        with mock.patch('builtins.open', mock_open):
            with mock.patch('os.path', mock_path):
                with mock.patch('os.listdir', mock_listdir):
                    result = await flow.async_step_discovery(discovery_info)

    assert result['type'] == 'create_entry'
    assert result['title'] == 'TestDevice'
    assert result['data']['AccessoryPairingID'] == '00:00:00:00:00:00'
示例#13
0
async def test_import_works(hass):
    """Test a device being discovered."""
    discovery_info = {
        'host': '127.0.0.1',
        'port': 8080,
        'properties': {
            'md': 'TestDevice',
            'id': '00:00:00:00:00:00',
            'c#': 1,
            'sf': 1,
        }
    }

    import_info = {
        'AccessoryPairingID': '00:00:00:00:00:00',
    }

    pairing = mock.Mock(pairing_data={
        'AccessoryPairingID': '00:00:00:00:00:00',
    })

    pairing.list_accessories_and_characteristics.return_value = [{
        "aid":
        1,
        "services": [{
            "characteristics": [{
                "type": "23",
                "value": "Koogeek-LS1-20833F"
            }],
            "type":
            "3e",
        }]
    }]

    flow = config_flow.HomekitControllerFlowHandler()
    flow.hass = hass

    pairing_cls_imp = "homekit.controller.ip_implementation.IpPairing"

    with mock.patch(pairing_cls_imp) as pairing_cls:
        pairing_cls.return_value = pairing
        result = await flow.async_import_legacy_pairing(
            discovery_info['properties'], import_info)

    assert result['type'] == 'create_entry'
    assert result['title'] == 'Koogeek-LS1-20833F'
    assert result['data'] == pairing.pairing_data
示例#14
0
def _setup_flow_handler(hass, pairing=None):
    flow = config_flow.HomekitControllerFlowHandler()
    flow.hass = hass
    flow.context = {}

    finish_pairing = unittest.mock.AsyncMock(return_value=pairing)

    discovery = mock.Mock()
    discovery.device_id = "00:00:00:00:00:00"
    discovery.start_pairing = unittest.mock.AsyncMock(
        return_value=finish_pairing)

    flow.controller = mock.Mock()
    flow.controller.pairings = {}
    flow.controller.find_ip_by_device_id = unittest.mock.AsyncMock(
        return_value=discovery)

    return flow
示例#15
0
async def test_discovery_ignored_model(hass):
    """Already paired."""
    discovery_info = {
        'host': '127.0.0.1',
        'port': 8080,
        'properties': {
            'md': 'BSB002',
            'id': '00:00:00:00:00:00',
            'c#': 1,
            'sf': 1,
        }
    }

    flow = config_flow.HomekitControllerFlowHandler()
    flow.hass = hass

    result = await flow.async_step_discovery(discovery_info)
    assert result['type'] == 'abort'
    assert result['reason'] == 'ignored_model'
示例#16
0
async def test_user_no_unpaired_devices(hass):
    """Test user initiated pairing where no unpaired devices discovered."""
    flow = config_flow.HomekitControllerFlowHandler()
    flow.hass = hass

    discovery_info = {
        'host': '127.0.0.1',
        'port': 8080,
        'properties': {
            'md': 'TestDevice',
            'id': '00:00:00:00:00:00',
            'c#': 1,
            'sf': 0,
        }
    }

    with mock.patch('homekit.Controller') as controller_cls:
        controller_cls.return_value.discover.return_value = [
            discovery_info,
        ]
        result = await flow.async_step_user()

    assert result['type'] == 'abort'
    assert result['reason'] == 'no_devices'
示例#17
0
def _setup_flow_handler(hass):
    flow = config_flow.HomekitControllerFlowHandler()
    flow.hass = hass
    flow.context = {}
    return flow