Skip to content

Commit 77a2511

Browse files
authored
RI-6879: cluster page force standalone
ensure cluster analysis page does not show when cluster node is accessed as standalone
1 parent ede8f2c commit 77a2511

File tree

9 files changed

+136
-17
lines changed

9 files changed

+136
-17
lines changed

redisinsight/ui/src/components/analytics-tabs/AnalyticsTabs.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,17 @@ import { useParams, useHistory } from 'react-router-dom'
66
import { Pages } from 'uiSrc/constants'
77
import { AnalyticsViewTab } from 'uiSrc/slices/interfaces/analytics'
88
import { analyticsSettingsSelector, setAnalyticsViewTab } from 'uiSrc/slices/analytics/settings'
9-
import { connectedInstanceSelector } from 'uiSrc/slices/instances/instances'
109
import { ConnectionType } from 'uiSrc/slices/interfaces'
1110

1211
import { appFeatureOnboardingSelector, setOnboardNextStep } from 'uiSrc/slices/app/features'
1312
import { renderOnboardingTourWithChild } from 'uiSrc/utils/onboarding'
1413
import { OnboardingSteps } from 'uiSrc/constants/onboarding'
14+
import { useConnectionType } from 'uiSrc/components/hooks/useConnectionType'
1515
import { analyticsViewTabs } from './constants'
1616

