Skip to content

Commit cd7914e

Browse files
committed
Merge branch 'main' into e2e/bugfix/nightly-desktop-fixes
2 parents 92fde95 + 6a29c0a commit cd7914e

File tree

11 files changed

+142
-23
lines changed

11 files changed

+142
-23
lines changed

redisinsight/ui/src/components/monitor/MonitorOutputList/MonitorOutputList.spec.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ describe('MonitorOutputList', () => {
1515
expect(render(<MonitorOutputList {...mockedProps} />)).toBeTruthy()
1616
})
1717

18-
it('should "ReactVirtualized__Grid" be in the DOM', () => {
18+
it('should render items properly', () => {
1919
const item = { time: '112', args: ['ttl'], source: '12', database: '0' }
20-
const mockItems = [item]
20+
const mockItems = [item, item]
2121
const { container } = render(<MonitorOutputList {...mockedProps} items={mockItems} />)
22-
expect(container.getElementsByClassName('ReactVirtualized__Grid').length).toBe(1)
22+
expect(container.getElementsByClassName('item').length).toBe(2)
2323
})
2424
})

redisinsight/ui/src/components/query-card/QueryCard.spec.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,4 +120,21 @@ describe('QueryCard', () => {
120120

121121
expect(summaryString).toEqual(summaryText)
122122
})
123+
124+
it('should render QueryCardCliResultWrapper when command is null', () => {
125+
const { queryByTestId } = render(
126+
<QueryCard
127+
{...instance(mockedProps)}
128+
resultsMode={ResultsMode.GroupMode}
129+
result={null}
130+
isOpen
131+
command={null}
132+
/>
133+
)
134+
const queryCommonResultEl = queryByTestId('query-common-result-wrapper')
135+
const queryCliResultEl = queryByTestId('query-cli-result-wrapper')
136+
137+
expect(queryCommonResultEl).toBeInTheDocument()
138+
expect(queryCliResultEl).not.toBeInTheDocument()
139+
})
123140
})

redisinsight/ui/src/components/query-card/QueryCard.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { useDispatch, useSelector } from 'react-redux'
33
import cx from 'classnames'
44
import { EuiLoadingContent, keys } from '@elastic/eui'
55
import { useParams } from 'react-router-dom'
6+
import { isNull } from 'lodash'
67

