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});
         });
     });
 });