Example #1
0
async def test_initialize_loads_info(cloud_client):
    """Test initialize will load info from config file."""
    cl = cloud.Cloud(cloud_client, cloud.MODE_DEV)

    info_file = MagicMock(
        read_text=Mock(
            return_value=json.dumps({
                "id_token": "test-id-token",
                "access_token": "test-access-token",
                "refresh_token": "test-refresh-token",
            })),
        exists=Mock(return_value=True),
    )

    cl.iot = MagicMock()
    cl.iot.connect.return_value = mock_coro()

    with patch("hass_nabucasa.Cloud._decode_claims"), patch(
            "hass_nabucasa.Cloud.user_info_path",
            new_callable=PropertyMock(return_value=info_file),
    ):
        await cl.start()

    assert cl.id_token == "test-id-token"
    assert cl.access_token == "test-access-token"
    assert cl.refresh_token == "test-refresh-token"
    assert len(cl.iot.connect.mock_calls) == 1
Example #2
0
async def test_initialize_loads_invalid_info(cloud_client, caplog):
    """Test initialize load invalid info from config file."""
    cl = cloud.Cloud(cloud_client, cloud.MODE_DEV)

    info_file = MagicMock(
        read_text=Mock(return_value="invalid json"),
        exists=Mock(return_value=True),
        relative_to=Mock(return_value=".cloud/production_auth.json"),
    )

    cl.iot = MagicMock()
    cl.iot.connect.return_value = mock_coro()

    cl.remote = MagicMock()
    cl.remote.connect.return_value = mock_coro()

    cl._on_start.extend([cl.iot.connect, cl.remote.connect])

    with patch("hass_nabucasa.Cloud._decode_claims"), patch(
            "hass_nabucasa.Cloud.user_info_path",
            new_callable=PropertyMock(return_value=info_file),
    ):
        await cl.start()

    assert cl.id_token is None
    assert len(cl.iot.connect.mock_calls) == 0
    assert len(cl.remote.connect.mock_calls) == 0
    assert (
        "Error loading cloud authentication info from .cloud/production_auth.json: Expecting value: line 1 column 1 (char 0)"
        in caplog.text)
Example #3
0
def test_subscription_expired(cloud_client):
    """Test subscription being expired after 3 days of expiration."""
    cl = cloud.Cloud(cloud_client, cloud.MODE_DEV)

    token_val = {"custom:sub-exp": "2017-11-13"}
    with patch.object(cl, "_decode_claims", return_value=token_val), patch(
            "hass_nabucasa.utcnow",
            return_value=utcnow().replace(year=2017, month=11, day=13),
    ):
        assert not cl.subscription_expired

    with patch.object(cl, "_decode_claims", return_value=token_val), patch(
            "hass_nabucasa.utcnow",
            return_value=utcnow().replace(year=2017,
                                          month=11,
                                          day=19,
                                          hour=23,
                                          minute=59,
                                          second=59),
    ):
        assert not cl.subscription_expired

    with patch.object(cl, "_decode_claims", return_value=token_val), patch(
            "hass_nabucasa.utcnow",
            return_value=utcnow().replace(year=2017,
                                          month=11,
                                          day=20,
                                          hour=0,
                                          minute=0,
                                          second=0),
    ):
        assert cl.subscription_expired
Example #4
0
def test_constructor_loads_info_from_constant(cloud_client):
    """Test non-dev mode loads info from SERVERS constant."""
    with patch.dict(
            cloud.SERVERS,
        {
            "beer": {
                "cognito_client_id": "test-cognito_client_id",
                "user_pool_id": "test-user_pool_id",
                "region": "test-region",
                "relayer": "test-relayer",
                "google_actions_sync_url": "test-google_actions_sync_url",
                "subscription_info_url": "test-subscription-info-url",
                "cloudhook_create_url": "test-cloudhook_create_url",
                "remote_api_url": "test-remote_api_url",
                "alexa_access_token_url": "test-alexa-token-url",
                "acme_directory_server": "test-acme-directory-server",
            }
        },
    ):
        cl = cloud.Cloud(cloud_client, "beer")

    assert cl.mode == "beer"
    assert cl.cognito_client_id == "test-cognito_client_id"
    assert cl.user_pool_id == "test-user_pool_id"
    assert cl.region == "test-region"
    assert cl.relayer == "test-relayer"
    assert cl.google_actions_sync_url == "test-google_actions_sync_url"
    assert cl.subscription_info_url == "test-subscription-info-url"
    assert cl.cloudhook_create_url == "test-cloudhook_create_url"
    assert cl.acme_directory_server == "test-acme-directory-server"
Example #5
0
def test_subscription_not_expired(cloud_client):
    """Test subscription not being expired."""
    cl = cloud.Cloud(cloud_client, cloud.MODE_DEV)

    token_val = {"custom:sub-exp": "2017-11-13"}
    with patch.object(cl, "_decode_claims", return_value=token_val), patch(
            "hass_nabucasa.utcnow",
            return_value=utcnow().replace(year=2017, month=11, day=9),
    ):
        assert not cl.subscription_expired
