Skip to content

Commit 9a1e702

Browse files
Merge pull request #3530 from RedisInsight/fe/feature/RI-5855_cover_wrong_structure_response
Fe/feature/ri 5855 cover wrong structure response
2 parents 32f007d + bd1367b commit 9a1e702

File tree

6 files changed

+119
-13
lines changed

6 files changed

+119
-13
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import React from 'react'
2+
import { act, render, screen } from 'uiSrc/utils/test-utils'
3+
4+
import { rdiDryRunJobSelector } from 'uiSrc/slices/rdi/dryRun'
5+
import DryRunJobCommands from './DryRunJobCommands'
6+
7+
jest.mock('uiSrc/slices/rdi/dryRun', () => ({
8+
...jest.requireActual('uiSrc/slices/rdi/dryRun'),
9+
rdiDryRunJobSelector: jest.fn().mockReturnValue({
10+
results: null,
11+
})
12+
}))
13+
14+
describe('DryRunJobCommands', () => {
15+
it('should render', () => {
16+
expect(render(<DryRunJobCommands />)).toBeTruthy()
17+
})
18+
19+
it('should render no commands message', async () => {
20+
const rdiDryRunJobSelectorMock = jest.fn().mockReturnValue({
21+
results: { output: {} },
22+
});
23+
(rdiDryRunJobSelector as jest.Mock).mockImplementationOnce(rdiDryRunJobSelectorMock)
24+
25+
await act(async () => {
26+
render(<DryRunJobCommands />)
27+
})
28+
29+
expect(screen.getByTestId('commands-output')).toHaveTextContent('No Redis commands provided.')
30+
})
31+
32+
it('should render transformations', async () => {
33+
const rdiDryRunJobSelectorMock = jest.fn().mockReturnValue({
34+
results: {
35+
output: [
36+
{
37+
connection: 'target',
38+
commands: [
39+
'HSET person:Yossi:Shirizli FNAME Yossi LAST_NAME Shirizli COUNTRY IL'
40+
]
41+
}
42+
],
43+
},
44+
});
45+
(rdiDryRunJobSelector as jest.Mock).mockImplementationOnce(rdiDryRunJobSelectorMock)
46+
47+
await act(async () => {
48+
render(<DryRunJobCommands target="target" />)
49+
})
50+
expect(screen.getByTestId('commands-output')).toHaveTextContent('HSET person:Yossi:Shirizli FNAME Yossi LAST_NAME Shirizli COUNTRY IL')
51+
})
52+
})

redisinsight/ui/src/pages/rdi/pipeline-management/components/dry-run-job-commands/DryRunJobCommands.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,28 @@ export interface Props {
1111
target?: string
1212
}
1313

