Beispiel #1
0
async def test_smartapp_install_creates_flow(hass, smartthings_mock,
                                             config_entry, location,
                                             device_factory):
    """Test installation creates flow."""
    # Arrange
    config_entry.add_to_hass(hass)
    app = Mock()
    app.app_id = config_entry.data["app_id"]
    request = Mock()
    request.installed_app_id = str(uuid4())
    request.auth_token = str(uuid4())
    request.refresh_token = str(uuid4())
    request.location_id = location.location_id
    devices = [
        device_factory("", [Capability.battery, "ping"]),
        device_factory("", [Capability.switch, Capability.switch_level]),
        device_factory("", [Capability.switch]),
    ]
    smartthings_mock.devices.return_value = devices
    # Act
    await smartapp.smartapp_install(hass, request, None, app)
    # Assert
    await hass.async_block_till_done()
    entries = hass.config_entries.async_entries("smartthings")
    assert len(entries) == 2
    assert entries[1].data["app_id"] == app.app_id
    assert entries[1].data["installed_app_id"] == request.installed_app_id
    assert entries[1].data["location_id"] == request.location_id
    assert entries[1].data["access_token"] == config_entry.data["access_token"]
    assert entries[1].data["refresh_token"] == request.refresh_token
    assert entries[1].data["client_secret"] == config_entry.data[
        "client_secret"]
    assert entries[1].data["client_id"] == config_entry.data["client_id"]
    assert entries[1].title == location.name
Beispiel #2
0
async def test_smartapp_install_creates_flow(hass, smartthings_mock,
                                             config_entry, location,
                                             device_factory):
    """Test installation creates flow."""
    # Arrange
    setattr(hass.config_entries, '_entries', [config_entry])
    app = Mock()
    app.app_id = config_entry.data['app_id']
    request = Mock()
    request.installed_app_id = str(uuid4())
    request.auth_token = str(uuid4())
    request.refresh_token = str(uuid4())
    request.location_id = location.location_id
    devices = [
        device_factory('', [Capability.battery, 'ping']),
        device_factory('', [Capability.switch, Capability.switch_level]),
        device_factory('', [Capability.switch])
    ]
    smartthings_mock.devices.return_value = devices
    # Act
    await smartapp.smartapp_install(hass, request, None, app)
    # Assert
    await hass.async_block_till_done()
    entries = hass.config_entries.async_entries('smartthings')
    assert len(entries) == 2
    assert entries[1].data['app_id'] == app.app_id
    assert entries[1].data['installed_app_id'] == request.installed_app_id
    assert entries[1].data['location_id'] == request.location_id
    assert entries[1].data['access_token'] == \
        config_entry.data['access_token']
    assert entries[1].data['refresh_token'] == request.refresh_token
    assert entries[1].data['client_secret'] == \
        config_entry.data['client_secret']
    assert entries[1].data['client_id'] == config_entry.data['client_id']
    assert entries[1].title == location.name
Beispiel #3
0
async def test_smartapp_update_configures_flow(hass):
    """Test update event continues an existing flow."""
    # Arrange
    flow_id = str(uuid4())
    flows = [{"flow_id": flow_id, "handler": DOMAIN}]
    app = Mock()
    app.app_id = uuid4()
    request = Mock()
    request.installed_app_id = str(uuid4())
    request.auth_token = str(uuid4())
    request.location_id = str(uuid4())
    request.refresh_token = str(uuid4())

    # Act
    with patch.object(
        hass.config_entries.flow, "async_progress", return_value=flows
    ), patch.object(hass.config_entries.flow, "async_configure") as configure_mock:

        await smartapp.smartapp_update(hass, request, None, app)

        configure_mock.assert_called_once_with(
            flow_id,
            {
                CONF_INSTALLED_APP_ID: request.installed_app_id,
                CONF_LOCATION_ID: request.location_id,
                CONF_REFRESH_TOKEN: request.refresh_token,
            },
        )
