Skip to content

Commit 60f2a45

Browse files
committed
#RI-1697 - When user switches between table and text view, request /send-command is sent
1 parent cadd93d commit 60f2a45

File tree

26 files changed

+226
-101
lines changed

26 files changed

+226
-101
lines changed

redisinsight/api/src/modules/cli/dto/cli.dto.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export class SendCommandDto {
5151

5252
@ApiPropertyOptional({
5353
description: 'Define output format',
54-
default: CliOutputFormatterTypes.Text,
54+
default: CliOutputFormatterTypes.Raw,
5555
enum: CliOutputFormatterTypes,
5656
})
5757
@IsOptional()

redisinsight/api/src/modules/cli/services/cli-business/cli-business.service.spec.ts

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ const mockENotFoundMessage = 'ENOTFOUND some message';
5555
const mockMemoryUsageCommand = 'memory usage key';
5656
const mockGetEscapedKeyCommand = 'get "\\\\key';
5757
const mockServerInfoCommand = 'info server';
58-
const mockIntegerResponse = '(integer) 5';
58+
const mockIntegerResponse = 5;
5959

6060
describe('CliBusinessService', () => {
6161
let service: CliBusinessService;
@@ -199,7 +199,7 @@ describe('CliBusinessService', () => {
199199
describe('sendCommand', () => {
200200
it('should successfully execute command and return text response', async () => {
201201
const dto: SendCommandDto = { command: mockMemoryUsageCommand };
202-
const formatSpy = jest.spyOn(textFormatter, 'format');
202+
const formatSpy = jest.spyOn(rawFormatter, 'format');
203203
const mockResult: SendCommandResponse = {
204204
response: mockIntegerResponse,
205205
status: CommandExecutionStatus.Success,
@@ -551,7 +551,38 @@ describe('CliBusinessService', () => {
551551
);
552552
});
553553

554-
it('should successfully execute command for single node with redirection', async () => {
554+
it('should successfully execute command for single node with redirection (RAW format)', async () => {
555+
const command = 'set foo bar';
556+
const mockResult: SendClusterCommandResponse = {
557+
response: 'OK',
558+
node: { ...mockNode, port: 7002 },
559+
status: CommandExecutionStatus.Success,
560+
};
561+
cliTool.execCommandForNode
562+
.mockResolvedValueOnce({
563+
response: mockRedisMovedError.message,
564+
error: mockRedisMovedError,
565+
status: CommandExecutionStatus.Fail,
566+
})
567+
.mockResolvedValueOnce({
568+
response: 'OK',
569+
host: '127.0.0.1',
570+
port: 7002,
571+
status: CommandExecutionStatus.Success,
572+
});
573+
574+
const result = await service.sendCommandForSingleNode(
575+
mockClientOptions,
576+
command,
577+
ClusterNodeRole.All,
578+
nodeOptions,
579+
CliOutputFormatterTypes.Raw,
580+
);
581+
582+
expect(cliTool.execCommandForNode).toHaveBeenCalledTimes(2);
583+
expect(result).toEqual(mockResult);
584+
});
585+
it('should successfully execute command for single node with redirection (Text format)', async () => {
555586
const command = 'set foo bar';
556587
const mockResult: SendClusterCommandResponse = {
557588
response: '-> Redirected to slot [7008] located at 127.0.0.1:7002\nOK',
@@ -576,6 +607,7 @@ describe('CliBusinessService', () => {
576607
command,
577608
ClusterNodeRole.All,
578609
nodeOptions,
610+
CliOutputFormatterTypes.Text,
579611
);
580612

581613
expect(cliTool.execCommandForNode).toHaveBeenCalledTimes(2);

redisinsight/api/src/modules/cli/services/cli-business/cli-business.service.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ export class CliBusinessService {
142142
this.logger.log('Executing redis CLI command.');
143143
const { command: commandLine } = dto;
144144
let namespace = AppTool.CLI.toString();
145-
const outputFormat = dto.outputFormat || CliOutputFormatterTypes.Text;
145+
const outputFormat = dto.outputFormat || CliOutputFormatterTypes.Raw;
146146
try {
147147
const formatter = this.outputFormatterManager.getStrategy(outputFormat);
148148
const [command, ...args] = splitCliCommandLine(commandLine);
@@ -216,7 +216,7 @@ export class CliBusinessService {
216216
clientOptions: IFindRedisClientInstanceByOptions,
217217
commandLine: string,
218218
role: ClusterNodeRole,
219-
outputFormat: CliOutputFormatterTypes = CliOutputFormatterTypes.Text,
219+
outputFormat: CliOutputFormatterTypes = CliOutputFormatterTypes.Raw,
220220
): Promise<SendClusterCommandResponse[]> {
221221
let namespace = AppTool.CLI.toString();
222222
this.logger.log(`Executing redis.cluster CLI command for [${role}] nodes.`);
@@ -278,7 +278,7 @@ export class CliBusinessService {
278278
commandLine: string,
279279
role: ClusterNodeRole,
280280
nodeOptions: ClusterSingleNodeOptions,
281-
outputFormat: CliOutputFormatterTypes = CliOutputFormatterTypes.Text,
281+
outputFormat: CliOutputFormatterTypes = CliOutputFormatterTypes.Raw,
282282
): Promise<SendClusterCommandResponse> {
283283
this.logger.log(`Executing redis.cluster CLI command for single node ${JSON.stringify(nodeOptions)}`);
284284
try {

redisinsight/api/src/modules/cli/services/cli-business/output-formatter/output-formatter-manager.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class TestFormatterStrategy implements IOutputFormatterStrategy {
1111
return '';
1212
}
1313
}
14-
const strategyName = CliOutputFormatterTypes.Text;
14+
const strategyName = CliOutputFormatterTypes.Raw;
1515
const testStrategy = new TestFormatterStrategy();
1616

1717
describe('OutputFormatterManager', () => {

redisinsight/splash.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@
9090
</svg>
9191
</div>
9292
<span id="text" class="text"></span>
93-
<span class="copyright">RedisInsight 2.0.2-preview © 2021 Redis Ltd.</span>
93+
<span class="copyright">RedisInsight 2.0.3-preview © 2021 Redis Ltd.</span>
9494
</div>
9595
</div>
9696

redisinsight/ui/src/components/cli/components/cli-body/CliBody/CliBody.spec.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import React from 'react'
33
import { keys } from '@elastic/eui'
44
import { instance, mock } from 'ts-mockito'
55
import { cleanup, fireEvent, mockedStore, render, screen } from 'uiSrc/utils/test-utils'
6-
import { clearOutput, updateCliHistoryStorage } from 'uiSrc/utils/cli'
6+
import { clearOutput, updateCliHistoryStorage } from 'uiSrc/utils/cliHelper'
77
import CLI from 'uiSrc/components/cli/Cli'
88
import { MOCK_COMMANDS_ARRAY } from 'uiSrc/constants'
99
import CliBody, { Props } from './CliBody'
@@ -48,8 +48,8 @@ jest.mock(redisCommandsPath, () => {
4848
}
4949
})
5050

51-
jest.mock('uiSrc/utils/cli', () => ({
52-
...jest.requireActual('uiSrc/utils/cli'),
51+
jest.mock('uiSrc/utils/cliHelper', () => ({
52+
...jest.requireActual('uiSrc/utils/cliHelper'),
5353
updateCliHistoryStorage: jest.fn(),
5454
clearOutput: jest.fn(),
5555
}))

redisinsight/ui/src/components/cli/components/cli-body/CliBody/CliBody.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { ClearCommand } from 'uiSrc/constants/cliOutput'
88
import { outputSelector } from 'uiSrc/slices/cli/cli-output'
99
import { cliSettingsSelector } from 'uiSrc/slices/cli/cli-settings'
1010
import CliInputWrapper from 'uiSrc/components/cli/components/cli-input'
11-
import { clearOutput, updateCliHistoryStorage } from 'uiSrc/utils/cli'
11+
import { clearOutput, updateCliHistoryStorage } from 'uiSrc/utils/cliHelper'
1212
import { appRedisCommandsSelector } from 'uiSrc/slices/app/redis-commands'
1313

1414
import styles from './styles.module.scss'

redisinsight/ui/src/components/cli/components/cli-body/CliBodyWrapper.spec.tsx

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import React from 'react'
22
import { cloneDeep, first } from 'lodash'
3-
import { instance, mock } from 'ts-mockito'
43
import {
54
cleanup,
65
fireEvent,
@@ -21,9 +20,7 @@ import { processCliClient } from 'uiSrc/slices/cli/cli-settings'
2120
import { connectedInstanceSelector } from 'uiSrc/slices/instances'
2221
import { sessionStorageService } from 'uiSrc/services'
2322

24-
import CliBodyWrapper, { Props } from './CliBodyWrapper'
25-
26-
const mockedProps = mock<Props>()
23+
import CliBodyWrapper from './CliBodyWrapper'
2724

2825
let store: typeof mockedStore
2926
beforeEach(() => {
@@ -55,8 +52,8 @@ jest.mock('uiSrc/slices/cli/cli-output', () => ({
5552
updateCliCommandHistory: jest.fn,
5653
}))
5754

58-
jest.mock('uiSrc/utils/cli', () => ({
59-
...jest.requireActual('uiSrc/utils/cli'),
55+
jest.mock('uiSrc/utils/cliHelper', () => ({
56+
...jest.requireActual('uiSrc/utils/cliHelper'),
6057
updateCliHistoryStorage: jest.fn(),
6158
clearOutput: jest.fn(),
6259
cliParseTextResponse: jest.fn(),
@@ -78,20 +75,20 @@ jest.mock('uiSrc/slices/cli/cli-settings', () => ({
7875

7976
describe('CliBodyWrapper', () => {
8077
it('should render', () => {
81-
expect(render(<CliBodyWrapper {...instance(mockedProps)} />)).toBeTruthy()
78+
expect(render(<CliBodyWrapper />)).toBeTruthy()
8279
})
8380

8481
it('should SessionStorage be called', () => {
8582
const mockUuid = 'test-uuid'
8683
sessionStorageService.get = jest.fn().mockReturnValue(mockUuid)
8784

88-
render(<CliBodyWrapper {...instance(mockedProps)} />)
85+
render(<CliBodyWrapper />)
8986

9087
expect(sessionStorageService.get).toBeCalledWith(BrowserStorageItem.cliClientUuid)
9188
})
9289

9390
it('should render with SessionStorage', () => {
94-
render(<CliBodyWrapper {...instance(mockedProps)} />)
91+
render(<CliBodyWrapper />)
9592

9693
const expectedActions = [concatToOutput(InitOutputText('', 0)), processCliClient()]
9794
expect(clearStoreActions(store.getActions().slice(0, expectedActions.length))).toEqual(
@@ -100,7 +97,7 @@ describe('CliBodyWrapper', () => {
10097
})
10198

10299
it('"onSubmit" should be called after keyDown Enter', () => {
103-
render(<CliBodyWrapper {...instance(mockedProps)} />)
100+
render(<CliBodyWrapper />)
104101

105102
fireEvent.keyDown(screen.getByTestId(cliCommandTestId), {
106103
key: 'Enter',
@@ -114,7 +111,7 @@ describe('CliBodyWrapper', () => {
114111
})
115112

116113
it('CliHelper should be opened by default', () => {
117-
render(<CliBodyWrapper {...instance(mockedProps)} />)
114+
render(<CliBodyWrapper />)
118115

119116
expect(screen.getByTestId('cli-helper')).toBeInTheDocument()
120117
})
@@ -127,7 +124,7 @@ describe('CliBodyWrapper', () => {
127124

128125
processUnsupportedCommand.mockImplementation(() => processUnsupportedCommandMock)
129126

130-
render(<CliBodyWrapper {...instance(mockedProps)} />)
127+
render(<CliBodyWrapper />)
131128

132129
// Act
133130
fireEvent.change(screen.getByTestId(cliCommandTestId), {
@@ -152,7 +149,7 @@ describe('CliBodyWrapper', () => {
152149

153150
sendCliClusterCommandAction.mockImplementation(() => sendCliClusterActionMock)
154151

155-
render(<CliBodyWrapper {...instance(mockedProps)} />)
152+
render(<CliBodyWrapper />)
156153

157154
// Act
158155
fireEvent.keyDown(screen.getByTestId(cliCommandTestId), {

redisinsight/ui/src/components/cli/components/cli-body/CliBodyWrapper.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import { ConnectionType } from 'uiSrc/slices/interfaces'
2626
import { sessionStorageService } from 'uiSrc/services'
2727
import { ClusterNodeRole } from 'uiSrc/slices/interfaces/cli'
2828
import { connectedInstanceSelector } from 'uiSrc/slices/instances'
29-
import { checkUnsupportedCommand, clearOutput } from 'uiSrc/utils/cli'
29+
import { checkUnsupportedCommand, clearOutput } from 'uiSrc/utils/cliHelper'
3030
import { InitOutputText, ConnectionSuccessOutputText } from 'uiSrc/constants/cliOutput'
3131
import { SendClusterCommandDto } from 'apiSrc/modules/cli/dto/cli.dto'
3232

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

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import { appPluginsSelector } from 'uiSrc/slices/app/plugins'
1010
import { IPluginVisualization } from 'uiSrc/slices/interfaces'
1111
import { CommandExecutionStatus } from 'uiSrc/slices/interfaces/cli'
1212
import { sendEventTelemetry, TelemetryEvent } from 'uiSrc/telemetry'
13-
import { appRedisCommandsSelector } from 'uiSrc/slices/app/redis-commands'
1413

1514
import QueryCardHeader from './QueryCardHeader'
1615
import QueryCardCliResult from './QueryCardCliResult'
@@ -25,7 +24,6 @@ export interface Props {
2524
data: any;
2625
status: Maybe<CommandExecutionStatus>;
2726
fromStore: boolean;
28-
matched?: number;
2927
time?: number;
3028
loading?: boolean;
3129
onQueryRun: (queryType: WBQueryType) => void;
@@ -51,7 +49,6 @@ const QueryCard = (props: Props) => {
5149
} = props
5250

5351
const { visualizations = [] } = useSelector(appPluginsSelector)
54-
const { commandsArray: REDIS_COMMANDS_ARRAY } = useSelector(appRedisCommandsSelector)
5552

5653
const { instanceId = '' } = useParams<{ instanceId: string }>()
5754
const [isOpen, setIsOpen] = useState(!fromStore)
@@ -110,25 +107,9 @@ const QueryCard = (props: Props) => {
110107
}
111108
}, [data, time])
112109

113-
const sendEventToggleOpenTelemetry = () => {
114-
const matchedCommand = REDIS_COMMANDS_ARRAY.find((commandName) =>
115-
query.toUpperCase().startsWith(commandName))
116-
117-
sendEventTelemetry({
118-
event: isOpen
119-
? TelemetryEvent.WORKBENCH_RESULTS_COLLAPSED
120-
: TelemetryEvent.WORKBENCH_RESULTS_EXPANDED,
121-
eventData: {
122-
databaseId: instanceId,
123-
command: matchedCommand ?? query.split(' ')?.[0]
124-
}
125-
})
126-
}
127-
128110
const toggleOpen = () => {
129111
if (isFullScreen) return
130112

131-
sendEventToggleOpenTelemetry()
132113
setIsOpen(!isOpen)
133114

134115
if (!isOpen && !data) {
@@ -137,8 +118,6 @@ const QueryCard = (props: Props) => {
137118
}
138119

139120
const changeViewTypeSelected = (type: WBQueryType, value: string) => {
140-
onQueryRun(type)
141-
setResult(undefined)
142121
setViewTypeSelected(type)
143122
setSelectedViewValue(value)
144123
}
@@ -191,7 +170,7 @@ const QueryCard = (props: Props) => {
191170
</>
192171
)}
193172
{viewTypeSelected === WBQueryType.Text && (
194-
<QueryCardCliResult status={status} result={result} />
173+
<QueryCardCliResult query={query} status={status} result={result} />
195174
)}
196175
</>
197176
)}

0 commit comments

Comments
 (0)