1717
const AnalyticsTabs = () => {
1818
const { viewTab } = useSelector(analyticsSettingsSelector)
19-
const { connectionType } = useSelector(connectedInstanceSelector)
19+
const connectionType = useConnectionType()
2020
const { currentStep } = useSelector(appFeatureOnboardingSelector)
2121
const history = useHistory()
2222

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import { cloneDeep } from 'lodash'
2+
import { ConnectionType, Instance } from 'uiSrc/slices/interfaces'
3+
import { cleanup, mockedStore, renderHook } from 'uiSrc/utils/test-utils'
4+
import { connectedInstanceSelector } from 'uiSrc/slices/instances/instances'
5+
import { useConnectionType } from 'uiSrc/components/hooks/useConnectionType'
6+
7+
jest.mock('uiSrc/slices/instances/instances', () => ({
8+
...jest.requireActual('uiSrc/slices/instances/instances'),
9+
connectedInstanceSelector: jest.fn().mockReturnValue({
10+
connectedInstance: {},
11+
}),
12+
}))
13+
14+
let store: typeof mockedStore
15+
type ConnType = 'cluster' | 'standalone' | 'sentinel'
16+
let instances: Record<ConnType, Instance>
17+
beforeEach(() => {
18+
cleanup()
19+
store = cloneDeep(mockedStore)
20+
store.clearActions()
21+
22+
instances = {
23+
standalone: {
24+
id: 'e37cc441-a4f2-402c-8bdb-fc2413cbbaff',
25+
host: 'localhost',
26+
port: 6379,
27+
name: 'localhost',
28+
connectionType: ConnectionType.Standalone,
29+
modules: [],
30+
version: '6.2.6',
31+
},
32+
cluster: {
33+
id: 'a0db1bc8-a353-4c43-a856-b72f4811d2d4',
34+
host: 'localhost',
35+
port: 12000,
36+
name: 'oea123123',
37+
connectionType: ConnectionType.Cluster,
38+
modules: [],
39+
version: '6.2.6',
40+
},
41+
sentinel: {
42+
id: 'b83a3932-e95f-4f09-9d8a-55079f400186',
43+
version: '6.2.6',
44+
host: 'localhost',
45+
port: 5005,
46+
connectionType: ConnectionType.Sentinel,
47+
modules: [],
48+
},
49+
}
50+
})
51+
52+
describe('useConnectionType', () => {
53+
it.each([[ConnectionType.Cluster, 'cluster' as ConnType], [ConnectionType.Standalone, 'standalone' as ConnType], [ConnectionType.Sentinel, 'sentinel' as ConnType]])(
54+
'should return %i when forceStandalone is undefined',
55+
async (expected, type) => {
56+
const instance = { ...instances[type] };
57+
(connectedInstanceSelector as jest.Mock).mockReturnValue(instance)
58+
59+
const { result } = renderHook(useConnectionType)
60+
const connectionType = result.current
61+
expect(connectionType).toEqual(expected)
62+
},
63+
)
64+
65+
it.each([[ConnectionType.Cluster, 'cluster' as ConnType], [ConnectionType.Standalone, 'standalone' as ConnType], [ConnectionType.Sentinel, 'sentinel' as ConnType]])(
66+
'should return %i when forceStandalone is false',
67+
async (expected, type) => {
68+
const instance = {
69+
...instances[type],
70+
forceStandalone: false,
71+
};
72+
(connectedInstanceSelector as jest.Mock).mockReturnValue(instance)
73+
74+
const { result } = renderHook(useConnectionType)
75+
const connectionType = result.current
76+
expect(connectionType).toEqual(expected)
77+
},
78+
)
79+
it.each([[ConnectionType.Standalone, 'cluster' as ConnType], [ConnectionType.Standalone, 'standalone' as ConnType], [ConnectionType.Sentinel, 'sentinel' as ConnType]])(
80+
'should return STANDALONE ',
81+
async (expected, type) => {
82+
const instance = {
83+
...instances[type],
84+
forceStandalone: true,
85+
};
86+
(connectedInstanceSelector as jest.Mock).mockReturnValue(instance)
87+
88+
const { result } = renderHook(useConnectionType)
89+
const connectionType = result.current
90+
expect(connectionType).toEqual(expected)
91+
},
92+
)
93+
})
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { useSelector } from 'react-redux'
2+
import { ConnectionType } from 'uiSrc/slices/interfaces'
3+
import { connectedInstanceSelector } from 'uiSrc/slices/instances/instances'
4+
5+
export const useConnectionType = () => {
6+
const { connectionType, forceStandalone } = useSelector(connectedInstanceSelector)
7+
8+
if (forceStandalone && connectionType !== ConnectionType.Sentinel) {
9+
return ConnectionType.Standalone
10+
}
11+
return connectionType
12+
}

redisinsight/ui/src/pages/analytics/AnalyticsPage.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import { useDispatch, useSelector } from 'react-redux'
33
import { useHistory, useParams, useLocation } from 'react-router-dom'
44
import { Pages } from 'uiSrc/constants'
55
import { appContextAnalytics, setLastAnalyticsPage } from 'uiSrc/slices/app/context'
6-
import { connectedInstanceSelector } from 'uiSrc/slices/instances/instances'
76
import { ConnectionType } from 'uiSrc/slices/interfaces'
7+
import { useConnectionType } from 'uiSrc/components/hooks/useConnectionType'
88

99
import AnalyticsPageRouter from './AnalyticsPageRouter'
1010

@@ -18,9 +18,8 @@ const AnalyticsPage = ({ routes = [] }: Props) => {
1818
const history = useHistory()
1919
const { instanceId } = useParams<{ instanceId: string }>()
2020
const { pathname } = useLocation()
21-
const { connectionType } = useSelector(connectedInstanceSelector)
21+
const connectionType = useConnectionType()
2222
const { lastViewedPage } = useSelector(appContextAnalytics)
23-
2423
const pathnameRef = useRef<string>('')
2524

2625
const dispatch = useDispatch()

redisinsight/ui/src/pages/pub-sub/components/messages-list/MessagesList/MessagesList.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ import styles from './styles.module.scss'
1111

1212
export interface Props {
1313
items: IMessage[]
14-
width: number
15-
height: number
14+
width?: number
15+
height?: number
1616
}
1717

1818
const PROTRUDING_OFFSET = 2

redisinsight/ui/src/pages/pub-sub/components/messages-list/MessagesListWrapper.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
1-
import React, { useState, useEffect } from 'react'
1+
import React, { useEffect, useState } from 'react'
22
import { useSelector } from 'react-redux'
33
import AutoSizer from 'react-virtualized-auto-sizer'
44

5-
import { connectedInstanceSelector, connectedInstanceOverviewSelector } from 'uiSrc/slices/instances/instances'
5+
import { connectedInstanceOverviewSelector } from 'uiSrc/slices/instances/instances'
66
import { pubSubSelector } from 'uiSrc/slices/pubsub/pubsub'
77
import { isVersionHigherOrEquals } from 'uiSrc/utils'
88
import { CommandsVersions } from 'uiSrc/constants/commandsVersions'
9+
import { useConnectionType } from 'uiSrc/components/hooks/useConnectionType'
910
import EmptyMessagesList from './EmptyMessagesList'
1011
import MessagesList from './MessagesList'
1112

1213
import styles from './MessagesList/styles.module.scss'
1314

1415
const MessagesListWrapper = () => {
1516
const { messages = [], isSubscribed } = useSelector(pubSubSelector)
16-
const { connectionType } = useSelector(connectedInstanceSelector)
17+
const connectionType = useConnectionType()
1718
const { version } = useSelector(connectedInstanceOverviewSelector)
1819

1920
const [isSpublishNotSupported, setIsSpublishNotSupported] = useState<boolean>(true)

redisinsight/ui/src/pages/pub-sub/components/publish-message/PublishMessage.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,25 @@ import {
66
EuiFlexItem,
77
EuiForm,
88
EuiFormRow,
9-
EuiIcon
9+
EuiIcon,
1010
} from '@elastic/eui'
1111
import cx from 'classnames'
1212
import React, { ChangeEvent, FormEvent, useEffect, useRef, useState } from 'react'
1313
import { useDispatch, useSelector } from 'react-redux'
1414
import { useParams } from 'react-router-dom'
1515
import { appContextPubSub, setPubSubFieldsContext } from 'uiSrc/slices/app/context'
16-
import { connectedInstanceSelector } from 'uiSrc/slices/instances/instances'
1716
import { ConnectionType } from 'uiSrc/slices/interfaces'
1817
import { publishMessageAction } from 'uiSrc/slices/pubsub/pubsub'
1918
import UserIcon from 'uiSrc/assets/img/icons/user.svg?react'
19+
import { useConnectionType } from 'uiSrc/components/hooks/useConnectionType'
2020

2121
import styles from './styles.module.scss'
2222

2323
const HIDE_BADGE_TIMER = 3000
2424

2525
const PublishMessage = () => {
2626
const { channel: channelContext, message: messageContext } = useSelector(appContextPubSub)
27-
const { connectionType } = useSelector(connectedInstanceSelector)
27+
const connectionType = useConnectionType()
2828

2929
const [channel, setChannel] = useState<string>(channelContext)
3030
const [message, setMessage] = useState<string>(messageContext)

redisinsight/ui/src/pages/slow-log/components/SlowLogConfig/SlowLogConfig.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,16 @@ import {
1717
DEFAULT_SLOWLOG_DURATION_UNIT,
1818
DEFAULT_SLOWLOG_MAX_LEN,
1919
DEFAULT_SLOWLOG_SLOWER_THAN,
20-
DurationUnits,
2120
DURATION_UNITS,
21+
DurationUnits,
2222
MINUS_ONE,
2323
} from 'uiSrc/constants'
2424
import { appContextDbConfig } from 'uiSrc/slices/app/context'
2525
import { ConnectionType } from 'uiSrc/slices/interfaces'
2626
import { patchSlowLogConfigAction, slowLogConfigSelector, slowLogSelector } from 'uiSrc/slices/analytics/slowlog'
2727
import { errorValidateNegativeInteger, validateNumber } from 'uiSrc/utils'
28-
import { connectedInstanceSelector } from 'uiSrc/slices/instances/instances'
2928
import { numberWithSpaces } from 'uiSrc/utils/numbers'
29+
import { useConnectionType } from 'uiSrc/components/hooks/useConnectionType'
3030
import { convertNumberByUnits } from '../../utils'
3131
import styles from './styles.module.scss'
3232

@@ -38,7 +38,7 @@ export interface Props {
3838
const SlowLogConfig = ({ closePopover, onRefresh }: Props) => {
3939
const options = DURATION_UNITS
4040
const { instanceId } = useParams<{ instanceId: string }>()
41-
const { connectionType } = useSelector(connectedInstanceSelector)
41+
const connectionType = useConnectionType()
4242
const { loading } = useSelector(slowLogSelector)
4343
const { slowLogDurationUnit } = useSelector(appContextDbConfig)
4444
const {

redisinsight/ui/src/utils/test-utils.tsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { Provider } from 'react-redux'
55
import thunk from 'redux-thunk'
66
import { BrowserRouter } from 'react-router-dom'
77
import configureMockStore from 'redux-mock-store'
8-
import { render as rtlRender, waitFor } from '@testing-library/react'
8+
import { render as rtlRender, renderHook as rtlRenderHook, waitFor } from '@testing-library/react'
99

1010
import { RootState, store as rootStore } from 'uiSrc/slices/store'
1111
import { initialState as initialStateInstances } from 'uiSrc/slices/instances/instances'
@@ -169,6 +169,19 @@ const render = (
169169
return rtlRender(ui, { wrapper, ...renderOptions })
170170
}
171171

172+
const renderHook = (
173+
hook: (initialProps: unknown) => unknown,
174+
{ initialState, store = mockedStore, withRouter, ...renderOptions }: Options = initialStateDefault
175+
) => {
176+
const Wrapper = ({ children }: { children: JSX.Element }) => (
177+
<Provider store={store}>{children}</Provider>
178+
)
179+
180+
const wrapper = !withRouter ? Wrapper : BrowserRouter
181+
182+
return rtlRenderHook(hook, { wrapper, ...renderOptions })
183+
}
184+
172185
// for render components WithRouter
173186
const renderWithRouter = (ui: JSX.Element, { route = '/' } = {}) => {
174187
window.history.pushState({}, 'Test page', route)
@@ -345,6 +358,7 @@ export * from '@testing-library/react'
345358
export {
346359
initialStateDefault,
347360
render,
361+
renderHook,
348362
renderWithRouter,
349363
clearStoreActions,
350364
waitForEuiToolTipVisible,

0 commit comments

Comments
 (0)