Beispiel #4
0
async def test_smartapp_install_store_if_no_other(hass, smartthings_mock,
                                                  device_factory):
    """Test aborts if no other app was configured already."""
    # Arrange
    app = Mock()
    app.app_id = uuid4()
    request = Mock()
    request.installed_app_id = str(uuid4())
    request.auth_token = str(uuid4())
    request.location_id = str(uuid4())
    request.refresh_token = str(uuid4())
    # Act
    await smartapp.smartapp_install(hass, request, None, app)
    # Assert
    entries = hass.config_entries.async_entries("smartthings")
    assert not entries
    data = hass.data[DOMAIN][CONF_INSTALLED_APPS][0]
    assert data[CONF_REFRESH_TOKEN] == request.refresh_token
    assert data[CONF_LOCATION_ID] == request.location_id
    assert data[CONF_INSTALLED_APP_ID] == request.installed_app_id
Beispiel #5
0
async def test_smartapp_update_saves_token(hass, smartthings_mock, location,
                                           device_factory):
    """Test update saves token."""
    # Arrange
    entry = Mock()
    entry.data = {'installed_app_id': str(uuid4()), 'app_id': str(uuid4())}
    entry.domain = DOMAIN

    setattr(hass.config_entries, '_entries', [entry])
    app = Mock()
    app.app_id = entry.data['app_id']
    request = Mock()
    request.installed_app_id = entry.data['installed_app_id']
    request.auth_token = str(uuid4())
    request.refresh_token = str(uuid4())
    request.location_id = location.location_id

    # Act
    await smartapp.smartapp_update(hass, request, None, app)
    # Assert
    assert entry.data[CONF_REFRESH_TOKEN] == request.refresh_token
Beispiel #6
0
async def test_smartapp_update_saves_token(
    hass, smartthings_mock, location, device_factory
):
    """Test update saves token."""
    # Arrange
    entry = MockConfigEntry(
        domain=DOMAIN, data={"installed_app_id": str(uuid4()), "app_id": str(uuid4())}
    )
    entry.add_to_hass(hass)
    app = Mock()
    app.app_id = entry.data["app_id"]
    request = Mock()
    request.installed_app_id = entry.data["installed_app_id"]
    request.auth_token = str(uuid4())
    request.refresh_token = str(uuid4())
    request.location_id = location.location_id

    # Act
    await smartapp.smartapp_update(hass, request, None, app)
    # Assert
    assert entry.data[CONF_REFRESH_TOKEN] == request.refresh_token
Beispiel #7
0
async def test_entry_created(hass, app, app_oauth_client, location,
                             smartthings_mock):
    """Test local webhook, new app, install event creates entry."""
    token = str(uuid4())
    installed_app_id = str(uuid4())
    refresh_token = str(uuid4())
    smartthings_mock.apps.return_value = []
    smartthings_mock.create_app.return_value = (app, app_oauth_client)
    smartthings_mock.locations.return_value = [location]
    request = Mock()
    request.installed_app_id = installed_app_id
    request.auth_token = token
    request.location_id = location.location_id
    request.refresh_token = refresh_token

    # Webhook confirmation shown
    result = await hass.config_entries.flow.async_init(
        DOMAIN, context={"source": "user"})
    assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
    assert result["step_id"] == "user"
    assert result["description_placeholders"][
        "webhook_url"] == smartapp.get_webhook_url(hass)

    # Advance to PAT screen
    result = await hass.config_entries.flow.async_configure(
        result["flow_id"], {})
    assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
    assert result["step_id"] == "pat"
    assert "token_url" in result["description_placeholders"]
    assert "component_url" in result["description_placeholders"]

    # Enter token and advance to location screen
    result = await hass.config_entries.flow.async_configure(
        result["flow_id"], {CONF_ACCESS_TOKEN: token})
    assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
    assert result["step_id"] == "select_location"

    # Select location and advance to external auth
    result = await hass.config_entries.flow.async_configure(
        result["flow_id"], {CONF_LOCATION_ID: location.location_id})
    assert result["type"] == data_entry_flow.RESULT_TYPE_EXTERNAL_STEP
    assert result["step_id"] == "authorize"
    assert result["url"] == format_install_url(app.app_id,
                                               location.location_id)

    # Complete external auth and advance to install
    await smartapp.smartapp_install(hass, request, None, app)

    # Finish
    result = await hass.config_entries.flow.async_configure(result["flow_id"])
    assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
    assert result["data"]["app_id"] == app.app_id
    assert result["data"]["installed_app_id"] == installed_app_id
    assert result["data"]["location_id"] == location.location_id
    assert result["data"]["access_token"] == token
    assert result["data"]["refresh_token"] == request.refresh_token
    assert result["data"]["client_secret"] == app_oauth_client.client_secret
    assert result["data"]["client_id"] == app_oauth_client.client_id
    assert result["title"] == location.name
    entry = next(
        (entry for entry in hass.config_entries.async_entries(DOMAIN)),
        None,
    )
    assert entry.unique_id == smartapp.format_unique_id(
        app.app_id, location.location_id)
