UNPKG

eightsleep

Version:
593 lines (570 loc) 18 kB
import EightSleep, { OptsType } from '..' import MockEightAppAPIServer, { PORT as appAPIServerPort, } from './__fixtures__/MockEightAppAPIServer' import MockEightClientAPIServer, { PORT as clientAPIServerPort, } from './__fixtures__/MockEightClientAPIServer' import { Sides } from './../EightSleepAppApi' const email = process.env.EMAIL || 'owner@email.com' const password = process.env.PASSWORD || 'ownerpassword' const oauthClient = { id: process.env.OAUTH_CLIENT_ID || '1234567890abcdef1234567890123456', secret: process.env.OAUTH_CLIENT_SECRET || '1234567890123456789012345678901234567890234567890123456789012345', } function createEightSleep(customAuth?: { email: OptsType['email'] password: OptsType['password'] }) { const eightSleep = new EightSleep({ email: customAuth?.email || email, password: customAuth?.password || password, oauthClient, }) if (!process.env.REAL_API) { // hack so request hit mock api servers // @ts-ignore eightSleep.host = `http://localhost:${clientAPIServerPort}` const appApi = eightSleep.getAppApiClient() // @ts-ignore appApi.host = `http://localhost:${appAPIServerPort}` } return eightSleep } describe('eightsleep', () => { const clientServer = new MockEightClientAPIServer() const appServer = new MockEightAppAPIServer() beforeEach(async () => { await clientServer.start() await appServer.start() }) afterEach(async () => { await clientServer.stop() await appServer.stop() }) it('should not login with invalid credentials', async () => { const e = createEightSleep({ email, password: password + password, }) await expect(async () => { await e.login() }).rejects.toMatchInlineSnapshot(`[StatusCodeError: unexpected status]`) }) it('should login', async () => { const e = createEightSleep() const session = await e.login() expect(session).toMatchInlineSnapshot(` Object { "expirationDate": 3020-06-30T05:40:30.880Z, "token": "1234567890abcdef1234567890abcdef-1234567890abcdef1234567890abcdef", "userId": "1234567890abcdef123456789011111", } `) }) it('should get me', async () => { const e = createEightSleep() await e.login() const me = await e.getMe() expect(me).toMatchInlineSnapshot(` Object { "currentDevice": Object { "id": "123456789012345678901234", "side": "left", }, "devices": Array [ "123456789012345678901234", ], "dob": 1900-04-01T08:34:30.000Z, "email": "owner@email.com", "emailVerified": true, "features": Array [ "warming", "cooling", ], "firstName": "Owner", "gender": "male", "lastName": "Person", "notifications": Object { "sessionProcessed": true, "weeklyReportEmail": true, }, "sharingMetricsFrom": Array [ "1234567890abcdef123456789022222", ], "sharingMetricsTo": Array [ "1234567890abcdef123456789022222", ], "timezone": "America/Los_Angeles", "userId": "1234567890abcdef123456789011111", "zip": 11111, } `) }) it('should get a device', async () => { const e = createEightSleep() await e.login() const me = await e.getDevice('123456789012345678901234') expect(me).toMatchInlineSnapshot(` Object { "deviceId": "123456789012345678901234", "features": Array [ "warming", "cooling", ], "firmwareUpdated": true, "firmwareUpdating": false, "firmwareVersion": "2.3.18.0", "hasWater": true, "hubInfo": "12345-0001-A01-AABBCCDD", "lastHeard": 2020-06-21T03:36:57.441Z, "lastLowWater": 2020-03-04T21:10:38.334Z, "lastPrime": 2020-03-04T21:11:23.746Z, "ledBrightnessLevel": 30, "leftHeatingDuration": 0, "leftHeatingLevel": -15, "leftKelvin": Object { "active": false, "alarms": Array [], "currentActivity": "off", "currentTargetLevel": 0, "level": 0, "scheduleProfiles": Array [ Object { "enabled": true, "startLocalTime": "22:00:00", "weekDays": Object { "friday": true, "monday": true, "saturday": true, "sunday": true, "thursday": true, "tuesday": true, "wednesday": true, }, }, ], "targetLevels": Array [ -10, -10, -20, ], }, "leftNowHeating": false, "leftSchedule": Object { "daysUTC": Object { "friday": false, "monday": false, "saturday": false, "sunday": false, "thursday": false, "tuesday": false, "wednesday": false, }, "durationSeconds": 0, "enabled": false, "startUTCHour": 0, "startUTCMinute": 0, }, "leftTargetHeatingLevel": 0, "leftUserId": "1234567890abcdef123456789011111", "location": Array [ -122.32171311, 37.55987324, ], "mattressInfo": Object { "brand": null, "eightMattress": null, "firstUsedDate": null, }, "needsPriming": false, "online": true, "ownerId": "1234567890abcdef123456789011111", "priming": false, "rightHeatingDuration": 3575, "rightHeatingLevel": 21, "rightKelvin": Object { "active": true, "alarms": Array [], "currentActivity": "schedule", "currentTargetLevel": 50, "level": 50, "phases": Array [ Object { "active": false, "operation": "on", "position": 0, }, Object { "active": true, "level": 50, "operation": "temperature", "position": 0, }, Object { "active": false, "level": 10, "operation": "temperature", "position": 0.33, }, Object { "active": false, "level": 30, "operation": "temperature", "position": 0.67, }, Object { "active": false, "operation": "off", "position": 1, }, ], "scheduleProfiles": Array [ Object { "enabled": true, "startLocalTime": "21:30:00", "weekDays": Object { "friday": true, "monday": true, "saturday": true, "sunday": true, "thursday": true, "tuesday": true, "wednesday": true, }, }, ], "targetLevels": Array [ 50, 10, 30, ], }, "rightNowHeating": true, "rightSchedule": Object { "daysUTC": Object { "friday": false, "monday": false, "saturday": false, "sunday": false, "thursday": false, "tuesday": false, "wednesday": false, }, "durationSeconds": 0, "enabled": false, "startUTCHour": 0, "startUTCMinute": 0, }, "rightTargetHeatingLevel": 50, "rightUserId": "1234567890abcdef123456789022222", "sensorInfo": Object { "connected": true, "hwRevision": "A01", "label": "12345-0001-A01-00000000", "lastConnected": 2020-06-21T03:36:57.441Z, "partNumber": "12345", "serialNumber": "00000000", "sku": "0001", "skuName": "queen", }, "timezone": "America/Los_Angeles", } `) }) it('should get a device', async () => { const e = createEightSleep() await e.login() const me = await e.getDevice('123456789012345678901234', { filter: 'sensorInfo', }) expect(me).toMatchInlineSnapshot(` Object { "sensorInfo": Object { "connected": true, "hwRevision": "A01", "label": "12345-0001-A01-00000000", "lastConnected": "2020-06-21T03:36:57.441Z", "partNumber": "12345", "serialNumber": "00000000", "sku": "0001", "skuName": "queen", }, } `) }) it('should get a device w/ filter', async () => { const e = createEightSleep() await e.login() const me = await e.getMe() const device = await e.getDevice(me.currentDevice.id, { filter: 'deviceId', }) expect(device).toMatchInlineSnapshot(` Object { "deviceId": "123456789012345678901234", } `) }) it('should get owner user by id', async () => { const e = createEightSleep() await e.login() const me = await e.getUser('1234567890abcdef123456789011111') expect(me).toMatchInlineSnapshot(` Object { "currentDevice": Object { "id": "123456789012345678901234", "side": "left", }, "devices": Array [ "123456789012345678901234", ], "dob": 1900-04-01T08:34:30.000Z, "email": "owner@email.com", "emailVerified": true, "features": Array [ "warming", "cooling", ], "firstName": "Owner", "gender": "male", "lastName": "Person", "notifications": Object { "sessionProcessed": true, "weeklyReportEmail": true, }, "sharingMetricsFrom": Array [ "1234567890abcdef123456789022222", ], "sharingMetricsTo": Array [ "1234567890abcdef123456789022222", ], "timezone": "America/Los_Angeles", "userId": "1234567890abcdef123456789011111", "zip": 11111, } `) }) it('should get partner user by id', async () => { const e = createEightSleep() await e.login() const me = await e.getUser('1234567890abcdef123456789022222') expect(me).toMatchInlineSnapshot(` Object { "currentDevice": Object { "id": "123456789012345678901234", "side": "right", }, "devices": Array [ "123456789012345678901234", ], "dob": 1900-10-26T08:34:30.000Z, "email": "partner@email.com", "emailVerified": true, "features": Array [ "warming", "cooling", ], "firstName": "Partner", "gender": "female", "lastName": "Person", "notifications": Object { "sessionProcessed": true, "weeklyReportEmail": true, }, "sharingMetricsFrom": Array [ "1234567890abcdef123456789011111", ], "sharingMetricsTo": Array [ "1234567890abcdef123456789011111", ], "timezone": "America/Los_Angeles", "userId": "1234567890abcdef123456789022222", "zip": 11111, } `) }) it('should get oauth tokens', async () => { const e = createEightSleep() await e.login() const oauth = await e.oauth() expect(oauth).toMatchInlineSnapshot(` Object { "accessToken": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZiIsImlzcyI6ImVpZ2h0OnYxIiwiYXVkIjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJzdWIiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImV4cCI6MTU5NDU4ODE2OSwic2NvIjpbInJlYWRfc2xlZXAiLCJ3cml0ZV9zbGVlcCIsInJlYWRfZGV2aWNlIiwid3JpdGVfZGV2aWNlIl0sInR5cCI6ImF1dGgiLCJpYXQiOjE1OTQ1MDE3Njl9.2odxApSPTrELwtTlIRtJeek8ke96sWcbxvDGJLcgEehXeNRGIrUPnqwHLjI6gsyregEJ6wetF8qtHB7MCu_b-A", "expiresIn": 2020-07-11T21:10:38.035Z, "refreshToken": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZiIsImlzcyI6ImVpZ2h0OnYxIiwiYXVkIjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJzdWIiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImV4cCI6MTU5NDU4ODE2OSwic2NvIjpbInJlYWRfc2xlZXAiLCJ3cml0ZV9zbGVlcCIsInJlYWRfZGV2aWNlIiwid3JpdGVfZGV2aWNlIl0sInR5cCI6ImF1dGgiLCJpYXQiOjE1OTQ1MDE3Njl9.l3XCxV4Sy_Bbg8398p8I5a4sAgiVt8pU2gxTLRpIrlfMrf0IGeRsvIVWC4UzcWUlwfn-RwANnAJ6Y-38K7yoAA", "tokenType": "bearer", } `) }) describe('appApi', () => { it('should get device status', async () => { const e = createEightSleep() await e.login() const appApi = e.getAppApiClient() const status = await appApi.getDeviceStatus('123456789012345678901234') expect(status).toMatchInlineSnapshot(` Object { "left": Object { "currentActivity": "off", "currentLevel": -29, "currentTargetLevel": 0, "version": 2, }, "right": Object { "currentActivity": "off", "currentLevel": -33, "currentTargetLevel": 0, "version": 2, }, } `) }) it('should turn device side off', async () => { const e = createEightSleep() await e.login() const appApi = e.getAppApiClient() const status = await appApi.setDeviceSideOff( '123456789012345678901234', Sides.LEFT, ) expect(status).toMatchInlineSnapshot(` Object { "left": Object { "currentActivity": "off", "currentLevel": -33, "currentTargetLevel": 0, "version": 2, }, "right": Object { "currentActivity": "off", "currentLevel": -33, "currentTargetLevel": 0, "version": 2, }, } `) }) it('should turn device side on', async () => { const e = createEightSleep() await e.login() const appApi = e.getAppApiClient() const status = await appApi.setDeviceSideOn( '123456789012345678901234', Sides.LEFT, ) expect(status).toMatchInlineSnapshot(` Object { "left": Object { "currentActivity": "schedule", "currentLevel": -31, "currentTargetLevel": 10, "smartTemperature": Object { "bedLocalTime": "00:00:00", "bedTimeLevel": 10, "currentPhase": "bedtime", "finalSleepLevel": -10, "initialSleepLevel": -10, }, "version": 2, }, "right": Object { "currentActivity": "off", "currentLevel": -33, "currentTargetLevel": 0, "version": 2, }, } `) }) it('should set device side temperature (while off)', async () => { const e = createEightSleep() await e.login() const appApi = e.getAppApiClient() await appApi.setDeviceSideOff('123456789012345678901234', Sides.LEFT) const status = await appApi.setDeviceSideLevel( '123456789012345678901234', Sides.LEFT, 10, ) expect(status).toMatchInlineSnapshot(` Object { "left": Object { "currentActivity": "off", "currentLevel": -33, "currentTargetLevel": 0, "version": 2, }, "right": Object { "currentActivity": "off", "currentLevel": -33, "currentTargetLevel": 0, "version": 2, }, } `) }) it('should set device side temperature (while on)', async () => { const e = createEightSleep() await e.login() const appApi = e.getAppApiClient() await appApi.setDeviceSideOn('123456789012345678901234', Sides.LEFT) const status = await appApi.setDeviceSideLevel( '123456789012345678901234', Sides.LEFT, 10, ) expect(status).toMatchInlineSnapshot(` Object { "left": Object { "currentActivity": "schedule", "currentLevel": -31, "currentTargetLevel": 10, "smartTemperature": Object { "bedLocalTime": "00:00:00", "bedTimeLevel": 10, "currentPhase": "bedtime", "finalSleepLevel": -10, "initialSleepLevel": -10, }, "version": 2, }, "right": Object { "currentActivity": "off", "currentLevel": -33, "currentTargetLevel": 0, "version": 2, }, } `) }) if (process.env.REAL_API) { it.only('test', async () => { const e = createEightSleep() await e.login() const me = await e.getMe() const appApi = e.getAppApiClient() const json = await e.getDevice(me.currentDevice.id) // const json = await appApi.get( // 'v1/devices/' + // me.currentDevice.id + // '/metrics/ambient?granularity=minute&from=2020-07-19T10:20:59.495Z&scope=humidity&scope=roomTemperature', // { // headers: { // 'user-agent': 'Eight/786 CFNetwork/1125.2 Darwin/19.4.0', // 'accept-language': 'en-us', // 'accept-encoding': 'gzip, deflate, br', // accept: 'application/json', // 'user-id': '1234567890abcdef123456789011111', // 'session-token': // '1234567890abcdef1234567890abcdef-1234567890abcdef1234567890abcdef', // }, // }, // ) console.log(JSON.stringify(json, null, 2)) }) } }) })