Exemple #1
0
async def test_auth_refresh(aiohttp_server) -> None:
    r = Recorder()
    handler = NewDeviceHandler(
        r,
        [
            {
                "name": "enterprises/project-id1/devices/device-id1",
                "type": "sdm.devices.types.device-type1",
                "traits": {},
                "parentRelations": [],
            },
        ],
        token="updated-token",
    )

    async def auth_handler(
            request: aiohttp.web.Request) -> aiohttp.web.Response:
        return aiohttp.web.json_response({"token": "updated-token"})

    app = aiohttp.web.Application()
    app.router.add_get("/enterprises/project-id1/devices", handler)
    app.router.add_get("/refresh-auth", auth_handler)
    server = await aiohttp_server(app)

    async with aiohttp.test_utils.TestClient(server) as client:
        api = google_nest_api.GoogleNestAPI(RefreshingAuth(client), PROJECT_ID)
        devices = await api.async_get_devices()
        assert len(devices) == 1
        assert "enterprises/project-id1/devices/device-id1" == devices[0].name
        assert "sdm.devices.types.device-type1" == devices[0].type
Exemple #2
0
async def test_get_devices(aiohttp_server) -> None:
    r = Recorder()
    handler = NewDeviceHandler(
        r,
        [
            {
                "name": "enterprises/project-id1/devices/device-id1",
                "type": "sdm.devices.types.device-type1",
                "traits": {},
                "parentRelations": [],
            },
            {
                "name": "enterprises/project-id1/devices/device-id2",
                "type": "sdm.devices.types.device-type2",
                "traits": {},
                "parentRelations": [],
            },
        ],
    )

    app = aiohttp.web.Application()
    app.router.add_get("/enterprises/project-id1/devices", handler)
    server = await aiohttp_server(app)

    async with aiohttp.test_utils.TestClient(server) as client:
        api = google_nest_api.GoogleNestAPI(FakeAuth(client), PROJECT_ID)
        devices = await api.async_get_devices()
        assert len(devices) == 2
        assert "enterprises/project-id1/devices/device-id1" == devices[0].name
        assert "sdm.devices.types.device-type1" == devices[0].type
        assert "enterprises/project-id1/devices/device-id2" == devices[1].name
        assert "sdm.devices.types.device-type2" == devices[1].type
async def test_request(aiohttp_server) -> None:
    async def handler(request: aiohttp.web.Request) -> aiohttp.web.Response:
        assert request.headers['Authorization'] == 'Bearer some-token'
        return aiohttp.web.json_response({
            'devices': [
                {
                    'name': 'enterprises/project-id/devices/device-id1',
                    'type': 'sdm.devices.types.device-type1',
                    'traits': {},
                    'parentRelations': [],
                },
                {
                    'name': 'enterprises/project-id/devices/device-id2',
                    'type': 'sdm.devices.types.device-type2',
                    'traits': {},
                    'parentRelations': [],
                },
            ]
        })

    app = aiohttp.web.Application()
    app.router.add_get('/devices', handler)
    server = await aiohttp_server(app)

    async with aiohttp.test_utils.TestClient(server) as client:
        auth = FakeAuth(client)
        api = google_nest_api.GoogleNestAPI(auth)
        devices = await api.async_get_devices()
        assert len(devices) == 2
        assert 'enterprises/project-id/devices/device-id1' == devices[0].name
        assert 'sdm.devices.types.device-type1' == devices[0].type
        assert 'enterprises/project-id/devices/device-id2' == devices[1].name
        assert 'sdm.devices.types.device-type2' == devices[1].type
Exemple #4
0
async def test_api_get_error(aiohttp_server) -> None:
    # No server endpoint registered
    app = aiohttp.web.Application()
    server = await aiohttp_server(app)

    async with aiohttp.test_utils.TestClient(server) as client:
        api = google_nest_api.GoogleNestAPI(FakeAuth(client), PROJECT_ID)
        with pytest.raises(ApiException):
            await api.async_get_structures()
Exemple #5
0
async def test_no_devices(aiohttp_server) -> None:
    r = Recorder()
    app = aiohttp.web.Application()
    app.router.add_get("/enterprises/project-id1/devices", NewHandler(r, [{}]))
    server = await aiohttp_server(app)

    async with aiohttp.test_utils.TestClient(server) as client:
        api = google_nest_api.GoogleNestAPI(FakeAuth(client), PROJECT_ID)
        devices = await api.async_get_devices()
        assert len(devices) == 0
Exemple #6
0
async def test_missing_structures(aiohttp_server) -> None:
    r = Recorder()
    app = aiohttp.web.Application()
    app.router.add_get("/enterprises/project-id1/structures/abc",
                       NewHandler(r, [{}]))
    server = await aiohttp_server(app)

    async with aiohttp.test_utils.TestClient(server) as client:
        api = google_nest_api.GoogleNestAPI(FakeAuth(client), PROJECT_ID)
        structure = await api.async_get_structure("abc")
        assert structure is None
Exemple #7
0
async def test_camera_event_image(aiohttp_server) -> None:
    r = Recorder()
    handler = NewDeviceHandler(
        r,
        [{
            "name": "enterprises/project-id1/devices/device-id1",
            "traits": {
                "sdm.devices.traits.CameraEventImage": {},
            },
        }],
    )

    post_handler = NewRequestRecorder(
        r,
        [{
            "results": {
                "url":
                "https://domain/sdm_event_snapshot/dGNUlTU2CjY5Y3VKaTZwR3o4Y",
                "token": "g.0.eventToken",
            },
        }],
    )

    app = aiohttp.web.Application()
    app.router.add_get("/enterprises/project-id1/devices", handler)
    app.router.add_post(
        "/enterprises/project-id1/devices/device-id1:executeCommand",
        post_handler)
    server = await aiohttp_server(app)

    async with aiohttp.test_utils.TestClient(server) as client:
        api = google_nest_api.GoogleNestAPI(FakeAuth(client), PROJECT_ID)
        devices = await api.async_get_devices()
        assert len(devices) == 1
        device = devices[0]
        assert "enterprises/project-id1/devices/device-id1" == device.name
        trait = device.traits["sdm.devices.traits.CameraEventImage"]
        image = await trait.generate_image("some-eventId")
        expected_request = {
            "command": "sdm.devices.commands.CameraEventImage.GenerateImage",
            "params": {
                "eventId": "some-eventId"
            },
        }
        assert expected_request == r.request
        assert ("https://domain/sdm_event_snapshot/dGNUlTU2CjY5Y3VKaTZwR3o4Y"
                == image.url)
        assert "g.0.eventToken" == image.token
Exemple #8
0
async def test_auth_refresh_error(aiohttp_server) -> None:
    r = Recorder()

    async def auth_handler(
            request: aiohttp.web.Request) -> aiohttp.web.Response:
        return aiohttp.web.Response(status=401)

    app = aiohttp.web.Application()
    app.router.add_get("/enterprises/project-id1/devices",
                       NewDeviceHandler(r, []))
    app.router.add_get("/refresh-auth", auth_handler)
    server = await aiohttp_server(app)

    async with aiohttp.test_utils.TestClient(server) as client:
        api = google_nest_api.GoogleNestAPI(RefreshingAuth(client), PROJECT_ID)
        with pytest.raises(AuthException):
            await api.async_get_devices()
Exemple #9
0
async def test_thermostat_eco_set_mode(aiohttp_server) -> None:
    r = Recorder()
    handler = NewDeviceHandler(
        r,
        [{
            "name": "enterprises/project-id1/devices/device-id1",
            "traits": {
                "sdm.devices.traits.ThermostatEco": {
                    "availableModes": ["MANUAL_ECO", "OFF"],
                    "mode": "MANUAL_ECO",
                    "heatCelsius": 20.0,
                    "coolCelsius": 22.0,
                },
            },
        }],
    )
    post_handler = NewRequestRecorder(r, [])

    app = aiohttp.web.Application()
    app.router.add_get("/enterprises/project-id1/devices", handler)
    app.router.add_post(
        "/enterprises/project-id1/devices/device-id1:executeCommand",
        post_handler)
    server = await aiohttp_server(app)

    async with aiohttp.test_utils.TestClient(server) as client:
        api = google_nest_api.GoogleNestAPI(FakeAuth(client), PROJECT_ID)
        devices = await api.async_get_devices()
        assert len(devices) == 1
        device = devices[0]
        assert "enterprises/project-id1/devices/device-id1" == device.name
        trait = device.traits["sdm.devices.traits.ThermostatEco"]
        assert trait.mode == "MANUAL_ECO"
        await trait.set_mode("OFF")
        expected_request = {
            "command": "sdm.devices.commands.ThermostatEco.SetMode",
            "params": {
                "mode": "OFF"
            },
        }
        assert expected_request == r.request
