diff --git a/assets/package-lock.json b/assets/package-lock.json index 3b6d97171447f455a56355041fff62fd94672834..87f7632b368c09a812459b8f35ccdf3a96e8e0db 100644 --- a/assets/package-lock.json +++ b/assets/package-lock.json @@ -1,12 +1,12 @@ { "name": "waterdataui-assets", - "version": "0.55.0dev", + "version": "0.57.0dev", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "waterdataui-assets", - "version": "0.55.0dev", + "version": "0.57.0dev", "license": "CC0-1.0", "dependencies": { "autotrack": "2.4.1", @@ -49,6 +49,7 @@ "gulp-rev-all": "3.0.0", "isparta": "4.1.1", "jest": "27.3.1", + "jest-fetch-mock": "^3.0.3", "jest-mock-console": "1.2.3", "nodemon": "2.0.14", "npm-run-all": "4.1.5", @@ -60,9 +61,9 @@ "rollup-plugin-terser": "7.0.2", "sass": "1.43.3", "sinon": "11.1.2", - "stylelint": "^14.0.1", - "stylelint-config-recommended-scss": "^5.0.0", - "stylelint-scss": "^4.0.0", + "stylelint": "14.0.1", + "stylelint-config-recommended-scss": "5.0.0", + "stylelint-scss": "4.0.0", "terser": "5.9.0" }, "engines": { @@ -4488,6 +4489,15 @@ "node": ">=8" } }, + "node_modules/cross-fetch": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz", + "integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==", + "dev": true, + "dependencies": { + "node-fetch": "2.6.1" + } + }, "node_modules/cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -9783,6 +9793,16 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, + "node_modules/jest-fetch-mock": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/jest-fetch-mock/-/jest-fetch-mock-3.0.3.tgz", + "integrity": "sha512-Ux1nWprtLrdrH4XwE7O7InRY6psIi3GOsqNESJgMJ+M5cv4A8Lh7SN9d2V2kKRZ8ebAfcd1LNyZguAOb6JiDqw==", + "dev": true, + "dependencies": { + "cross-fetch": "^3.0.4", + "promise-polyfill": "^8.1.3" + } + }, "node_modules/jest-get-type": { "version": "27.3.1", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.3.1.tgz", @@ -12402,6 +12422,15 @@ "path-to-regexp": "^1.7.0" } }, + "node_modules/node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", + "dev": true, + "engines": { + "node": "4.x || >=6.0.0" + } + }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -13866,6 +13895,12 @@ "node": ">=0.4.0" } }, + "node_modules/promise-polyfill": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-8.2.1.tgz", + "integrity": "sha512-3p9zj0cEHbp7NVUxEYUWjQlffXqnXaZIMPkAO7HhFh8u5636xLRDHOUo2vpWSK0T2mqm6fKLXYn1KP6PAZ2gKg==", + "dev": true + }, "node_modules/prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", @@ -20399,6 +20434,15 @@ } } }, + "cross-fetch": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz", + "integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==", + "dev": true, + "requires": { + "node-fetch": "2.6.1" + } + }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -24483,6 +24527,16 @@ "jest-util": "^27.3.1" } }, + "jest-fetch-mock": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/jest-fetch-mock/-/jest-fetch-mock-3.0.3.tgz", + "integrity": "sha512-Ux1nWprtLrdrH4XwE7O7InRY6psIi3GOsqNESJgMJ+M5cv4A8Lh7SN9d2V2kKRZ8ebAfcd1LNyZguAOb6JiDqw==", + "dev": true, + "requires": { + "cross-fetch": "^3.0.4", + "promise-polyfill": "^8.1.3" + } + }, "jest-get-type": { "version": "27.3.1", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.3.1.tgz", @@ -26498,6 +26552,12 @@ "path-to-regexp": "^1.7.0" } }, + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", + "dev": true + }, "node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -27577,6 +27637,12 @@ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true }, + "promise-polyfill": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-8.2.1.tgz", + "integrity": "sha512-3p9zj0cEHbp7NVUxEYUWjQlffXqnXaZIMPkAO7HhFh8u5636xLRDHOUo2vpWSK0T2mqm6fKLXYn1KP6PAZ2gKg==", + "dev": true + }, "prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", diff --git a/assets/package.json b/assets/package.json index c23847d317c7ea7bacedfd855fa9800c7ea04eb7..f9381b0dd20dd98178fb55ca9bcf6c077c0b9a36 100644 --- a/assets/package.json +++ b/assets/package.json @@ -61,6 +61,7 @@ "gulp-rev-all": "3.0.0", "isparta": "4.1.1", "jest": "27.3.1", + "jest-fetch-mock": "3.0.3", "jest-mock-console": "1.2.3", "nodemon": "2.0.14", "npm-run-all": "4.1.5", diff --git a/assets/src/scripts/monitoring-location/store/hydrograph-data.js b/assets/src/scripts/monitoring-location/store/hydrograph-data.js index b5bf19ac5d1145cc53f469b6aaba88a483992fa9..df0efd8c20be8f6954f475bdcc9ead408d2b2b9a 100644 --- a/assets/src/scripts/monitoring-location/store/hydrograph-data.js +++ b/assets/src/scripts/monitoring-location/store/hydrograph-data.js @@ -5,7 +5,7 @@ import config from 'ui/config'; import {convertCelsiusToFahrenheit} from 'ui/utils'; import {fetchGroundwaterLevels} from 'ui/web-services/groundwater-levels'; -import {fetchNewTimeSeries} from 'ui/web-services/instantaneous-values'; +import {fetchTimeSeries} from 'ui/web-services/instantaneous-values'; import {fetchSiteStatistics} from 'ui/web-services/statistics-data'; import {fetchDataFromSensorThings} from 'ui/web-services/sensor-things'; @@ -112,7 +112,7 @@ const retrieveIVData = function(siteno, dataKind, {parameterCode, period, startT return function(dispatch) { const isCalculatedTemperatureCode = isCalculatedTemperature(parameterCode); - return fetchNewTimeSeries({ + return fetchTimeSeries({ siteno: siteno, parameterCode: getParameterToFetch(parameterCode), period: period, diff --git a/assets/src/scripts/web-services/camera-images.js b/assets/src/scripts/web-services/camera-images.js index e3f2413acc516c2ebe3fd77c8c19bb5704f48cec..3e8a9496e70e90b1cd41313244c16d0483564392 100644 --- a/assets/src/scripts/web-services/camera-images.js +++ b/assets/src/scripts/web-services/camera-images.js @@ -1,4 +1,3 @@ -import {get} from 'ui/ajax'; import config from 'ui/config'; /* @@ -7,17 +6,30 @@ import config from 'ui/config'; * @param {String} siteno * @return {Promise} which resolves to an Object. */ -export const fetchCameraMetaData = function(siteno) { - return get(`${config.MONITORING_LOCATION_CAMERA_ENDPOINT}/php/getSiteCameras.php?siteID=${siteno}`) - .then((response) => { +export const fetchCameraMetaData = async function(siteno) { + const url = `${config.MONITORING_LOCATION_CAMERA_ENDPOINT}/php/getSiteCameras.php?siteID=${siteno}`; + try { + const response = await fetch(url, { + method: 'GET' + }); + if (response.status === 200) { try { - return JSON.parse(response); + return await response.json(); } catch (e) { - return {success: false}; + return { + success: false + }; } - }) - .catch(reason => { - console.log(`Unable to get camera data for ${siteno} with reason: ${reason}`); - return {success: false}; - }); + } else { + console.error(`Received bad status, ${response.status} for camera meta data at ${url}`); + return { + success: false + }; + } + } catch(error) { + console.error(`Failed fetch for ${url}`); + return { + success: false + } + } }; diff --git a/assets/src/scripts/web-services/camera-images.test.js b/assets/src/scripts/web-services/camera-images.test.js index 81a932cc9f2cc0af5483c0c1fa46e1d14e1b91b3..0272bf9e57c9de762f64480e0d60cc9a6deabe04 100644 --- a/assets/src/scripts/web-services/camera-images.test.js +++ b/assets/src/scripts/web-services/camera-images.test.js @@ -1,47 +1,58 @@ -import sinon from 'sinon'; +import {enableFetchMocks, disableFetchMocks} from 'jest-fetch-mock'; +import mockConsole from 'jest-mock-console'; -import {fetchCameraMetaData} from './camera-images'; import {MOCK_CAMERA_METADATA} from '../mock-service-data'; +import {fetchCameraMetaData} from './camera-images'; + describe('web-services/camera-images', () => { - let fakeServer; beforeEach(() => { - fakeServer = sinon.createFakeServer(); + enableFetchMocks(); }); afterEach(() => { - fakeServer.restore(); + disableFetchMocks(); }); describe('fetchCameraMetaData', () => { - it('puts the site number in the request url', () => { - fetchCameraMetaData('05428500'); + let restoreConsole; + beforeEach(() => { + fetch.resetMocks(); + restoreConsole = mockConsole(); + }); + + afterEach(() => { + restoreConsole(); + }) + it('puts the site number in the request url and returns valid response data', async() => { + fetch.once(MOCK_CAMERA_METADATA, {status: 200}); + let resp = await fetchCameraMetaData('05428500'); - expect(fakeServer.requests[0].url).toContain('siteID=05428500'); + expect(fetch.mock.calls).toHaveLength(1); + expect(fetch.mock.calls[0][0]).toContain('siteID=05428500'); + expect(resp).toEqual(JSON.parse(MOCK_CAMERA_METADATA)); }); - it('Successfully request with valid JSON returns response data', () => { - const fetchPromise = fetchCameraMetaData('05428500'); - fakeServer.requests[0].respond(200, {'Content-Type': 'application/json'}, MOCK_CAMERA_METADATA); - return fetchPromise.then((resp) => { - expect(resp).toEqual(JSON.parse(MOCK_CAMERA_METADATA)); - }); + + it('Successful request with no data returns an object with success set to false', async() => { + fetch.once('No data returned', {status: 200}); + const resp= await fetchCameraMetaData('05428500'); + + expect(resp).toEqual({success: false}); }); - it('Successful request with no data returns an object with success set to false', () => { - const fetchPromise = fetchCameraMetaData('05428500'); - fakeServer.requests[0].respond(200, {'Content-Type': 'text/html'}, 'No data returned'); - return fetchPromise.then((resp) => { - expect(resp).toEqual({success: false}); - }); + it('handles a 400 bad status', async() => { + fetch.once('{}', {status: 400}); + const resp= await fetchCameraMetaData('05428500'); + + expect(resp).toEqual({success: false}); }); - it('Unsuccesful request returns an object with success set to false', () => { - const fetchPromise = fetchCameraMetaData('05428500'); - fakeServer.requests[0].respond(500, {'Content-Type': 'text/html'}, 'Internal Error'); - return fetchPromise.then((resp) => { - expect(resp).toEqual({success: false}); - }); + it('handles a bad fetch', async() => { + fetch.mockReject(new Error('fake error message')); + const resp= await fetchCameraMetaData('05428500'); + + expect(resp).toEqual({success: false}); }); }); });