Example #6
0
async def test_initialize_loads_info(cloud_client):
    """Test initialize will load info from config file.

    Also tests that on_initialized callbacks are called when initialization finishes.
    """
    cl = cloud.Cloud(cloud_client, cloud.MODE_DEV)

    assert len(cl._on_start) == 2
    cl._on_start.clear()
    assert len(cl._on_stop) == 3
    cl._on_stop.clear()

    info_file = MagicMock(
        read_text=Mock(
            return_value=json.dumps({
                "id_token": "test-id-token",
                "access_token": "test-access-token",
                "refresh_token": "test-refresh-token",
            })),
        exists=Mock(return_value=True),
    )

    cl.iot = MagicMock()
    cl.iot.connect = AsyncMock()

    cl.remote = MagicMock()
    cl.remote.connect = AsyncMock()

    start_done_event = asyncio.Event()

    async def start_done():
        start_done_event.set()

    cl._on_start.extend([cl.iot.connect, cl.remote.connect])
    cl.register_on_initialized(start_done)

    with patch(
            "hass_nabucasa.Cloud._decode_claims",
            return_value={"custom:sub-exp": "2080-01-01"},
    ), patch(
            "hass_nabucasa.Cloud.user_info_path",
            new_callable=PropertyMock(return_value=info_file),
    ), patch("hass_nabucasa.auth.CognitoAuth.async_check_token"):
        await cl.initialize()
        await start_done_event.wait()

    assert cl.id_token == "test-id-token"
    assert cl.access_token == "test-access-token"
    assert cl.refresh_token == "test-refresh-token"
    assert len(cl.iot.connect.mock_calls) == 1
    assert len(cl.remote.connect.mock_calls) == 1
Example #7
0
async def test_logout_clears_info(cloud_client):
    """Test logging out disconnects and removes info."""
    cl = cloud.Cloud(cloud_client, cloud.MODE_DEV)

    assert len(cl._on_start) == 2
    cl._on_start.clear()
    assert len(cl._on_stop) == 3
    cl._on_stop.clear()

    info_file = MagicMock(exists=Mock(return_value=True),
                          unlink=Mock(return_value=True))

    cl.id_token = "id_token"
    cl.access_token = "access_token"
    cl.refresh_token = "refresh_token"

    cl.iot = MagicMock()
    cl.iot.disconnect.return_value = mock_coro()

    cl.google_report_state = MagicMock()
    cl.google_report_state.disconnect.return_value = mock_coro()

    cl.remote = MagicMock()
    cl.remote.disconnect.return_value = mock_coro()

    cl._on_stop.extend([
        cl.iot.disconnect, cl.remote.disconnect,
        cl.google_report_state.disconnect
    ])

    with patch(
            "hass_nabucasa.Cloud.user_info_path",
            new_callable=PropertyMock(return_value=info_file),
    ):
        await cl.logout()

    assert len(cl.iot.disconnect.mock_calls) == 1
    assert len(cl.google_report_state.disconnect.mock_calls) == 1
    assert len(cl.remote.disconnect.mock_calls) == 1
    assert cl.id_token is None
    assert cl.access_token is None
    assert cl.refresh_token is None
    assert info_file.unlink.called
Example #8
0
def test_write_user_info(cloud_client):
    """Test writing user info works."""
    cl = cloud.Cloud(cloud_client, cloud.MODE_DEV)

    cl.id_token = "test-id-token"
    cl.access_token = "test-access-token"
    cl.refresh_token = "test-refresh-token"

    with patch("hass_nabucasa.atomic_write", ) as mock_write:
        cl.write_user_info()

    mock_file = mock_write.return_value.__enter__.return_value

    assert mock_file.write.called
    data = json.loads(mock_file.write.mock_calls[0][1][0])
    assert data == {
        "access_token": "test-access-token",
        "id_token": "test-id-token",
        "refresh_token": "test-refresh-token",
    }
Example #9
0
def test_write_user_info(cloud_client):
    """Test writing user info works."""
    cl = cloud.Cloud(cloud_client, cloud.MODE_DEV)

    info_file = MagicMock(exists=Mock(return_value=True),
                          write_text=Mock(return_value=True))

    cl.id_token = "test-id-token"
    cl.access_token = "test-access-token"
    cl.refresh_token = "test-refresh-token"

    with patch(
            "hass_nabucasa.Cloud.user_info_path",
            new_callable=PropertyMock(return_value=info_file),
    ):
        cl.write_user_info()

    assert info_file.write_text.called
    data = json.loads(info_file.write_text.mock_calls[0][1][0])
    assert data == {
        "access_token": "test-access-token",
        "id_token": "test-id-token",
        "refresh_token": "test-refresh-token",
    }