Exemple #10
0
async def test_api_post_error(aiohttp_server) -> None:
    r = Recorder()
    handler = NewDeviceHandler(
        r,
        [{
            "name": "enterprises/project-id1/devices/device-id1",
            "traits": {
                "sdm.devices.traits.ThermostatTemperatureSetpoint": {
                    "heatCelsius": 23.0,
                    "coolCelsius": 24.0,
                },
            },
        }],
    )

    async def fail_handler(
            request: aiohttp.web.Request) -> aiohttp.web.Response:
        assert request.headers["Authorization"] == "Bearer %s" % FAKE_TOKEN
        return aiohttp.web.Response(status=502)

    app = aiohttp.web.Application()
    app.router.add_get("/enterprises/project-id1/devices", handler)
    app.router.add_post(
        "/enterprises/project-id1/devices/device-id1:executeCommand",
        fail_handler)
    server = await aiohttp_server(app)

    async with aiohttp.test_utils.TestClient(server) as client:
        api = google_nest_api.GoogleNestAPI(FakeAuth(client), PROJECT_ID)
        devices = await api.async_get_devices()
        assert len(devices) == 1
        device = devices[0]
        assert "enterprises/project-id1/devices/device-id1" == device.name
        trait = device.traits[
            "sdm.devices.traits.ThermostatTemperatureSetpoint"]
        assert trait.heat_celsius == 23.0
        assert trait.cool_celsius == 24.0

        with pytest.raises(ApiException):
            await trait.set_heat(25.0)
Exemple #11
0
async def test_fan_set_timer(aiohttp_server) -> None:
    r = Recorder()
    handler = NewDeviceHandler(
        r,
        [{
            "name": "enterprises/project-id1/devices/device-id1",
            "traits": {
                "sdm.devices.traits.Fan": {
                    "timerMode": "OFF",
                },
            },
        }],
    )
    post_handler = NewHandler(r, [{}])

    app = aiohttp.web.Application()
    app.router.add_get("/enterprises/project-id1/devices", handler)
    app.router.add_post(
        "/enterprises/project-id1/devices/device-id1:executeCommand",
        post_handler)
    server = await aiohttp_server(app)

    async with aiohttp.test_utils.TestClient(server) as client:
        api = google_nest_api.GoogleNestAPI(FakeAuth(client), PROJECT_ID)
        devices = await api.async_get_devices()
        assert len(devices) == 1
        device = devices[0]
        assert "enterprises/project-id1/devices/device-id1" == device.name
        trait = device.traits["sdm.devices.traits.Fan"]
        assert trait.timer_mode == "OFF"
        await trait.set_timer("ON", 3600)
        expected_request = {
            "command": "sdm.devices.commands.Fan.SetTimer",
            "params": {
                "timerMode": "ON",
                "duration": "3600s",
            },
        }
        assert expected_request == r.request
Exemple #12
0
async def test_get_structures(aiohttp_server) -> None:
    r = Recorder()
    handler = NewStructureHandler(
        r,
        [
            {
                "name": "enterprises/project-id1/structures/structure-id1",
                "traits": {
                    "sdm.structures.traits.Info": {
                        "customName": "some-name1",
                    }
                },
            },
            {
                "name": "enterprises/project-id1/structures/structure-id2",
                "traits": {
                    "sdm.structures.traits.Info": {
                        "customName": "some-name2",
                    }
                },
            },
        ],
    )

    app = aiohttp.web.Application()
    app.router.add_get("/enterprises/project-id1/structures", handler)
    server = await aiohttp_server(app)

    async with aiohttp.test_utils.TestClient(server) as client:
        api = google_nest_api.GoogleNestAPI(FakeAuth(client), PROJECT_ID)
        structures = await api.async_get_structures()
        assert len(structures) == 2
        assert "enterprises/project-id1/structures/structure-id1" == structures[
            0].name
        assert "sdm.structures.traits.Info" in structures[0].traits
        assert "enterprises/project-id1/structures/structure-id2" == structures[
            1].name
        assert "sdm.structures.traits.Info" in structures[1].traits
