diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/flood-level-lines.js b/assets/src/scripts/monitoring-location/components/hydrograph/flood-level-lines.js
index c564d80f4595fbecbac0bcc9b547e8490fa20cb7..34600fca4d42018d41d72eafe3a3afcff7ca906a 100644
--- a/assets/src/scripts/monitoring-location/components/hydrograph/flood-level-lines.js
+++ b/assets/src/scripts/monitoring-location/components/hydrograph/flood-level-lines.js
@@ -26,7 +26,7 @@ export const drawFloodLevelLines = function(svg, {visible, xscale, yscale, flood
             const yRange = yscale(level.value);
             const floodLine = d3Line()([[xRange[0], yRange], [xRange[1], yRange]]);
             group.append('path')
-                .classed('waterwatch-data-series', true)
+                .classed('flood-levels-series', true)
                 .classed(level.class, true)
                 .attr('d', floodLine);
         }
diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/index.js b/assets/src/scripts/monitoring-location/components/hydrograph/index.js
index 43d7a814e3beffad88a8f6e94130e4f48b711ad4..c8573079cd121a0a24c2bbe3436cf366e9baea6e 100644
--- a/assets/src/scripts/monitoring-location/components/hydrograph/index.js
+++ b/assets/src/scripts/monitoring-location/components/hydrograph/index.js
@@ -16,7 +16,7 @@ import {setSelectedParameterCode, setCompareDataVisibility, setSelectedTimeSpan,
     setSelectedIVMethodID
 } from 'ml/store/hydrograph-state';
 
-import {Actions as floodDataActions} from 'ml/store/flood-inundation';
+import {Actions as floodDataActions} from 'ml/store/flood-data';
 
 import {getPreferredIVMethodID} from './selectors/time-series-data';
 
@@ -102,9 +102,9 @@ export const attachToNode = function(store,
     }
 
     let fetchDataPromises = [fetchHydrographDataPromise];
-    // Fetch waterwatch flood levels
+    // Fetch flood levels
     if (config.ivPeriodOfRecord && config.GAGE_HEIGHT_PARAMETER_CODE in config.ivPeriodOfRecord) {
-        const fetchFloodLevelsPromise =  store.dispatch(floodDataActions.retrieveWaterwatchData(siteno));
+        const fetchFloodLevelsPromise =  store.dispatch(floodDataActions.retrieveFloodLevels(siteno));
         // If flood levels are to be shown then wait to render the hydrograph until those have been fetched.
         if (parameterCode === config.GAGE_HEIGHT_PARAMETER_CODE) {
             fetchDataPromises.push(fetchFloodLevelsPromise);
diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/index.test.js b/assets/src/scripts/monitoring-location/components/hydrograph/index.test.js
index 18fbdd165ef993a2a4cc463f2ea29fde9f25f5d1..a9ebb5bb8c018b7a7bb231823c6c51631207451f 100644
--- a/assets/src/scripts/monitoring-location/components/hydrograph/index.test.js
+++ b/assets/src/scripts/monitoring-location/components/hydrograph/index.test.js
@@ -1,4 +1,6 @@
 import {select, selectAll} from 'd3-selection';
+import {enableFetchMocks, disableFetchMocks} from 'jest-fetch-mock';
+import mockConsole from 'jest-mock-console';
 import sinon from 'sinon';
 
 import * as utils from 'ui/utils';
@@ -6,7 +8,7 @@ import config from 'ui/config';
 
 
 import {configureStore} from 'ml/store';
-import {Actions as floodDataActions} from 'ml/store/flood-inundation';
+import {Actions as floodDataActions} from 'ml/store/flood-data';
 import * as hydrographData from 'ml/store/hydrograph-data';
 import * as hydrographParameters from 'ml/store/hydrograph-parameters';
 
@@ -63,6 +65,18 @@ describe('monitoring-location/components/hydrograph module', () => {
         parameterCode: '72019'
     };
 
+    let restoreConsole;
+
+    beforeAll(() => {
+        enableFetchMocks();
+        restoreConsole = mockConsole();
+    });
+
+    afterAll(() => {
+        disableFetchMocks();
+        restoreConsole();
+    });
+
     beforeEach(() => {
         let body = select('body');
         body.append('a')
@@ -94,7 +108,7 @@ describe('monitoring-location/components/hydrograph module', () => {
 
     describe('Tests for initial data fetching and setting', () => {
         let store;
-        let retrieveHydrographDataSpy, retrieveHydrographParametersSpy, retrieveWaterwatchDataSpy;
+        let retrieveHydrographDataSpy, retrieveHydrographParametersSpy, retrieveFloodLevelsSpy;
 
         beforeEach(() => {
             store = configureStore({
@@ -108,7 +122,7 @@ describe('monitoring-location/components/hydrograph module', () => {
             });
             retrieveHydrographDataSpy = jest.spyOn(hydrographData, 'retrieveHydrographData');
             retrieveHydrographParametersSpy = jest.spyOn(hydrographParameters, 'retrieveHydrographParameters');
-            retrieveWaterwatchDataSpy = jest.spyOn(floodDataActions, 'retrieveWaterwatchData');
+            retrieveFloodLevelsSpy = jest.spyOn(floodDataActions, 'retrieveFloodLevels');
         });
 
         it('Loading indicator should be shown', () => {
@@ -209,9 +223,9 @@ describe('monitoring-location/components/hydrograph module', () => {
             expect(retrieveHydrographParametersSpy).toHaveBeenCalledWith('11112222');
         });
 
-        it('Should fetch the waterwatch flood levels', () => {
+        it('Should fetch the  flood levels', () => {
             attachToNode(store, graphNode, INITIAL_PARAMETERS);
-            expect(retrieveWaterwatchDataSpy).toHaveBeenCalledWith('11112222');
+            expect(retrieveFloodLevelsSpy).toHaveBeenCalledWith('11112222');
         });
 
         it('Should fetch the data and set the hydrograph state but not does not fetch hydrograph parameters when showOnlyGraph is true', () => {
@@ -233,7 +247,7 @@ describe('monitoring-location/components/hydrograph module', () => {
                 selectedTimeSpan: 'P7D',
                 showCompareIVData: false
             });
-            expect(retrieveWaterwatchDataSpy).toHaveBeenCalled();
+            expect(retrieveFloodLevelsSpy).toHaveBeenCalled();
             expect(retrieveHydrographParametersSpy).not.toHaveBeenCalled();
         });
     });
diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/selectors/flood-level-data.js b/assets/src/scripts/monitoring-location/components/hydrograph/selectors/flood-level-data.js
index 429eafd02562b4606796d541acb558e641760254..de698713c3ef609e34227ee108137d164f4c670e 100644
--- a/assets/src/scripts/monitoring-location/components/hydrograph/selectors/flood-level-data.js
+++ b/assets/src/scripts/monitoring-location/components/hydrograph/selectors/flood-level-data.js
@@ -1,21 +1,21 @@
 import {createSelector} from 'reselect';
 
-import {getWaterwatchFloodLevels} from 'ml/selectors/flood-data-selector';
+import {getFloodLevels} from 'ml/selectors/flood-data-selector';
 
 const STAGES = {
-    actionStage: {
+    action_stage: {
         label: 'Action stage',
         class: 'action-stage'
     },
-    floodStage: {
+    flood_stage: {
         label: 'Minor flood stage',
         class: 'minor-flood-stage'
     },
-    moderateFloodStage: {
+    moderate_flood_stage: {
         label: 'Moderate flood stage',
         class: 'moderate-flood-stage'
     },
-    majorFloodStage: {
+    major_flood_stage: {
         label: 'Major flood stage',
         class: 'major-flood-stage'
     }
@@ -25,20 +25,21 @@ const STAGES = {
  * Returns a selector function which returns an array of {Object}. Each object
  * represents a flood level and includes the properties:
  *      @prop {Number} value - the value of the flood level
+ *      @prop {String} displayValue - the string value (preserves significant digits)
  *      @prop {String} label - a human friendly label for the flood level
  *      @prop {String} class - a class to be used to decorate the flood level
  */
 export const getFloodLevelData = createSelector(
-    getWaterwatchFloodLevels,
+    getFloodLevels,
     levels => {
         const result = [];
         if (levels) {
-            Object.keys(levels).forEach(stage => {
+            Object.keys(STAGES).forEach(stage => {
                 if (levels[stage]) {
                     result.push({
-                        value: levels[stage],
-                        label: STAGES[stage].label,
-                        class: STAGES[stage].class
+                        ...STAGES[stage],
+                        displayValue: levels[stage],
+                        value: parseFloat(levels[stage])
                     });
                 }
             });
diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/selectors/flood-level-data.test.js b/assets/src/scripts/monitoring-location/components/hydrograph/selectors/flood-level-data.test.js
index 413a5c696c8449cb03f25e6bb4dafd3289ed4183..1f4617fe000d5ceeb1a6c3875bd7bb10caeedee1 100644
--- a/assets/src/scripts/monitoring-location/components/hydrograph/selectors/flood-level-data.test.js
+++ b/assets/src/scripts/monitoring-location/components/hydrograph/selectors/flood-level-data.test.js
@@ -25,6 +25,7 @@ describe('monitoring-location/components/hydrograph/selectors/flood-level-data',
             expect(result).toHaveLength(4);
             expect(result[0].label).toBeDefined();
             expect(result[0].class).toBeDefined();
+            expect(result.map(level => level.displayValue)).toEqual(['5', '10', '12', '14']);
             expect(result.map(level => level.value)).toEqual([5, 10, 12, 14]);
         });
     });
diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/selectors/legend-data.js b/assets/src/scripts/monitoring-location/components/hydrograph/selectors/legend-data.js
index 69e89e5138ee1cf2a1c2551b20ac956d690eecac..abf96b600e0fb263e5e8ba143e3fee4553fd9cb9 100644
--- a/assets/src/scripts/monitoring-location/components/hydrograph/selectors/legend-data.js
+++ b/assets/src/scripts/monitoring-location/components/hydrograph/selectors/legend-data.js
@@ -4,7 +4,7 @@ import config from 'ui/config';
 
 import {defineLineMarker, defineRectangleMarker, defineCircleMarker, defineTextOnlyMarker} from 'd3render/markers';
 
-import {isWaterwatchVisible} from 'ml/selectors/flood-data-selector';
+import {showFloodLevels} from 'ml/selectors/flood-data-selector';
 import {getPrimaryMedianStatisticsData, getPrimaryParameter} from 'ml/selectors/hydrograph-data-selector';
 import {isCompareIVDataVisible, isMedianDataVisible} from 'ml/selectors/hydrograph-state-selector';
 
@@ -36,11 +36,11 @@ const getLegendDisplay = createSelector(
     getPrimaryMedianStatisticsData,
     getIVUniqueDataKinds('primary'),
     getIVUniqueDataKinds('compare'),
-    isWaterwatchVisible,
+    showFloodLevels,
     getFloodLevelData,
     getUniqueGWKinds,
     getPrimaryParameter,
-    (showCompare, showMedian, thresholds, medianSeries, currentClasses, compareClasses, showWaterWatch, floodLevels, gwLevelKinds,
+    (showCompare, showMedian, thresholds, medianSeries, currentClasses, compareClasses, showFloodLevels, floodLevels, gwLevelKinds,
      primaryParameter) => {
         const parameterCode = primaryParameter ? primaryParameter.parameterCode : null;
         const hasIVData = config.ivPeriodOfRecord && parameterCode ? parameterCode in config.ivPeriodOfRecord : false;
@@ -49,7 +49,7 @@ const getLegendDisplay = createSelector(
             primaryIV: hasIVData ? currentClasses : undefined,
             compareIV: hasIVData && showCompare ? compareClasses : undefined,
             median: showMedian ? medianSeries : undefined,
-            floodLevels: showWaterWatch ? floodLevels : undefined,
+            floodLevels: showFloodLevels ? floodLevels : undefined,
             groundwaterLevels: hasGWLevelsData ? gwLevelKinds : undefined,
             thresholds: thresholds
         };
@@ -123,8 +123,8 @@ const getFloodLevelMarkers = function(floodLevels) {
             defineTextOnlyMarker(level.label),
             defineLineMarker(
                 null,
-                `waterwatch-data-series ${level.class}`,
-                `${level.value} ft`)
+                `flood-levels-series ${level.class}`,
+                `${level.displayValue} ft`)
         ];
     });
 };
diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/time-series-graph.js b/assets/src/scripts/monitoring-location/components/hydrograph/time-series-graph.js
index 9c9aca1c4f661efea74a5637e42b1272a27ae76c..8bcb0586c90968af2197a79ac80b9708fd13626f 100644
--- a/assets/src/scripts/monitoring-location/components/hydrograph/time-series-graph.js
+++ b/assets/src/scripts/monitoring-location/components/hydrograph/time-series-graph.js
@@ -10,7 +10,7 @@ import {appendAxes} from 'd3render/axes';
 import {renderMaskDefs} from 'd3render/data-masks';
 import {appendInfoTooltip} from 'd3render/info-tooltip';
 
-import {isWaterwatchVisible} from 'ml/selectors/flood-data-selector';
+import {showFloodLevels} from 'ml/selectors/flood-data-selector';
 import {getPrimaryParameter, getPrimaryMedianStatisticsData} from 'ml/selectors/hydrograph-data-selector';
 
 import {getAxes}  from './selectors/axes';
@@ -230,7 +230,7 @@ export const drawTimeSeriesGraphData = function(elem, store, showTooltip) {
             enableClip: () => true
         })))
         .call(link(store, drawFloodLevelLines, createStructuredSelector({
-            visible: isWaterwatchVisible,
+            visible: showFloodLevels,
             xscale: getMainXScale('current'),
             yscale: getMainYScale,
             floodLevels: getFloodLevelData
diff --git a/assets/src/scripts/monitoring-location/components/map/flood-slider.js b/assets/src/scripts/monitoring-location/components/map/flood-slider.js
index e7d84f0c1c21701a5924e7dfb316dc74294f851e..fc68eff28551bbd91d21f2519f0290a4feb9b26e 100644
--- a/assets/src/scripts/monitoring-location/components/map/flood-slider.js
+++ b/assets/src/scripts/monitoring-location/components/map/flood-slider.js
@@ -5,7 +5,7 @@ import {link} from 'ui/lib/d3-redux';
 import {appendInfoTooltip} from 'd3render/info-tooltip';
 
 import {getFloodStages, getFloodStageHeight, getFloodGageHeightStageIndex, hasFloodData} from 'ml/selectors/flood-data-selector';
-import {Actions} from 'ml/store/flood-inundation';
+import {Actions} from 'ml/store/flood-data';
 
 
 const createSlider = function(elem, stages, store) {
diff --git a/assets/src/scripts/monitoring-location/components/map/index.js b/assets/src/scripts/monitoring-location/components/map/index.js
index e1e97be16d63639ead3507300ce3e74cefb31132..00bbab0a31b8d58bdf3cb1e1658027d7866e5e71 100644
--- a/assets/src/scripts/monitoring-location/components/map/index.js
+++ b/assets/src/scripts/monitoring-location/components/map/index.js
@@ -14,7 +14,7 @@ import {hasFloodData, getFloodExtent, getFloodStageHeight} from 'ml/selectors/fl
 import {hasNldiData, getNldiDownstreamFlows, getNldiUpstreamFlows, getNldiUpstreamBasin}
     from 'ml/selectors/nldi-data-selector';
 import {Actions as nldiDataActions} from 'ml/store/nldi-data';
-import {Actions as floodInundationActions} from 'ml/store/flood-inundation';
+import {Actions as floodDataActions} from 'ml/store/flood-data';
 
 import {floodSlider} from './flood-slider';
 import {drawCircleMarkerLegend, drawFIMLegend, drawMonitoringLocationMarkerLegend} from './legend';
@@ -230,7 +230,7 @@ const siteMap = function(node, {siteno, latitude, longitude, zoom}, store) {
  * @param {Number} zoom - zoom level to initially set the map to
  */
 export const attachToNode = function(store, node, {siteno, latitude, longitude, zoom}) {
-    store.dispatch(floodInundationActions.retrieveFloodData(siteno));
+    store.dispatch(floodDataActions.retrieveFIMFloodData(siteno));
     // hydrates the store with nldi data
     store.dispatch(nldiDataActions.retrieveNldiData(siteno));
 
diff --git a/assets/src/scripts/monitoring-location/components/map/index.test.js b/assets/src/scripts/monitoring-location/components/map/index.test.js
index 5cb364e853e9cca454cf6838603c58d19aedcc40..1da05b368bea6bddb5366f84acda2271bfa240f9 100644
--- a/assets/src/scripts/monitoring-location/components/map/index.test.js
+++ b/assets/src/scripts/monitoring-location/components/map/index.test.js
@@ -1,4 +1,6 @@
 import {select} from 'd3-selection';
+import {enableFetchMocks, disableFetchMocks} from 'jest-fetch-mock';
+import mockConsole from 'jest-mock-console';
 import sinon from 'sinon';
 
 import config from 'ui/config';
@@ -22,6 +24,18 @@ describe('monitoring-location/components/map module', () => {
     let mapNode;
     let store;
     let fakeServer;
+    let restoreConsole;
+
+    beforeAll(() => {
+        enableFetchMocks();
+        restoreConsole = mockConsole();
+    });
+
+    afterAll(() => {
+        disableFetchMocks();
+        restoreConsole();
+    });
+
 
     beforeEach(() => {
         fakeServer = sinon.createFakeServer();
diff --git a/assets/src/scripts/monitoring-location/selectors/flood-data-selector.js b/assets/src/scripts/monitoring-location/selectors/flood-data-selector.js
index a390def4a3938b7b11a7f392668d110dcca3bcc1..368d3b54f407c1433e9951b869d7c8d3d407daef 100644
--- a/assets/src/scripts/monitoring-location/selectors/flood-data-selector.js
+++ b/assets/src/scripts/monitoring-location/selectors/flood-data-selector.js
@@ -23,17 +23,16 @@ export const hasFloodData = createSelector(
 /*
  * Provides a function which returns True if waterwatch flood levels is not empty.
  */
-export const hasWaterwatchData = createSelector(
+export const hasFloodLevels = createSelector(
     getFloodLevels,
-    (floodLevels) =>
-        floodLevels != null
+    (floodLevels) => floodLevels != null
 );
 
 /*
- * Provides a function which returns True if waterwatch flood levels should be visible.
+ * Provides a function which returns True if flood levels should be visible.
  */
-export const isWaterwatchVisible = createSelector(
-    hasWaterwatchData,
+export const showFloodLevels = createSelector(
+    hasFloodLevels,
     getPrimaryParameter,
     (hasFloodLevels, parameter) => hasFloodLevels && parameter && parameter.parameterCode === config.GAGE_HEIGHT_PARAMETER_CODE
 );
@@ -79,7 +78,7 @@ export const getFloodGageHeightStageIndex= createSelector(
 /*
  * Provides a function which returns the Waterwatch Flood Levels
  */
-export const getWaterwatchFloodLevels = createSelector(
+export const getFloodLevelValues = createSelector(
     getFloodLevels,
     (floodLevels) => {
         return floodLevels ? {
diff --git a/assets/src/scripts/monitoring-location/selectors/flood-data-selector.test.js b/assets/src/scripts/monitoring-location/selectors/flood-data-selector.test.js
index cf7406aabe34c2e30f0e7fd84e6eda36bf09d629..97820072c7c3223d2021f745307268596a20c73d 100644
--- a/assets/src/scripts/monitoring-location/selectors/flood-data-selector.test.js
+++ b/assets/src/scripts/monitoring-location/selectors/flood-data-selector.test.js
@@ -1,6 +1,6 @@
 import {
     getFloodStageHeight, hasFloodData, getFloodGageHeightStageIndex,
-    hasWaterwatchData, getWaterwatchFloodLevels, isWaterwatchVisible
+    showFloodLevels, getFloodLevels, hasFloodLevels
 } from './flood-data-selector';
 
 describe('monitoring-location/selectors/flood-data-selector', () => {
@@ -81,17 +81,17 @@ describe('monitoring-location/selectors/flood-data-selector', () => {
         });
     });
 
-    describe('hasWaterwatchData', () => {
-        it('Return false if no waterwatch flood levels are available', () => {
-            expect(hasWaterwatchData({
+    describe('hasFloodLevels', () => {
+        it('Return false if no flood levels are available', () => {
+            expect(hasFloodLevels({
                 floodData: {
                     floodLevels: null
                 }
             })).toBeFalsy();
         });
 
-        it('return true if waterwatch flood levels are available', () => {
-            expect(hasWaterwatchData({
+        it('return true if flood levels are available', () => {
+            expect(hasFloodLevels({
                 floodData: {
                     floodLevels: {
                         site_no: '07144100',
@@ -105,17 +105,17 @@ describe('monitoring-location/selectors/flood-data-selector', () => {
         });
     });
 
-    describe('getWaterwatchFloodLevels', () => {
+    describe('getFloodLevels', () => {
         it('Expects null if no flood levels are defined', () => {
-           expect(getWaterwatchFloodLevels({
+           expect(getFloodLevels({
                floodData: {
                    floodLevels: null
                }
            })).toBeNull();
         });
-        
-        it('Waterwatch flood levels are returned', () => {
-            expect(Object.values(getWaterwatchFloodLevels({
+
+        it('Flood levels are returned', () => {
+            expect(getFloodLevels({
                 floodData: {
                     floodLevels: {
                         site_no: '07144100',
@@ -125,13 +125,19 @@ describe('monitoring-location/selectors/flood-data-selector', () => {
                         major_flood_stage: '26'
                     }
                 }
-            }))).toEqual([20, 22.5, 25, 26]);
+            })).toEqual({
+                site_no: '07144100',
+                action_stage: '20',
+                flood_stage: '22.5',
+                moderate_flood_stage: '25',
+                major_flood_stage: '26'
+            });
         });
     });
 
-    describe('isWaterwatchVisible', () => {
-        it('Return false if waterwatch flood levels exist but no primary parameter exists', () => {
-            expect(isWaterwatchVisible({
+    describe('showFloodLevels', () => {
+        it('Return false if flood levels exist but no primary parameter exists', () => {
+            expect(showFloodLevels({
                 floodData: {
                     floodLevels: {
                         site_no: '07144100',
@@ -145,8 +151,8 @@ describe('monitoring-location/selectors/flood-data-selector', () => {
             })).toBeFalsy();
         });
 
-        it('Return false if waterwatch flood levels should not be visible due to parameter code', () => {
-            expect(isWaterwatchVisible({
+        it('Return false if flood levels should not be visible due to parameter code', () => {
+            expect(showFloodLevels({
                 floodData: {
                     floodLevels: {
                         site_no: '07144100',
@@ -166,8 +172,8 @@ describe('monitoring-location/selectors/flood-data-selector', () => {
             })).toBeFalsy();
         });
 
-        it('Return false if waterwatch flood levels should not be visible due to no flood levels', () => {
-            expect(isWaterwatchVisible({
+        it('Return false if flood levels should not be visible due to no flood levels', () => {
+            expect(showFloodLevels({
                 floodData: {
                     floodLevels: null
                 },
@@ -181,8 +187,8 @@ describe('monitoring-location/selectors/flood-data-selector', () => {
             })).toBeFalsy();
         });
 
-        it('Return true if waterwatch flood levels should be visible', () => {
-            expect(isWaterwatchVisible({
+        it('Return true if flood levels should be visible', () => {
+            expect(showFloodLevels({
                 floodData: {
                     floodLevels: {
                         site_no: '07144100',
diff --git a/assets/src/scripts/monitoring-location/store/flood-inundation.js b/assets/src/scripts/monitoring-location/store/flood-data.js
similarity index 80%
rename from assets/src/scripts/monitoring-location/store/flood-inundation.js
rename to assets/src/scripts/monitoring-location/store/flood-data.js
index 3d98bcf659e1ab786080cc13a07400558350c343..ceae0dbbc58e02a612a5b7c5b65091f0893ef07c 100644
--- a/assets/src/scripts/monitoring-location/store/flood-inundation.js
+++ b/assets/src/scripts/monitoring-location/store/flood-data.js
@@ -1,5 +1,6 @@
-import {fetchFloodExtent, fetchFloodFeatures, fetchFIMPublicStatus,
-    fetchWaterwatchFloodLevels} from 'ui/web-services/flood-data';
+import {fetchFloodExtent, fetchFloodFeatures,
+    fetchFIMPublicStatus} from 'ui/web-services/fim-data';
+import {fetchFloodLevels} from 'ui/web-services/flood-levels';
 
 const INITIAL_DATA = {
     stages: [],
@@ -25,7 +26,7 @@ const setFloodFeatures = function(stages, extent) {
  * @param {String} siteno
  * @return {Function} which returns a Promise
  */
-const retrieveFloodData = function(siteno) {
+export const retrieveFIMFloodData = function(siteno) {
     return function(dispatch) {
         const publicStatus = fetchFIMPublicStatus(siteno);
         const floodFeatures = fetchFloodFeatures(siteno);
@@ -46,8 +47,6 @@ const retrieveFloodData = function(siteno) {
     };
 };
 
-
-
 /*
  * Slice reducer
  */
@@ -59,7 +58,7 @@ export const floodDataReducer = function(floodData=INITIAL_DATA, action) {
                 stages: action.stages,
                 extent: action.extent
             };
-        case 'SET_WATERWACH_FLOOD_LEVELS':
+        case 'SET_FLOOD_LEVELS':
             return {
                 ...floodData,
                 floodLevels: action.floodLevels
@@ -85,22 +84,22 @@ const setGageHeight = function(gageHeight) {
  * @param {JSON Object} floodLevels
  * @return {Object} Redux action
  */
-const setWaterwatchFloodLevels = function(floodLevels) {
+const setFloodLevels = function(floodLevels) {
     return {
-        type: 'SET_WATERWACH_FLOOD_LEVELS',
+        type: 'SET_FLOOD_LEVELS',
         floodLevels
     };
 };
 
 /*
- * Asynchronous Redux action to fetch the Waterwatch flood levels data
+ * Asynchronous Redux action to fetch the  flood levels data
  * @param {String} siteno
  * @return {Function} which returns a Promise
  */
-const retrieveWaterwatchData = function(siteno) {
+const retrieveFloodLevels = function(siteno) {
     return function(dispatch) {
-        return fetchWaterwatchFloodLevels(siteno).then(function(floodLevels) {
-            dispatch(setWaterwatchFloodLevels(floodLevels));
+        return fetchFloodLevels(siteno).then(function(floodLevels) {
+            dispatch(setFloodLevels(floodLevels));
         });
     };
 };
@@ -122,8 +121,8 @@ export const floodStateReducer = function(floodState={}, action) {
 
 export const Actions = {
     setFloodFeatures,
-    retrieveFloodData,
+    retrieveFIMFloodData,
     setGageHeight,
-    setWaterwatchFloodLevels,
-    retrieveWaterwatchData
+    setFloodLevels,
+    retrieveFloodLevels
 };
\ No newline at end of file
diff --git a/assets/src/scripts/monitoring-location/store/flood-data.test.js b/assets/src/scripts/monitoring-location/store/flood-data.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..71568c3f8d49239ec3e10243161848835e7e57ce
--- /dev/null
+++ b/assets/src/scripts/monitoring-location/store/flood-data.test.js
@@ -0,0 +1,179 @@
+import {applyMiddleware, combineReducers, createStore} from 'redux';
+import {default as thunk} from 'redux-thunk';
+
+import {MOCK_WATERWATCH_FLOOD_LEVELS} from 'ui/mock-service-data';
+
+import * as fimDataService from 'ui/web-services/fim-data';
+import * as floodLevelsService from 'ui/web-services/flood-levels';
+
+import {Actions, floodDataReducer, floodStateReducer} from './flood-data';
+
+describe('monitoring-location/store/flood-data module', () => {
+    /* eslint no-use-before-define: 0 */
+    let store;
+    let fakeServer;
+
+    beforeEach(() => {
+        store = createStore(
+            combineReducers({
+                floodData: floodDataReducer,
+                floodState: floodStateReducer
+            }),
+            {
+                floodData: {},
+                floodState: {}
+            },
+            applyMiddleware(thunk)
+        );
+    });
+
+    describe('floodDataReducer', () => {
+        describe('Actions.setFloodFeatures', () => {
+            it('Updates the flood features', () => {
+                store.dispatch(Actions.setFloodFeatures([1, 2, 3], {
+                    xmin: -87.46671436884024,
+                    ymin: 39.434393043085194,
+                    xmax: -87.40838667928894,
+                    ymax: 39.514453931168774
+                }));
+                const floodData = store.getState().floodData;
+
+                expect(floodData.stages).toEqual([1, 2, 3]);
+                expect(floodData.extent).toEqual({
+                    xmin: -87.46671436884024,
+                    ymin: 39.434393043085194,
+                    xmax: -87.40838667928894,
+                    ymax: 39.514453931168774
+                });
+            });
+        });
+
+        describe('Actions.retrieveFIMFloodData', () => {
+
+            beforeEach(() => {
+                fimDataService.fetchFloodFeatures =
+                    jest.fn().mockReturnValue(Promise.resolve(MOCK_STAGES));
+                fimDataService.fetchFloodExtent =
+                    jest.fn().mockReturnValue(Promise.resolve(MOCK_EXTENT));
+            })
+
+            it('Expects a public site to populate the store', async() => {
+                fimDataService.fetchFIMPublicStatus =
+                    jest.fn().mockReturnValue(Promise.resolve(true));
+                let promise = store.dispatch(Actions.retrieveFIMFloodData('1234567'));
+
+                return promise.then(() => {
+                    const floodData = store.getState().floodData;
+
+                    expect(floodData.stages).toEqual([28, 29, 30]);
+                    expect(floodData.extent).toEqual(MOCK_EXTENT.extent);
+                });
+            });
+
+            it('Expects a site that is not public to not populate the store', () => {
+                fimDataService.fetchFIMPublicStatus =
+                    jest.fn().mockReturnValue(Promise.resolve(false));
+                let promise = store.dispatch(Actions.retrieveFIMFloodData('1234567'));
+
+                return promise.then(() => {
+                    const floodData = store.getState().floodData;
+
+                    expect(floodData.stages).toEqual([]);
+                    expect(floodData.extent).toEqual({});
+                });
+            });
+        });
+
+        describe('retrieveFloodLevels', () => {
+            const FLOOD_LEVELS = JSON.parse(MOCK_WATERWATCH_FLOOD_LEVELS);
+
+            it('Expects the store to be updated on successful fetches', () => {
+                floodLevelsService.fetchFloodLevels =
+                    jest.fn().mockReturnValue(Promise.resolve(FLOOD_LEVELS.sites[0]))
+                const promise = store.dispatch(Actions.retrieveFloodLevels('12345678'));
+
+                return promise.then(() => {
+                    const floodLevels = store.getState().floodData.floodLevels;
+                    expect(floodLevels.action_stage)
+                        .toEqual(FLOOD_LEVELS.sites[0].action_stage);
+                    expect(floodLevels.flood_stage)
+                        .toEqual(FLOOD_LEVELS.sites[0].flood_stage);
+                    expect(floodLevels.moderate_flood_stage)
+                        .toEqual(FLOOD_LEVELS.sites[0].moderate_flood_stage);
+                    expect(floodLevels.major_flood_stage)
+                        .toEqual(FLOOD_LEVELS.sites[0].major_flood_stage);
+                });
+            });
+
+            it('Expects the store to contain empty flood levels if calls are unsuccessful', () => {
+                floodLevelsService.fetchFloodLevels =
+                    jest.fn().mockReturnValue(Promise.resolve(null));
+                const promise = store.dispatch(Actions.retrieveFloodLevels('12345678'));
+
+                return promise.then(() => {
+                    expect(store.getState().floodData.floodLevels).toEqual(null);
+                });
+            });
+        });
+
+        describe('setFloodLevels', () => {
+            const FLOOD_LEVELS =
+                {
+                    site_no: '07144100',
+                    action_stage: '20',
+                    flood_stage: '22',
+                    moderate_flood_stage: '25',
+                    major_flood_stage: '26'
+                };
+
+            it('expect flood levels data to be updated', () => {
+                store.dispatch(
+                    Actions.setFloodLevels(FLOOD_LEVELS));
+                const floodLevels = store.getState().floodData.floodLevels;
+
+                expect(floodLevels.action_stage).toEqual(FLOOD_LEVELS.action_stage);
+                expect(floodLevels.flood_stage).toEqual(FLOOD_LEVELS.flood_stage);
+                expect(floodLevels.moderate_flood_stage).toEqual(FLOOD_LEVELS.moderate_flood_stage);
+                expect(floodLevels.major_flood_stage).toEqual(FLOOD_LEVELS.major_flood_stage);
+            });
+        });
+    });
+
+    describe('floodStateReducer', () => {
+        describe('Actions.setGageHeight', () => {
+            it('Updates the gageHeight', () => {
+                store.dispatch(Actions.setGageHeight(12));
+
+                expect(store.getState().floodState.gageHeight).toBe(12);
+            });
+        });
+    });
+});
+
+const MOCK_STAGES =
+    [{
+        'attributes': {
+            'USGSID': '03341500',
+            'STAGE': 30
+        }
+    }, {
+        'attributes': {
+            'USGSID': '03341500',
+            'STAGE': 29
+        }
+    }, {
+        'attributes': {
+            'USGSID': '03341500',
+            'STAGE': 28
+        }
+    }];
+
+const MOCK_EXTENT = {
+    extent: {
+        xmin: -87.46671436884024,
+        ymin: 39.434393043085194,
+        xmax: -87.40838667928894,
+        ymax: 39.514453931168774,
+        spatialReference: {wkid: 4326, latestWkid: 4326}
+    }
+};
\ No newline at end of file
diff --git a/assets/src/scripts/monitoring-location/store/flood-inundation.test.js b/assets/src/scripts/monitoring-location/store/flood-inundation.test.js
deleted file mode 100644
index 11174288b76aa84c7feb585601cf5bc305d74551..0000000000000000000000000000000000000000
--- a/assets/src/scripts/monitoring-location/store/flood-inundation.test.js
+++ /dev/null
@@ -1,240 +0,0 @@
-import {applyMiddleware, combineReducers, createStore} from 'redux';
-import {default as thunk} from 'redux-thunk';
-import sinon from 'sinon';
-
-import {MOCK_WATERWATCH_FLOOD_LEVELS} from 'ui/mock-service-data';
-
-import {Actions, floodDataReducer, floodStateReducer} from './flood-inundation';
-
-describe('monitoring-location/store/flood-inundation module', () => {
-    /* eslint no-use-before-define: 0 */
-    let store;
-    let fakeServer;
-
-    beforeEach(() => {
-        store = createStore(
-            combineReducers({
-                floodData: floodDataReducer,
-                floodState: floodStateReducer
-            }),
-            {
-                floodData: {},
-                floodState: {}
-            },
-            applyMiddleware(thunk)
-        );
-        fakeServer = sinon.createFakeServer();
-    });
-
-    afterEach(() => {
-        fakeServer.restore();
-    });
-
-    describe('floodDataReducer', () => {
-        describe('Actions.setFloodFeatures', () => {
-            it('Updates the flood features', () => {
-                store.dispatch(Actions.setFloodFeatures([1, 2, 3], {
-                    xmin: -87.46671436884024,
-                    ymin: 39.434393043085194,
-                    xmax: -87.40838667928894,
-                    ymax: 39.514453931168774
-                }));
-                const floodData = store.getState().floodData;
-
-                expect(floodData.stages).toEqual([1, 2, 3]);
-                expect(floodData.extent).toEqual({
-                    xmin: -87.46671436884024,
-                    ymin: 39.434393043085194,
-                    xmax: -87.40838667928894,
-                    ymax: 39.514453931168774
-                });
-            });
-        });
-
-        describe('Actions.retrieveFloodData', () => {
-            const PUBLIC_SITE = `{
-                        "features" :[{
-                            "attributes": {
-                                "Public": 1,
-                                "SITE_NO": "12345678"
-                            }
-                        }]
-                    }`;
-            const NOT_PUBLIC_SITE = `{
-                        "features" :[{
-                            "attributes": {
-                                "Public": 0,
-                                "SITE_NO": "12345678"
-                            }
-                        }]
-                    }`;
-            it('Expects call to determine FIM Public Status to occur', () => {
-                store.dispatch(Actions.retrieveFloodData('12345678'));
-
-                expect(fakeServer.requests).toHaveLength(3);
-                const req1 = fakeServer.requests[0];
-                const req2 = fakeServer.requests[1];
-                const req3 = fakeServer.requests[2];
-                expect(req1.url).toContain('12345678');
-                expect(req1.url).toContain('outFields=PUBLIC%2CSITE_NO');
-
-                expect(req2.url).toContain('1234567');
-                expect(req3.url).toContain('1234567');
-
-                expect(req2.url).toContain('outFields=USGSID%2C+STAGE');
-                expect(req3.url).toContain('returnExtentOnly=true');
-            });
-
-            it('Expects a public site with successful ajax calls to populate the store', () => {
-                let promise = store.dispatch(Actions.retrieveFloodData('1234567'));
-                fakeServer.requests[0].respond(200, {}, PUBLIC_SITE);
-                fakeServer.requests[1].respond(200, {}, MOCK_STAGES);
-                fakeServer.requests[2].respond(200, {}, MOCK_EXTENT);
-
-                return promise.then(() => {
-                    const floodData = store.getState().floodData;
-
-                    expect(floodData.stages).toEqual([28, 29, 30]);
-                    expect(floodData.extent).toEqual(JSON.parse(MOCK_EXTENT).extent);
-                });
-            });
-
-            it('Expects a not public site with successful ajax calls to populate the store', () => {
-                let promise = store.dispatch(Actions.retrieveFloodData('1234567'));
-                fakeServer.requests[0].respond(200, {}, NOT_PUBLIC_SITE);
-                fakeServer.requests[1].respond(200, {}, MOCK_STAGES);
-                fakeServer.requests[2].respond(200, {}, MOCK_EXTENT);
-
-                return promise.then(() => {
-                    const floodData = store.getState().floodData;
-
-                    expect(floodData.stages).toEqual([]);
-                    expect(floodData.extent).toEqual({});
-                });
-            });
-        });
-
-        describe('retrieveWaterwatchData', () => {
-            it('Expects that fetching urls have the siteno', () => {
-                store.dispatch(Actions.retrieveWaterwatchData('12345678'));
-
-                expect(fakeServer.requests).toHaveLength(1);
-                expect(fakeServer.requests[0].url).toContain('12345678');
-            });
-
-            it('Expects the store to be updated on successful fetches', () => {
-                const promise = store.dispatch(Actions.retrieveWaterwatchData('12345678'));
-
-                fakeServer.requests[0].respond(200, {}, MOCK_WATERWATCH_FLOOD_LEVELS);
-
-                return promise.then(() => {
-                    const waterwatchData = store.getState().floodData;
-                    expect(waterwatchData.floodLevels.action_stage)
-                        .toEqual(JSON.parse(MOCK_WATERWATCH_FLOOD_LEVELS).sites[0].action_stage);
-                    expect(waterwatchData.floodLevels.flood_stage)
-                        .toEqual(JSON.parse(MOCK_WATERWATCH_FLOOD_LEVELS).sites[0].flood_stage);
-                    expect(waterwatchData.floodLevels.moderate_flood_stage)
-                        .toEqual(JSON.parse(MOCK_WATERWATCH_FLOOD_LEVELS).sites[0].moderate_flood_stage);
-                    expect(waterwatchData.floodLevels.major_flood_stage)
-                        .toEqual(JSON.parse(MOCK_WATERWATCH_FLOOD_LEVELS).sites[0].major_flood_stage);
-                });
-            });
-
-            it('Expects the store to not contain empty features if calls are unsuccessful', () => {
-
-                const promise = store.dispatch(Actions.retrieveWaterwatchData('12345678'));
-
-                fakeServer.requests[0].respond(500, {}, 'Internal server error');
-
-                return promise.then(() => {
-                    const waterwatchData = store.getState().floodData;
-
-                    expect(waterwatchData.floodLevels).toEqual(null);
-                });
-            });
-        });
-
-        describe('setWaterwatchFloodLevels', () => {
-            const FLOOD_LEVELS = [
-                    {
-                        site_no: '07144100',
-                        action_stage: '20',
-                        flood_stage: '22',
-                        moderate_flood_stage: '25',
-                        major_flood_stage: '26'
-                    }
-                ];
-
-            it('expect waterwatch data to be updated', () => {
-                store.dispatch(
-                    Actions.setWaterwatchFloodLevels(FLOOD_LEVELS));
-                const waterwatchData = store.getState().floodData;
-
-                expect(waterwatchData.floodLevels[0].action_stage).toEqual(FLOOD_LEVELS[0].action_stage);
-                expect(waterwatchData.floodLevels[0].flood_stage).toEqual(FLOOD_LEVELS[0].flood_stage);
-                expect(waterwatchData.floodLevels[0].moderate_flood_stage).toEqual(FLOOD_LEVELS[0].moderate_flood_stage);
-                expect(waterwatchData.floodLevels[0].major_flood_stage).toEqual(FLOOD_LEVELS[0].major_flood_stage);
-            });
-        });
-    });
-
-    describe('floodStateReducer', () => {
-        describe('Actions.setGageHeight', () => {
-            it('Updates the gageHeight', () => {
-                store.dispatch(Actions.setGageHeight(12));
-
-                expect(store.getState().floodState.gageHeight).toBe(12);
-            });
-        });
-    });
-});
-
-const MOCK_STAGES = `
-{
-	"displayFieldName": "USGSID",
-	"fieldAliases": {
-		"USGSID": "USGSID",
-		"STAGE": "STAGE"
-	},
-	"fields": [{
-			"name": "USGSID",
-			"type": "esriFieldTypeString",
-			"alias": "USGSID",
-			"length": 254
-		},
-		{
-			"name": "STAGE",
-			"type": "esriFieldTypeDouble",
-			"alias": "STAGE"
-		}
-	],
-	"features": [{
-			"attributes": {
-				"USGSID": "03341500",
-				"STAGE": 30
-			}
-		},
-		{
-			"attributes": {
-				"USGSID": "03341500",
-				"STAGE": 29
-			}
-		},
-		{
-			"attributes": {
-				"USGSID": "03341500",
-				"STAGE": 28
-			}
-		}
-	]
-}`;
-
-const MOCK_EXTENT = `{
-    "extent": {
-        "xmin": -87.46671436884024,
-        "ymin": 39.434393043085194,
-        "xmax": -87.40838667928894,
-        "ymax": 39.514453931168774,
-        "spatialReference": {"wkid": 4326, "latestWkid": 4326}
-    }
-}`;
\ No newline at end of file
diff --git a/assets/src/scripts/monitoring-location/store/hydrograph-data.test.js b/assets/src/scripts/monitoring-location/store/hydrograph-data.test.js
index ed7b2561390ce1cefa4a6b8e25059fc0c41416b5..5ea5d7a93fcfd3146af58ae0eab8f0ed0029d204 100644
--- a/assets/src/scripts/monitoring-location/store/hydrograph-data.test.js
+++ b/assets/src/scripts/monitoring-location/store/hydrograph-data.test.js
@@ -2,7 +2,6 @@ import mockConsole from 'jest-mock-console';
 import * as luxon from 'luxon';
 import {applyMiddleware, combineReducers, createStore} from 'redux';
 import {default as thunk} from 'redux-thunk';
-import sinon from 'sinon';
 
 import {
     MOCK_IV_DATA,
@@ -29,7 +28,6 @@ import {
 
 describe('monitoring-location/store/hydrograph-data', () => {
     let store;
-    let fakeServer;
     let restoreConsole;
 
     config.locationTimeZone = 'America/Chicago';
@@ -45,12 +43,10 @@ describe('monitoring-location/store/hydrograph-data', () => {
             },
             applyMiddleware(thunk)
         );
-        fakeServer = sinon.createFakeServer();
         restoreConsole = mockConsole();
     });
 
     afterEach(() => {
-        fakeServer.restore();
         restoreConsole();
     });
 
diff --git a/assets/src/scripts/monitoring-location/store/hydrograph-parameters.js b/assets/src/scripts/monitoring-location/store/hydrograph-parameters.js
index b867b0a76a1ea7e1e3b94ecd0ea561cdb89bf942..5b63103a6a8bc86c9bc657050bf3c463db3429f0 100644
--- a/assets/src/scripts/monitoring-location/store/hydrograph-parameters.js
+++ b/assets/src/scripts/monitoring-location/store/hydrograph-parameters.js
@@ -7,7 +7,7 @@ import {fetchGroundwaterLevels} from 'ui/web-services/groundwater-levels';
 import {fetchTimeSeries} from 'ui/web-services/instantaneous-values';
 
 import {getConvertedTemperatureParameter, hasMeasuredFahrenheitParameter} from 'ml/iv-data-utils';
-import {Actions as floodStateActions} from './flood-inundation';
+import {Actions as floodStateActions} from './flood-data';
 
 /*
  * Synchronous Redux action - updatethe hydrograph variables
diff --git a/assets/src/scripts/monitoring-location/store/index.js b/assets/src/scripts/monitoring-location/store/index.js
index 781710d7d38cf90a84a7acf235177743534cff0b..773a32fe5b23616647f30c3bfe746281aa7e04cc 100644
--- a/assets/src/scripts/monitoring-location/store/index.js
+++ b/assets/src/scripts/monitoring-location/store/index.js
@@ -5,7 +5,7 @@ import {dailyValueTimeSeriesDataReducer as dailyValueTimeSeriesData} from './dai
 import {dailyValueTimeSeriesStateReducer as dailyValueTimeSeriesState} from './daily-value-time-series';
 import {
     floodDataReducer as floodData,
-    floodStateReducer as floodState} from './flood-inundation';
+    floodStateReducer as floodState} from './flood-data';
 import {hydrographDataReducer as hydrographData} from './hydrograph-data';
 import {hydrographParametersReducer as hydrographParameters,
     initializeParameters} from './hydrograph-parameters';
diff --git a/assets/src/scripts/web-services/camera-images.test.js b/assets/src/scripts/web-services/camera-images.test.js
index 0272bf9e57c9de762f64480e0d60cc9a6deabe04..9db28923cdf671501c5bc7335be4c86eb04f68ac 100644
--- a/assets/src/scripts/web-services/camera-images.test.js
+++ b/assets/src/scripts/web-services/camera-images.test.js
@@ -1,7 +1,7 @@
 import {enableFetchMocks, disableFetchMocks} from 'jest-fetch-mock';
 import mockConsole from 'jest-mock-console';
 
-import {MOCK_CAMERA_METADATA} from '../mock-service-data';
+import {MOCK_CAMERA_METADATA} from 'ui/mock-service-data';
 
 import {fetchCameraMetaData} from './camera-images';
 
@@ -23,10 +23,11 @@ describe('web-services/camera-images', () => {
 
         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');
+            const resp = await fetchCameraMetaData('05428500');
 
             expect(fetch.mock.calls).toHaveLength(1);
             expect(fetch.mock.calls[0][0]).toContain('siteID=05428500');
@@ -36,21 +37,21 @@ describe('web-services/camera-images', () => {
 
         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');
+            const resp = await fetchCameraMetaData('05428500');
 
             expect(resp).toEqual({success: false});
         });
 
         it('handles a 400 bad status', async() => {
             fetch.once('{}', {status: 400});
-            const resp= await fetchCameraMetaData('05428500');
+            const resp = await fetchCameraMetaData('05428500');
 
             expect(resp).toEqual({success: false});
         });
 
         it('handles a bad fetch', async() => {
             fetch.mockReject(new Error('fake error message'));
-            const resp= await fetchCameraMetaData('05428500');
+            const resp = await fetchCameraMetaData('05428500');
 
             expect(resp).toEqual({success: false});
         });
diff --git a/assets/src/scripts/web-services/fim-data.js b/assets/src/scripts/web-services/fim-data.js
new file mode 100644
index 0000000000000000000000000000000000000000..f6ba492e938b983368972fd42e0a40d76aaf074b
--- /dev/null
+++ b/assets/src/scripts/web-services/fim-data.js
@@ -0,0 +1,78 @@
+import config from 'ui/config';
+
+const FLOOD_SITES_ENDPOINT = `${config.FIM_GIS_ENDPOINT}sites/MapServer/`;
+const FLOOD_EXTENTS_ENDPOINT = `${config.FIM_GIS_ENDPOINT}floodExtents/MapServer/`;
+
+/*
+ * Determine if a site has public FIM data
+ * @param {String} siteno
+ * @return {Promise} resolves to a boolean, true if public, false otherwise
+ */
+export const fetchFIMPublicStatus = async function(siteno) {
+    const query = `where=SITE_NO='${siteno}'&outFields=PUBLIC,SITE_NO&f=json`;
+    const url = `${FLOOD_SITES_ENDPOINT}0/query?${encodeURI(query)}`;
+    try {
+        const response = await fetch(url, {
+            method: 'GET'
+        });
+        if (response.status === 200) {
+            const respJSON = await response.json();
+            return respJSON.features[0].attributes.Public > 0;
+        } else {
+            console.error(`Received bad status, ${response.status} from ${url}`);
+            return false;
+        }
+    } catch(error) {
+        console.error(`Failed fetch for ${url}`);
+        return false;
+    }
+};
+
+/*
+ * Retrieve flood features if any for siteno
+ * @param {String} siteno
+ * @return {Promise} resolves to an array of features for the site
+ */
+export const fetchFloodFeatures = async function(siteno) {
+    const query = `where=USGSID = '${siteno}'&outFields=USGSID,STAGE&returnGeometry=false&f=json`;
+    const url = `${FLOOD_EXTENTS_ENDPOINT}0/query?${encodeURI(query)}`;
+    try {
+        const response = await fetch(url, {
+            method: 'GET'
+        });
+        if (response.status === 200) {
+            const respJSON = await response.json();
+            return respJSON.features ? respJSON.features : [];
+        } else {
+            console.error(`Received bad status, ${response.status} for ${url}`);
+            return [];
+        }
+    } catch(error) {
+        console.error(`Failed fetch for ${url}`);
+        return [];
+    }
+};
+
+/*
+ * Retrieve the extent of the flood information for siteno
+ * @param {String} siteno
+ * @return {Promise} resolves to the extent Object or the empty object if any errors
+ */
+export const fetchFloodExtent = async function(siteno) {
+    const query = `where=USGSID = '${siteno}'&returnExtentOnly=true&outSR=4326&f=json`
+    const url = `${FLOOD_EXTENTS_ENDPOINT}0/query?${encodeURI(query)}`;
+    try {
+        const response = await fetch(url, {
+            method: 'GET'
+        });
+        if (response.status === 200) {
+            return await response.json();
+        } else {
+            console.error(`Received bad status, ${response.status} for ${url}`)
+            return {};
+        }
+    } catch(error) {
+        console.error(`Failed fetch for ${url}`);
+        return {};
+    }
+};
diff --git a/assets/src/scripts/web-services/fim-data.test.js b/assets/src/scripts/web-services/fim-data.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..b79872abab532e7073039a57a94ea1a05441e07b
--- /dev/null
+++ b/assets/src/scripts/web-services/fim-data.test.js
@@ -0,0 +1,200 @@
+import {disableFetchMocks, enableFetchMocks} from "jest-fetch-mock";
+import mockConsole from 'jest-mock-console';
+
+import {fetchFIMPublicStatus, fetchFloodExtent, fetchFloodFeatures} from './fim-data';
+
+
+describe('web-services/fim-data', () => {
+    beforeEach(() => {
+        enableFetchMocks();
+    });
+
+    afterEach(() => {
+        disableFetchMocks();
+    });
+
+    describe('web-services/fetchFIMPublicStatus', () => {
+        const siteno = '12345678';
+        let restoreConsole;
+        beforeEach(() => {
+            fetch.resetMocks();
+            restoreConsole = mockConsole();
+        });
+
+        afterEach(() => {
+            restoreConsole();
+        });
+
+        it('Expects response true if valid response and response indicates the site is public', async () => {
+            fetch.once(`{
+                            "features" :[{
+                                "attributes": {
+                                    "Public": 1,
+                                    "SITE_NO": "12345678"
+                                }
+                            }]
+                        }`, {status: 200});
+            const resp = await fetchFIMPublicStatus('12345678');
+
+            expect(fetch.mock.calls).toHaveLength(1);
+            expect(fetch.mock.calls[0][0]).toContain('12345678');
+            expect(resp).toBeTruthy();
+        });
+
+        it('Expects response false if valid response indicates the status is not public', async () => {
+            fetch.once(`{
+                            "features" :[{
+                                "attributes": {
+                                    "Public": 0,
+                                    "SITE_NO": "12345678"
+                                }
+                            }]
+                        }`, {status: 200});
+            const resp = await fetchFIMPublicStatus('12345678');
+
+            expect(resp).toBeFalsy();
+        });
+
+        it('handles a 400 bad status', async () => {
+            fetch.once('{}', {status: 400});
+            const resp = await fetchFIMPublicStatus('12345678');
+
+            expect(resp).toBeFalsy();
+        });
+
+        it('handles a bad fetch', async () => {
+            fetch.mockReject(new Error('fake error message'));
+            const resp = await fetchFIMPublicStatus('12345678');
+
+            expect(resp).toBeFalsy();
+        });
+    });
+
+    describe('web-services/fetchFloodFeatures', () => {
+        let restoreConsole;
+        beforeEach(() => {
+            fetch.resetMocks();
+            restoreConsole = mockConsole();
+        });
+
+        afterEach(() => {
+            restoreConsole();
+        });
+
+        it('Expects valid response to return features if in response', async () => {
+            fetch.once(MOCK_FLOOD_FEATURE, {status: 200});
+            const resp = await fetchFloodFeatures('12345678');
+
+            expect(fetch.mock.calls).toHaveLength(1);
+            expect(fetch.mock.calls[0][0]).toContain('12345678');
+            expect(resp).toEqual(JSON.parse(MOCK_FLOOD_FEATURE).features);
+        });
+
+        it('Expects valid response with no features to return an emty array', async () => {
+            fetch.once('{}', {status: 200});
+            const resp = await fetchFloodFeatures('12345678');
+
+            expect(resp).toHaveLength(0);
+        });
+
+        it('handles a 400 bad status', async () => {
+            fetch.once('{}', {status: 400});
+            const resp = await fetchFloodFeatures('12345678')
+
+            expect(resp).toHaveLength(0);
+        });
+
+        it('handles a bad fetch', async () => {
+            fetch.mockReject(new Error('fake error message'));
+            const resp = await await fetchFloodFeatures('12345678')
+
+            expect(resp).toHaveLength(0);
+        });
+    });
+
+    describe('web-services/fetchFloodExtent', () => {
+        let restoreConsole;
+        beforeEach(() => {
+            fetch.resetMocks();
+            restoreConsole = mockConsole();
+        });
+
+        afterEach(() => {
+            restoreConsole();
+        });
+
+        it('Expects a valid response to return the payload', async () => {
+            fetch.once(MOCK_FLOOD_EXTENT, {status: 200});
+            const resp = await fetchFloodExtent('12345678');
+
+            expect(fetch.mock.calls).toHaveLength(1);
+            expect(fetch.mock.calls[0][0]).toContain('12345678');
+            expect(resp).toEqual(JSON.parse(MOCK_FLOOD_EXTENT));
+        });
+
+        it('handles a 400 bad status', async () => {
+            fetch.once('{}', {status: 400});
+            const resp = await fetchFloodExtent('12345678');
+
+            expect(resp).toEqual({});
+        });
+
+        it('handles a bad fetch', async () => {
+            fetch.mockReject(new Error('fake error message'));
+            const resp = await fetchFloodExtent('12345678');
+
+            expect(resp).toEqual({});
+        });
+    });
+});
+
+const MOCK_FLOOD_FEATURE = `
+{
+	"displayFieldName": "USGSID",
+	"fieldAliases": {
+		"USGSID": "USGSID",
+		"STAGE": "STAGE"
+	},
+	"fields": [{
+		"name": "USGSID",
+		"type": "esriFieldTypeString",
+		"alias": "USGSID",
+		"length": 254
+	}, {
+		"name": "STAGE",
+		"type": "esriFieldTypeDouble",
+		"alias": "STAGE"
+	}],
+	"features": [{
+		"attributes": {
+			"USGSID": "03341500",
+			"STAGE": 30
+		}
+	}, {
+		"attributes": {
+			"USGSID": "03341500",
+			"STAGE": 29
+		}
+	}, {
+		"attributes": {
+			"USGSID": "03341500",
+			"STAGE": 28
+		}
+	}]
+}
+`;
+
+const MOCK_FLOOD_EXTENT = `
+{
+	"extent": {
+		"xmin": -84.353211731250525,
+		"ymin": 34.016663666167332,
+		"xmax": -84.223456338038901,
+		"ymax": 34.100999075364072,
+		"spatialReference": {
+			"wkid": 4326,
+			"latestWkid": 4326
+		}
+	}
+}
+`;
diff --git a/assets/src/scripts/web-services/flood-data.js b/assets/src/scripts/web-services/flood-data.js
deleted file mode 100644
index 30f7d7f52f149caf4961b2b500f15e7c3174765a..0000000000000000000000000000000000000000
--- a/assets/src/scripts/web-services/flood-data.js
+++ /dev/null
@@ -1,87 +0,0 @@
-import {get} from 'ui/ajax';
-import config from 'ui/config';
-
-export const FLOOD_SITES_ENDPOINT = `${config.FIM_GIS_ENDPOINT}sites/MapServer/`;
-export const FLOOD_EXTENTS_ENDPOINT = `${config.FIM_GIS_ENDPOINT}floodExtents/MapServer/`;
-
-const WATERWATCH_URL = config.WATERWATCH_ENDPOINT;
-const FORMAT = 'json';
-
-/*
- * Determine if a site has public FIM data
- * @param {String} siteno
- * @return {Promise} resolves to a boolean, true if public, false otherwise
- */
-export const fetchFIMPublicStatus = function(siteno) {
-    const FIM_SITE_QUERY = `${FLOOD_SITES_ENDPOINT}/0/query?where=SITE_NO%3D%27${siteno}%27&text=&objectIds=&time=&geometry=&geometryType=esriGeometryEnvelope&inSR=&spatialRel=esriSpatialRelIntersects&relationParam=&outFields=PUBLIC%2CSITE_NO&returnGeometry=false&returnTrueCurves=false&maxAllowableOffset=&geometryPrecision=&outSR=&returnIdsOnly=false&returnCountOnly=false&orderByFields=&groupByFieldsForStatistics=&outStatistics=&returnZ=false&returnM=false&gdbVersion=&returnDistinctValues=false&resultOffset=&resultRecordCount=&f=pjson`;
-    return get(FIM_SITE_QUERY)
-        .then((response) => {
-            const respJson = JSON.parse(response);
-            return respJson.features[0].attributes.Public > 0;
-        })
-        .catch(reason => {
-            console.log(`Unable to get FIM Public Status data for ${siteno} with reason: ${reason}`);
-            return false;
-        });
-};
-
-/*
- * Retrieve flood features if any for siteno
- * @param {String} siteno
- * @return {Promise} resolves to an array of features for the site
- */
-export const fetchFloodFeatures = function(siteno) {
-    const FIM_QUERY = `${FLOOD_EXTENTS_ENDPOINT}/0/query?where=USGSID+%3D+%27${siteno}%27&outFields=USGSID%2C+STAGE&returnGeometry=false&returnTrueCurves=false&returnIdsOnly=false&returnCountOnly=false&returnZ=false&returnM=falsereturnDistinctValues=false&f=json`;
-
-    return get(FIM_QUERY)
-        .then((response) => {
-            const respJson = JSON.parse(response);
-            return respJson.features ? respJson.features : [];
-        })
-        .catch(reason => {
-            console.log(`Unable to get FIM stages for ${siteno} with reason: ${reason}`);
-            return [];
-        });
-};
-/*
- * Retrieve the extent of the flood information for siteno
- * @param {String} siteno
- * @return {Promise} resolves to the extent Object or the empty object if an errors
- */
-export const fetchFloodExtent = function(siteno) {
-    const FIM_QUERY = `${FLOOD_EXTENTS_ENDPOINT}/0/query?where=USGSID+%3D+%27${siteno}%27&returnExtentOnly=true&outSR=4326&f=json`;
-    return get(FIM_QUERY)
-        .then((response) => {
-            return JSON.parse(response);
-        })
-        .catch(reason => {
-            console.log(`Unable to get FIM extents for ${siteno} with reason: ${reason}`);
-            return {};
-        });
-};
-
-/*
- * Retrieve waterwatch flood levels any for siteno
- * @param {String} siteno
- * @return {Promise} resolves to an array of features for the site
- */
-const fetchWaterwatchData = function(waterwatchQuery, siteno) {
-    return get(waterwatchQuery)
-        .then((responseText) => {
-            const response = JSON.parse(responseText);
-            if (!response.sites || !response.sites.length) {
-                return null;
-            }
-            return response.sites[0];
-        })
-        .catch(reason => {
-            console.log(`Unable to get Waterwatch data for ${siteno} with reason: ${reason}`);
-            return null;
-        });
-};
-
-// waterwatch webservice calls
-export const fetchWaterwatchFloodLevels = function(siteno) {
-    const waterwatchQuery = `${WATERWATCH_URL}/floodstage?format=${FORMAT}&site=${siteno}`;
-    return fetchWaterwatchData(waterwatchQuery, siteno);
-};
diff --git a/assets/src/scripts/web-services/flood-data.test.js b/assets/src/scripts/web-services/flood-data.test.js
deleted file mode 100644
index f12abc46159172be037d5cd44306426680caddb9..0000000000000000000000000000000000000000
--- a/assets/src/scripts/web-services/flood-data.test.js
+++ /dev/null
@@ -1,250 +0,0 @@
-import sinon from 'sinon';
-
-import {MOCK_WATERWATCH_FLOOD_LEVELS} from 'ui/mock-service-data';
-
-import {fetchFIMPublicStatus, fetchFloodExtent, fetchFloodFeatures,
-    fetchWaterwatchFloodLevels} from './flood-data';
-
-
-describe('web-services/flood-data', () => {
-    let fakeServer;
-    beforeEach(() => {
-        fakeServer = sinon.createFakeServer();
-    });
-
-    afterEach(() => {
-        fakeServer.restore();
-    });
-
-    describe('fetchFIMPublicStatus', () => {
-        const siteno = '12345678';
-        describe('with valid response', () => {
-            let promise;
-
-            it('expected response is true', () => {
-                promise = fetchFIMPublicStatus(siteno);
-                fakeServer.requests[0].respond(
-                    200,
-                    {'Content-Type': 'application/json'},
-                    `{
-                        "features" :[{
-                            "attributes": {
-                                "Public": 1,
-                                "SITE_NO": "12345678"
-                            }
-                        }]
-                    }`
-                );
-
-                return promise.then((resp) => {
-                    expect(resp).toBeTruthy();
-                });
-            });
-
-            it('expected response is False', () => {
-                promise = fetchFIMPublicStatus(siteno);
-                fakeServer.requests[0].respond(
-                    200,
-                    {
-                        'Content-Type': 'appliation/json'
-                    },
-                    `{
-                        "features": [{
-                            "attributes": {
-                                "Public": 0,
-                                "SITE_NO": "12345678"
-                            }
-                        }]
-                    }`
-                );
-
-                return promise.then((resp) => {
-                    expect(resp).toBeFalsy();
-                });
-            });
-        });
-
-        describe('with error response', () => {
-            it('On failed response return false', () => {
-                const fetchPromise = fetchFIMPublicStatus(siteno);
-                fakeServer.requests[0].respond(500);
-                return fetchPromise.then((resp) => {
-                   expect(resp).toBeFalsy();
-                });
-            });
-        });
-    });
-
-    describe('fetchFloodFeatures', () => {
-        const siteno = '12345678';
-
-        describe('with valid response', () => {
-            let promise;
-
-            beforeEach(() => {
-                /* eslint no-use-before-define: 0 */
-                promise = fetchFloodFeatures(siteno);
-                fakeServer.requests[0].respond(
-                    200,
-                    {
-                        'Content-Type': 'application/json'
-                    },
-                    MOCK_FLOOD_FEATURE
-                );
-            });
-
-            it('expected response is json object with the stages', () => {
-                return promise.then((resp) => {
-                    expect(resp).toHaveLength(3);
-                    expect(resp[0].attributes.STAGE).toBe(30);
-                    expect(resp[1].attributes.STAGE).toBe(29);
-                    expect(resp[2].attributes.STAGE).toBe(28);
-                });
-            });
-        });
-
-        describe('with error response', () => {
-            it('On failed response return an empty feature list', () => {
-                const fetchPromise = fetchFloodFeatures(siteno);
-                fakeServer.requests[0].respond(500);
-                return fetchPromise.then((resp) => {
-                   expect(resp).toHaveLength(0);
-                });
-            });
-        });
-    });
-
-    describe('web-services/fetchFloodExtent', () => {
-        let promise;
-        const siteno = '12345678';
-
-        describe('with valid response', () => {
-
-            beforeEach(() => {
-                /* eslint no-use-before-define: 0 */
-                promise = fetchFloodExtent(siteno);
-                fakeServer.requests[0].respond(
-                    200,
-                    {
-                        'Content-Type': 'application/json'
-                    },
-                    MOCK_FLOOD_EXTENT
-                );
-            });
-
-            it('expected response is json object with the extent', () => {
-                return promise.then((resp) => {
-                    expect(resp.extent).toBeDefined();
-                    expect(resp.extent.xmin).toBe(-84.353211731250525);
-                    expect(resp.extent.xmax).toBe(-84.223456338038901);
-                    expect(resp.extent.ymin).toBe(34.016663666167332);
-                    expect(resp.extent.ymax).toBe(34.100999075364072);
-                });
-            });
-        });
-
-        describe('with error response', () => {
-            beforeEach(() => {
-                /* eslint no-use-before-define: 0 */
-                promise = fetchFloodExtent(siteno);
-                fakeServer.requests[0].respond(500);
-            });
-
-            it('On failed response return an empty feature list', () => {
-               return promise.then((resp) => {
-                   expect(resp).toEqual({});
-               });
-            });
-        });
-    });
-
-    describe('web-services/fetchWaterwatchFloodLevels', () => {
-        let floodLevelPromise;
-        const siteno = '07144100';
-
-        describe('with valid response', () => {
-
-            beforeEach(() => {
-                /* eslint no-use-before-define: 0 */
-
-                floodLevelPromise = fetchWaterwatchFloodLevels(siteno);
-
-                fakeServer.requests[0].respond(
-                    200,
-                    {
-                        'Content-Type': 'application/json'
-                    },
-                    MOCK_WATERWATCH_FLOOD_LEVELS
-                );
-            });
-
-            it('expected response is json object with the flood levels', () => {
-                return floodLevelPromise.then((resp) => {
-                    expect(resp).not.toEqual(null);
-                    expect(resp.site_no).toBe('07144100');
-                });
-            });
-        });
-
-        describe('with error response', () => {
-            it('On failed response return an empty flood levels list', () => {
-                const fetchPromise = fetchWaterwatchFloodLevels(siteno);
-                fakeServer.requests[0].respond(500, {}, 'Error');
-                return fetchPromise.then((resp) => {
-                    expect(resp).toBeNull();
-                });
-            });
-        });
-    });
-});
-
-const MOCK_FLOOD_FEATURE = `
-{
-	"displayFieldName": "USGSID",
-	"fieldAliases": {
-		"USGSID": "USGSID",
-		"STAGE": "STAGE"
-	},
-	"fields": [{
-		"name": "USGSID",
-		"type": "esriFieldTypeString",
-		"alias": "USGSID",
-		"length": 254
-	}, {
-		"name": "STAGE",
-		"type": "esriFieldTypeDouble",
-		"alias": "STAGE"
-	}],
-	"features": [{
-		"attributes": {
-			"USGSID": "03341500",
-			"STAGE": 30
-		}
-	}, {
-		"attributes": {
-			"USGSID": "03341500",
-			"STAGE": 29
-		}
-	}, {
-		"attributes": {
-			"USGSID": "03341500",
-			"STAGE": 28
-		}
-	}]
-}
-`;
-
-const MOCK_FLOOD_EXTENT = `
-{
-	"extent": {
-		"xmin": -84.353211731250525,
-		"ymin": 34.016663666167332,
-		"xmax": -84.223456338038901,
-		"ymax": 34.100999075364072,
-		"spatialReference": {
-			"wkid": 4326,
-			"latestWkid": 4326
-		}
-	}
-}
-`;
diff --git a/assets/src/scripts/web-services/flood-levels.js b/assets/src/scripts/web-services/flood-levels.js
new file mode 100644
index 0000000000000000000000000000000000000000..ad6d5a74b23027e84af7a3e5549eea07881dda3f
--- /dev/null
+++ b/assets/src/scripts/web-services/flood-levels.js
@@ -0,0 +1,25 @@
+import config from 'ui/config';
+
+/*
+ * Retrieve NOAA flood levels from the water watch endpointany for siteno
+ * @param {String} siteno
+ * @return {Promise} resolves to an Object containing the available flood levels or null if none.
+ */
+export const fetchFloodLevels = async function(siteno) {
+    const url = `${config.WATERWATCH_ENDPOINT}/floodstage?site=${siteno}&format=json`;
+    try {
+        const response = await fetch(url, {
+            method: 'GET'
+        });
+        if (response.status === 200) {
+            const respJSON = await response.json();
+            return respJSON.sites && respJSON.sites.length ? respJSON.sites[0] : null;
+        } else {
+            console.error(`Received bad status, ${response.status} for ${url}`)
+            return null;
+        }
+    } catch(error) {
+        console.error(`Failed fetch for ${url}`);
+        return null;
+    }
+}
diff --git a/assets/src/scripts/web-services/flood-levels.test.js b/assets/src/scripts/web-services/flood-levels.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..c37c2179c2c28742fe0cfed752a7f8e3b8979882
--- /dev/null
+++ b/assets/src/scripts/web-services/flood-levels.test.js
@@ -0,0 +1,58 @@
+import {enableFetchMocks, disableFetchMocks} from 'jest-fetch-mock';
+import mockConsole from 'jest-mock-console';
+
+import {MOCK_WATERWATCH_FLOOD_LEVELS} from 'ui/mock-service-data';
+
+import {fetchFloodLevels} from './flood-levels';
+
+describe('web-services/flood-levels', () => {
+    beforeEach(() => {
+        enableFetchMocks();
+    });
+
+    afterEach(() => {
+        disableFetchMocks();
+    });
+
+    describe('fetchFloodLevels', () => {
+        let restoreConsole;
+        beforeEach(() => {
+            fetch.resetMocks();
+            restoreConsole = mockConsole();
+        });
+
+        afterEach(() => {
+            restoreConsole();
+        });
+
+        it('Valid response with flood levels returns the flood level object', async () => {
+            fetch.once(MOCK_WATERWATCH_FLOOD_LEVELS, {status: 200});
+            const resp = await fetchFloodLevels('12345678');
+
+            expect(fetch.mock.calls).toHaveLength(1);
+            expect(fetch.mock.calls[0][0]).toContain('site=12345678');
+            expect(resp).toEqual(JSON.parse(MOCK_WATERWATCH_FLOOD_LEVELS).sites[0]);
+        });
+
+        it('valid response without flood levels returns null', async() => {
+            fetch.once('{sites:[]}', {status: 200});
+            const resp = await fetchFloodLevels('12345678');
+
+            expect(resp).toBeNull();
+        });
+
+        it('handles a 400 bad status', async() => {
+            fetch.once('{}', {status: 400});
+            const resp = await fetchFloodLevels('12345678');
+
+            expect(resp).toBeNull();
+        });
+
+        it('handles a bad fetch', async() => {
+            fetch.mockReject(new Error('fake error message'));
+            const resp = await fetchFloodLevels('12345678');
+
+            expect(resp).toBeNull();
+        });
+    });
+});
\ No newline at end of file
diff --git a/assets/src/styles/components/hydrograph/_graph.scss b/assets/src/styles/components/hydrograph/_graph.scss
index 43eb0822f14219c0d4a09a63ff795a00794ae06c..1a0d741584d2f945a5d9b2c3493a745413cebf9e 100644
--- a/assets/src/styles/components/hydrograph/_graph.scss
+++ b/assets/src/styles/components/hydrograph/_graph.scss
@@ -211,7 +211,7 @@ svg {
     stroke: #ff2600;
   }
 
-  .waterwatch-data-series {
+  .flood-levels-series {
     fill: none;
     stroke-width: 1px;
     stroke: #001aff;