Beispiel #8
0
async def test_entry_created_existing_app_copies_oauth_client(
        hass, app, location, smartthings_mock):
    """Test entry is created with an existing app and copies the oauth client from another entry."""
    token = str(uuid4())
    installed_app_id = str(uuid4())
    refresh_token = str(uuid4())
    oauth_client_id = str(uuid4())
    oauth_client_secret = str(uuid4())
    smartthings_mock.apps.return_value = [app]
    smartthings_mock.locations.return_value = [location]
    request = Mock()
    request.installed_app_id = installed_app_id
    request.auth_token = token
    request.location_id = location.location_id
    request.refresh_token = refresh_token
    entry = MockConfigEntry(
        domain=DOMAIN,
        data={
            CONF_APP_ID: app.app_id,
            CONF_OAUTH_CLIENT_ID: oauth_client_id,
            CONF_OAUTH_CLIENT_SECRET: oauth_client_secret,
            CONF_LOCATION_ID: str(uuid4()),
            CONF_INSTALLED_APP_ID: str(uuid4()),
            CONF_ACCESS_TOKEN: token,
        },
    )
    entry.add_to_hass(hass)

    # Webhook confirmation shown
    result = await hass.config_entries.flow.async_init(
        DOMAIN, context={"source": "user"})
    assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
    assert result["step_id"] == "user"
    assert result["description_placeholders"][
        "webhook_url"] == smartapp.get_webhook_url(hass)

    # Advance to PAT screen
    result = await hass.config_entries.flow.async_configure(
        result["flow_id"], {})
    assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
    assert result["step_id"] == "pat"
    assert "token_url" in result["description_placeholders"]
    assert "component_url" in result["description_placeholders"]
    # Assert access token is defaulted to an existing entry for convenience.
    assert result["data_schema"]({}) == {CONF_ACCESS_TOKEN: token}

    # Enter token and advance to location screen
    result = await hass.config_entries.flow.async_configure(
        result["flow_id"], {CONF_ACCESS_TOKEN: token})
    assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
    assert result["step_id"] == "select_location"

    # Select location and advance to external auth
    result = await hass.config_entries.flow.async_configure(
        result["flow_id"], {CONF_LOCATION_ID: location.location_id})
    assert result["type"] == data_entry_flow.RESULT_TYPE_EXTERNAL_STEP
    assert result["step_id"] == "authorize"
    assert result["url"] == format_install_url(app.app_id,
                                               location.location_id)

    # Complete external auth and advance to install
    await smartapp.smartapp_install(hass, request, None, app)

    # Finish
    result = await hass.config_entries.flow.async_configure(result["flow_id"])
    assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
    assert result["data"]["app_id"] == app.app_id
    assert result["data"]["installed_app_id"] == installed_app_id
    assert result["data"]["location_id"] == location.location_id
    assert result["data"]["access_token"] == token
    assert result["data"]["refresh_token"] == request.refresh_token
    assert result["data"]["client_secret"] == oauth_client_secret
    assert result["data"]["client_id"] == oauth_client_id
    assert result["title"] == location.name
    entry = next(
        (entry for entry in hass.config_entries.async_entries(DOMAIN)
         if entry.data[CONF_INSTALLED_APP_ID] == installed_app_id),
        None,
    )
    assert entry.unique_id == smartapp.format_unique_id(
        app.app_id, location.location_id)