From 5fa31119d54d8a7914ac78abe6862d621f0c9ad1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Schl=C3=BCter?= Date: Tue, 26 Mar 2024 11:50:49 +0100 Subject: [PATCH] Fixed unit tests --- package-lock.json | 4 +- src/index.ts | 4 +- src/nightscout/apiv1.ts | 110 ++++++++++--------- tests/setup.js | 1 + tests/unit-tests/librelink/librelink.test.ts | 31 +++--- 5 files changed, 84 insertions(+), 66 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1983ec0..fd1f46e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "nightscout-librelink-up", - "version": "2.4.1", + "version": "2.5.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "nightscout-librelink-up", - "version": "2.4.1", + "version": "2.5.0", "license": "MIT", "dependencies": { "axios": "^1.4.0", diff --git a/src/index.ts b/src/index.ts index dc3e9a1..318b5d6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -294,11 +294,11 @@ async function uploadToNightScout(measurementData: GraphData): Promise if (formattedMeasurements.length > 0) { logger.info("Trying to upload " + formattedMeasurements.length + " glucose measurement items to Nightscout"); - try + try { await nightscoutClient.uploadEntries(formattedMeasurements); logger.info("Upload of " + formattedMeasurements.length + " measurements to Nightscout succeeded"); - } catch (error) + } catch (error) { logger.error("Upload to NightScout failed ", error); } diff --git a/src/nightscout/apiv1.ts b/src/nightscout/apiv1.ts index 213b36a..0ffaf80 100644 --- a/src/nightscout/apiv1.ts +++ b/src/nightscout/apiv1.ts @@ -1,53 +1,65 @@ -import { Entry, NightscoutAPI, NightscoutConfig } from './interface'; -import { OutgoingHttpHeaders } from 'http'; -import axios from 'axios'; +import {Entry, NightscoutAPI, NightscoutConfig} from "./interface"; +import {OutgoingHttpHeaders} from "http"; +import axios from "axios"; -interface NightscoutHttpHeaders extends OutgoingHttpHeaders { - 'api-secret': string | undefined; +interface NightscoutHttpHeaders extends OutgoingHttpHeaders +{ + "api-secret": string | undefined; } -export class Client implements NightscoutAPI { - readonly baseUrl: string; - readonly headers: NightscoutHttpHeaders; - readonly device: string; - - constructor(config: NightscoutConfig) { - this.baseUrl = config.nightscoutBaseUrl; - this.headers = { - 'api-secret': config.nightscoutApiToken, - 'User-Agent': 'FreeStyle LibreLink Up NightScout Uploader', - 'Content-Type': 'application/json', - }; - this.device = config.nightscoutDevice; - } - - async lastEntry(): Promise { - const url = new URL('/api/v1/entries?count=1', this.baseUrl).toString(); - const resp = await axios.get(url, { headers: this.headers }); - if (resp.status !== 200) { - throw Error(`failed to get last entry: ${resp.statusText}`); - } - if (!resp.data || resp.data.length === 0) { - return null; - } - return resp.data.pop(); - } - - async uploadEntries(entries: Entry[]): Promise { - const url = new URL('/api/v1/entries', this.baseUrl).toString(); - const entriesV1 = entries.map((e) => ({ - type: 'sgv', - sgv: e.sgv, - direction: e.direction?.toString(), - device: this.device, - date: e.date.getTime(), - dateString: e.date.toISOString(), - })); - const resp = await axios.post(url, entriesV1, { headers: this.headers }); - if (resp.status !== 200) { - throw Error(`failed to post new entries: ${resp.statusText}`); - } - - return; - } +export class Client implements NightscoutAPI +{ + readonly baseUrl: string; + readonly headers: NightscoutHttpHeaders; + readonly device: string; + + constructor(config: NightscoutConfig) + { + this.baseUrl = config.nightscoutBaseUrl; + this.headers = { + "api-secret": config.nightscoutApiToken, + "User-Agent": "FreeStyle LibreLink Up NightScout Uploader", + "Content-Type": "application/json", + }; + this.device = config.nightscoutDevice; + } + + async lastEntry(): Promise + { + const url = new URL("/api/v1/entries?count=1", this.baseUrl).toString(); + const resp = await axios.get(url, {headers: this.headers}); + + if (resp.status !== 200) + { + throw Error(`failed to get last entry: ${resp.statusText}`); + } + + if (!resp.data || resp.data.length === 0) + { + return null; + } + return resp.data.pop(); + } + + async uploadEntries(entries: Entry[]): Promise + { + const url = new URL("/api/v1/entries", this.baseUrl).toString(); + const entriesV1 = entries.map((e) => ({ + type: "sgv", + sgv: e.sgv, + direction: e.direction?.toString(), + device: this.device, + date: e.date.getTime(), + dateString: e.date.toISOString(), + })); + + const resp = await axios.post(url, entriesV1, {headers: this.headers}); + + if (resp.status !== 200) + { + throw Error(`failed to post new entries: ${resp.statusText}`); + } + + return; + } } diff --git a/tests/setup.js b/tests/setup.js index a016113..97d09a1 100644 --- a/tests/setup.js +++ b/tests/setup.js @@ -1,3 +1,4 @@ process.env.SINGLE_SHOT="true"; process.env.NIGHTSCOUT_URL="localhost:1337"; process.env.NIGHTSCOUT_DISABLE_HTTPS="true"; +process.env.NIGHTSCOUT_API_TOKEN="abcdefg"; diff --git a/tests/unit-tests/librelink/librelink.test.ts b/tests/unit-tests/librelink/librelink.test.ts index 873e403..32ddb00 100644 --- a/tests/unit-tests/librelink/librelink.test.ts +++ b/tests/unit-tests/librelink/librelink.test.ts @@ -7,12 +7,13 @@ import { } from "../../../src"; import axios from "axios"; import MockAdapter from "axios-mock-adapter"; + const mock = new MockAdapter(axios); -import { default as loginSuccessResponse } from "../../data/login.json"; -import { default as loginFailedResponse } from "../../data/login-failed.json"; -import { default as connectionsResponse } from "../../data/connections.json"; -import { default as entriesResponse } from "../../data/entries.json"; -import { default as graphResponse } from "../../data/graph.json"; +import {default as loginSuccessResponse} from "../../data/login.json"; +import {default as loginFailedResponse} from "../../data/login-failed.json"; +import {default as connectionsResponse} from "../../data/connections.json"; +import {default as entriesResponse} from "../../data/entries.json"; +import {default as graphResponse} from "../../data/graph.json"; import {AuthTicket} from "../../../src/interfaces/librelink/common"; import {GraphData} from "../../../src/interfaces/librelink/graph-response"; import {Entry} from "../../../src/nightscout/interface"; @@ -20,16 +21,20 @@ import {Entry} from "../../../src/nightscout/interface"; mock.onPost("https://api-eu.libreview.io/llu/auth/login").reply(200, loginSuccessResponse); mock.onGet("https://api-eu.libreview.io/llu/connections").reply(200, connectionsResponse); mock.onGet("https://api-eu.libreview.io/llu/connections/7ad66b40-ba9b-401e-9845-4f49f998cf16/graph").reply(200, graphResponse); +mock.onGet("http://localhost:1337/api/v1/entries?count=1").reply(200, []); -describe("LibreLink Up", () => { +describe("LibreLink Up", () => +{ const env = process.env - beforeEach(() => { + beforeEach(() => + { jest.resetModules() - process.env = { ...env } + process.env = {...env} }) - afterEach(() => { + afterEach(() => + { process.env = env }) @@ -89,11 +94,11 @@ describe("LibreLink Up", () => { const formattedMeasurements: Entry[] = await createFormattedMeasurements(glucoseMeasurements); expect(formattedMeasurements.length).toBe(142); - expect(formattedMeasurements[0].date).toBe(1672418860000); + expect(formattedMeasurements[0].date.getTime()).toBe(1672418860000); expect(formattedMeasurements[0].direction).toBe("Flat"); expect(formattedMeasurements[0].sgv).toBe(115); - expect(formattedMeasurements[1].date).toBe(1672375840000); + expect(formattedMeasurements[1].date.getTime()).toBe(1672375840000); expect(formattedMeasurements[1]).not.toHaveProperty("direction"); expect(formattedMeasurements[1].sgv).toBe(173); }); @@ -110,11 +115,11 @@ describe("LibreLink Up", () => { const formattedMeasurements: Entry[] = await createFormattedMeasurements(glucoseMeasurements); expect(formattedMeasurements.length).toBe(112); - expect(formattedMeasurements[0].date).toBe(1672418860000); + expect(formattedMeasurements[0].date.getTime()).toBe(1672418860000); expect(formattedMeasurements[0].direction).toBe("Flat"); expect(formattedMeasurements[0].sgv).toBe(115); - expect(formattedMeasurements[1].date).toBe(1672384839000); + expect(formattedMeasurements[1].date.getTime()).toBe(1672384839000); expect(formattedMeasurements[1]).not.toHaveProperty("direction"); expect(formattedMeasurements[1].sgv).toBe(177); });