Exemple #13
0
async def test_camera_live_stream(aiohttp_server) -> None:
    r = Recorder()
    handler = NewDeviceHandler(
        r,
        [{
            "name": "enterprises/project-id1/devices/device-id1",
            "traits": {
                "sdm.devices.traits.CameraLiveStream": {},
            },
        }],
    )

    post_handler = NewRequestRecorder(
        r,
        [
            {
                "results": {
                    "streamUrls": {
                        "rtsp_url":
                        "rtsps://someurl.com/CjY5Y3VKaTZwR3o4Y19YbTVfMF...?auth=g.0.streamingToken"
                    },
                    "streamExtensionToken": "CjY5Y3VKaTZwR3o4Y19YbTVfMF...",
                    "streamToken": "g.0.streamingToken",
                    "expiresAt": "2018-01-04T18:30:00.000Z",
                },
            },
            {
                "results": {
                    "streamExtensionToken": "dGNUlTU2CjY5Y3VKaTZwR3o4Y1...",
                    "streamToken": "g.1.newStreamingToken",
                    "expiresAt": "2019-01-04T18:30:00.000Z",
                }
            },
            {
                "results": {
                    "streamExtensionToken": "last-token...",
                    "streamToken": "g.2.newStreamingToken",
                    "expiresAt": "2020-01-04T18:30:00.000Z",
                }
            },
            {},
        ],
    )
    app = aiohttp.web.Application()
    app.router.add_get("/enterprises/project-id1/devices", handler)
    app.router.add_post(
        "/enterprises/project-id1/devices/device-id1:executeCommand",
        post_handler)
    server = await aiohttp_server(app)

    async with aiohttp.test_utils.TestClient(server) as client:
        api = google_nest_api.GoogleNestAPI(FakeAuth(client), PROJECT_ID)
        devices = await api.async_get_devices()
        assert len(devices) == 1
        device = devices[0]
        assert "enterprises/project-id1/devices/device-id1" == device.name
        trait = device.traits["sdm.devices.traits.CameraLiveStream"]
        stream = await trait.generate_rtsp_stream()
        expected_request = {
            "command":
            "sdm.devices.commands.CameraLiveStream.GenerateRtspStream",
            "params": {},
        }
        assert expected_request == r.request
        assert "g.0.streamingToken" == stream.stream_token
        assert (datetime.datetime(
            2018, 1, 4, 18, 30,
            tzinfo=datetime.timezone.utc) == stream.expires_at)

        stream = await stream.extend_rtsp_stream()
        expected_request = {
            "command":
            "sdm.devices.commands.CameraLiveStream.ExtendRtspStream",
            "params": {
                "streamExtensionToken": "CjY5Y3VKaTZwR3o4Y19YbTVfMF...",
            },
        }
        assert expected_request == r.request
        assert "g.1.newStreamingToken" == stream.stream_token
        assert (datetime.datetime(
            2019, 1, 4, 18, 30,
            tzinfo=datetime.timezone.utc) == stream.expires_at)

        stream = await stream.extend_rtsp_stream()
        expected_request = {
            "command":
            "sdm.devices.commands.CameraLiveStream.ExtendRtspStream",
            "params": {
                "streamExtensionToken": "dGNUlTU2CjY5Y3VKaTZwR3o4Y1...",
            },
        }
        assert expected_request == r.request
        assert "g.2.newStreamingToken" == stream.stream_token
        assert (datetime.datetime(
            2020, 1, 4, 18, 30,
            tzinfo=datetime.timezone.utc) == stream.expires_at)

        await stream.stop_rtsp_stream()
        expected_request = {
            "command": "sdm.devices.commands.CameraLiveStream.StopRtspStream",
            "params": {
                "streamExtensionToken": "last-token...",
            },
        }
        assert expected_request == r.request
Exemple #14
0
async def test_thermostat_temperature_set_point(aiohttp_server) -> None:
    r = Recorder()
    handler = NewDeviceHandler(
        r,
        [{
            "name": "enterprises/project-id1/devices/device-id1",
            "traits": {
                "sdm.devices.traits.ThermostatTemperatureSetpoint": {
                    "heatCelsius": 23.0,
                    "coolCelsius": 24.0,
                },
            },
        }],
    )
    post_handler = NewRequestRecorder(r, [])

    app = aiohttp.web.Application()
    app.router.add_get("/enterprises/project-id1/devices", handler)
    app.router.add_post(
        "/enterprises/project-id1/devices/device-id1:executeCommand",
        post_handler)
    server = await aiohttp_server(app)

    async with aiohttp.test_utils.TestClient(server) as client:
        api = google_nest_api.GoogleNestAPI(FakeAuth(client), PROJECT_ID)
        devices = await api.async_get_devices()
        assert len(devices) == 1
        device = devices[0]
        assert "enterprises/project-id1/devices/device-id1" == device.name
        trait = device.traits[
            "sdm.devices.traits.ThermostatTemperatureSetpoint"]
        assert trait.heat_celsius == 23.0
        assert trait.cool_celsius == 24.0
        await trait.set_heat(25.0)
        expected_request = {
            "command":
            "sdm.devices.commands.ThermostatTemperatureSetpoint.SetHeat",
            "params": {
                "heatCelsius": 25.0
            },
        }
        assert expected_request == r.request

        await trait.set_cool(26.0)
        expected_request = {
            "command":
            "sdm.devices.commands.ThermostatTemperatureSetpoint.SetCool",
            "params": {
                "coolCelsius": 26.0
            },
        }
        assert expected_request == r.request

        await trait.set_range(27.0, 28.0)
        expected_request = {
            "command":
            "sdm.devices.commands.ThermostatTemperatureSetpoint.SetRange",
            "params": {
                "heatCelsius": 27.0,
                "coolCelsius": 28.0,
            },
        }
        assert expected_request == r.request