diff --git a/src/components/graphCard/graphCard.js b/src/components/graphCard/graphCard.js index eb0041b36..0487d935e 100644 --- a/src/components/graphCard/graphCard.js +++ b/src/components/graphCard/graphCard.js @@ -25,7 +25,7 @@ class GraphCard extends React.Component { } onUpdateGraphData = () => { - const { getGraphCapacity, getGraphReports, graphGranularity, startDate, endDate, productId } = this.props; + const { getGraphReportsCapacity, graphGranularity, startDate, endDate, productId } = this.props; const query = { [rhsmApiTypes.RHSM_API_QUERY_GRANULARITY]: graphGranularity, [rhsmApiTypes.RHSM_API_QUERY_START_DATE]: startDate.toISOString(), @@ -33,8 +33,7 @@ class GraphCard extends React.Component { }; if (productId) { - getGraphCapacity(productId, query); - getGraphReports(productId, query); + getGraphReportsCapacity(productId, query); } }; @@ -164,8 +163,7 @@ GraphCard.propTypes = { stroke: PropTypes.string }) ), - getGraphCapacity: PropTypes.func, - getGraphReports: PropTypes.func, + getGraphReportsCapacity: PropTypes.func, graphData: PropTypes.object, graphGranularity: PropTypes.oneOf([ GRANULARITY_TYPES.DAILY, @@ -186,8 +184,7 @@ GraphCard.defaultProps = { cardTitle: null, error: false, filterGraphData: [], - getGraphCapacity: helpers.noop, - getGraphReports: helpers.noop, + getGraphReportsCapacity: helpers.noop, graphData: {}, graphGranularity: GRANULARITY_TYPES.DAILY, pending: false, @@ -208,8 +205,7 @@ const makeMapStateToProps = () => { }; const mapDispatchToProps = dispatch => ({ - getGraphCapacity: (id, query) => dispatch(reduxActions.rhsm.getGraphCapacity(id, query)), - getGraphReports: (id, query) => dispatch(reduxActions.rhsm.getGraphReports(id, query)) + getGraphReportsCapacity: (id, query) => dispatch(reduxActions.rhsm.getGraphReportsCapacity(id, query)) }); const ConnectedGraphCard = connectTranslate(makeMapStateToProps, mapDispatchToProps)(GraphCard); diff --git a/src/components/i18n/__tests__/__snapshots__/i18n.test.js.snap b/src/components/i18n/__tests__/__snapshots__/i18n.test.js.snap index f1cf5b4be..1e4d11e40 100644 --- a/src/components/i18n/__tests__/__snapshots__/i18n.test.js.snap +++ b/src/components/i18n/__tests__/__snapshots__/i18n.test.js.snap @@ -30,8 +30,8 @@ msgstr \\"\\" msgid \\"curiosity-graph.dropdownMonthly\\" msgstr \\"\\" -#: src/components/graphCard/graphCard.js:131 -#: src/components/graphCard/graphCard.js:135 +#: src/components/graphCard/graphCard.js:130 +#: src/components/graphCard/graphCard.js:134 msgid \\"curiosity-graph.dropdownPlaceholder\\" msgstr \\"\\" diff --git a/src/redux/actions/__tests__/rhsmActions.test.js b/src/redux/actions/__tests__/rhsmActions.test.js index 106058d93..11cfa23ef 100644 --- a/src/redux/actions/__tests__/rhsmActions.test.js +++ b/src/redux/actions/__tests__/rhsmActions.test.js @@ -19,15 +19,14 @@ describe('RhsmActions', () => { beforeEach(() => { moxios.install(); - moxios.wait(() => { - const request = moxios.requests.mostRecent(); - request.respondWith({ - status: 200, - response: { - test: 'success', - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA]: ['success'] - } - }); + moxios.stubRequest(/\/(tally|capacity|version).*?/, { + status: 200, + responseText: 'success', + timeout: 1, + response: { + test: 'success', + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA]: ['success'] + } }); }); @@ -35,6 +34,17 @@ describe('RhsmActions', () => { moxios.uninstall(); }); + it('Should return response content for getGraphReportsCapacity method', done => { + const store = generateStore(); + const dispatcher = rhsmActions.getGraphReportsCapacity(); + + dispatcher(store.dispatch).then(() => { + const response = store.getState().graph; + expect(response.reportCapacity.fulfilled).toBe(true); + done(); + }); + }); + it('Should return response content for getGraphReports method', done => { const store = generateStore(); const dispatcher = rhsmActions.getGraphReports(); diff --git a/src/redux/actions/rhsmActions.js b/src/redux/actions/rhsmActions.js index a61176e1f..3d6a34cc4 100644 --- a/src/redux/actions/rhsmActions.js +++ b/src/redux/actions/rhsmActions.js @@ -1,6 +1,23 @@ import { rhsmTypes } from '../types'; import { rhsmServices } from '../../services/rhsmServices'; +const getGraphReportsCapacity = (id = null, query = {}) => dispatch => + dispatch({ + type: rhsmTypes.GET_GRAPH_REPORT_CAPACITY_RHSM, + payload: Promise.all([rhsmServices.getGraphReports(id, query), rhsmServices.getGraphCapacity(id, query)]), + meta: { + data: { id }, + query, + notifications: { + rejected: { + variant: 'info', + title: 'Reporting and capacity connection has failed', + description: `Product ID: ${id}` + } + } + } + }); + const getGraphReports = (id = null, query = {}) => dispatch => dispatch({ type: rhsmTypes.GET_GRAPH_REPORT_RHSM, @@ -35,6 +52,6 @@ const getGraphCapacity = (id = null, query = {}) => dispatch => } }); -const rhsmActions = { getGraphCapacity, getGraphReports }; +const rhsmActions = { getGraphReportsCapacity, getGraphCapacity, getGraphReports }; -export { rhsmActions as default, rhsmActions, getGraphCapacity, getGraphReports }; +export { rhsmActions as default, rhsmActions, getGraphReportsCapacity, getGraphCapacity, getGraphReports }; diff --git a/src/redux/common/__tests__/__snapshots__/reduxHelpers.test.js.snap b/src/redux/common/__tests__/__snapshots__/reduxHelpers.test.js.snap index 9aa676708..e5a996510 100644 --- a/src/redux/common/__tests__/__snapshots__/reduxHelpers.test.js.snap +++ b/src/redux/common/__tests__/__snapshots__/reduxHelpers.test.js.snap @@ -1,5 +1,13 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`ReduxHelpers should get a date from a service call response: ARRAY date 1`] = `"Fri, 07 Feb 2020 10:46:53 GMT"`; + +exports[`ReduxHelpers should get a date from a service call response: date 1`] = `"Fri, 07 Feb 2020 10:46:53 GMT"`; + +exports[`ReduxHelpers should get a http status from a service call response: ARRAY mismatched status 1`] = `400`; + +exports[`ReduxHelpers should get a http status from a service call response: ARRAY status 1`] = `200`; + exports[`ReduxHelpers should get a http status from a service call response: fallback status 1`] = `200`; exports[`ReduxHelpers should get a http status from a service call response: missing status 1`] = `0`; @@ -12,6 +20,12 @@ exports[`ReduxHelpers should get a message from a service call response: 4XX fal exports[`ReduxHelpers should get a message from a service call response: 5XX fallback message 1`] = `"Internal Server Error"`; +exports[`ReduxHelpers should get a message from a service call response: ARRAY mismatched response messages 1`] = `"Request failed with status code 400"`; + +exports[`ReduxHelpers should get a message from a service call response: ARRAY response for 2XX 1`] = `"OK"`; + +exports[`ReduxHelpers should get a message from a service call response: ARRAY response for 4XX 1`] = `"Request failed with status code 400"`; + exports[`ReduxHelpers should get a message from a service call response: response for 2XX 1`] = `"OK"`; exports[`ReduxHelpers should get a message from a service call response: response for 4XX 1`] = `"Request failed with status code 400"`; @@ -23,9 +37,12 @@ Object { "PENDING_ACTION": [Function], "REJECTED_ACTION": [Function], "generatedPromiseActionReducer": [Function], + "getDateFromResults": [Function], "getMessageFromResults": [Function], + "getSingleResponseFromResultArray": [Function], "getStatusFromResults": [Function], "setStateProp": [Function], + "singlePromiseDataResponseFromArray": [Function], } `; diff --git a/src/redux/common/__tests__/reduxHelpers.test.js b/src/redux/common/__tests__/reduxHelpers.test.js index 3c3546936..a6f124442 100644 --- a/src/redux/common/__tests__/reduxHelpers.test.js +++ b/src/redux/common/__tests__/reduxHelpers.test.js @@ -23,6 +23,21 @@ describe('ReduxHelpers', () => { }) ).toMatchSnapshot('response for 2XX'); + expect( + reduxHelpers.getMessageFromResults([ + { + status: 200, + statusText: 'OK', + data: { lorem: 'ipsum', dolor: 'sit' } + }, + { + status: 200, + statusText: 'OK', + data: { hello: 'world' } + } + ]) + ).toMatchSnapshot('ARRAY response for 2XX'); + expect( reduxHelpers.getMessageFromResults({ response: { @@ -34,6 +49,23 @@ describe('ReduxHelpers', () => { }) ).toMatchSnapshot('response for 4XX'); + expect( + reduxHelpers.getMessageFromResults([ + { + status: 400, + statusText: 'Bad Request', + data: { lorem: 'ipsum', dolor: 'sit' }, + message: 'Request failed with status code 400' + }, + { + status: 400, + statusText: 'Bad Request', + data: { hello: 'world' }, + message: 'Request failed with status code 400' + } + ]) + ).toMatchSnapshot('ARRAY response for 4XX'); + expect( reduxHelpers.getMessageFromResults({ response: { @@ -60,6 +92,22 @@ describe('ReduxHelpers', () => { } }) ).toMatchSnapshot('5XX fallback message'); + + expect( + reduxHelpers.getMessageFromResults([ + { + status: 200, + statusText: 'OK', + data: { lorem: 'ipsum', dolor: 'sit' } + }, + { + status: 400, + statusText: 'Bad Request', + data: { hello: 'world' }, + message: 'Request failed with status code 400' + } + ]) + ).toMatchSnapshot('ARRAY mismatched response messages'); }); it('should get a http status from a service call response', () => { @@ -71,6 +119,17 @@ describe('ReduxHelpers', () => { }) ).toMatchSnapshot('status'); + expect( + reduxHelpers.getStatusFromResults([ + { + status: 200 + }, + { + status: 200 + } + ]) + ).toMatchSnapshot('ARRAY status'); + expect( reduxHelpers.getStatusFromResults({ status: 200 @@ -78,6 +137,44 @@ describe('ReduxHelpers', () => { ).toMatchSnapshot('fallback status'); expect(reduxHelpers.getStatusFromResults({})).toMatchSnapshot('missing status'); + + expect( + reduxHelpers.getStatusFromResults([ + { + status: 200 + }, + { + status: 400 + } + ]) + ).toMatchSnapshot('ARRAY mismatched status'); + }); + + it('should get a date from a service call response', () => { + expect( + reduxHelpers.getDateFromResults({ + headers: { + date: 'Fri, 07 Feb 2020 10:46:53 GMT' + } + }) + ).toMatchSnapshot('date'); + + expect( + reduxHelpers.getDateFromResults([ + { + headers: { + date: 'Fri, 07 Feb 2020 10:46:53 GMT' + }, + status: 200 + }, + { + headers: { + date: 'Fri, 07 Feb 2020 10:46:53 GMT' + }, + status: 200 + } + ]) + ).toMatchSnapshot('ARRAY date'); }); it('should update a state object', () => { diff --git a/src/redux/common/reduxHelpers.js b/src/redux/common/reduxHelpers.js index ba9447899..4346f1280 100644 --- a/src/redux/common/reduxHelpers.js +++ b/src/redux/common/reduxHelpers.js @@ -10,9 +10,22 @@ const REJECTED_ACTION = (base = '') => `${base}_REJECTED`; const HTTP_STATUS_RANGE = status => `${status}_STATUS_RANGE`; -const getMessageFromResults = results => { +const getSingleResponseFromResultArray = results => { const updatedResults = results.payload || results; + if (Array.isArray(updatedResults)) { + const firstErrorResponse = updatedResults.find(value => _get(value, 'response.status', value.status) >= 300); + const firstSuccessResponse = updatedResults.find(value => _get(value, 'response.status', value.status) < 300); + + return firstErrorResponse || firstSuccessResponse; + } + + return updatedResults; +}; + +const getMessageFromResults = results => { + const updatedResults = getSingleResponseFromResultArray(results); + if (helpers.isPromise(updatedResults)) { return null; } @@ -38,16 +51,24 @@ const getMessageFromResults = results => { return (statusResponse && statusResponse.trim()) || null; }; +const getDateFromResults = results => { + const updatedResults = getSingleResponseFromResultArray(results); + + if (helpers.isPromise(updatedResults)) { + return null; + } + + return _get(updatedResults, 'headers.date', null); +}; + const getStatusFromResults = results => { - const updatedResults = results.payload || results; + const updatedResults = getSingleResponseFromResultArray(results); if (helpers.isPromise(updatedResults)) { return 0; } - const status = _get(updatedResults, 'response.status', updatedResults.status); - - return status || 0; + return _get(updatedResults, 'response.status', updatedResults.status) || 0; }; const setStateProp = (prop, data, options) => { @@ -89,6 +110,15 @@ const setStateProp = (prop, data, options) => { return obj; }; +const singlePromiseDataResponseFromArray = results => { + const updatedResults = results.payload || results; + + if (Array.isArray(updatedResults)) { + return updatedResults.map(value => value.data || {}); + } + return updatedResults.data || {}; +}; + const generatedPromiseActionReducer = (types = [], state = {}, action = {}) => { const { type } = action; const expandedTypes = []; @@ -151,8 +181,8 @@ const generatedPromiseActionReducer = (types = [], state = {}, action = {}) => { return setStateProp( whichType.ref || null, setId({ - date: action.payload.headers && action.payload.headers.date, - data: (action.payload && action.payload.data) || {}, + date: getDateFromResults(action), + data: singlePromiseDataResponseFromArray(action), fulfilled: true }), { @@ -171,9 +201,12 @@ const reduxHelpers = { REJECTED_ACTION, HTTP_STATUS_RANGE, generatedPromiseActionReducer, + getDateFromResults, getMessageFromResults, + getSingleResponseFromResultArray, getStatusFromResults, - setStateProp + setStateProp, + singlePromiseDataResponseFromArray }; export { reduxHelpers as default, reduxHelpers }; diff --git a/src/redux/reducers/__tests__/__snapshots__/graphReducer.test.js.snap b/src/redux/reducers/__tests__/__snapshots__/graphReducer.test.js.snap index 0554f6450..9d8009fe8 100644 --- a/src/redux/reducers/__tests__/__snapshots__/graphReducer.test.js.snap +++ b/src/redux/reducers/__tests__/__snapshots__/graphReducer.test.js.snap @@ -16,11 +16,34 @@ Object { }, "component": Object {}, "report": Object {}, + "reportCapacity": Object {}, }, "type": "GET_GRAPH_CAPACITY_RHSM_REJECTED", } `; +exports[`GraphReducer should handle all defined error types: rejected types GET_GRAPH_REPORT_CAPACITY_RHSM 1`] = ` +Object { + "result": Object { + "capacity": Object {}, + "component": Object {}, + "report": Object {}, + "reportCapacity": Object { + "error": true, + "errorMessage": "MESSAGE", + "errorStatus": 0, + "fulfilled": false, + "metaData": undefined, + "metaId": undefined, + "metaQuery": undefined, + "pending": false, + "update": false, + }, + }, + "type": "GET_GRAPH_REPORT_CAPACITY_RHSM_REJECTED", +} +`; + exports[`GraphReducer should handle all defined error types: rejected types GET_GRAPH_REPORT_RHSM 1`] = ` Object { "result": Object { @@ -37,6 +60,7 @@ Object { "pending": false, "update": false, }, + "reportCapacity": Object {}, }, "type": "GET_GRAPH_REPORT_RHSM_REJECTED", } @@ -49,7 +73,7 @@ Object { "data": Object { "test": "success", }, - "date": undefined, + "date": null, "error": false, "errorMessage": "", "fulfilled": true, @@ -61,11 +85,37 @@ Object { }, "component": Object {}, "report": Object {}, + "reportCapacity": Object {}, }, "type": "GET_GRAPH_CAPACITY_RHSM_FULFILLED", } `; +exports[`GraphReducer should handle all defined fulfilled types: fulfilled types GET_GRAPH_REPORT_CAPACITY_RHSM 1`] = ` +Object { + "result": Object { + "capacity": Object {}, + "component": Object {}, + "report": Object {}, + "reportCapacity": Object { + "data": Object { + "test": "success", + }, + "date": null, + "error": false, + "errorMessage": "", + "fulfilled": true, + "metaData": undefined, + "metaId": undefined, + "metaQuery": undefined, + "pending": false, + "update": false, + }, + }, + "type": "GET_GRAPH_REPORT_CAPACITY_RHSM_FULFILLED", +} +`; + exports[`GraphReducer should handle all defined fulfilled types: fulfilled types GET_GRAPH_REPORT_RHSM 1`] = ` Object { "result": Object { @@ -75,7 +125,7 @@ Object { "data": Object { "test": "success", }, - "date": undefined, + "date": null, "error": false, "errorMessage": "", "fulfilled": true, @@ -85,6 +135,7 @@ Object { "pending": false, "update": false, }, + "reportCapacity": Object {}, }, "type": "GET_GRAPH_REPORT_RHSM_FULFILLED", } @@ -105,11 +156,33 @@ Object { }, "component": Object {}, "report": Object {}, + "reportCapacity": Object {}, }, "type": "GET_GRAPH_CAPACITY_RHSM_PENDING", } `; +exports[`GraphReducer should handle all defined pending types: pending types GET_GRAPH_REPORT_CAPACITY_RHSM 1`] = ` +Object { + "result": Object { + "capacity": Object {}, + "component": Object {}, + "report": Object {}, + "reportCapacity": Object { + "error": false, + "errorMessage": "", + "fulfilled": false, + "metaData": undefined, + "metaId": undefined, + "metaQuery": undefined, + "pending": true, + "update": false, + }, + }, + "type": "GET_GRAPH_REPORT_CAPACITY_RHSM_PENDING", +} +`; + exports[`GraphReducer should handle all defined pending types: pending types GET_GRAPH_REPORT_RHSM 1`] = ` Object { "result": Object { @@ -125,6 +198,7 @@ Object { "pending": true, "update": false, }, + "reportCapacity": Object {}, }, "type": "GET_GRAPH_REPORT_RHSM_PENDING", } @@ -140,6 +214,7 @@ Object { "startDate": 2019-06-20T00:00:00.000Z, }, "report": Object {}, + "reportCapacity": Object {}, }, "type": "SET_GRAPH_GRANULARITY_RHSM", } diff --git a/src/redux/reducers/__tests__/graphReducer.test.js b/src/redux/reducers/__tests__/graphReducer.test.js index c797900d2..ffd330cda 100644 --- a/src/redux/reducers/__tests__/graphReducer.test.js +++ b/src/redux/reducers/__tests__/graphReducer.test.js @@ -22,7 +22,11 @@ describe('GraphReducer', () => { }); it('should handle all defined error types', () => { - const specificTypes = [types.GET_GRAPH_CAPACITY_RHSM, types.GET_GRAPH_REPORT_RHSM]; + const specificTypes = [ + types.GET_GRAPH_REPORT_CAPACITY_RHSM, + types.GET_GRAPH_CAPACITY_RHSM, + types.GET_GRAPH_REPORT_RHSM + ]; specificTypes.forEach(value => { const dispatched = { @@ -49,7 +53,11 @@ describe('GraphReducer', () => { }); it('should handle all defined pending types', () => { - const specificTypes = [types.GET_GRAPH_CAPACITY_RHSM, types.GET_GRAPH_REPORT_RHSM]; + const specificTypes = [ + types.GET_GRAPH_REPORT_CAPACITY_RHSM, + types.GET_GRAPH_CAPACITY_RHSM, + types.GET_GRAPH_REPORT_RHSM + ]; specificTypes.forEach(value => { const dispatched = { @@ -65,7 +73,11 @@ describe('GraphReducer', () => { }); it('should handle all defined fulfilled types', () => { - const specificTypes = [types.GET_GRAPH_CAPACITY_RHSM, types.GET_GRAPH_REPORT_RHSM]; + const specificTypes = [ + types.GET_GRAPH_REPORT_CAPACITY_RHSM, + types.GET_GRAPH_CAPACITY_RHSM, + types.GET_GRAPH_REPORT_RHSM + ]; specificTypes.forEach(value => { const dispatched = { diff --git a/src/redux/reducers/graphReducer.js b/src/redux/reducers/graphReducer.js index 60123dc0f..8156ea52a 100644 --- a/src/redux/reducers/graphReducer.js +++ b/src/redux/reducers/graphReducer.js @@ -5,7 +5,8 @@ import { dateHelpers } from '../../common/dateHelpers'; const initialState = { capacity: {}, component: {}, - report: {} + report: {}, + reportCapacity: {} }; const graphReducer = (state = initialState, action) => { @@ -26,6 +27,7 @@ const graphReducer = (state = initialState, action) => { default: return reduxHelpers.generatedPromiseActionReducer( [ + { ref: 'reportCapacity', type: rhsmTypes.GET_GRAPH_REPORT_CAPACITY_RHSM }, { ref: 'capacity', type: rhsmTypes.GET_GRAPH_CAPACITY_RHSM }, { ref: 'report', type: rhsmTypes.GET_GRAPH_REPORT_RHSM } ], diff --git a/src/redux/selectors/__tests__/__snapshots__/graphCardSelectors.test.js.snap b/src/redux/selectors/__tests__/__snapshots__/graphCardSelectors.test.js.snap index ecde50fb7..a9562fb81 100644 --- a/src/redux/selectors/__tests__/__snapshots__/graphCardSelectors.test.js.snap +++ b/src/redux/selectors/__tests__/__snapshots__/graphCardSelectors.test.js.snap @@ -210,7 +210,7 @@ Object { } `; -exports[`GraphCardSelectors should pass data through on a product ID when granularity provided mismatches between aggregated responses: rhelGraphCard: granularity mismatch on API 1`] = ` +exports[`GraphCardSelectors should populate data from the in memory cache: granularity cached data: ERROR, no component reportCapacity mismatch 1`] = ` Object { "error": false, "errorStatus": null, @@ -271,44 +271,6 @@ Object { } `; -exports[`GraphCardSelectors should pass data through on a product ID when granularity provided mismatches between aggregated responses: rhelGraphCard: granularity mismatch on API fulfilled 1`] = ` -Object { - "error": true, - "errorStatus": null, - "fulfilled": false, - "graphData": Object { - "cores": Array [], - "hypervisorCores": Array [], - "hypervisorSockets": Array [], - "physicalCores": Array [], - "physicalSockets": Array [], - "sockets": Array [], - "threshold": Array [], - }, - "initialLoad": true, - "pending": false, -} -`; - -exports[`GraphCardSelectors should populate data from the in memory cache: granularity cached data: ERROR, no component, report and capacity mismatch 1`] = ` -Object { - "error": true, - "errorStatus": null, - "fulfilled": false, - "graphData": Object { - "cores": Array [], - "hypervisorCores": Array [], - "hypervisorSockets": Array [], - "physicalCores": Array [], - "physicalSockets": Array [], - "sockets": Array [], - "threshold": Array [], - }, - "initialLoad": true, - "pending": false, -} -`; - exports[`GraphCardSelectors should populate data from the in memory cache: granularity cached data: cached data 1`] = ` Object { "error": false, @@ -366,72 +328,11 @@ Object { ], }, "initialLoad": false, - "pending": false, -} -`; - -exports[`GraphCardSelectors should populate data from the in memory cache: granularity cached data: component and capacity match 1`] = ` -Object { - "error": false, - "errorStatus": null, - "fulfilled": true, - "graphData": Object { - "cores": Array [ - Object { - "date": 2019-09-04T00:00:00.000Z, - "x": 0, - "y": 2, - }, - ], - "hypervisorCores": Array [ - Object { - "date": 2019-09-04T00:00:00.000Z, - "x": 0, - "y": 1, - }, - ], - "hypervisorSockets": Array [ - Object { - "date": 2019-09-04T00:00:00.000Z, - "x": 0, - "y": 1, - }, - ], - "physicalCores": Array [ - Object { - "date": 2019-09-04T00:00:00.000Z, - "x": 0, - "y": 1, - }, - ], - "physicalSockets": Array [ - Object { - "date": 2019-09-04T00:00:00.000Z, - "x": 0, - "y": 1, - }, - ], - "sockets": Array [ - Object { - "date": 2019-09-04T00:00:00.000Z, - "x": 0, - "y": 2, - }, - ], - "threshold": Array [ - Object { - "date": 2019-09-04T00:00:00.000Z, - "x": 0, - "y": 100, - }, - ], - }, - "initialLoad": false, - "pending": false, + "pending": true, } `; -exports[`GraphCardSelectors should populate data from the in memory cache: granularity cached data: component and report match 1`] = ` +exports[`GraphCardSelectors should populate data from the in memory cache: granularity cached data: component and reportCapacity match 1`] = ` Object { "error": false, "errorStatus": null, @@ -487,8 +388,9 @@ Object { }, ], }, + "graphGranularity": "daily", "initialLoad": false, - "pending": false, + "pending": true, } `; diff --git a/src/redux/selectors/__tests__/graphCardSelectors.test.js b/src/redux/selectors/__tests__/graphCardSelectors.test.js index fc24072e7..7f871360d 100644 --- a/src/redux/selectors/__tests__/graphCardSelectors.test.js +++ b/src/redux/selectors/__tests__/graphCardSelectors.test.js @@ -16,21 +16,16 @@ describe('GraphCardSelectors', () => { const state = { graph: { component: {}, - capacity: { + reportCapacity: { fulfilled: true, metaData: { id: 'Lorem Ipsum ID missing granularity' }, metaQuery: {}, - data: { [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA]: [] } - }, - report: { - fulfilled: true, - metaData: { - id: 'Lorem Ipsum ID missing granularity' - }, - metaQuery: {}, - data: { [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA]: [] } + data: [ + { [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA]: [] }, + { [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA]: [] } + ] } } }; @@ -42,21 +37,16 @@ describe('GraphCardSelectors', () => { const state = { graph: { component: {}, - capacity: { - fulfilled: true, - metaData: {}, - metaQuery: { - [rhsmApiTypes.RHSM_API_QUERY_GRANULARITY]: rhsmApiTypes.RHSM_API_QUERY_GRANULARITY_TYPES.DAILY - }, - data: { [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA]: [] } - }, - report: { + reportCapacity: { fulfilled: true, metaData: {}, metaQuery: { [rhsmApiTypes.RHSM_API_QUERY_GRANULARITY]: rhsmApiTypes.RHSM_API_QUERY_GRANULARITY_TYPES.DAILY }, - data: { [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA]: [] } + data: [ + { [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA]: [] }, + { [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA]: [] } + ] } } }; @@ -68,17 +58,7 @@ describe('GraphCardSelectors', () => { const state = { graph: { component: {}, - capacity: { - fulfilled: true, - metaData: { - id: 'Lorem Ipsum ID pending state' - }, - metaQuery: { - [rhsmApiTypes.RHSM_API_QUERY_GRANULARITY]: rhsmApiTypes.RHSM_API_QUERY_GRANULARITY_TYPES.DAILY - }, - data: { [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA]: [] } - }, - report: { + reportCapacity: { pending: true, metaData: { id: 'Lorem Ipsum ID pending state' @@ -86,7 +66,10 @@ describe('GraphCardSelectors', () => { metaQuery: { [rhsmApiTypes.RHSM_API_QUERY_GRANULARITY]: rhsmApiTypes.RHSM_API_QUERY_GRANULARITY_TYPES.DAILY }, - data: { [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA]: [] } + data: [ + { [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA]: [] }, + { [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA]: [] } + ] } } }; @@ -94,73 +77,6 @@ describe('GraphCardSelectors', () => { expect(graphCardSelectors.graphCard(state)).toMatchSnapshot('rhelGraphCard: pending'); }); - it('should pass data through on a product ID when granularity provided mismatches between aggregated responses', () => { - const state = { - graph: { - component: {}, - capacity: { - fulfilled: true, - metaData: { - id: 'Lorem Ipsum mismatched granularity' - }, - metaQuery: { - [rhsmApiTypes.RHSM_API_QUERY_GRANULARITY]: rhsmApiTypes.RHSM_API_QUERY_GRANULARITY_TYPES.MONTHLY - }, - data: { - [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA]: [ - { - [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.DATE]: '2019-09-04T00:00:00.000Z', - [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.SOCKETS]: 100, - [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.HYPERVISOR_SOCKETS]: 50, - [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.PHYSICAL_SOCKETS]: 50 - } - ] - } - }, - report: { - fulfilled: true, - metaData: { - id: 'Lorem Ipsum mismatched granularity' - }, - metaQuery: { - [rhsmApiTypes.RHSM_API_QUERY_GRANULARITY]: rhsmApiTypes.RHSM_API_QUERY_GRANULARITY_TYPES.DAILY - }, - data: { - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA]: [ - { - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.DATE]: '2019-09-04T00:00:00.000Z', - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.CORES]: 2, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.SOCKETS]: 2, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_CORES]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_SOCKETS]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_CORES]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_SOCKETS]: 1 - } - ] - } - } - } - }; - - expect(graphCardSelectors.graphCard(state)).toMatchSnapshot('rhelGraphCard: granularity mismatch on API fulfilled'); - - expect( - graphCardSelectors.graphCard({ - graph: { - capacity: { - ...state.graph.capacity, - metaQuery: { - [rhsmApiTypes.RHSM_API_QUERY_GRANULARITY]: rhsmApiTypes.RHSM_API_QUERY_GRANULARITY_TYPES.DAILY - } - }, - report: { - ...state.graph.report - } - } - }) - ).toMatchSnapshot('rhelGraphCard: granularity mismatch on API'); - }); - it('should populate data on a product ID when the api response provided mismatches index or date', () => { const state = { graph: { @@ -168,7 +84,7 @@ describe('GraphCardSelectors', () => { graphGranularity: rhsmApiTypes.RHSM_API_QUERY_GRANULARITY_TYPES.DAILY, ...dateHelpers.getRangedDateTime(rhsmApiTypes.RHSM_API_QUERY_GRANULARITY_TYPES.DAILY) }, - capacity: { + reportCapacity: { fulfilled: true, metaData: { id: 'Lorem Ipsum mismatched index or date' @@ -176,29 +92,22 @@ describe('GraphCardSelectors', () => { metaQuery: { [rhsmApiTypes.RHSM_API_QUERY_GRANULARITY]: rhsmApiTypes.RHSM_API_QUERY_GRANULARITY_TYPES.DAILY }, - data: { [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA]: [] } - }, - report: { - fulfilled: true, - metaData: { - id: 'Lorem Ipsum mismatched index or date' - }, - metaQuery: { - [rhsmApiTypes.RHSM_API_QUERY_GRANULARITY]: rhsmApiTypes.RHSM_API_QUERY_GRANULARITY_TYPES.DAILY - }, - data: { - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA]: [ - { - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.DATE]: '2019-09-04T00:00:00.000Z', - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.CORES]: 2, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.SOCKETS]: 2, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_CORES]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_SOCKETS]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_CORES]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_SOCKETS]: 1 - } - ] - } + data: [ + { + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA]: [ + { + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.DATE]: '2019-09-04T00:00:00.000Z', + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.CORES]: 2, + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.SOCKETS]: 2, + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_CORES]: 1, + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_SOCKETS]: 1, + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_CORES]: 1, + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_SOCKETS]: 1 + } + ] + }, + { [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA]: [] } + ] } } }; @@ -213,38 +122,7 @@ describe('GraphCardSelectors', () => { graphGranularity: rhsmApiTypes.RHSM_API_QUERY_GRANULARITY_TYPES.DAILY, ...dateHelpers.getRangedDateTime(rhsmApiTypes.RHSM_API_QUERY_GRANULARITY_TYPES.DAILY) }, - capacity: { - fulfilled: true, - metaData: { - id: 'Lorem Ipsum missing expected properties' - }, - metaQuery: { - [rhsmApiTypes.RHSM_API_QUERY_GRANULARITY]: rhsmApiTypes.RHSM_API_QUERY_GRANULARITY_TYPES.DAILY - }, - data: { - [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA]: [ - { - [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.DATE]: '2019-09-04T00:00:00.000Z', - [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.SOCKETS]: 100, - [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.HYPERVISOR_SOCKETS]: 50, - [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.PHYSICAL_SOCKETS]: 50 - }, - { - [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.DATE]: '2019-09-05T00:00:00.000Z', - [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.SOCKETS]: 0, - [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.HYPERVISOR_SOCKETS]: 0, - [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.PHYSICAL_SOCKETS]: 0 - }, - { - [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.DATE]: '2019-09-06T00:00:00.000Z', - [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.SOCKETS]: 100, - [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.HYPERVISOR_SOCKETS]: 50, - [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.PHYSICAL_SOCKETS]: 50 - } - ] - } - }, - report: { + reportCapacity: { fulfilled: true, metaData: { id: 'Lorem Ipsum missing expected properties' @@ -252,25 +130,49 @@ describe('GraphCardSelectors', () => { metaQuery: { [rhsmApiTypes.RHSM_API_QUERY_GRANULARITY]: rhsmApiTypes.RHSM_API_QUERY_GRANULARITY_TYPES.DAILY }, - data: { - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA]: [ - { - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.DATE]: '2019-09-04T00:00:00.000Z', - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.SOCKETS]: 2, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_SOCKETS]: 1 - }, - { - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.DATE]: '2019-09-05T00:00:00.000Z', - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.SOCKETS]: 2, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_SOCKETS]: 1 - }, - { - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.DATE]: '2019-09-06T00:00:00.000Z', - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.SOCKETS]: 4, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_SOCKETS]: 2 - } - ] - } + data: [ + { + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA]: [ + { + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.DATE]: '2019-09-04T00:00:00.000Z', + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.SOCKETS]: 2, + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_SOCKETS]: 1 + }, + { + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.DATE]: '2019-09-05T00:00:00.000Z', + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.SOCKETS]: 2, + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_SOCKETS]: 1 + }, + { + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.DATE]: '2019-09-06T00:00:00.000Z', + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.SOCKETS]: 4, + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_SOCKETS]: 2 + } + ] + }, + { + [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA]: [ + { + [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.DATE]: '2019-09-04T00:00:00.000Z', + [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.SOCKETS]: 100, + [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.HYPERVISOR_SOCKETS]: 50, + [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.PHYSICAL_SOCKETS]: 50 + }, + { + [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.DATE]: '2019-09-05T00:00:00.000Z', + [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.SOCKETS]: 0, + [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.HYPERVISOR_SOCKETS]: 0, + [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.PHYSICAL_SOCKETS]: 0 + }, + { + [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.DATE]: '2019-09-06T00:00:00.000Z', + [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.SOCKETS]: 100, + [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.HYPERVISOR_SOCKETS]: 50, + [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.PHYSICAL_SOCKETS]: 50 + } + ] + } + ] } } }; @@ -285,7 +187,7 @@ describe('GraphCardSelectors', () => { graphGranularity: rhsmApiTypes.RHSM_API_QUERY_GRANULARITY_TYPES.DAILY, ...dateHelpers.getRangedDateTime(rhsmApiTypes.RHSM_API_QUERY_GRANULARITY_TYPES.DAILY) }, - capacity: { + reportCapacity: { fulfilled: true, metaData: { id: 'Lorem Ipsum fulfilled aggregated output' @@ -293,68 +195,61 @@ describe('GraphCardSelectors', () => { metaQuery: { [rhsmApiTypes.RHSM_API_QUERY_GRANULARITY]: rhsmApiTypes.RHSM_API_QUERY_GRANULARITY_TYPES.DAILY }, - data: { - [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA]: [ - { - [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.DATE]: '2019-09-04T00:00:00.000Z', - [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.SOCKETS]: 100, - [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.HYPERVISOR_SOCKETS]: 50, - [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.PHYSICAL_SOCKETS]: 50 - }, - { - [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.DATE]: '2019-09-05T00:00:00.000Z', - [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.SOCKETS]: 0, - [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.HYPERVISOR_SOCKETS]: 0, - [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.PHYSICAL_SOCKETS]: 0 - }, - { - [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.DATE]: '2019-09-06T00:00:00.000Z', - [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.SOCKETS]: 100, - [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.HYPERVISOR_SOCKETS]: 50, - [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.PHYSICAL_SOCKETS]: 50 - } - ] - } - }, - report: { - fulfilled: true, - metaData: { - id: 'Lorem Ipsum fulfilled aggregated output' - }, - metaQuery: { - [rhsmApiTypes.RHSM_API_QUERY_GRANULARITY]: rhsmApiTypes.RHSM_API_QUERY_GRANULARITY_TYPES.DAILY - }, - data: { - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA]: [ - { - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.DATE]: '2019-09-04T00:00:00.000Z', - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.CORES]: 2, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.SOCKETS]: 2, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_CORES]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_SOCKETS]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_CORES]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_SOCKETS]: 1 - }, - { - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.DATE]: '2019-09-05T00:00:00.000Z', - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.CORES]: 2, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.SOCKETS]: 2, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_CORES]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_SOCKETS]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_CORES]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_SOCKETS]: 1 - }, - { - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.DATE]: '2019-09-06T00:00:00.000Z', - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.CORES]: 4, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.SOCKETS]: 4, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_CORES]: 2, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_SOCKETS]: 2, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_CORES]: 2, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_SOCKETS]: 2 - } - ] - } + data: [ + { + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA]: [ + { + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.DATE]: '2019-09-04T00:00:00.000Z', + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.CORES]: 2, + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.SOCKETS]: 2, + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_CORES]: 1, + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_SOCKETS]: 1, + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_CORES]: 1, + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_SOCKETS]: 1 + }, + { + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.DATE]: '2019-09-05T00:00:00.000Z', + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.CORES]: 2, + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.SOCKETS]: 2, + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_CORES]: 1, + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_SOCKETS]: 1, + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_CORES]: 1, + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_SOCKETS]: 1 + }, + { + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.DATE]: '2019-09-06T00:00:00.000Z', + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.CORES]: 4, + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.SOCKETS]: 4, + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_CORES]: 2, + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_SOCKETS]: 2, + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_CORES]: 2, + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_SOCKETS]: 2 + } + ] + }, + { + [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA]: [ + { + [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.DATE]: '2019-09-04T00:00:00.000Z', + [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.SOCKETS]: 100, + [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.HYPERVISOR_SOCKETS]: 50, + [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.PHYSICAL_SOCKETS]: 50 + }, + { + [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.DATE]: '2019-09-05T00:00:00.000Z', + [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.SOCKETS]: 0, + [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.HYPERVISOR_SOCKETS]: 0, + [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.PHYSICAL_SOCKETS]: 0 + }, + { + [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.DATE]: '2019-09-06T00:00:00.000Z', + [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.SOCKETS]: 100, + [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.HYPERVISOR_SOCKETS]: 50, + [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.PHYSICAL_SOCKETS]: 50 + } + ] + } + ] } } }; @@ -366,26 +261,7 @@ describe('GraphCardSelectors', () => { const stateDailyGranularityFulfilled = { graph: { component: {}, - capacity: { - fulfilled: true, - metaData: { - id: 'Lorem Ipsum ID cached' - }, - metaQuery: { - [rhsmApiTypes.RHSM_API_QUERY_GRANULARITY]: rhsmApiTypes.RHSM_API_QUERY_GRANULARITY_TYPES.DAILY - }, - data: { - [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA]: [ - { - [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.DATE]: '2019-09-04T00:00:00.000Z', - [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.SOCKETS]: 100, - [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.HYPERVISOR_SOCKETS]: 50, - [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.PHYSICAL_SOCKETS]: 50 - } - ] - } - }, - report: { + reportCapacity: { fulfilled: true, metaData: { id: 'Lorem Ipsum ID cached' @@ -393,19 +269,31 @@ describe('GraphCardSelectors', () => { metaQuery: { [rhsmApiTypes.RHSM_API_QUERY_GRANULARITY]: rhsmApiTypes.RHSM_API_QUERY_GRANULARITY_TYPES.DAILY }, - data: { - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA]: [ - { - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.DATE]: '2019-09-04T00:00:00.000Z', - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.CORES]: 2, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.SOCKETS]: 2, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_CORES]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_SOCKETS]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_CORES]: 1, - [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_SOCKETS]: 1 - } - ] - } + data: [ + { + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA]: [ + { + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.DATE]: '2019-09-04T00:00:00.000Z', + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.CORES]: 2, + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.SOCKETS]: 2, + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_CORES]: 1, + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.HYPERVISOR_SOCKETS]: 1, + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_CORES]: 1, + [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA_TYPES.PHYSICAL_SOCKETS]: 1 + } + ] + }, + { + [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA]: [ + { + [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.DATE]: '2019-09-04T00:00:00.000Z', + [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.SOCKETS]: 100, + [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.HYPERVISOR_SOCKETS]: 50, + [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA_TYPES.PHYSICAL_SOCKETS]: 50 + } + ] + } + ] } } }; @@ -415,12 +303,8 @@ describe('GraphCardSelectors', () => { const stateDailyGranularityPending = { graph: { component: {}, - capacity: { - ...stateDailyGranularityFulfilled.graph.capacity, - pending: true - }, - report: { - ...stateDailyGranularityFulfilled.graph.report, + reportCapacity: { + ...stateDailyGranularityFulfilled.graph.reportCapacity, pending: true } } @@ -431,65 +315,35 @@ describe('GraphCardSelectors', () => { ); const stateDailyComponentCapacityGranularity = { - component: { - graphGranularity: rhsmApiTypes.RHSM_API_QUERY_GRANULARITY_TYPES.DAILY - }, graph: { - component: {}, - capacity: { - ...stateDailyGranularityFulfilled.graph.capacity, - fulfilled: true - }, - report: { - ...stateDailyGranularityFulfilled.graph.report, - pending: true - } - } - }; - - expect(graphCardSelectors.graphCard(stateDailyComponentCapacityGranularity)).toMatchSnapshot( - 'granularity cached data: component and capacity match' - ); - - const stateDailyComponentReportGranularity = { - component: { - graphGranularity: rhsmApiTypes.RHSM_API_QUERY_GRANULARITY_TYPES.DAILY - }, - graph: { - component: {}, - capacity: { - ...stateDailyGranularityFulfilled.graph.capacity, - pending: true + component: { + graphGranularity: rhsmApiTypes.RHSM_API_QUERY_GRANULARITY_TYPES.DAILY }, - report: { - ...stateDailyGranularityFulfilled.graph.report, + reportCapacity: { + ...stateDailyGranularityFulfilled.graph.reportCapacity, fulfilled: true } } }; - expect(graphCardSelectors.graphCard(stateDailyComponentReportGranularity)).toMatchSnapshot( - 'granularity cached data: component and report match' + expect(graphCardSelectors.graphCard(stateDailyComponentCapacityGranularity)).toMatchSnapshot( + 'granularity cached data: component and reportCapacity match' ); const stateDailyReportCapacityGranularityMismatch = { - component: {}, graph: { component: {}, - capacity: { - ...stateDailyGranularityFulfilled.graph.capacity, + reportCapacity: { + ...stateDailyGranularityFulfilled.graph.reportCapacity, metaQuery: { [rhsmApiTypes.RHSM_API_QUERY_GRANULARITY]: rhsmApiTypes.RHSM_API_QUERY_GRANULARITY_TYPES.WEEKLY } - }, - report: { - ...stateDailyGranularityFulfilled.graph.report } } }; expect(graphCardSelectors.graphCard(stateDailyReportCapacityGranularityMismatch)).toMatchSnapshot( - 'granularity cached data: ERROR, no component, report and capacity mismatch' + 'granularity cached data: ERROR, no component reportCapacity mismatch' ); }); }); diff --git a/src/redux/selectors/graphCardSelectors.js b/src/redux/selectors/graphCardSelectors.js index 293890760..95e03160d 100644 --- a/src/redux/selectors/graphCardSelectors.js +++ b/src/redux/selectors/graphCardSelectors.js @@ -10,21 +10,20 @@ const graph = state => state.graph; const graphCardSelector = createSelector( [graph], graphReducer => { - const { component = {}, capacity = {}, report = {} } = graphReducer || {}; + const { component = {}, reportCapacity = {} } = graphReducer || {}; const graphGranularity = component.graphGranularity || null; - const reportGranularity = _get(report, ['metaQuery', rhsmApiTypes.RHSM_API_QUERY_GRANULARITY], null); - const capacityGranularity = _get(capacity, ['metaQuery', rhsmApiTypes.RHSM_API_QUERY_GRANULARITY], null); - const reportProductId = _get(report, ['metaData', 'id'], null); - const capacityProductId = _get(capacity, ['metaData', 'id'], null); + const reportCapacityGranularity = _get( + reportCapacity, + ['metaQuery', rhsmApiTypes.RHSM_API_QUERY_GRANULARITY], + null + ); - const productId = (reportProductId === capacityProductId && reportProductId) || null; + const productId = _get(reportCapacity, ['metaData', 'id'], null); let granularity = null; - if (graphGranularity === reportGranularity || reportGranularity === capacityGranularity) { - granularity = reportGranularity; - } else if (graphGranularity === capacityGranularity) { - granularity = capacityGranularity; + if (graphGranularity === reportCapacityGranularity) { + granularity = reportCapacityGranularity; } const cachedGranularity = (granularity && productId && graphCardCache[`${productId}_${granularity}`]) || {}; @@ -49,21 +48,25 @@ const graphCardSelector = createSelector( ...component }; + if (initialLoad && granularity === null) { + granularity = reportCapacityGranularity; + } + if (granularity === null || productId === null) { updatedData.error = true; return updatedData; } if (initialLoad) { - updatedData.pending = report.pending || capacity.pending || false; + updatedData.pending = reportCapacity.pending || false; } - updatedData.error = report.error || capacity.error || false; - updatedData.errorStatus = report.errorStatus || capacity.errorStatus || null; + updatedData.error = reportCapacity.error || false; + updatedData.errorStatus = reportCapacity.errorStatus || null; - if (capacity.fulfilled && report.fulfilled && granularity && productId) { - const productsData = _get(report, ['data', rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA], []); - const thresholdData = _get(capacity, ['data', rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA], []); + if (reportCapacity.fulfilled && granularity && productId) { + const productsData = _get(reportCapacity.data[0], [rhsmApiTypes.RHSM_API_RESPONSE_PRODUCTS_DATA], []); + const thresholdData = _get(reportCapacity.data[1], [rhsmApiTypes.RHSM_API_RESPONSE_CAPACITY_DATA], []); updatedData.graphData.cores.length = 0; updatedData.graphData.hypervisorCores.length = 0; diff --git a/src/redux/types/__tests__/__snapshots__/index.test.js.snap b/src/redux/types/__tests__/__snapshots__/index.test.js.snap index 314129bfa..ddb4d2f16 100644 --- a/src/redux/types/__tests__/__snapshots__/index.test.js.snap +++ b/src/redux/types/__tests__/__snapshots__/index.test.js.snap @@ -19,6 +19,7 @@ Object { }, "rhsm": Object { "GET_GRAPH_CAPACITY_RHSM": "GET_GRAPH_CAPACITY_RHSM", + "GET_GRAPH_REPORT_CAPACITY_RHSM": "GET_GRAPH_REPORT_CAPACITY_RHSM", "GET_GRAPH_REPORT_RHSM": "GET_GRAPH_REPORT_RHSM", "SET_GRAPH_GRANULARITY_RHSM": "SET_GRAPH_GRANULARITY_RHSM", }, @@ -47,6 +48,7 @@ Object { }, "rhsm": Object { "GET_GRAPH_CAPACITY_RHSM": "GET_GRAPH_CAPACITY_RHSM", + "GET_GRAPH_REPORT_CAPACITY_RHSM": "GET_GRAPH_REPORT_CAPACITY_RHSM", "GET_GRAPH_REPORT_RHSM": "GET_GRAPH_REPORT_RHSM", "SET_GRAPH_GRANULARITY_RHSM": "SET_GRAPH_GRANULARITY_RHSM", }, @@ -58,6 +60,7 @@ Object { }, "rhsmTypes": Object { "GET_GRAPH_CAPACITY_RHSM": "GET_GRAPH_CAPACITY_RHSM", + "GET_GRAPH_REPORT_CAPACITY_RHSM": "GET_GRAPH_REPORT_CAPACITY_RHSM", "GET_GRAPH_REPORT_RHSM": "GET_GRAPH_REPORT_RHSM", "SET_GRAPH_GRANULARITY_RHSM": "SET_GRAPH_GRANULARITY_RHSM", }, @@ -83,6 +86,7 @@ Object { }, "rhsm": Object { "GET_GRAPH_CAPACITY_RHSM": "GET_GRAPH_CAPACITY_RHSM", + "GET_GRAPH_REPORT_CAPACITY_RHSM": "GET_GRAPH_REPORT_CAPACITY_RHSM", "GET_GRAPH_REPORT_RHSM": "GET_GRAPH_REPORT_RHSM", "SET_GRAPH_GRANULARITY_RHSM": "SET_GRAPH_GRANULARITY_RHSM", }, diff --git a/src/redux/types/rhsmTypes.js b/src/redux/types/rhsmTypes.js index a6d860df1..5862602a6 100644 --- a/src/redux/types/rhsmTypes.js +++ b/src/redux/types/rhsmTypes.js @@ -1,11 +1,20 @@ const GET_GRAPH_CAPACITY_RHSM = 'GET_GRAPH_CAPACITY_RHSM'; const GET_GRAPH_REPORT_RHSM = 'GET_GRAPH_REPORT_RHSM'; +const GET_GRAPH_REPORT_CAPACITY_RHSM = 'GET_GRAPH_REPORT_CAPACITY_RHSM'; const SET_GRAPH_GRANULARITY_RHSM = 'SET_GRAPH_GRANULARITY_RHSM'; const rhsmTypes = { GET_GRAPH_CAPACITY_RHSM, GET_GRAPH_REPORT_RHSM, + GET_GRAPH_REPORT_CAPACITY_RHSM, SET_GRAPH_GRANULARITY_RHSM }; -export { rhsmTypes as default, rhsmTypes, GET_GRAPH_CAPACITY_RHSM, GET_GRAPH_REPORT_RHSM, SET_GRAPH_GRANULARITY_RHSM }; +export { + rhsmTypes as default, + rhsmTypes, + GET_GRAPH_CAPACITY_RHSM, + GET_GRAPH_REPORT_RHSM, + GET_GRAPH_REPORT_CAPACITY_RHSM, + SET_GRAPH_GRANULARITY_RHSM +};