78
import { WBQueryType, ProfileQueryType, DEFAULT_TEXT_VIEW_TYPE } from 'uiSrc/pages/workbench/constants'
89
import { RunQueryMode, ResultsMode, ResultsSummary } from 'uiSrc/slices/interfaces/workbench'
@@ -194,7 +195,7 @@ const QueryCard = (props: Props) => {
194195
/>
195196
{isOpen && (
196197
<>
197-
{React.isValidElement(commonError) && !isGroupResults(resultsMode)
198+
{React.isValidElement(commonError) && (!isGroupResults(resultsMode) || isNull(command))
198199
? <QueryCardCommonResult loading={loading} result={commonError} />
199200
: (
200201
<>
Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import React from 'react'
2-
import { render } from 'uiSrc/utils/test-utils'
3-
import QueryCardCliGroupResult from './QueryCardCliGroupResult'
2+
import { instance, mock } from 'ts-mockito'
3+
import { render, screen } from 'uiSrc/utils/test-utils'
4+
import { CommandExecutionStatus } from 'uiSrc/slices/interfaces/cli'
5+
import QueryCardCliGroupResult, { Props } from './QueryCardCliGroupResult'
6+
7+
const mockedProps = mock<Props>()
48

59
describe('QueryCardCliGroupResult', () => {
610
it('should render', () => {
@@ -11,10 +15,59 @@ describe('QueryCardCliGroupResult', () => {
1115
}],
1216
status: 'success'
1317
}]
14-
expect(render(<QueryCardCliGroupResult result={mockResult} />)).toBeTruthy()
18+
expect(render(<QueryCardCliGroupResult {...instance(mockedProps)} result={mockResult} />)).toBeTruthy()
1519
})
1620

1721
it('Should render result when result is undefined', () => {
18-
expect(render(<QueryCardCliGroupResult />)).toBeTruthy()
22+
expect(render(<QueryCardCliGroupResult {...instance(mockedProps)} />)).toBeTruthy()
23+
})
24+
25+
it('should render error when command is psubscribe', () => {
26+
const mockResult = [
27+
{
28+
response: [
29+
{
30+
id: 'id',
31+
command: 'psubscribe',
32+
response: 'response',
33+
status: CommandExecutionStatus.Success
34+
}
35+
]
36+
}
37+
]
38+
const { container } = render(
39+
<QueryCardCliGroupResult
40+
{...instance(mockedProps)}
41+
result={mockResult}
42+
/>
43+
)
44+
const errorBtn = container.querySelector('[data-test-subj="pubsub-page-btn"]')
45+
46+
expect(errorBtn).toBeInTheDocument()
47+
})
48+
49+
it('should render (nil) when response is null', () => {
50+
const mockResult = [
51+
{
52+
response: [
53+
{
54+
id: 'id',
55+
command: 'psubscribe',
56+
response: null,
57+
status: CommandExecutionStatus.Success
58+
}
59+
]
60+
}
61+
]
62+
const { container } = render(
63+
<QueryCardCliGroupResult
64+
{...instance(mockedProps)}
65+
result={mockResult}
66+
/>
67+
)
68+
const errorBtn = container.querySelector('[data-test-subj="pubsub-page-btn"]')
69+
70+
expect(errorBtn).not.toBeInTheDocument()
71+
expect(screen.getByText('(nil)')).toBeInTheDocument()
1972
})
2073
})

redisinsight/ui/src/components/query-card/QueryCardCliGroupResult/QueryCardCliGroupResult.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { flatten } from 'lodash'
1+
import { flatten, isNull } from 'lodash'
22
import React from 'react'
33

44
import { CommandExecutionResult } from 'uiSrc/slices/interfaces'
@@ -21,7 +21,7 @@ const QueryCardCliGroupResult = (props: Props) => {
2121
isFullScreen={isFullScreen}
2222
items={flatten(result?.[0]?.response.map((item: any) => {
2323
const commonError = CommonErrorResponse(item.id, item.command, item.response)
24-
if (React.isValidElement(commonError)) {
24+
if (React.isValidElement(commonError) && !isNull(item.response)) {
2525
return ([wbSummaryCommand(item.command), commonError])
2626
}
2727
return flatten(cliParseCommandsGroupResult(item, db))

redisinsight/ui/src/components/query-card/QueryCardCliPlugin/QueryCardCliPlugin.spec.tsx

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { instance, mock } from 'ts-mockito'
44
import { PluginEvents } from 'uiSrc/plugins/pluginEvents'
55
import { pluginApi } from 'uiSrc/services/PluginAPI'
66
import { cleanup, mockedStore, render } from 'uiSrc/utils/test-utils'
7-
import { formatToText } from 'uiSrc/utils'
7+
import { formatToText, replaceEmptyValue } from 'uiSrc/utils'
88
import { sendPluginCommandAction, getPluginStateAction, setPluginStateAction } from 'uiSrc/slices/app/plugins'
99
import QueryCardCliPlugin, { Props } from './QueryCardCliPlugin'
1010

@@ -19,7 +19,8 @@ jest.mock('uiSrc/services/PluginAPI', () => ({
1919

2020
jest.mock('uiSrc/utils', () => ({
2121
...jest.requireActual('uiSrc/utils'),
22-
formatToText: jest.fn()
22+
formatToText: jest.fn(),
23+
replaceEmptyValue: jest.fn(),
2324
}))
2425

2526
jest.mock('uiSrc/slices/app/plugins', () => ({
@@ -156,7 +157,9 @@ describe('QueryCardCliPlugin', () => {
156157
})
157158

158159
it('should subscribes and call formatToText', () => {
159-
const formatToTextMock = jest.fn();
160+
const formatToTextMock = jest.fn()
161+
const replaceEmptyValueMock = jest.fn();
162+
(replaceEmptyValue as jest.Mock).mockImplementation(replaceEmptyValueMock).mockReturnValue([]);
160163
(formatToText as jest.Mock).mockImplementation(formatToTextMock)
161164
const onEventMock = jest.fn().mockImplementation(
162165
(_iframeId: string, event: string, callback: (dat: any) => void) => {
@@ -172,4 +175,22 @@ describe('QueryCardCliPlugin', () => {
172175

173176
expect(formatToTextMock).toBeCalledWith([], 'info')
174177
})
178+
179+
it('should subscribes and call replaceEmptyValue', () => {
180+
const replaceEmptyValueMock = jest.fn();
181+
(replaceEmptyValue as jest.Mock).mockImplementation(replaceEmptyValueMock)
182+
const onEventMock = jest.fn().mockImplementation(
183+
(_iframeId: string, event: string, callback: (dat: any) => void) => {
184+
if (event === PluginEvents.formatRedisReply) {
185+
callback({ requestId: '1', data: { response: [], command: 'info' } })
186+
}
187+
}
188+
);
189+
190+
(pluginApi.onEvent as jest.Mock).mockImplementation(onEventMock)
191+
192+
render(<QueryCardCliPlugin {...instance(mockedProps)} id="1" />)
193+
194+
expect(replaceEmptyValueMock).toBeCalledWith([])
195+
})
175196
})

redisinsight/ui/src/components/query-card/QueryCardCliPlugin/QueryCardCliPlugin.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { v4 as uuidv4 } from 'uuid'
55
import { EuiFlexItem, EuiIcon, EuiLoadingContent, EuiTextColor } from '@elastic/eui'
66
import { pluginApi } from 'uiSrc/services/PluginAPI'
77
import { ThemeContext } from 'uiSrc/contexts/themeContext'
8-
import { getBaseApiUrl, Nullable, formatToText } from 'uiSrc/utils'
8+
import { getBaseApiUrl, Nullable, formatToText, replaceEmptyValue } from 'uiSrc/utils'
99
import { Theme } from 'uiSrc/constants'
1010
import { CommandExecutionResult, IPluginVisualization, RunQueryMode } from 'uiSrc/slices/interfaces'
1111
import { PluginEvents } from 'uiSrc/plugins/pluginEvents'
@@ -161,7 +161,7 @@ const QueryCardCliPlugin = (props: Props) => {
161161
{ requestId, data }: { requestId: string, data: { response: any, command: string } }
162162
) => {
163163
try {
164-
const reply = formatToText(data?.response || '(nil)', data.command)
164+
const reply = formatToText(replaceEmptyValue(data?.response), data.command)
165165

166166
sendMessageToPlugin({
167167
event: PluginEvents.formatRedisReply,

redisinsight/ui/src/components/query-card/QueryCardCliResultWrapper/QueryCardCliResultWrapper.tsx

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { isArray } from 'lodash'
55

66
import { CommandExecutionResult } from 'uiSrc/slices/interfaces'
77
import { ResultsMode } from 'uiSrc/slices/interfaces/workbench'
8-
import { cliParseTextResponse, formatToText, isGroupResults, Maybe } from 'uiSrc/utils'
8+
import { cliParseTextResponse, formatToText, replaceEmptyValue, isGroupResults, Maybe } from 'uiSrc/utils'
99

1010
import { CommandExecutionStatus } from 'uiSrc/slices/interfaces/cli'
1111
import QueryCardCliDefaultResult from '../QueryCardCliDefaultResult'
@@ -16,7 +16,6 @@ export interface Props {
1616
query: string
1717
result: Maybe<CommandExecutionResult[]>
1818
loading?: boolean
19-
status?: string
2019
resultsMode?: ResultsMode
2120
isNotStored?: boolean
2221
isFullScreen?: boolean
@@ -27,7 +26,7 @@ const QueryCardCliResultWrapper = (props: Props) => {
2726
const { result = [], query, loading, resultsMode, isNotStored, isFullScreen, db } = props
2827

2928
return (
30-
<div className={cx('queryResultsContainer', styles.container)}>
29+
<div data-testid="query-cli-result-wrapper" className={cx('queryResultsContainer', styles.container)}>
3130
{!loading && (
3231
<div data-testid="query-cli-result" className={cx(styles.content)}>
3332
{isNotStored && (
@@ -42,9 +41,9 @@ const QueryCardCliResultWrapper = (props: Props) => {
4241
<QueryCardCliDefaultResult
4342
isFullScreen={isFullScreen}
4443
items={
45-
result[0].status === CommandExecutionStatus.Success
46-
? formatToText(result[0].response || '(nil)', query).split('\n')
47-
: [cliParseTextResponse(result[0].response || '(nil)', '', result[0].status)]
44+
result[0]?.status === CommandExecutionStatus.Success
45+
? formatToText(replaceEmptyValue(result[0]?.response), query).split('\n')
46+
: [cliParseTextResponse(replaceEmptyValue(result[0]?.response), '', result[0]?.status)]
4847
}
4948
/>
5049
)}

redisinsight/ui/src/components/query-card/QueryCardCommonResult/QueryCardCommonResult.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const QueryCardCommonResult = (props: Props) => {
1313
const { result, loading } = props
1414

1515
return (
16-
<div className={cx('queryResultsContainer', styles.container)}>
16+
<div data-testid="query-common-result-wrapper" className={cx('queryResultsContainer', styles.container)}>
1717
{!loading && (
1818
<div data-testid="query-common-result">
1919
{ result || '(nil)' }

redisinsight/ui/src/utils/cliHelper.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React from 'react'
22
import { Dispatch, PayloadAction } from '@reduxjs/toolkit'
33
import parse from 'html-react-parser'
4+
import { isUndefined } from 'lodash'
45

56
import { localStorageService } from 'uiSrc/services'
67
import { CommandExecutionStatus } from 'uiSrc/slices/interfaces/cli'
@@ -49,6 +50,14 @@ const cliParseTextResponseWithOffset = (
4950
status: CommandExecutionStatus = CommandExecutionStatus.Success,
5051
) => [cliParseTextResponse(text, command, status), '\n']
5152

53+
const replaceEmptyValue = (value: any) => {
54+
if (
55+
isUndefined(value) || value === '' || value === false) {
56+
return '(nil)'
57+
}
58+
return value
59+
}
60+
5261
const cliParseTextResponse = (
5362
text: string | JSX.Element = '',
5463
command: string = '',
@@ -104,7 +113,7 @@ const cliParseCommandsGroupResult = (
104113

105114
let executionResult = []
106115
if (result.status === CommandExecutionStatus.Success) {
107-
executionResult = formatToText(result.response || '(nil)', result.command).split('\n')
116+
executionResult = formatToText(replaceEmptyValue(result.response), result.command).split('\n')
108117
} else {
109118
executionResult = [cliParseTextResponse(result.response || '(nil)', result.command, result.status)]
110119
}
@@ -229,4 +238,5 @@ export {
229238
getDbIndexFromSelectQuery,
230239
getCommandNameFromQuery,
231240
wbSummaryCommand,
241+
replaceEmptyValue,
232242
}

0 commit comments

Comments
 (0)