import {select, selectAll} from 'd3-selection'; import {enableFetchMocks, disableFetchMocks} from 'jest-fetch-mock'; import mockConsole from 'jest-mock-console'; import * as utils from 'ui/utils'; import config from 'ui/config'; import {configureStore} from 'ml/store'; import {Actions as floodDataActions} from 'ml/store/flood-data'; import * as groundwaterLevelData from 'ml/store/groundwater-level-field-visits'; import * as hydrographData from 'ml/store/hydrograph-data'; import * as hydrographParameters from 'ml/store/hydrograph-parameters'; import * as hydrographParameterSelectors from 'ml/selectors/hydrograph-parameters-selector'; import {attachToNode} from './index'; import { TEST_CURRENT_TIME_RANGE, TEST_GW_LEVELS, TEST_HYDROGRAPH_PARAMETERS, TEST_STATS_DATA, TEST_PRIMARY_IV_DATA } from './mock-hydrograph-state'; describe('monitoring-location/components/hydrograph module', () => { utils.mediaQuery = jest.fn().mockReturnValue(true); utils.wrap = jest.fn(); config.locationTimeZone = 'America/Chicago'; config.ivPeriodOfRecord = { '72019': { begin_date: '01-02-2001', end_date: '10-15-2015' }, '00060': { begin_date: '04-01-1991', end_date: '10-15-2007' }, '00065': { begin_date: '04-01-1991', end_date: '10-15-2007' }, '00093': { begin_date: '11-25-2001', end_date: '03-01-2020' }, '00067': { begin_date: '04-01-1990', end_date: '10-15-2006' } }; config.gwPeriodOfRecord = { '72019': { begin_date: '01-02-2000', end_date: '10-15-2015' } }; let graphNode; let nodeElem; const INITIAL_PARAMETERS = { siteno: '11112222', agencyCd: 'USGS', sitename: 'Site name', parameterCode: '72019' }; let restoreConsole; beforeAll(() => { enableFetchMocks(); restoreConsole = mockConsole(); }); afterAll(() => { disableFetchMocks(); restoreConsole(); }); beforeEach(() => { let body = select('body'); body.append('a') .attr('id', 'classic-page-link') .attr('href', 'https://fakeserver/link'); let component = body.append('div') .attr('id', 'hydrograph'); component.append('div').attr('id', 'hydrograph-method-picker-container'); component.append('div').attr('class', 'graph-container') .append('div') .attr('id', 'hydrograph-loading-indicator-container') .attr('class', 'loading-indicator-container'); component.append('div').attr('class', 'short-cut-time-span-container'); component.append('div').attr('class', 'select-actions-container'); component.append('div').attr('class', 'select-time-series-container'); component.append('div').attr('id', 'iv-data-table-container'); component.append('div').attr('class', 'daily-statistical-data'); graphNode = document.getElementById('hydrograph'); nodeElem = select(graphNode); }); afterEach(() => { select('#hydrograph').remove(); select('#classic-page-link').remove(); }); describe('Tests for initial data fetching and setting', () => { let store; let retrieveHydrographDataSpy, retrieveHydrographParametersSpy, retrieveFloodLevelsSpy; beforeEach(() => { store = configureStore({ hydrographData: {}, groundwaterLevelData: { all: [] }, hydrographState: {}, hydrographParameters: {}, floodData: {}, ui: { width: 1000 } }); retrieveHydrographDataSpy = jest.spyOn(hydrographData, 'retrieveHydrographData'); retrieveHydrographParametersSpy = jest.spyOn(hydrographParameters, 'retrieveHydrographParameters'); retrieveFloodLevelsSpy = jest.spyOn(floodDataActions, 'retrieveFloodLevels'); }); it('Loading indicator should be shown', () => { attachToNode(store, graphNode, INITIAL_PARAMETERS); expect(nodeElem.select('.loading-indicator').size()).toBe(1); }); describe('Fetching initial hydrograph data', () => { it('With just parameter code set', () => { attachToNode(store, graphNode, INITIAL_PARAMETERS); expect(retrieveHydrographDataSpy).toHaveBeenCalledWith('11112222', 'USGS', { parameterCode: '72019', secondaryParameterCode: null, period: 'P7D', startTime: null, endTime: null, loadCompare: false }, true ); expect(store.getState().hydrographState).toEqual({ selectedParameterCode: '72019', selectedTimeSpan: 'P7D', showCompareIVData: false, selectedIVMethodID: undefined }); }); it('With custom period', () => { attachToNode(store, graphNode, { ...INITIAL_PARAMETERS, period: 'P45D' }); expect(retrieveHydrographDataSpy).toHaveBeenCalledWith('11112222', 'USGS', { parameterCode: '72019', secondaryParameterCode: null, period: 'P45D', startTime: null, endTime: null, loadCompare: false }, true ); expect(store.getState().hydrographState).toEqual({ selectedParameterCode: '72019', selectedTimeSpan: 'P45D', showCompareIVData: false, selectedIVMethodID: undefined }); }); it('With custom time range', () => { attachToNode(store, graphNode, { ...INITIAL_PARAMETERS, startDT: '2020-02-01', endDT: '2020-02-15' }); expect(retrieveHydrographDataSpy).toHaveBeenCalledWith('11112222', 'USGS', { parameterCode: '72019', secondaryParameterCode: null, period: null, startTime: '2020-02-01T00:00:00.000-06:00', endTime: '2020-02-15T23:59:59.999-06:00', loadCompare: false }, true ); expect(store.getState().hydrographState).toEqual({ selectedParameterCode: '72019', selectedTimeSpan: { start: '2020-02-01', end: '2020-02-15' }, showCompareIVData: false, selectedIVMethodID: undefined }); }); it('With compare enabled', () => { attachToNode(store, graphNode, { ...INITIAL_PARAMETERS, compare: true }); expect(retrieveHydrographDataSpy).toHaveBeenCalledWith('11112222', 'USGS', { parameterCode: '72019', secondaryParameterCode: null, period: 'P7D', startTime: null, endTime: null, loadCompare: true }, true ); expect(store.getState().hydrographState).toEqual({ selectedParameterCode: '72019', selectedTimeSpan: 'P7D', showCompareIVData: true, selectedIVMethodID: undefined }); }); }); it('Should fetch the hydrograph parameters', () => { attachToNode(store, graphNode, INITIAL_PARAMETERS); expect(retrieveHydrographParametersSpy).toHaveBeenCalledWith('11112222', 'USGS'); }); it('Should fetch the flood levels', () => { attachToNode(store, graphNode, INITIAL_PARAMETERS); 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', () => { attachToNode(store, graphNode, { ...INITIAL_PARAMETERS, showOnlyGraph: true }); expect(retrieveHydrographDataSpy).toHaveBeenCalledWith('11112222', 'USGS', { parameterCode: '72019', secondaryParameterCode: null, period: 'P7D', startTime: null, endTime: null, loadCompare: false }, true ); expect(store.getState().hydrographState).toEqual({ selectedParameterCode: '72019', selectedTimeSpan: 'P7D', showCompareIVData: false }); expect(retrieveFloodLevelsSpy).toHaveBeenCalled(); expect(retrieveHydrographParametersSpy).not.toHaveBeenCalled(); }); }); describe('Tests for rendering once fetching is complete when showOnlyGraph is false', () => { let store; beforeEach(() => { store = configureStore({ hydrographData: { primaryIVData: TEST_PRIMARY_IV_DATA, currentTimeRange: TEST_CURRENT_TIME_RANGE, statisticsData: TEST_STATS_DATA }, groundwaterLevelData: { all: [TEST_GW_LEVELS] }, hydrographState: { selectedIVMethodID: '90649', selectedParameterCode: null, showMedianData: true }, hydrographParameters: TEST_HYDROGRAPH_PARAMETERS, floodData: {}, ui: { width: 1000 } }); hydrographData.retrieveHydrographData = jest.fn(() => { return function() { return Promise.resolve(); }; }); hydrographParameters.retrieveHydrographParameters = jest.fn(() => { return function() { return Promise.resolve(); }; }); hydrographParameterSelectors.latestSelectedParameterValue = jest.fn().mockReturnValue(() => { return function() { return 123; }; }); attachToNode(store, graphNode, { ...INITIAL_PARAMETERS, showOnlyGraph: false }); jest.useFakeTimers('modern'); jest.setSystemTime(new Date(2020, 0, 1)); }); afterEach(() => { jest.useRealTimers(); }); it('loading indicator should be hidden', () => { expect(nodeElem.select('.loading-indicator').size()).toBe(0); }); it('should render the correct number of svg nodes', () => { expect(select('#hydrograph').select('.graph-container').selectAll('svg').size()).toBe(5); }); it('should have a title div', () => { const titleDiv = selectAll('.time-series-graph-title'); expect(titleDiv.size()).toBe(1); expect(titleDiv.select('div').text()).toContain('Depth to water level'); expect(titleDiv.select('.usa-tooltip').text()).toEqual('Depth to water level, feet'); }); it('should have a defs node', () => { expect(selectAll('defs').size()).toBe(1); expect(selectAll('defs mask').size()).toBe(1); expect(selectAll('defs pattern').size()).toBe(3); }); it('should render time series data as a line', () => { // There should be four segments expect(selectAll('.hydrograph-svg .line-segment').size()).toBe(4); }); it('should render a rectangle for masked data', () => { expect(selectAll('.hydrograph-svg g.iv-mask-group').size()).toBe(1); }); it('should have a point for the median stat data with a label', () => { expect(selectAll('#median-points path').size()).toBe(2); expect(selectAll('#median-points text').size()).toBe(0); }); it('should have brush element for the hydrograph', () => { expect(selectAll('.brush').size()).toBe(1); }); it('should have .cursor-slider-svg element', () => { expect(selectAll('.cursor-slider-svg').size()).toBe(1); }); it('should have method select element', () => { expect(selectAll('.method-picker-container').size()).toBe(1); }); it('should have the select time series element', () => { expect(selectAll('.main-parameter-selection-container').size()).toBe(1); }); it('should have data tables for hydrograph data', () => { expect(select('#iv-primary-table-container').size()).toBe(1); expect(select('#iv-secondary-table-container').size()).toBe(1); expect(select('#gw-table-container').size()).toBe(1); }); it('expects to create the daily statistics section', () => { expect(select('.stats-accordion').size()).toBe(1); }); }); describe('Tests for rendering once fetching is complete when showOnlyGraph is true', () => { let store; beforeEach(() => { store = configureStore({ hydrographData: { primaryIVData: TEST_PRIMARY_IV_DATA, currentTimeRange: TEST_CURRENT_TIME_RANGE, statisticsData: TEST_STATS_DATA }, groundwaterLevelData: { all: [TEST_GW_LEVELS] }, hydrographState: { selectedIVMethodID: '90649', showMedianData: true, selectedParameterCode: null }, hydrographParameters: TEST_HYDROGRAPH_PARAMETERS, floodData: {}, ui: { width: 1000 } }); hydrographData.retrieveHydrographData = jest.fn(() => { return function() { return Promise.resolve(); }; }); groundwaterLevelData.retrieveGroundwaterLevelData = jest.fn(() => { return function() { return Promise.resolve(); }; }); hydrographParameters.retrieveHydrographParameters = jest.fn(() => { return function() { return Promise.resolve(); }; }); attachToNode(store, graphNode, { ...INITIAL_PARAMETERS, showOnlyGraph: true }); }); it('loading indicator should be hidden', () => { expect(nodeElem.select('.loading-indicator').size()).toBe(0); }); it('should render the correct number of svg nodes', () => { expect(selectAll('svg').size()).toBe(1); }); it('should have a title div', () => { const titleDiv = selectAll('.time-series-graph-title'); expect(titleDiv.size()).toBe(1); }); it('should have a defs node', () => { expect(selectAll('defs').size()).toBe(1); expect(selectAll('defs mask').size()).toBe(1); expect(selectAll('defs pattern').size()).toBe(3); }); it('should render time series data as a line', () => { // There should be four segments expect(selectAll('.hydrograph-svg .line-segment').size()).toBe(4); }); it('should render a rectangle for masked data', () => { expect(selectAll('.hydrograph-svg g.iv-mask-group').size()).toBe(1); }); it('should have a point for the median stat data with a label', () => { expect(selectAll('#median-points path').size()).toBe(2); expect(selectAll('#median-points text').size()).toBe(0); }); it('should not have brush element for the hydrograph', () => { expect(selectAll('.brush').size()).toBe(0); }); it('should not have .cursor-slider-svg element', () => { expect(selectAll('.cursor-slider-svg').size()).toBe(0); }); it('should not have time span elements', () => { expect(selectAll('#change-time-span-container').size()).toBe(0); }); it('should not have the download data element', () => { expect(selectAll('#download-graph-data-container-select-actions').size()).toBe(0); }); it('should not have method select element', () => { expect(selectAll('#ts-method-select-container').size()).toBe(0); }); it('should not have the select time series element', () => { expect(selectAll('#select-time-series').size()).toBe(0); }); it('should not have data tables for hydrograph data', () => { expect(select('#iv-primary-table-container').size()).toBe(0); expect(select('#iv-secondary-table-container').size()).toBe(0); expect(select('#gw-table-container').size()).toBe(0); }); it('expects to not create the daily statistics section', () => { expect(select('.stats-accordion').size()).toBe(0); }); }); });