Skip to content

Commit 2677d88

Browse files
authored
Merge pull request #2718 from RedisInsight/fe/bugfix/RI-5084
#RI-5084 - fix loading key details from context
2 parents 8c24e6e + a8923d3 commit 2677d88

File tree

8 files changed

+127
-108
lines changed

8 files changed

+127
-108
lines changed

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

Lines changed: 15 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
import React from 'react'
2-
import { useSelector } from 'react-redux'
32
import reactRouterDom from 'react-router-dom'
43
import { AnalyticsViewTab } from 'uiSrc/slices/interfaces/analytics'
5-
import { RootState, store } from 'uiSrc/slices/store'
64
import { ConnectionType } from 'uiSrc/slices/interfaces'
75
import { act, fireEvent, render, screen } from 'uiSrc/utils/test-utils'
6+
import { connectedInstanceSelector } from 'uiSrc/slices/instances/instances'
87
import AnalyticsTabs from './AnalyticsTabs'
98

10-
jest.mock('react-redux', () => ({
11-
...jest.requireActual('react-redux'),
12-
useSelector: jest.fn()
9+
const mockedStandaloneConnection = ConnectionType.Standalone
10+
jest.mock('uiSrc/slices/instances/instances', () => ({
11+
...jest.requireActual('uiSrc/slices/instances/instances'),
12+
connectedInstanceSelector: jest.fn().mockReturnValue({
13+
connectionType: mockedStandaloneConnection
14+
}),
1315
}))
1416

1517
jest.mock('react-router-dom', () => ({
@@ -19,20 +21,6 @@ jest.mock('react-router-dom', () => ({
1921
}),
2022
}))
2123

22-
beforeEach(() => {
23-
const state: RootState = store.getState();
24-
25-
(useSelector as jest.Mock).mockImplementation((callback: (arg0: RootState) => RootState) => callback({
26-
...state,
27-
analytics: {
28-
...state.analytics
29-
},
30-
connections: {
31-
...state.connections
32-
}
33-
}))
34-
})
35-
3624
describe('AnalyticsTabs', () => {
3725
it('should render', () => {
3826
expect(render(<AnalyticsTabs />)).toBeTruthy()
@@ -66,65 +54,27 @@ describe('AnalyticsTabs', () => {
6654
})
6755

6856
it('should render cluster details tab when connectionType is Cluster', async () => {
69-
const state: RootState = store.getState();
70-
71-
(useSelector as jest.Mock).mockImplementation((callback: (arg0: RootState) => RootState) => callback({
72-
...state,
73-
connections: {
74-
...state.connections,
75-
instances: {
76-
...state.connections.instances,
77-
connectedInstance: {
78-
...state.connections.instances.connectedInstance,
79-
connectionType: ConnectionType.Cluster
80-
}
81-
},
82-
}
83-
}))
57+
const mockConnectionType = ConnectionType.Cluster;
58+
(connectedInstanceSelector as jest.Mock).mockReturnValueOnce({
59+
connectionType: mockConnectionType
60+
})
8461

8562
render(<AnalyticsTabs />)
8663

8764
expect(screen.getByTestId(`analytics-tab-${AnalyticsViewTab.ClusterDetails}`)).toBeInTheDocument()
8865
})
8966

9067
it('should not render cluster details tab when connectionType is not Cluster', async () => {
91-
const state: RootState = store.getState();
92-
93-
(useSelector as jest.Mock).mockImplementation((callback: (arg0: RootState) => RootState) => callback({
94-
...state,
95-
connections: {
96-
...state.connections,
97-
instances: {
98-
...state.connections.instances,
99-
connectedInstance: {
100-
...state.connections.instances.connectedInstance,
101-
connectionType: ConnectionType.Standalone
102-
}
103-
},
104-
}
105-
}))
106-
10768
const { queryByTestId } = render(<AnalyticsTabs />)
10869

10970
expect(queryByTestId(`analytics-tab-${AnalyticsViewTab.ClusterDetails}`)).not.toBeInTheDocument()
11071
})
11172

11273
it('should call History push with /cluster-details path when click on ClusterDetails tab ', async () => {
113-
const state: RootState = store.getState();
114-
115-
(useSelector as jest.Mock).mockImplementation((callback: (arg0: RootState) => RootState) => callback({
116-
...state,
117-
connections: {
118-
...state.connections,
119-
instances: {
120-
...state.connections.instances,
121-
connectedInstance: {
122-
...state.connections.instances.connectedInstance,
123-
connectionType: ConnectionType.Cluster
124-
}
125-
},
126-
}
127-
}))
74+
const mockConnectionType = ConnectionType.Cluster;
75+
(connectedInstanceSelector as jest.Mock).mockReturnValueOnce({
76+
connectionType: mockConnectionType
77+
})
12878
const pushMock = jest.fn()
12979
reactRouterDom.useHistory = jest.fn().mockReturnValue({ push: pushMock })
13080

redisinsight/ui/src/pages/instance/InstancePage.spec.tsx

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,36 @@ import React from 'react'
33
import { BrowserRouter } from 'react-router-dom'
44
import { instance, mock } from 'ts-mockito'
55

6-
import { cleanup, mockedStore, render } from 'uiSrc/utils/test-utils'
6+
import { cleanup, mockedStore, render, act } from 'uiSrc/utils/test-utils'
77
import { BrowserStorageItem } from 'uiSrc/constants'
88
import { localStorageService } from 'uiSrc/services'
99
import { appFeatureFlagsFeaturesSelector } from 'uiSrc/slices/app/features'
10+
import { resetKeys, resetPatternKeysData } from 'uiSrc/slices/browser/keys'
11+
import { setMonitorInitialState } from 'uiSrc/slices/cli/monitor'
12+
import { setInitialPubSubState } from 'uiSrc/slices/pubsub/pubsub'
13+
import { setBulkActionsInitialState } from 'uiSrc/slices/browser/bulkActions'
14+
import {
15+
appContextSelector,
16+
setAppContextConnectedInstanceId,
17+
setAppContextInitialState,
18+
setDbConfig
19+
} from 'uiSrc/slices/app/context'
20+
import { resetCliHelperSettings } from 'uiSrc/slices/cli/cli-settings'
21+
import { resetRedisearchKeysData, setRedisearchInitialState } from 'uiSrc/slices/browser/redisearch'
22+
import { setClusterDetailsInitialState } from 'uiSrc/slices/analytics/clusterDetails'
23+
import { setDatabaseAnalysisInitialState } from 'uiSrc/slices/analytics/dbAnalysis'
24+
import { setInitialAnalyticsSettings } from 'uiSrc/slices/analytics/settings'
25+
import { resetRecommendationsHighlighting } from 'uiSrc/slices/recommendations/recommendations'
26+
import { setTriggeredFunctionsInitialState } from 'uiSrc/slices/triggeredFunctions/triggeredFunctions'
27+
import {
28+
getDatabaseConfigInfo,
29+
setConnectedInfoInstance,
30+
setConnectedInstance,
31+
setDefaultInstance
32+
} from 'uiSrc/slices/instances/instances'
1033
import InstancePage, { getDefaultSizes, Props } from './InstancePage'
1134

35+
const INSTANCE_ID_MOCK = 'instanceId'
1236
const mockedProps = mock<Props>()
1337

1438
jest.mock('uiSrc/services', () => ({
@@ -27,6 +51,13 @@ jest.mock('uiSrc/slices/app/features', () => ({
2751
}),
2852
}))
2953

54+
jest.mock('uiSrc/slices/app/context', () => ({
55+
...jest.requireActual('uiSrc/slices/app/context'),
56+
appContextSelector: jest.fn().mockReturnValue({
57+
contextInstanceId: INSTANCE_ID_MOCK
58+
}),
59+
}))
60+
3061
let store: typeof mockedStore
3162
beforeEach(() => {
3263
cleanup()
@@ -102,4 +133,47 @@ describe('InstancePage', () => {
102133
defaultSizes
103134
)
104135
})
136+
137+
it('should call proper actions with resetting context', async () => {
138+
(appContextSelector as jest.Mock).mockReturnValue({
139+
contextInstanceId: 'prevId'
140+
})
141+
142+
await act(() => {
143+
render(
144+
<BrowserRouter>
145+
<InstancePage {...instance(mockedProps)} />
146+
</BrowserRouter>
147+
)
148+
})
149+
150+
const resetContextActions = [
151+
resetKeys(),
152+
setMonitorInitialState(),
153+
setInitialPubSubState(),
154+
setBulkActionsInitialState(),
155+
setAppContextInitialState(),
156+
resetPatternKeysData(),
157+
resetCliHelperSettings(),
158+
resetRedisearchKeysData(),
159+
setClusterDetailsInitialState(),
160+
setDatabaseAnalysisInitialState(),
161+
setInitialAnalyticsSettings(),
162+
setRedisearchInitialState(),
163+
resetRecommendationsHighlighting(),
164+
setTriggeredFunctionsInitialState(),
165+
]
166+
167+
const expectedActions = [
168+
setDefaultInstance(),
169+
setConnectedInstance(),
170+
getDatabaseConfigInfo(),
171+
setConnectedInfoInstance(),
172+
...resetContextActions,
173+
setAppContextConnectedInstanceId(INSTANCE_ID_MOCK),
174+
setDbConfig(undefined),
175+
]
176+
177+
expect(store.getActions().slice(0, expectedActions.length)).toEqual(expectedActions)
178+
})
105179
})

redisinsight/ui/src/pages/instance/InstancePage.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ import {
1919
setAppContextInitialState,
2020
setDbConfig,
2121
} from 'uiSrc/slices/app/context'
22-
import { resetPatternKeysData } from 'uiSrc/slices/browser/keys'
22+
import { resetKeys, resetPatternKeysData } from 'uiSrc/slices/browser/keys'
2323
import { BrowserStorageItem, FeatureFlags } from 'uiSrc/constants'
2424
import { localStorageService } from 'uiSrc/services'
2525
import { FeatureFlagComponent } from 'uiSrc/components'
2626
import { resetOutput } from 'uiSrc/slices/cli/cli-output'
27-
import { cliSettingsSelector } from 'uiSrc/slices/cli/cli-settings'
27+
import { cliSettingsSelector, resetCliHelperSettings } from 'uiSrc/slices/cli/cli-settings'
2828
import BottomGroupComponents from 'uiSrc/components/bottom-group-components/BottomGroupComponents'
2929
import LiveTimeRecommendations from 'uiSrc/components/live-time-recommendations'
3030
import { monitorSelector, setMonitorInitialState } from 'uiSrc/slices/cli/monitor'
@@ -39,7 +39,7 @@ import InstancePageRouter from './InstancePageRouter'
3939
import styles from './styles.module.scss'
4040

4141
export interface Props {
42-
routes: any[];
42+
routes: any[]
4343
}
4444

4545
export const firstPanelId = 'main-component'
@@ -105,11 +105,13 @@ const InstancePage = ({ routes = [] }: Props) => {
105105
}, [])
106106

107107
const resetContext = () => {
108+
dispatch(resetKeys())
108109
dispatch(setMonitorInitialState())
109110
dispatch(setInitialPubSubState())
110111
dispatch(setBulkActionsInitialState())
111112
dispatch(setAppContextInitialState())
112113
dispatch(resetPatternKeysData())
114+
dispatch(resetCliHelperSettings())
113115
dispatch(resetRedisearchKeysData())
114116
dispatch(setClusterDetailsInitialState())
115117
dispatch(setDatabaseAnalysisInitialState())

redisinsight/ui/src/pages/pubSub/components/messages-list/MessagesListWrapper.spec.tsx

Lines changed: 13 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,17 @@
11
import React from 'react'
2-
import { useSelector } from 'react-redux'
3-
import { RootState, store } from 'uiSrc/slices/store'
42
import { render } from 'uiSrc/utils/test-utils'
53

4+
import { pubSubSelector } from 'uiSrc/slices/pubsub/pubsub'
65
import MessagesListWrapper from './MessagesListWrapper'
76

8-
jest.mock('react-redux', () => ({
9-
...jest.requireActual('react-redux'),
10-
useSelector: jest.fn()
7+
jest.mock('uiSrc/slices/pubsub/pubsub', () => ({
8+
...jest.requireActual('uiSrc/slices/pubsub/pubsub'),
9+
pubSubSelector: jest.fn().mockReturnValue({
10+
isSubscribed: false,
11+
messages: []
12+
}),
1113
}))
1214

13-
beforeEach(() => {
14-
const state: RootState = store.getState();
15-
16-
(useSelector as jest.Mock).mockImplementation((callback: (arg0: RootState) => RootState) => callback({
17-
...state,
18-
pubsub: {
19-
...state.pubsub,
20-
}
21-
}))
22-
})
23-
2415
describe('MessagesListWrapper', () => {
2516
it('should render', () => {
2617
expect(
@@ -36,15 +27,9 @@ describe('MessagesListWrapper', () => {
3627
})
3728

3829
it('should render MessagesList if isSubscribed === true', () => {
39-
const state: RootState = store.getState();
40-
41-
(useSelector as jest.Mock).mockImplementation((callback: (arg0: RootState) => RootState) => callback({
42-
...state,
43-
pubsub: {
44-
...state.pubsub,
45-
isSubscribed: true,
46-
}
47-
}))
30+
(pubSubSelector as jest.Mock).mockReturnValue({
31+
isSubscribed: true
32+
})
4833

4934
const { queryByTestId } = render(<MessagesListWrapper />)
5035

@@ -53,15 +38,9 @@ describe('MessagesListWrapper', () => {
5338
})
5439

5540
it('should render MessagesList if messages.length !== 0', () => {
56-
const state: RootState = store.getState();
57-
58-
(useSelector as jest.Mock).mockImplementation((callback: (arg0: RootState) => RootState) => callback({
59-
...state,
60-
pubsub: {
61-
...state.pubsub,
62-
messages: [{ time: 123, channel: 'channel', message: 'msg' }],
63-
}
64-
}))
41+
(pubSubSelector as jest.Mock).mockReturnValue({
42+
messages: [{ time: 123, channel: 'channel', message: 'msg' }]
43+
})
6544

6645
const { queryByTestId } = render(<MessagesListWrapper />)
6746

redisinsight/ui/src/slices/app/context.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import {
88
DEFAULT_SLOWLOG_DURATION_UNIT,
99
KeyTypes,
1010
DEFAULT_SHOW_HIDDEN_RECOMMENDATIONS,
11-
DurationUnits,
1211
} from 'uiSrc/constants'
1312
import { localStorageService, setDBConfigStorageField } from 'uiSrc/services'
1413
import { RootState } from '../store'

redisinsight/ui/src/slices/instances/instances.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import ApiErrors from 'uiSrc/constants/apiErrors'
66
import { apiService, localStorageService, sessionStorageService } from 'uiSrc/services'
77
import { ApiEndpoints, BrowserStorageItem, CustomErrorCodes } from 'uiSrc/constants'
88
import { setAppContextInitialState } from 'uiSrc/slices/app/context'
9+
import { resetKeys } from 'uiSrc/slices/browser/keys'
910
import successMessages from 'uiSrc/components/notifications/success-messages'
1011
import { checkRediStack, getApiErrorMessage, isStatusSuccessful, Nullable } from 'uiSrc/utils'
1112
import { INFINITE_MESSAGES, InfiniteMessagesIds } from 'uiSrc/components/notifications/components'
@@ -442,6 +443,7 @@ function autoCreateAndConnectToInstanceActionSuccess(
442443
const state = stateInit()
443444
const isConnectedId = state.app?.context?.contextInstanceId === id
444445
if (!isConnectedId) {
446+
dispatch(resetKeys())
445447
dispatch(setAppContextInitialState())
446448
dispatch(setConnectedInstanceId(id ?? ''))
447449
}
@@ -532,6 +534,7 @@ export function deleteInstancesAction(instances: Instance[], onSuccess?: () => v
532534

533535
if (databasesIds.includes(state.app.context.contextInstanceId)) {
534536
dispatch(resetConnectedInstance())
537+
dispatch(resetKeys())
535538
dispatch(setAppContextInitialState())
536539
}
537540
onSuccess?.()

redisinsight/ui/src/slices/oauth/cloud.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
} from 'uiSrc/components/notifications/components'
1313
import successMessages from 'uiSrc/components/notifications/success-messages'
1414
import { getCloudSsoUtmParams } from 'uiSrc/utils/oauth/cloudSsoUtm'
15+
import { resetKeys } from 'uiSrc/slices/browser/keys'
1516
import { CloudUser } from 'apiSrc/modules/cloud/user/models'
1617
import { CloudJobInfo } from 'apiSrc/modules/cloud/job/models'
1718
import { CloudSubscriptionPlanResponse } from 'apiSrc/modules/cloud/subscription/dto'
@@ -235,13 +236,20 @@ export const oauthCapiKeysSelector = (state: RootState) => state.oauth.cloud.cap
235236
export default oauthCloudSlice.reducer
236237

237238
export function createFreeDbSuccess(id: string, history: any) {
238-
return async (dispatch: AppDispatch) => {
239+
return async (dispatch: AppDispatch, stateInit: () => RootState) => {
239240
try {
240241
const onConnect = () => {
241-
dispatch(setAppContextInitialState())
242-
dispatch(setConnectedInstanceId(id ?? ''))
242+
const state = stateInit()
243+
const isConnected = state.app?.context?.contextInstanceId === id
244+
243245
dispatch(removeInfiniteNotification(InfiniteMessagesIds.oAuthSuccess))
244-
dispatch(checkConnectToInstanceAction(id))
246+
247+
if (!isConnected) {
248+
dispatch(resetKeys())
249+
dispatch(setAppContextInitialState())
250+
dispatch(setConnectedInstanceId(id ?? ''))
251+
dispatch(checkConnectToInstanceAction(id))
252+
}
245253

246254
history.push(Pages.workbench(id))
247255
}

0 commit comments

Comments
 (0)