14+
const NO_COMMANDS_MESSAGE = 'No Redis commands provided.'
15+
1416
const DryRunJobCommands = ({ target }: Props) => {
1517
const { results } = useSelector(rdiDryRunJobSelector)
1618
const [commands, setCommands] = useState<string>('')
1719

1820
useEffect(() => {
19-
const targetCommands = results?.output
20-
?.find((el) => el.connection === target)
21-
?.commands
21+
if (!results) {
22+
return
23+
}
2224

2325
try {
26+
const targetCommands = results?.output
27+
?.find((el) => el.connection === target)
28+
?.commands
29+
2430
monaco.editor.colorize((targetCommands ?? []).join('\n').trim(), MonacoLanguage.Redis, {})
2531
.then((data) => {
2632
setCommands(data)
2733
})
2834
} catch (e) {
29-
setCommands((targetCommands ?? []).join(''))
35+
setCommands(NO_COMMANDS_MESSAGE)
3036
}
3137
}, [results, target])
3238

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import React from 'react'
2+
import { render, screen } from 'uiSrc/utils/test-utils'
3+
4+
import { rdiDryRunJobSelector } from 'uiSrc/slices/rdi/dryRun'
5+
import DryRunJobTransformations from './DryRunJobTransformations'
6+
7+
jest.mock('uiSrc/slices/rdi/dryRun', () => ({
8+
...jest.requireActual('uiSrc/slices/rdi/dryRun'),
9+
rdiDryRunJobSelector: jest.fn().mockReturnValue({
10+
results: null,
11+
})
12+
}))
13+
14+
describe('DryRunJobTransformations', () => {
15+
it('should render', () => {
16+
expect(render(<DryRunJobTransformations />)).toBeTruthy()
17+
})
18+
19+
it('should render no transformation message', () => {
20+
const rdiDryRunJobSelectorMock = jest.fn().mockReturnValue({
21+
results: {},
22+
});
23+
(rdiDryRunJobSelector as jest.Mock).mockImplementationOnce(rdiDryRunJobSelectorMock)
24+
25+
render(<DryRunJobTransformations />)
26+
expect(screen.getByTestId('transformations-output')).toHaveTextContent('No transformation results provided.')
27+
})
28+
29+
it('should render transformations', () => {
30+
const rdiDryRunJobSelectorMock = jest.fn().mockReturnValue({
31+
results: { transformation: [] },
32+
});
33+
(rdiDryRunJobSelector as jest.Mock).mockImplementationOnce(rdiDryRunJobSelectorMock)
34+
35+
render(<DryRunJobTransformations />)
36+
expect(screen.getByTestId('transformations-output')).toHaveTextContent('[]')
37+
})
38+
})

redisinsight/ui/src/pages/rdi/pipeline-management/components/dry-run-job-transformations/DryRunJobTransformations.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,23 @@ import { useSelector } from 'react-redux'
44
import { rdiDryRunJobSelector } from 'uiSrc/slices/rdi/dryRun'
55
import MonacoJson from 'uiSrc/components/monaco-editor/components/monaco-json'
66

7+
const NO_TRANSFORMATION_MESSAGE = 'No transformation results provided.'
8+
79
const DryRunJobTransformations = () => {
810
const { results } = useSelector(rdiDryRunJobSelector)
911

1012
const [transformations, setTransformations] = useState('')
1113

1214
useEffect(() => {
15+
if (!results) {
16+
return
17+
}
18+
1319
try {
1420
const transformations = JSON.stringify(results?.transformation, null, 2)
15-
setTransformations(transformations)
21+
setTransformations(transformations || NO_TRANSFORMATION_MESSAGE)
1622
} catch (e) {
17-
// ignore error
23+
setTransformations(NO_TRANSFORMATION_MESSAGE)
1824
}
1925
}, [results])
2026

redisinsight/ui/src/pages/rdi/pipeline-management/components/jobs-panel/Panel.spec.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,15 @@ describe('JobsPanel', () => {
5353
expect(screen.getByTestId('dry-run-btn')).toBeDisabled()
5454

5555
// set valid json value
56-
fireEvent.change(screen.getByTestId('input-value'), { target: { value: 1 } })
56+
fireEvent.change(screen.getByTestId('input-value'), { target: { value: '[]' } })
5757

5858
expect(screen.getByTestId('dry-run-btn')).not.toBeDisabled()
5959
})
6060

6161
it('should call proper telemetry events', () => {
6262
render(<JobsPanel {...instance(mockedProps)} />)
6363

64-
fireEvent.change(screen.getByTestId('input-value'), { target: { value: 1 } })
64+
fireEvent.change(screen.getByTestId('input-value'), { target: { value: '[]' } })
6565
fireEvent.click(screen.getByTestId('dry-run-btn'))
6666

6767
expect(sendEventTelemetry).toBeCalledWith({
@@ -92,7 +92,7 @@ describe('JobsPanel', () => {
9292
it('should fetch dry run job results', () => {
9393
render(<JobsPanel {...instance(mockedProps)} />)
9494

95-
fireEvent.change(screen.getByTestId('input-value'), { target: { value: 1 } })
95+
fireEvent.change(screen.getByTestId('input-value'), { target: { value: '[]' } })
9696
fireEvent.click(screen.getByTestId('dry-run-btn'))
9797

9898
const expectedActions = [

redisinsight/ui/src/pages/rdi/pipeline-management/components/jobs-panel/Panel.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
} from '@elastic/eui'
1414
import { useDispatch, useSelector } from 'react-redux'
1515
import { useParams } from 'react-router-dom'
16+
import { isArray } from 'lodash'
1617
import yaml from 'js-yaml'
1718

1819
import { PipelineJobsTabs } from 'uiSrc/slices/interfaces/rdi'
@@ -65,8 +66,8 @@ const DryRunJobPanel = (props: Props) => {
6566

6667
useEffect(() => {
6768
try {
68-
JSON.parse(input)
69-
setIsFormValid(true)
69+
const jsonValue = JSON.parse(input)
70+
setIsFormValid(isArray(jsonValue))
7071
} catch (e) {
7172
setIsFormValid(false)
7273
}
@@ -78,9 +79,11 @@ const DryRunJobPanel = (props: Props) => {
7879
}, [])
7980

8081
useEffect(() => {
81-
if (!results?.output) return
82+
if (!results?.output || !isArray(results.output)) return
8283

83-
const targets = results.output.map(({ connection }) => getTargetOption(connection))
84+
const targets = results.output
85+
.filter(({ connection }) => connection)
86+
.map(({ connection }) => getTargetOption(connection))
8487
setTargetOptions(targets)
8588
setSelectedTarget(targets[0]?.value)
8689
}, [results])
@@ -114,6 +117,7 @@ const DryRunJobPanel = (props: Props) => {
114117
const isSelectAvailable = selectedTab === PipelineJobsTabs.Output
115118
&& !!results?.output
116119
&& (results?.output?.length > 1)
120+
&& !!targetOptions.length
117121

118122
const Tabs = useCallback(() => (
119123
<EuiTabs className={styles.tabs}>

0 commit comments

Comments
 (0)