From 937bafc3f08fadb793c7f089ce6bd2cd54677ae6 Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Mon, 30 Sep 2019 19:10:11 +0100 Subject: [PATCH] Add tests for API functions --- jest.config.js | 1 + package.json | 1 + tests/api.test.js | 219 ++++++++++++++++++++++++++++++++++++++++++++++ tests/setup.js | 1 + yarn.lock | 31 +++++++ 5 files changed, 253 insertions(+) create mode 100644 tests/api.test.js create mode 100644 tests/setup.js diff --git a/jest.config.js b/jest.config.js index 9ec7c9a..be348f2 100644 --- a/jest.config.js +++ b/jest.config.js @@ -19,4 +19,5 @@ module.exports = { "jest-watch-typeahead/filename", "jest-watch-typeahead/testname", ], + setupFiles: ["/tests/setup.js"], }; diff --git a/package.json b/package.json index 193d085..19d0c0b 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "eslint": "^6.4.0", "eslint-plugin-prettier": "^3.1.1", "eslint-plugin-vue": "^5.2.3", + "jest-fetch-mock": "^2.1.2", "lint-staged": "^9.4.0", "node-sass": "^4.12.0", "sass-loader": "^8.0.0", diff --git a/tests/api.test.js b/tests/api.test.js new file mode 100644 index 0000000..9ecc058 --- /dev/null +++ b/tests/api.test.js @@ -0,0 +1,219 @@ +import * as api from "@/api"; + +describe("API", () => { + beforeEach(() => { + fetch.resetMocks(); + }); + + test("getVersion", async () => { + fetch.mockResponse(JSON.stringify({ version: "1.2.3" })); + + const version = await api.getVersion(); + expect(version).toBe("1.2.3"); + + expect(fetch.mock.calls.length).toEqual(1); + expect(fetch.mock.calls[0][0].href).toEqual( + "http://localhost/api/0/version" + ); + }); + + test("getUsers", async () => { + fetch.mockResponse(JSON.stringify({ results: ["foo", "bar"] })); + + const users = await api.getUsers(); + expect(users).toEqual(["foo", "bar"]); + + expect(fetch.mock.calls.length).toEqual(1); + expect(fetch.mock.calls[0][0].href).toEqual("http://localhost/api/0/list"); + }); + + test("getDevices", async () => { + fetch.mockResponses( + [JSON.stringify({ results: ["phone", "tablet"] })], + [JSON.stringify({ results: ["laptop"] })] + ); + + const devices = await api.getDevices(["foo", "bar"]); + expect(devices).toEqual({ foo: ["phone", "tablet"], bar: ["laptop"] }); + + expect(fetch.mock.calls.length).toEqual(2); + expect(fetch.mock.calls[0][0].href).toEqual( + "http://localhost/api/0/list?user=foo" + ); + expect(fetch.mock.calls[1][0].href).toEqual( + "http://localhost/api/0/list?user=bar" + ); + }); + + test("getLastLocations", async () => { + const response = [ + { + _type: "location", + tid: "pp", + lat: 51.47879, + lon: -0.010677, + tst: 0, + _http: true, + topic: "owntracks/ping/ping", + username: "ping", + device: "ping", + ghash: "gcpuzg2", + isotst: "1970-01-01T00:00:00Z", + disptst: "1970-01-01 00:00:00", + }, + ]; + fetch.mockResponse(JSON.stringify(response)); + + const lastLocation = await api.getLastLocations(); + expect(lastLocation).toEqual(response); + + expect(fetch.mock.calls.length).toEqual(1); + expect(fetch.mock.calls[0][0].href).toEqual("http://localhost/api/0/last"); + }); + + test("getLastLocations with user", async () => { + const response = [ + // Other properties not relevant for testing + { + username: "foo", + device: "phone", + }, + { + username: "foo", + device: "tablet", + }, + ]; + fetch.mockResponse(JSON.stringify(response)); + + const lastLocation = await api.getLastLocations("foo"); + expect(lastLocation).toEqual(response); + + expect(fetch.mock.calls.length).toEqual(1); + expect(fetch.mock.calls[0][0].href).toEqual( + "http://localhost/api/0/last?user=foo" + ); + }); + + test("getLastLocations with user and device", async () => { + const response = [ + // Other properties not relevant for testing + { + username: "foo", + device: "phone", + }, + ]; + fetch.mockResponse(JSON.stringify(response)); + + const lastLocation = await api.getLastLocations("foo", "phone"); + expect(lastLocation).toEqual(response); + + expect(fetch.mock.calls.length).toEqual(1); + expect(fetch.mock.calls[0][0].href).toEqual( + "http://localhost/api/0/last?user=foo&device=phone" + ); + }); + + test("getUserDeviceLocationHistory", async () => { + const response = { + count: 1, + data: [ + { + batt: 100, + lon: -0.010677, + acc: 20, + bs: 1, + vac: 10, + topic: "owntracks/foo/phone", + lat: 51.47879, + conn: "w", + tst: 1568841029, + alt: 31, + _type: "location", + tid: "AD", + _http: true, + ghash: "gcpv4k9", + isorcv: "2019-09-18T21:10:29Z", + isotst: "2019-09-18T21:10:29Z", + disptst: "2019-09-18 21:10:29", + }, + ], + status: 200, + }; + fetch.mockResponse(JSON.stringify(response)); + + const locationHistory = await api.getUserDeviceLocationHistory( + "foo", + "phone", + new Date(1970, 1, 1), + new Date(1970, 12, 31) + ); + expect(locationHistory).toEqual(response.data); + + expect(fetch.mock.calls.length).toEqual(1); + expect(fetch.mock.calls[0][0].href).toEqual( + "http://localhost/api/0/locations?from=1970-01-31T00%3A00%3A00&to=1971-01-30T23%3A59%3A59&user=foo&device=phone&format=json" + ); + }); + + test("getLocationHistory", async () => { + fetch.mockResponses( + [ + JSON.stringify({ + count: 1, + data: [ + { + topic: "owntracks/foo/phone", + }, + ], + status: 200, + }), + ], + [ + JSON.stringify({ + count: 1, + data: [ + { + topic: "owntracks/foo/tablet", + }, + ], + status: 200, + }), + ], + [ + JSON.stringify({ + count: 1, + data: [ + { + topic: "owntracks/bar/laptop", + }, + ], + status: 200, + }), + ] + ); + + const locationHistory = await api.getLocationHistory( + { foo: ["phone", "tablet"], bar: ["laptop"] }, + new Date(1970, 1, 1), + new Date(1970, 12, 31) + ); + expect(locationHistory).toEqual({ + foo: { + phone: [{ topic: "owntracks/foo/phone" }], + tablet: [{ topic: "owntracks/foo/tablet" }], + }, + bar: { laptop: [{ topic: "owntracks/bar/laptop" }] }, + }); + + expect(fetch.mock.calls.length).toEqual(3); + expect(fetch.mock.calls[0][0].href).toEqual( + "http://localhost/api/0/locations?from=1970-01-31T00%3A00%3A00&to=1971-01-30T23%3A59%3A59&user=foo&device=phone&format=json" + ); + expect(fetch.mock.calls[1][0].href).toEqual( + "http://localhost/api/0/locations?from=1970-01-31T00%3A00%3A00&to=1971-01-30T23%3A59%3A59&user=foo&device=tablet&format=json" + ); + expect(fetch.mock.calls[2][0].href).toEqual( + "http://localhost/api/0/locations?from=1970-01-31T00%3A00%3A00&to=1971-01-30T23%3A59%3A59&user=bar&device=laptop&format=json" + ); + }); +}); diff --git a/tests/setup.js b/tests/setup.js new file mode 100644 index 0000000..52ec116 --- /dev/null +++ b/tests/setup.js @@ -0,0 +1 @@ +global.fetch = require("jest-fetch-mock"); diff --git a/yarn.lock b/yarn.lock index e33ad4e..c5965ad 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2966,6 +2966,14 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: safe-buffer "^5.0.1" sha.js "^2.4.8" +cross-fetch@^2.2.2: + version "2.2.3" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-2.2.3.tgz#e8a0b3c54598136e037f8650f8e823ccdfac198e" + integrity sha512-PrWWNH3yL2NYIb/7WF/5vFG3DCQiXDOVf8k3ijatbrtnwNuhMWLC7YF7uqf53tbTFDzHIUD8oITw4Bxt8ST3Nw== + dependencies: + node-fetch "2.1.2" + whatwg-fetch "2.0.4" + cross-spawn@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-3.0.1.tgz#1256037ecb9f0c5f79e3d6ef135e30770184b982" @@ -6056,6 +6064,14 @@ jest-environment-node@^23.4.0: jest-mock "^23.2.0" jest-util "^23.4.0" +jest-fetch-mock@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/jest-fetch-mock/-/jest-fetch-mock-2.1.2.tgz#1260b347918e3931c4ec743ceaf60433da661bd0" + integrity sha512-tcSR4Lh2bWLe1+0w/IwvNxeDocMI/6yIA2bijZ0fyWxC4kQ18lckQ1n7Yd40NKuisGmcGBRFPandRXrW/ti/Bw== + dependencies: + cross-fetch "^2.2.2" + promise-polyfill "^7.1.1" + jest-get-type@^22.1.0: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.4.3.tgz#e3a8504d8479342dd4420236b322869f18900ce4" @@ -7308,6 +7324,11 @@ node-cache@^4.1.1: clone "2.x" lodash "^4.17.15" +node-fetch@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5" + integrity sha1-q4hOjn5X44qUR1POxwb3iNF2i7U= + node-forge@0.7.5: version "0.7.5" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.5.tgz#6c152c345ce11c52f465c2abd957e8639cd674df" @@ -8563,6 +8584,11 @@ promise-inflight@^1.0.1: resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= +promise-polyfill@^7.1.1: + version "7.1.2" + resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-7.1.2.tgz#ab05301d8c28536301622d69227632269a70ca3b" + integrity sha512-FuEc12/eKqqoRYIGBrUptCBRhobL19PS2U31vMNTfyck1FxPyMfgsXyW4Mav85y/ZN1hop3hOwRlUDok23oYfQ== + prompts@^0.1.9: version "0.1.14" resolved "https://registry.yarnpkg.com/prompts/-/prompts-0.1.14.tgz#a8e15c612c5c9ec8f8111847df3337c9cbd443b2" @@ -10982,6 +11008,11 @@ whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: dependencies: iconv-lite "0.4.24" +whatwg-fetch@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" + integrity sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng== + whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf"