feat: Added warning message in response pane while prepared statement is on (#36407)
## Description Added warning message in response pane to show that use prepared statement is turned on. This will be showing up only if there is an error. Fixes #36326 ## Automation /ok-to-test tags="@tag.Sanity, @tag.Datasource" ### 🔍 Cypress test results <!-- This is an auto-generated comment: Cypress test results --> > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: <https://github.com/appsmithorg/appsmith/actions/runs/10987691166> > Commit: debc9f34515ee9303ac8e96d59cb8b59a6c5ecbf > <a href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=10987691166&attempt=1" target="_blank">Cypress dashboard</a>. > Tags: `@tag.Sanity, @tag.Datasource` > Spec: > <hr>Mon, 23 Sep 2024 05:25:23 UTC <!-- end of auto-generated comment: Cypress test results --> ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Introduced a warning message for users regarding prepared statements that may cause query errors. - Added a mechanism to navigate users to the settings page for resolving issues related to prepared statements. - Enhanced the Query Response Tab with contextual warnings and improved user guidance. - **Bug Fixes** - Improved error handling related to prepared statements in the query response. - **Tests** - Added comprehensive unit tests for the Query Response Tab to ensure correct behavior of the prepared statement warning under various conditions. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
parent
cd3472ac1d
commit
12986df894
|
|
@ -2503,3 +2503,9 @@ export const EMPTY_DATASOURCE_TOOLTIP_SIDEBUTTON = () =>
|
|||
"Create a datasource to power your app with data.";
|
||||
|
||||
export const FIELD_REQUIRED_MESSAGE = () => `This field is required`;
|
||||
|
||||
export const PREPARED_STATEMENT_WARNING = {
|
||||
MESSAGE: () =>
|
||||
"Prepared Statements are currently enabled, which may be causing the query error. Turn them off and try running the query again",
|
||||
LINK: () => "Open settings",
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,235 @@
|
|||
import React from "react";
|
||||
import { render } from "@testing-library/react";
|
||||
import { Provider } from "react-redux";
|
||||
import configureStore from "redux-mock-store";
|
||||
import QueryResponseTab from "./QueryResponseTab";
|
||||
import { ENTITY_TYPE } from "ee/entities/AppsmithConsole/utils";
|
||||
import type { Action } from "entities/Action";
|
||||
import { unitTestBaseMockStore } from "layoutSystems/common/dropTarget/unitTestUtils";
|
||||
import { EditorViewMode } from "ee/entities/IDE/constants";
|
||||
import { lightTheme } from "selectors/themeSelectors";
|
||||
import { ThemeProvider } from "styled-components";
|
||||
import { BrowserRouter as Router } from "react-router-dom";
|
||||
|
||||
// Mock store
|
||||
const mockStore = configureStore([]);
|
||||
|
||||
const defaultProps = {
|
||||
actionName: "Test Action",
|
||||
actionSource: {
|
||||
name: "test source",
|
||||
id: "test-source-id",
|
||||
type: ENTITY_TYPE.ACTION,
|
||||
},
|
||||
currentActionConfig: {
|
||||
id: "test-action-id",
|
||||
name: "Test Action",
|
||||
actionConfiguration: { pluginSpecifiedTemplates: [{ value: true }] },
|
||||
userPermissions: ["execute"],
|
||||
} as Action,
|
||||
isRunning: false,
|
||||
onRunClick: jest.fn(),
|
||||
runErrorMessage: "",
|
||||
};
|
||||
|
||||
const storeData = {
|
||||
...unitTestBaseMockStore,
|
||||
evaluations: {
|
||||
tree: {},
|
||||
},
|
||||
entities: {
|
||||
plugins: {
|
||||
list: [],
|
||||
},
|
||||
datasources: {
|
||||
structure: {},
|
||||
},
|
||||
},
|
||||
ui: {
|
||||
...unitTestBaseMockStore.ui,
|
||||
users: {
|
||||
featureFlag: {
|
||||
data: {},
|
||||
overriddenFlags: {},
|
||||
},
|
||||
},
|
||||
ide: {
|
||||
view: EditorViewMode.FullScreen,
|
||||
},
|
||||
debugger: {
|
||||
context: {
|
||||
errorCount: 0,
|
||||
},
|
||||
},
|
||||
queryPane: {
|
||||
debugger: {
|
||||
open: true,
|
||||
responseTabHeight: 200,
|
||||
selectedTab: "response",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
describe("QueryResponseTab", () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
let store: any;
|
||||
|
||||
beforeEach(() => {
|
||||
store = mockStore(storeData);
|
||||
});
|
||||
|
||||
/** Test use prepared statement warning **/
|
||||
it("1. Prepared statement warning should not be showing", () => {
|
||||
const { container } = render(
|
||||
<Provider store={store}>
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<Router>
|
||||
<QueryResponseTab {...defaultProps} />
|
||||
</Router>
|
||||
</ThemeProvider>
|
||||
</Provider>,
|
||||
);
|
||||
|
||||
// Check if the prepared statement warning is not showing
|
||||
expect(
|
||||
container.querySelector("[data-testid='t--prepared-statement-warning']"),
|
||||
).toBeNull();
|
||||
});
|
||||
|
||||
it("2. Check if prepared statement warning is not showing while running the query", () => {
|
||||
const { container } = render(
|
||||
<Provider store={store}>
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<Router>
|
||||
<QueryResponseTab {...defaultProps} isRunning />
|
||||
</Router>
|
||||
</ThemeProvider>
|
||||
</Provider>,
|
||||
);
|
||||
|
||||
// Check if the prepared statement warning is showing
|
||||
expect(
|
||||
container.querySelector("[data-testid='t--prepared-statement-warning']"),
|
||||
).toBeNull();
|
||||
});
|
||||
|
||||
it("3. Check if prepared statement warning is not showing when run is successful", () => {
|
||||
store = mockStore({
|
||||
...storeData,
|
||||
entities: {
|
||||
...storeData.entities,
|
||||
actions: [
|
||||
{
|
||||
config: {
|
||||
id: "test-action-id",
|
||||
name: "Test Action",
|
||||
},
|
||||
isLoading: false,
|
||||
data: {
|
||||
body: [{ key: "value" }],
|
||||
isExecutionSuccess: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const { container } = render(
|
||||
<Provider store={store}>
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<Router>
|
||||
<QueryResponseTab {...defaultProps} />
|
||||
</Router>
|
||||
</ThemeProvider>
|
||||
</Provider>,
|
||||
);
|
||||
|
||||
// Check if the prepared statement warning is showing
|
||||
expect(
|
||||
container.querySelector("[data-testid='t--prepared-statement-warning']"),
|
||||
).toBeNull();
|
||||
});
|
||||
|
||||
it("4. Check if prepared statement warning is showing when run is failed", () => {
|
||||
store = mockStore({
|
||||
...storeData,
|
||||
entities: {
|
||||
...storeData.entities,
|
||||
actions: [
|
||||
{
|
||||
config: {
|
||||
id: "test-action-id",
|
||||
name: "Test Action",
|
||||
},
|
||||
isLoading: false,
|
||||
data: {
|
||||
body: "ERROR: relation 'userssss' does not exist Position: 15",
|
||||
isExecutionSuccess: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const { container } = render(
|
||||
<Provider store={store}>
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<Router>
|
||||
<QueryResponseTab {...defaultProps} />
|
||||
</Router>
|
||||
</ThemeProvider>
|
||||
</Provider>,
|
||||
);
|
||||
|
||||
// Check if the prepared statement warning is showing
|
||||
expect(
|
||||
container.querySelector("[data-testid='t--prepared-statement-warning']"),
|
||||
).not.toBeNull();
|
||||
});
|
||||
|
||||
it("5. Check if prepared statement warning is not showing when prepared statement is turned off", () => {
|
||||
store = mockStore({
|
||||
...storeData,
|
||||
entities: {
|
||||
...storeData.entities,
|
||||
actions: [
|
||||
{
|
||||
config: {
|
||||
id: "test-action-id",
|
||||
name: "Test Action",
|
||||
},
|
||||
isLoading: false,
|
||||
data: {
|
||||
body: "ERROR: relation 'userssss' does not exist Position: 15",
|
||||
isExecutionSuccess: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const props = {
|
||||
...defaultProps,
|
||||
currentActionConfig: {
|
||||
...defaultProps.currentActionConfig,
|
||||
actionConfiguration: { pluginSpecifiedTemplates: [{ value: false }] },
|
||||
} as Action,
|
||||
};
|
||||
|
||||
const { container } = render(
|
||||
<Provider store={store}>
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<Router>
|
||||
<QueryResponseTab {...props} />
|
||||
</Router>
|
||||
</ThemeProvider>
|
||||
</Provider>,
|
||||
);
|
||||
|
||||
// Check if the prepared statement warning is showing
|
||||
expect(
|
||||
container.querySelector("[data-testid='t--prepared-statement-warning']"),
|
||||
).toBeNull();
|
||||
});
|
||||
});
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useState } from "react";
|
||||
import React, { useCallback, useState } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import ReactJson from "react-json-view";
|
||||
import {
|
||||
|
|
@ -13,7 +13,12 @@ import LogAdditionalInfo from "components/editorComponents/Debugger/ErrorLogs/co
|
|||
import LogHelper from "components/editorComponents/Debugger/ErrorLogs/components/LogHelper";
|
||||
import LOG_TYPE from "entities/AppsmithConsole/logtype";
|
||||
import { JsonWrapper } from "components/editorComponents/Debugger/ErrorLogs/components/LogCollapseData";
|
||||
import { Callout, Flex, SegmentedControl } from "@appsmith/ads";
|
||||
import {
|
||||
Callout,
|
||||
Flex,
|
||||
SegmentedControl,
|
||||
type CalloutLinkProps,
|
||||
} from "@appsmith/ads";
|
||||
import styled from "styled-components";
|
||||
import { DEBUGGER_TAB_KEYS } from "components/editorComponents/Debugger/helpers";
|
||||
import AnalyticsUtil from "ee/utils/AnalyticsUtil";
|
||||
|
|
@ -32,6 +37,12 @@ import ActionExecutionInProgressView from "components/editorComponents/ActionExe
|
|||
import { EditorTheme } from "components/editorComponents/CodeEditor/EditorConfig";
|
||||
import BindDataButton from "./BindDataButton";
|
||||
import { getQueryPaneDebuggerState } from "selectors/queryPaneSelectors";
|
||||
import { setQueryPaneConfigSelectedTabIndex } from "actions/queryPaneActions";
|
||||
import { EDITOR_TABS } from "constants/QueryEditorConstants";
|
||||
import {
|
||||
createMessage,
|
||||
PREPARED_STATEMENT_WARNING,
|
||||
} from "ee/constants/messages";
|
||||
|
||||
const HelpSection = styled.div``;
|
||||
|
||||
|
|
@ -151,6 +162,7 @@ const QueryResponseTab = (props: Props) => {
|
|||
|
||||
let error = runErrorMessage;
|
||||
let hintMessages: Array<string> = [];
|
||||
let showPreparedStatementWarning = false;
|
||||
// TODO: Fix this the next time the file is edited
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
let output: Record<string, any>[] | null = null;
|
||||
|
|
@ -189,8 +201,31 @@ const QueryResponseTab = (props: Props) => {
|
|||
error = "";
|
||||
hintMessages = actionResponse.messages;
|
||||
}
|
||||
|
||||
const { pluginSpecifiedTemplates } =
|
||||
currentActionConfig.actionConfiguration;
|
||||
|
||||
if (
|
||||
error &&
|
||||
pluginSpecifiedTemplates &&
|
||||
pluginSpecifiedTemplates.length > 0 &&
|
||||
pluginSpecifiedTemplates[0].value === true
|
||||
) {
|
||||
showPreparedStatementWarning = true;
|
||||
}
|
||||
}
|
||||
|
||||
const navigateToSettings = useCallback(() => {
|
||||
dispatch(setQueryPaneConfigSelectedTabIndex(EDITOR_TABS.SETTINGS));
|
||||
}, []);
|
||||
|
||||
const preparedStatementCalloutLinks: CalloutLinkProps[] = [
|
||||
{
|
||||
onClick: navigateToSettings,
|
||||
children: createMessage(PREPARED_STATEMENT_WARNING.LINK),
|
||||
},
|
||||
];
|
||||
|
||||
if (isRunning) {
|
||||
return (
|
||||
<ActionExecutionInProgressView
|
||||
|
|
@ -202,6 +237,15 @@ const QueryResponseTab = (props: Props) => {
|
|||
|
||||
return (
|
||||
<ResponseContentWrapper isError={!!error}>
|
||||
{showPreparedStatementWarning && (
|
||||
<Callout
|
||||
data-testid="t--prepared-statement-warning"
|
||||
kind="warning"
|
||||
links={preparedStatementCalloutLinks}
|
||||
>
|
||||
{createMessage(PREPARED_STATEMENT_WARNING.MESSAGE)}
|
||||
</Callout>
|
||||
)}
|
||||
{error && (
|
||||
<ResponseTabErrorContainer>
|
||||
<ResponseTabErrorContent>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user