diff --git a/src/reducers/index.js b/src/reducers/index.js index 8e81e18a..feaf6d5d 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -14,7 +14,7 @@ import tagsListReducer from '../tags/reducers/tagsList'; import tagDeleteReducer from '../tags/reducers/tagDelete'; import tagEditReducer from '../tags/reducers/tagEdit'; import mercureInfoReducer from '../mercure/reducers/mercureInfo'; -import realTimeUpdatesReducer from '../settings/reducers/realTimeUpdates'; +import settingsReducer from '../settings/reducers/settings'; export default combineReducers({ servers: serversReducer, @@ -32,5 +32,5 @@ export default combineReducers({ tagDelete: tagDeleteReducer, tagEdit: tagEditReducer, mercureInfo: mercureInfoReducer, - realTimeUpdates: realTimeUpdatesReducer, + settings: settingsReducer, }); diff --git a/src/settings/RealTimeUpdates.js b/src/settings/RealTimeUpdates.js index eccd585f..1425a0ac 100644 --- a/src/settings/RealTimeUpdates.js +++ b/src/settings/RealTimeUpdates.js @@ -4,14 +4,14 @@ import PropTypes from 'prop-types'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faInfoCircle } from '@fortawesome/free-solid-svg-icons'; import Checkbox from '../utils/Checkbox'; -import { RealTimeUpdatesType } from './reducers/realTimeUpdates'; +import { SettingsType } from './reducers/settings'; const propTypes = { - realTimeUpdates: RealTimeUpdatesType, + settings: SettingsType, setRealTimeUpdates: PropTypes.func, }; -const RealTimeUpdates = ({ realTimeUpdates, setRealTimeUpdates }) => ( +const RealTimeUpdates = ({ settings: { realTimeUpdates }, setRealTimeUpdates }) => ( Real-time updates diff --git a/src/settings/reducers/realTimeUpdates.js b/src/settings/reducers/settings.js similarity index 68% rename from src/settings/reducers/realTimeUpdates.js rename to src/settings/reducers/settings.js index c5cd726f..3160862b 100644 --- a/src/settings/reducers/realTimeUpdates.js +++ b/src/settings/reducers/settings.js @@ -3,16 +3,20 @@ import PropTypes from 'prop-types'; export const LOAD_REAL_TIME_UPDATES = 'shlink/realTimeUpdates/LOAD_REAL_TIME_UPDATES'; -export const RealTimeUpdatesType = PropTypes.shape({ - enabled: PropTypes.bool.isRequired, +export const SettingsType = PropTypes.shape({ + realTimeUpdates: PropTypes.shape({ + enabled: PropTypes.bool.isRequired, + }), }); const initialState = { - enabled: true, + realTimeUpdates: { + enabled: true, + }, }; export default handleActions({ - [LOAD_REAL_TIME_UPDATES]: (state, { enabled }) => ({ ...state, enabled }), + [LOAD_REAL_TIME_UPDATES]: (state, { realTimeUpdates }) => ({ ...state, realTimeUpdates }), }, initialState); export const setRealTimeUpdates = ({ updateSettings }, loadRealTimeUpdatesAction) => (enabled) => { @@ -23,10 +27,9 @@ export const setRealTimeUpdates = ({ updateSettings }, loadRealTimeUpdatesAction export const loadRealTimeUpdates = ({ loadSettings }) => () => { const { realTimeUpdates = {} } = loadSettings(); - const { enabled = true } = realTimeUpdates; return { type: LOAD_REAL_TIME_UPDATES, - enabled, + realTimeUpdates, }; }; diff --git a/src/settings/services/provideServices.js b/src/settings/services/provideServices.js index ef70b49f..cbc24a12 100644 --- a/src/settings/services/provideServices.js +++ b/src/settings/services/provideServices.js @@ -1,6 +1,6 @@ import RealTimeUpdates from '../RealTimeUpdates'; import Settings from '../Settings'; -import { loadRealTimeUpdates, setRealTimeUpdates } from '../reducers/realTimeUpdates'; +import { loadRealTimeUpdates, setRealTimeUpdates } from '../reducers/settings'; import SettingsService from './SettingsService'; const provideServices = (bottle, connect) => { @@ -8,7 +8,7 @@ const provideServices = (bottle, connect) => { bottle.serviceFactory('Settings', Settings, 'RealTimeUpdates'); bottle.serviceFactory('RealTimeUpdates', () => RealTimeUpdates); - bottle.decorator('RealTimeUpdates', connect([ 'realTimeUpdates' ], [ 'setRealTimeUpdates' ])); + bottle.decorator('RealTimeUpdates', connect([ 'settings' ], [ 'setRealTimeUpdates' ])); // Services bottle.service('SettingsService', SettingsService, 'Storage'); diff --git a/src/short-urls/ShortUrlsList.js b/src/short-urls/ShortUrlsList.js index 3b36d459..e0c2f30c 100644 --- a/src/short-urls/ShortUrlsList.js +++ b/src/short-urls/ShortUrlsList.js @@ -9,7 +9,7 @@ import SortingDropdown from '../utils/SortingDropdown'; import { determineOrderDir } from '../utils/utils'; import { MercureInfoType } from '../mercure/reducers/mercureInfo'; import { bindToMercureTopic } from '../mercure/helpers'; -import { RealTimeUpdatesType } from '../settings/reducers/realTimeUpdates'; +import { SettingsType } from '../settings/reducers/settings'; import { shortUrlType } from './reducers/shortUrlsList'; import { shortUrlsListParamsType } from './reducers/shortUrlsListParams'; import './ShortUrlsList.scss'; @@ -34,7 +34,7 @@ const propTypes = { createNewVisit: PropTypes.func, loadMercureInfo: PropTypes.func, mercureInfo: MercureInfoType, - realTimeUpdates: RealTimeUpdatesType, + settings: SettingsType, }; // FIXME Replace with typescript: (ShortUrlsRow component) @@ -52,7 +52,7 @@ const ShortUrlsList = (ShortUrlsRow) => { createNewVisit, loadMercureInfo, mercureInfo, - realTimeUpdates, + settings: { realTimeUpdates }, }) => { const { orderBy } = shortUrlsListParams; const [ order, setOrder ] = useState({ diff --git a/src/short-urls/services/provideServices.js b/src/short-urls/services/provideServices.js index 6a35ac3d..02a0d5fa 100644 --- a/src/short-urls/services/provideServices.js +++ b/src/short-urls/services/provideServices.js @@ -31,7 +31,7 @@ const provideServices = (bottle, connect) => { bottle.serviceFactory('ShortUrlsList', ShortUrlsList, 'ShortUrlsRow'); bottle.decorator('ShortUrlsList', connect( - [ 'selectedServer', 'shortUrlsListParams', 'mercureInfo', 'realTimeUpdates' ], + [ 'selectedServer', 'shortUrlsListParams', 'mercureInfo', 'settings' ], [ 'listShortUrls', 'resetShortUrlParams', 'createNewVisit', 'loadMercureInfo' ] )); diff --git a/src/visits/ShortUrlVisits.js b/src/visits/ShortUrlVisits.js index 6882e478..12f5deb3 100644 --- a/src/visits/ShortUrlVisits.js +++ b/src/visits/ShortUrlVisits.js @@ -12,7 +12,7 @@ import { formatDate } from '../utils/helpers/date'; import { useToggle } from '../utils/helpers/hooks'; import { MercureInfoType } from '../mercure/reducers/mercureInfo'; import { bindToMercureTopic } from '../mercure/helpers'; -import { RealTimeUpdatesType } from '../settings/reducers/realTimeUpdates'; +import { SettingsType } from '../settings/reducers/settings'; import SortableBarGraph from './SortableBarGraph'; import { shortUrlVisitsType } from './reducers/shortUrlVisits'; import VisitsHeader from './VisitsHeader'; @@ -39,7 +39,7 @@ const propTypes = { createNewVisit: PropTypes.func, loadMercureInfo: PropTypes.func, mercureInfo: MercureInfoType, - realTimeUpdates: RealTimeUpdatesType, + settings: SettingsType, }; const highlightedVisitsToStats = (highlightedVisits, prop) => highlightedVisits.reduce((acc, highlightedVisit) => { @@ -68,7 +68,7 @@ const ShortUrlVisits = ({ processStatsFromVisits, normalizeVisits }, OpenMapModa createNewVisit, loadMercureInfo, mercureInfo, - realTimeUpdates, + settings: { realTimeUpdates }, }) => { const [ startDate, setStartDate ] = useState(undefined); const [ endDate, setEndDate ] = useState(undefined); diff --git a/src/visits/services/provideServices.js b/src/visits/services/provideServices.js index f9f31b80..404bc4a1 100644 --- a/src/visits/services/provideServices.js +++ b/src/visits/services/provideServices.js @@ -11,7 +11,7 @@ const provideServices = (bottle, connect) => { bottle.serviceFactory('MapModal', () => MapModal); bottle.serviceFactory('ShortUrlVisits', ShortUrlVisits, 'VisitsParser', 'OpenMapModalBtn'); bottle.decorator('ShortUrlVisits', connect( - [ 'shortUrlVisits', 'shortUrlDetail', 'mercureInfo', 'realTimeUpdates' ], + [ 'shortUrlVisits', 'shortUrlDetail', 'mercureInfo', 'settings' ], [ 'getShortUrlVisits', 'getShortUrlDetail', 'cancelGetShortUrlVisits', 'createNewVisit', 'loadMercureInfo' ] )); diff --git a/test/settings/reducers/realTimeUpdates.test.js b/test/settings/reducers/settings.test.js similarity index 60% rename from test/settings/reducers/realTimeUpdates.test.js rename to test/settings/reducers/settings.test.js index cdd463e6..2eb7e5db 100644 --- a/test/settings/reducers/realTimeUpdates.test.js +++ b/test/settings/reducers/settings.test.js @@ -2,34 +2,35 @@ import reducer, { LOAD_REAL_TIME_UPDATES, loadRealTimeUpdates, setRealTimeUpdates, -} from '../../../src/settings/reducers/realTimeUpdates'; +} from '../../../src/settings/reducers/settings'; -describe('realTimeUpdatesReducer', () => { +describe('settingsReducer', () => { const SettingsServiceMock = { updateSettings: jest.fn(), loadSettings: jest.fn(), }; + const realTimeUpdates = { enabled: true }; afterEach(jest.clearAllMocks); describe('reducer', () => { it('returns realTimeUpdates when action is LOAD_REAL_TIME_UPDATES', () => { - expect(reducer({}, { type: LOAD_REAL_TIME_UPDATES, enabled: true })).toEqual({ enabled: true }); + expect(reducer({}, { type: LOAD_REAL_TIME_UPDATES, realTimeUpdates })).toEqual({ realTimeUpdates }); }); }); describe('loadRealTimeUpdates', () => { - it.each([ - [{}, true ], - [{ realTimeUpdates: {} }, true ], - [{ realTimeUpdates: { enabled: true } }, true ], - [{ realTimeUpdates: { enabled: false } }, false ], - ])('loads settings and returns LOAD_REAL_TIME_UPDATES action', (loadedSettings, expectedEnabled) => { - SettingsServiceMock.loadSettings.mockReturnValue(loadedSettings); + it.each([[ true ], [ false ]])('loads settings and returns LOAD_REAL_TIME_UPDATES action', (enabled) => { + const realTimeUpdates = { enabled }; + + SettingsServiceMock.loadSettings.mockReturnValue({ realTimeUpdates }); const result = loadRealTimeUpdates(SettingsServiceMock)(); - expect(result).toEqual({ type: LOAD_REAL_TIME_UPDATES, enabled: expectedEnabled }); + expect(result).toEqual({ + type: LOAD_REAL_TIME_UPDATES, + realTimeUpdates, + }); expect(SettingsServiceMock.loadSettings).toHaveBeenCalled(); }); }); diff --git a/test/short-urls/ShortUrlsList.test.js b/test/short-urls/ShortUrlsList.test.js index 050238b9..b66e9ac0 100644 --- a/test/short-urls/ShortUrlsList.test.js +++ b/test/short-urls/ShortUrlsList.test.js @@ -9,6 +9,7 @@ describe('', () => { const ShortUrlsRow = () => ''; const listShortUrlsMock = jest.fn(); const resetShortUrlParamsMock = jest.fn(); + const realTimeUpdates = { enabled: true }; const ShortUrlsList = shortUrlsListCreator(ShortUrlsRow); @@ -37,6 +38,7 @@ describe('', () => { ] } mercureInfo={{ loading: true }} + settings={{ realTimeUpdates }} /> ); }); diff --git a/test/visits/ShortUrlVisits.test.js b/test/visits/ShortUrlVisits.test.js index 0f221308..76cf0b28 100644 --- a/test/visits/ShortUrlVisits.test.js +++ b/test/visits/ShortUrlVisits.test.js @@ -21,6 +21,7 @@ describe('', () => { const history = { goBack: jest.fn(), }; + const realTimeUpdates = { enabled: true }; const createComponent = (shortUrlVisits) => { const ShortUrlVisits = createShortUrlVisits({ processStatsFromVisits, normalizeVisits: identity }, () => ''); @@ -36,6 +37,7 @@ describe('', () => { shortUrlDetail={{}} cancelGetShortUrlVisits={identity} matchMedia={() => ({ matches: false })} + settings={{ realTimeUpdates }} /> );