From 88469ee72b252af8b79ddad7ba20414e9e07b23a Mon Sep 17 00:00:00 2001 From: sunjinkang <2060037942@qq.com> Date: Fri, 12 Jan 2024 19:19:08 +0800 Subject: [PATCH 01/17] [test]: add test for sql management hooks --- packages/shared/lib/testUtil/customRender.tsx | 11 ++- .../SQLEEIndex/hooks/useRuleTips.test.tsx | 91 +++++++++++++++++++ .../src/testUtils/mockApi/sqlManage/data.ts | 31 +++++++ .../src/testUtils/mockApi/sqlManage/index.ts | 47 ++++++++++ 4 files changed, 176 insertions(+), 4 deletions(-) create mode 100644 packages/sqle/src/page/SqlManagement/component/SQLEEIndex/hooks/useRuleTips.test.tsx create mode 100644 packages/sqle/src/testUtils/mockApi/sqlManage/data.ts create mode 100644 packages/sqle/src/testUtils/mockApi/sqlManage/index.ts diff --git a/packages/shared/lib/testUtil/customRender.tsx b/packages/shared/lib/testUtil/customRender.tsx index 5990b0807..88cb715a5 100644 --- a/packages/shared/lib/testUtil/customRender.tsx +++ b/packages/shared/lib/testUtil/customRender.tsx @@ -87,7 +87,8 @@ export const renderHooksWithReduxAndRouter = ( }; export const renderHooksWithTheme = ( - hooks: (props: TProps) => TResult + hooks: (props: TProps) => TResult, + initStore?: any ) => { return renderHook(hooks, { wrapper: ({ children }) => ( @@ -95,9 +96,11 @@ export const renderHooksWithTheme = ( locale={zhCN} theme={{ algorithm: antdTheme.defaultAlgorithm }} > - - {children} - + + + {children} + + ) }); diff --git a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/hooks/useRuleTips.test.tsx b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/hooks/useRuleTips.test.tsx new file mode 100644 index 000000000..c3b740865 --- /dev/null +++ b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/hooks/useRuleTips.test.tsx @@ -0,0 +1,91 @@ +import { renderHooksWithTheme } from '@actiontech/shared/lib/testUtil/customRender'; +import useRuleTips from './useRuleTips'; +import sqlManage from '../../../../../testUtils/mockApi/sqlManage'; +import { act, cleanup } from '@testing-library/react'; +import { mockProjectInfo } from '@actiontech/shared/lib/testUtil/mockHook/data'; +import { ruleTipsData } from '../../../../../testUtils/mockApi/sqlManage/data'; +import { createSpySuccessResponse } from '@actiontech/shared/lib/testUtil/mockApi'; +import { useSelector } from 'react-redux'; + +jest.mock('react-redux', () => { + return { + ...jest.requireActual('react-redux'), + useSelector: jest.fn() + }; +}); + +describe('SqlManagement/useRuleTips', () => { + beforeEach(() => { + sqlManage.mockAllApi(); + jest.useFakeTimers(); + (useSelector as jest.Mock).mockImplementation((selector) => { + return selector({ + database: { + driverMeta: [] + } + }); + }); + }); + + afterEach(() => { + jest.useRealTimers(); + cleanup(); + }); + + it('get rule tips', async () => { + const request = sqlManage.getSqlManageRuleTips(); + const { result } = renderHooksWithTheme(() => useRuleTips()); + await act(async () => { + result.current.updateRuleTips(mockProjectInfo.projectName); + }); + expect(result.current.loading).toBe(true); + await act(async () => jest.advanceTimersByTime(3000)); + expect(request).toBeCalledWith({ + project_name: mockProjectInfo.projectName + }); + expect(result.current.loading).toBe(false); + expect(result.current.ruleTips).toStrictEqual(ruleTipsData); + expect(result.current.generateRuleTipsSelectOptions.length).toBe(3); + expect(result.current.generateRuleTipsSelectOptions[0].options.length).toBe( + 1 + ); + expect( + result.current.generateRuleTipsSelectOptions[0].options[0].label + ).toBe(ruleTipsData?.[0].rule?.[0].desc); + }); + + it('get rule tips with return error code', async () => { + const request = sqlManage.getSqlManageRuleTips(); + request.mockImplementation(() => + createSpySuccessResponse({ + code: 500, + message: 'error' + }) + ); + const { result } = renderHooksWithTheme(() => useRuleTips()); + await act(async () => { + result.current.updateRuleTips(mockProjectInfo.projectName); + }); + await act(async () => jest.advanceTimersByTime(3000)); + expect(request).toBeCalledWith({ + project_name: mockProjectInfo.projectName + }); + expect(result.current.ruleTips).toStrictEqual([]); + expect(result.current.generateRuleTipsSelectOptions.length).toBe(0); + }); + + it('request rule tips failed', async () => { + const request = sqlManage.getSqlManageRuleTips(); + request.mockImplementation(() => Promise.reject('error')); + const { result } = renderHooksWithTheme(() => useRuleTips()); + await act(async () => { + result.current.updateRuleTips(mockProjectInfo.projectName); + }); + await act(async () => jest.advanceTimersByTime(3000)); + expect(request).toBeCalledWith({ + project_name: mockProjectInfo.projectName + }); + expect(result.current.ruleTips).toStrictEqual([]); + expect(result.current.generateRuleTipsSelectOptions.length).toBe(0); + }); +}); diff --git a/packages/sqle/src/testUtils/mockApi/sqlManage/data.ts b/packages/sqle/src/testUtils/mockApi/sqlManage/data.ts new file mode 100644 index 000000000..deaa98009 --- /dev/null +++ b/packages/sqle/src/testUtils/mockApi/sqlManage/data.ts @@ -0,0 +1,31 @@ +export const ruleTipsData = [ + { + db_type: 'MySQL', + rule: [ + { + desc: '用于测试', + rule_name: 'test' + } + ] + }, + { + rule: [ + { + desc: '用于测试', + rule_name: 'test' + } + ] + }, + { + db_type: 'MySQL' + } +]; + +export const sqlManageListData = { + data: [{}], + sql_manage_bad_num: 1, + sql_manage_optimized_num: 1, + sql_manage_total_num: 2 +}; + +export const exportSqlManageData = 'test'; diff --git a/packages/sqle/src/testUtils/mockApi/sqlManage/index.ts b/packages/sqle/src/testUtils/mockApi/sqlManage/index.ts new file mode 100644 index 000000000..cb81a6ab3 --- /dev/null +++ b/packages/sqle/src/testUtils/mockApi/sqlManage/index.ts @@ -0,0 +1,47 @@ +import SqlManage from '@actiontech/shared/lib/api/sqle/service/SqlManage'; +import { + MockSpyApy, + createSpySuccessResponse +} from '@actiontech/shared/lib/testUtil/mockApi'; +import { exportSqlManageData, ruleTipsData, sqlManageListData } from './data'; + +class MockSqlManageApi implements MockSpyApy { + public mockAllApi(): void { + this.getSqlManageRuleTips(); + this.batchUpdateSqlManage(); + this.getSqlManageList(); + this.exportSqlManage(); + } + + public getSqlManageRuleTips() { + const spy = jest.spyOn(SqlManage, 'GetSqlManageRuleTips'); + spy.mockImplementation(() => + createSpySuccessResponse({ + data: ruleTipsData + }) + ); + return spy; + } + + public batchUpdateSqlManage() { + const spy = jest.spyOn(SqlManage, 'BatchUpdateSqlManage'); + spy.mockImplementation(() => createSpySuccessResponse({})); + return spy; + } + + public getSqlManageList() { + const spy = jest.spyOn(SqlManage, 'GetSqlManageListV2'); + spy.mockImplementation(() => + createSpySuccessResponse({ ...sqlManageListData }) + ); + return spy; + } + + public exportSqlManage() { + const spy = jest.spyOn(SqlManage, 'exportSqlManageV1'); + spy.mockImplementation(() => createSpySuccessResponse(exportSqlManageData)); + return spy; + } +} + +export default new MockSqlManageApi(); From 4bc63f6081325ec5f5417c0017cd8f4b9aca3e24 Mon Sep 17 00:00:00 2001 From: sunjinkang <2060037942@qq.com> Date: Mon, 15 Jan 2024 19:05:29 +0800 Subject: [PATCH 02/17] [test]: add test for sql management assign --- .../__snapshots__/index.test.tsx.snap | 389 ++++++++++++++++++ .../Modal/AssignmentBatch/index.test.tsx | 121 ++++++ .../Modal/AssignmentBatch/index.tsx | 4 +- .../__snapshots__/index.test.tsx.snap | 332 +++++++++++++++ .../Modal/AssignmentForm/index.test.tsx | 80 ++++ .../__snapshots__/index.test.tsx.snap | 389 ++++++++++++++++++ .../Modal/AssignmentSingle/index.test.tsx | 121 ++++++ .../SQLEEIndex/hooks/useStaticStatus.test.ts | 24 ++ .../components/ReviewNodeInfo/index.test.tsx | 6 +- .../components/StepInfo/index.test.tsx | 6 +- .../UpdateWorkflowTemplate/index.test.tsx | 9 +- .../WorkflowTemplateStepInfo/index.test.tsx | 6 +- .../WorkflowTemplateDetail/index.test.tsx | 7 +- .../src/testUtils/mockApi/sqlManage/data.ts | 301 +++++++++++++- .../src/testUtils/mockApi/sqlManage/index.ts | 6 +- .../sqle/src/testUtils/mockApi/user/data.ts | 9 + .../sqle/src/testUtils/mockApi/user/index.ts | 24 ++ .../mockApi/workflowTemplate/data.ts | 10 - .../mockApi/workflowTemplate/index.ts | 13 +- packages/sqle/src/testUtils/mockRedux.tsx | 4 +- 20 files changed, 1815 insertions(+), 46 deletions(-) create mode 100644 packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentBatch/__snapshots__/index.test.tsx.snap create mode 100644 packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentBatch/index.test.tsx create mode 100644 packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentForm/__snapshots__/index.test.tsx.snap create mode 100644 packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentForm/index.test.tsx create mode 100644 packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentSingle/__snapshots__/index.test.tsx.snap create mode 100644 packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentSingle/index.test.tsx create mode 100644 packages/sqle/src/page/SqlManagement/component/SQLEEIndex/hooks/useStaticStatus.test.ts create mode 100644 packages/sqle/src/testUtils/mockApi/user/data.ts create mode 100644 packages/sqle/src/testUtils/mockApi/user/index.ts diff --git a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentBatch/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentBatch/__snapshots__/index.test.tsx.snap new file mode 100644 index 000000000..7b8e85985 --- /dev/null +++ b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentBatch/__snapshots__/index.test.tsx.snap @@ -0,0 +1,389 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`page/SqlManagement/AssignmentBatch close modal by click button 1`] = ` + +
+
+
+
+
+ +
+ +`; + +exports[`page/SqlManagement/AssignmentBatch render modal when not open 1`] = ` + +
+ +`; + +exports[`page/SqlManagement/AssignmentBatch update batch assign and submit change 1`] = ` + +
+
+
+
+
+ +
+ +`; diff --git a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentBatch/index.test.tsx b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentBatch/index.test.tsx new file mode 100644 index 000000000..72bde2195 --- /dev/null +++ b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentBatch/index.test.tsx @@ -0,0 +1,121 @@ +import { act, cleanup, fireEvent, screen } from '@testing-library/react'; +import AssignmentBatch from '.'; +import { superRender } from '../../../../../../testUtils/customRender'; +import user from '../../../../../../testUtils/mockApi/user'; +import { mockUseCurrentProject } from '@actiontech/shared/lib/testUtil/mockHook/mockUseCurrentProject'; +import { ModalName } from '../../../../../../data/ModalName'; +import { sqlManageListData } from '../../../../../../testUtils/mockApi/sqlManage/data'; +import sqlManage from '../../../../../../testUtils/mockApi/sqlManage'; +import { mockProjectInfo } from '@actiontech/shared/lib/testUtil/mockHook/data'; +import { + getAllBySelector, + getBySelector +} from '@actiontech/shared/lib/testUtil/customQuery'; +import { userTipListData } from '../../../../../../testUtils/mockApi/user/data'; +import EventEmitter from '../../../../../../utils/EventEmitter'; +import { useDispatch } from 'react-redux'; +import EmitterKey from '../../../../../../data/EmitterKey'; + +jest.mock('react-redux', () => ({ + ...jest.requireActual('react-redux'), + useDispatch: jest.fn() +})); + +describe('page/SqlManagement/AssignmentBatch', () => { + const dispatchSpy = jest.fn(); + + beforeEach(() => { + (useDispatch as jest.Mock).mockImplementation(() => dispatchSpy); + mockUseCurrentProject(); + user.mockAllApi(); + sqlManage.mockAllApi(); + jest.useFakeTimers(); + }); + + afterEach(() => { + jest.useRealTimers(); + jest.clearAllMocks(); + cleanup(); + }); + + const customRender = (data?: boolean) => { + return superRender(, undefined, { + initStore: { + sqleManagement: { + modalStatus: { + [ModalName.Assignment_Member_Batch]: data ?? true + }, + selectSqlIdList: [sqlManageListData.data[0]] + } + } + }); + }; + + it('render modal when not open', () => { + const { baseElement } = customRender(false); + expect(baseElement).toMatchSnapshot(); + }); + + it('update batch assign and submit change', async () => { + const eventEmitSpy = jest.spyOn(EventEmitter, 'emit'); + const optionRequest = user.getUserTip(); + const submitRequest = sqlManage.batchUpdateSqlManage(); + const { baseElement } = customRender(); + await act(async () => jest.advanceTimersByTime(3000)); + expect(optionRequest).toBeCalledWith({ + filter_project: mockProjectInfo.projectName + }); + expect(baseElement).toMatchSnapshot(); + expect(screen.getByText('批量指派')).toBeInTheDocument(); + fireEvent.mouseDown(getBySelector('#assignees')); + await act(async () => jest.advanceTimersByTime(300)); + const options = getAllBySelector('.ant-select-item-option'); + fireEvent.click(options[0]); + await act(async () => jest.advanceTimersByTime(300)); + fireEvent.click(screen.getByText('确 认')); + await act(async () => jest.advanceTimersByTime(300)); + expect(submitRequest).toBeCalledWith({ + project_name: mockProjectInfo.projectName, + sql_manage_id_list: [sqlManageListData.data[0].id], + assignees: [userTipListData[0].user_id] + }); + await act(async () => jest.advanceTimersByTime(3000)); + expect(screen.getByText('批量指派负责人成功')).toBeInTheDocument(); + await act(async () => jest.advanceTimersByTime(3300)); + expect(dispatchSpy).toBeCalledTimes(2); + expect(dispatchSpy).toBeCalledWith({ + type: 'sqleManagement/updateModalStatus', + payload: { + modalName: ModalName.Assignment_Member_Batch, + status: false + } + }); + expect(dispatchSpy).toBeCalledWith({ + type: 'sqleManagement/updateSqlIdList', + payload: null + }); + expect(eventEmitSpy).toBeCalledTimes(1); + expect(eventEmitSpy).toBeCalledWith(EmitterKey.Refresh_SQL_Management); + }); + + it('close modal by click button', async () => { + const { baseElement } = customRender(); + await act(async () => jest.advanceTimersByTime(3000)); + expect(baseElement).toMatchSnapshot(); + expect(screen.getByText('批量指派')).toBeInTheDocument(); + fireEvent.click(screen.getByText('取 消')); + await act(async () => jest.advanceTimersByTime(300)); + expect(dispatchSpy).toBeCalledTimes(2); + expect(dispatchSpy).toBeCalledWith({ + type: 'sqleManagement/updateModalStatus', + payload: { + modalName: ModalName.Assignment_Member_Batch, + status: false + } + }); + expect(dispatchSpy).toBeCalledWith({ + type: 'sqleManagement/updateSqlIdList', + payload: null + }); + }); +}); diff --git a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentBatch/index.tsx b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentBatch/index.tsx index 51366806c..a9c2b4787 100644 --- a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentBatch/index.tsx +++ b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentBatch/index.tsx @@ -10,7 +10,7 @@ import { useSelector } from 'react-redux'; import { IReduxState } from '../../../../../../../../base/src/store'; import { updateSqleManagementModalStatus, - updateSqleManagement + updateSqlIdList } from '../../../../../../store/sqleManagement'; import { useForm } from 'antd/es/form/Form'; import { BasicButton, BasicModal } from '@actiontech/shared'; @@ -53,7 +53,7 @@ const AssignmentBatch = () => { status: false }) ); - dispatch(updateSqleManagement(null)); + dispatch(updateSqlIdList(null)); }; const onSubmit = async () => { diff --git a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentForm/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentForm/__snapshots__/index.test.tsx.snap new file mode 100644 index 000000000..b436e6dd0 --- /dev/null +++ b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentForm/__snapshots__/index.test.tsx.snap @@ -0,0 +1,332 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`page/SqlManagement/AssignmentBatch disable select 1`] = ` + +
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+ +`; + +exports[`page/SqlManagement/AssignmentBatch render form when init 1`] = ` + +
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+ +`; + +exports[`page/SqlManagement/AssignmentBatch render form when not init 1`] = ` + +
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+ +`; diff --git a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentForm/index.test.tsx b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentForm/index.test.tsx new file mode 100644 index 000000000..18bc783dc --- /dev/null +++ b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentForm/index.test.tsx @@ -0,0 +1,80 @@ +import { mockUseCurrentProject } from '@actiontech/shared/lib/testUtil/mockHook/mockUseCurrentProject'; +import user from '../../../../../../testUtils/mockApi/user'; +import { act, cleanup, fireEvent, screen } from '@testing-library/react'; +import { AssignmentFormField } from './index.type'; +import AssignmentForm from '.'; +import { + renderHooksWithTheme, + superRender +} from '../../../../../../testUtils/customRender'; +import { Form } from 'antd'; +import { + getAllBySelector, + getBySelector +} from '@actiontech/shared/lib/testUtil/customQuery'; +import { userTipListData } from '../../../../../../testUtils/mockApi/user/data'; + +describe('page/SqlManagement/AssignmentBatch', () => { + const dispatchSpy = jest.fn(); + + beforeEach(() => { + mockUseCurrentProject(); + user.mockAllApi(); + jest.useFakeTimers(); + }); + + afterEach(() => { + jest.useRealTimers(); + jest.clearAllMocks(); + cleanup(); + }); + + const customRender = (data?: { [key: string]: boolean }) => { + const { result } = renderHooksWithTheme(() => + Form.useForm() + ); + return superRender( + + ); + }; + + it('render form when not init', async () => { + const { baseElement } = customRender({ init: false }); + expect(baseElement).toMatchSnapshot(); + fireEvent.mouseDown(getBySelector('#assignees')); + await act(async () => jest.advanceTimersByTime(300)); + expect(screen.getByText('暂无数据')).toBeInTheDocument(); + }); + + it('render form when init', async () => { + const request = user.getUserTip(); + const { baseElement } = customRender(); + expect(request).toBeCalled(); + await act(async () => jest.advanceTimersByTime(3000)); + expect(baseElement).toMatchSnapshot(); + fireEvent.mouseDown(getBySelector('#assignees')); + await act(async () => jest.advanceTimersByTime(300)); + const options = getAllBySelector('.ant-select-item-option'); + expect(options.length).toBe(4); + fireEvent.click(options[0]); + await act(async () => jest.advanceTimersByTime(300)); + expect(screen.getAllByText(userTipListData[0].user_name).length).toBe(2); + expect( + screen.getAllByText(userTipListData[0].user_name)?.[0] + ).toBeInTheDocument(); + }); + + it('disable select', async () => { + const request = user.getUserTip(); + const { baseElement } = customRender({ submitLoading: true }); + expect(request).toBeCalled(); + await act(async () => jest.advanceTimersByTime(3000)); + expect(baseElement).toMatchSnapshot(); + expect(getBySelector('.ant-select')).toHaveClass('ant-select-disabled'); + }); +}); diff --git a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentSingle/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentSingle/__snapshots__/index.test.tsx.snap new file mode 100644 index 000000000..d66f1cac2 --- /dev/null +++ b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentSingle/__snapshots__/index.test.tsx.snap @@ -0,0 +1,389 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`page/SqlManagement/AssignmentBatch close modal by click button 1`] = ` + +
+
+
+
+
+ +
+ +`; + +exports[`page/SqlManagement/AssignmentBatch render modal when not open 1`] = ` + +
+ +`; + +exports[`page/SqlManagement/AssignmentBatch update single assign and submit change 1`] = ` + +
+
+
+
+
+ +
+ +`; diff --git a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentSingle/index.test.tsx b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentSingle/index.test.tsx new file mode 100644 index 000000000..63554fc43 --- /dev/null +++ b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentSingle/index.test.tsx @@ -0,0 +1,121 @@ +import { act, cleanup, fireEvent, screen } from '@testing-library/react'; +import AssignmentBatch from '.'; +import { superRender } from '../../../../../../testUtils/customRender'; +import user from '../../../../../../testUtils/mockApi/user'; +import { mockUseCurrentProject } from '@actiontech/shared/lib/testUtil/mockHook/mockUseCurrentProject'; +import { ModalName } from '../../../../../../data/ModalName'; +import { sqlManageListData } from '../../../../../../testUtils/mockApi/sqlManage/data'; +import sqlManage from '../../../../../../testUtils/mockApi/sqlManage'; +import { mockProjectInfo } from '@actiontech/shared/lib/testUtil/mockHook/data'; +import { + getAllBySelector, + getBySelector +} from '@actiontech/shared/lib/testUtil/customQuery'; +import { userTipListData } from '../../../../../../testUtils/mockApi/user/data'; +import EventEmitter from '../../../../../../utils/EventEmitter'; +import { useDispatch } from 'react-redux'; +import EmitterKey from '../../../../../../data/EmitterKey'; + +jest.mock('react-redux', () => ({ + ...jest.requireActual('react-redux'), + useDispatch: jest.fn() +})); + +describe('page/SqlManagement/AssignmentBatch', () => { + const dispatchSpy = jest.fn(); + + beforeEach(() => { + (useDispatch as jest.Mock).mockImplementation(() => dispatchSpy); + mockUseCurrentProject(); + user.mockAllApi(); + sqlManage.mockAllApi(); + jest.useFakeTimers(); + }); + + afterEach(() => { + jest.useRealTimers(); + jest.clearAllMocks(); + cleanup(); + }); + + const customRender = (data?: boolean) => { + return superRender(, undefined, { + initStore: { + sqleManagement: { + modalStatus: { + [ModalName.Assignment_Member_Single]: data ?? true + }, + selectSqleManagement: sqlManageListData.data[0] + } + } + }); + }; + + it('render modal when not open', () => { + const { baseElement } = customRender(false); + expect(baseElement).toMatchSnapshot(); + }); + + it('update single assign and submit change', async () => { + const eventEmitSpy = jest.spyOn(EventEmitter, 'emit'); + const optionRequest = user.getUserTip(); + const submitRequest = sqlManage.batchUpdateSqlManage(); + const { baseElement } = customRender(); + await act(async () => jest.advanceTimersByTime(3000)); + expect(optionRequest).toBeCalledWith({ + filter_project: mockProjectInfo.projectName + }); + expect(baseElement).toMatchSnapshot(); + expect(screen.getByText('指派负责人')).toBeInTheDocument(); + fireEvent.mouseDown(getBySelector('#assignees')); + await act(async () => jest.advanceTimersByTime(300)); + const options = getAllBySelector('.ant-select-item-option'); + fireEvent.click(options[0]); + await act(async () => jest.advanceTimersByTime(300)); + fireEvent.click(screen.getByText('确 认')); + await act(async () => jest.advanceTimersByTime(300)); + expect(submitRequest).toBeCalledWith({ + project_name: mockProjectInfo.projectName, + sql_manage_id_list: [sqlManageListData.data[0].id], + assignees: [userTipListData[0].user_id] + }); + await act(async () => jest.advanceTimersByTime(3000)); + expect(screen.getByText('指派负责人成功')).toBeInTheDocument(); + await act(async () => jest.advanceTimersByTime(3300)); + expect(dispatchSpy).toBeCalledTimes(2); + expect(dispatchSpy).toBeCalledWith({ + type: 'sqleManagement/updateModalStatus', + payload: { + modalName: ModalName.Assignment_Member_Single, + status: false + } + }); + expect(dispatchSpy).toBeCalledWith({ + type: 'sqleManagement/updateSqleManagement', + payload: null + }); + expect(eventEmitSpy).toBeCalledTimes(1); + expect(eventEmitSpy).toBeCalledWith(EmitterKey.Refresh_SQL_Management); + }); + + it('close modal by click button', async () => { + const { baseElement } = customRender(); + await act(async () => jest.advanceTimersByTime(3000)); + expect(baseElement).toMatchSnapshot(); + expect(screen.getByText('指派负责人')).toBeInTheDocument(); + fireEvent.click(screen.getByText('取 消')); + await act(async () => jest.advanceTimersByTime(300)); + expect(dispatchSpy).toBeCalledTimes(2); + expect(dispatchSpy).toBeCalledWith({ + type: 'sqleManagement/updateModalStatus', + payload: { + modalName: ModalName.Assignment_Member_Single, + status: false + } + }); + expect(dispatchSpy).toBeCalledWith({ + type: 'sqleManagement/updateSqleManagement', + payload: null + }); + }); +}); diff --git a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/hooks/useStaticStatus.test.ts b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/hooks/useStaticStatus.test.ts new file mode 100644 index 000000000..155d682ca --- /dev/null +++ b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/hooks/useStaticStatus.test.ts @@ -0,0 +1,24 @@ +import { renderHooksWithTheme } from '@actiontech/shared/lib/testUtil/customRender'; +import useStaticStatus from './useStaticStatus'; +import { + GetSqlManageListV2FilterAuditLevelEnum, + GetSqlManageListV2FilterSourceEnum +} from '@actiontech/shared/lib/api/sqle/service/SqlManage/index.enum'; + +describe('SqlManagement/useStaticStatus', () => { + it('render select options', async () => { + const { result } = renderHooksWithTheme(() => useStaticStatus()); + expect(result.current.generateSourceSelectOptions.length).toBe(2); + expect(result.current.generateSourceSelectOptions[0].value).toBe( + GetSqlManageListV2FilterSourceEnum.sql_audit_record + ); + expect(result.current.generateSourceSelectOptions[0].label).toBe('SQL审核'); + expect(result.current.generateAuditLevelSelectOptions.length).toBe(4); + expect(result.current.generateAuditLevelSelectOptions[0].value).toBe( + GetSqlManageListV2FilterAuditLevelEnum.normal + ); + expect(result.current.generateAuditLevelSelectOptions[0].label).toBe( + '普通' + ); + }); +}); diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.test.tsx b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.test.tsx index c20465ab2..14c9863e9 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.test.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.test.tsx @@ -2,16 +2,14 @@ import { superRender } from '../../../../../testUtils/customRender'; import ReviewAndExecNodeInfo from '.'; import { Form, Select } from 'antd'; import { NodeTypeEnum } from './index.type'; -import { - userTipListData, - workflowTemplateData -} from '../../../../../testUtils/mockApi/workflowTemplate/data'; +import { workflowTemplateData } from '../../../../../testUtils/mockApi/workflowTemplate/data'; import { act, fireEvent, screen, renderHook } from '@testing-library/react'; import { getAllBySelector, getBySelector } from '@actiontech/shared/lib/testUtil/customQuery'; import { IWorkFlowStepTemplateResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; +import { userTipListData } from '../../../../../testUtils/mockApi/user/data'; describe('page/WorkflowTemplate/ReviewNodeInfo', () => { beforeEach(() => { diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/StepInfo/index.test.tsx b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/StepInfo/index.test.tsx index ac4c8851d..3ab2409bd 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/StepInfo/index.test.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/StepInfo/index.test.tsx @@ -1,9 +1,6 @@ import { superRender } from '../../../../../testUtils/customRender'; import StepInfo from '.'; -import { - userTipListData, - workflowTemplateData -} from '../../../../../testUtils/mockApi/workflowTemplate/data'; +import { workflowTemplateData } from '../../../../../testUtils/mockApi/workflowTemplate/data'; import { act, fireEvent, screen } from '@testing-library/react'; import { getAllBySelector, @@ -12,6 +9,7 @@ import { import { IUpdateWorkflowStepInfoProps } from '../../../components/StepCard/index.type'; import { WorkflowTemplateDetailResV1AllowSubmitWhenLessAuditLevelEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; import { mockUseCurrentUser } from '@actiontech/shared/lib/testUtil/mockHook/mockUseCurrentUser'; +import { userTipListData } from '../../../../../testUtils/mockApi/user/data'; describe('page/WorkflowTemplate/StepInfo', () => { beforeEach(() => { diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.test.tsx b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.test.tsx index 6990455af..1c45f1c2a 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.test.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.test.tsx @@ -16,6 +16,7 @@ import { IWorkFlowStepTemplateResV1 } from '@actiontech/shared/lib/api/sqle/serv import { cloneDeep } from 'lodash'; import { mockUseCurrentUser } from '@actiontech/shared/lib/testUtil/mockHook/mockUseCurrentUser'; import { ignoreAntdUseFormNotConnectedError } from '@actiontech/shared/lib/testUtil/common'; +import user from '../../../testUtils/mockApi/user'; jest.mock('react-router-dom', () => ({ ...jest.requireActual('react-router-dom'), @@ -51,7 +52,7 @@ describe('page/WorkflowTemplate/UpdateWorkflowTemplate', () => { it('render update workflow template and submit success', async () => { const getInfoRequest = workflowTemplate.getWorkflowTemplate(); const updateInfoRequest = workflowTemplate.updateWorkflowTemplate(); - const userInfoRequest = workflowTemplate.getUserTip(); + const userInfoRequest = user.getUserTip(); const { baseElement } = customRender(); await act(async () => jest.advanceTimersByTime(3000)); expect(userInfoRequest).toBeCalledWith({ @@ -98,7 +99,7 @@ describe('page/WorkflowTemplate/UpdateWorkflowTemplate', () => { message: 'error' }) ); - const userInfoRequest = workflowTemplate.getUserTip(); + const userInfoRequest = user.getUserTip(); const { baseElement } = customRender(); await act(async () => jest.advanceTimersByTime(3000)); expect(userInfoRequest).toBeCalledWith({ @@ -123,7 +124,7 @@ describe('page/WorkflowTemplate/UpdateWorkflowTemplate', () => { it('update workflow template info', async () => { const getInfoRequest = workflowTemplate.getWorkflowTemplate(); const updateInfoRequest = workflowTemplate.updateWorkflowTemplate(); - const userInfoRequest = workflowTemplate.getUserTip(); + const userInfoRequest = user.getUserTip(); const { baseElement } = customRender(); await act(async () => jest.advanceTimersByTime(3000)); expect(userInfoRequest).toBeCalledWith({ @@ -178,7 +179,7 @@ describe('page/WorkflowTemplate/UpdateWorkflowTemplate', () => { it('change workflow template node number and reset template', async () => { const getInfoRequest = workflowTemplate.getWorkflowTemplate(); - const userInfoRequest = workflowTemplate.getUserTip(); + const userInfoRequest = user.getUserTip(); const { baseElement } = customRender(); await act(async () => jest.advanceTimersByTime(3000)); expect(userInfoRequest).toBeCalledWith({ diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/components/WorkflowTemplateStepInfo/index.test.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/components/WorkflowTemplateStepInfo/index.test.tsx index b527508cf..a5f46635e 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/components/WorkflowTemplateStepInfo/index.test.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/components/WorkflowTemplateStepInfo/index.test.tsx @@ -1,11 +1,9 @@ import { superRender } from '../../../../../testUtils/customRender'; import WorkflowTemplateStepInfo from '.'; -import { - userTipListData, - workflowTemplateData -} from '../../../../../testUtils/mockApi/workflowTemplate/data'; +import { workflowTemplateData } from '../../../../../testUtils/mockApi/workflowTemplate/data'; import { screen } from '@testing-library/react'; import { IWorkflowTemplateStepInfoProps } from './index.type'; +import { userTipListData } from '../../../../../testUtils/mockApi/user/data'; describe('page/WorkflowTemplate/WorkflowTemplateStepInfo', () => { beforeEach(() => { diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx index 8cfcbfed8..e554c2ac1 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx @@ -8,6 +8,7 @@ import { mockUseCurrentUser } from '@actiontech/shared/lib/testUtil/mockHook/moc import { getBySelector } from '@actiontech/shared/lib/testUtil/customQuery'; import { mockProjectInfo } from '@actiontech/shared/lib/testUtil/mockHook/data'; import { createSpySuccessResponse } from '@actiontech/shared/lib/testUtil/mockApi'; +import user from '../../../testUtils/mockApi/user'; describe('page/WorkflowTemplate/WorkflowTemplateDetail', () => { beforeEach(() => { @@ -28,7 +29,7 @@ describe('page/WorkflowTemplate/WorkflowTemplateDetail', () => { it('render workflow template detail', async () => { const getInfoRequest = workflowTemplate.getWorkflowTemplate(); - const userInfoRequest = workflowTemplate.getUserTip(); + const userInfoRequest = user.getUserTip(); const { baseElement } = customRender(); await act(async () => jest.advanceTimersByTime(3000)); expect(getInfoRequest).toBeCalled(); @@ -52,7 +53,7 @@ describe('page/WorkflowTemplate/WorkflowTemplateDetail', () => { it('render workflow template detail without permission', async () => { mockUseCurrentUser({ isAdmin: false }); const getInfoRequest = workflowTemplate.getWorkflowTemplate(); - const userInfoRequest = workflowTemplate.getUserTip(); + const userInfoRequest = user.getUserTip(); const { baseElement } = customRender(); await act(async () => jest.advanceTimersByTime(3000)); expect(getInfoRequest).toBeCalled(); @@ -64,7 +65,7 @@ describe('page/WorkflowTemplate/WorkflowTemplateDetail', () => { it('render workflow template detail with not projectArchive', async () => { mockUseCurrentProject({ projectArchive: false }); const getInfoRequest = workflowTemplate.getWorkflowTemplate(); - const userInfoRequest = workflowTemplate.getUserTip(); + const userInfoRequest = user.getUserTip(); const { baseElement } = customRender(); await act(async () => jest.advanceTimersByTime(3000)); expect(getInfoRequest).toBeCalled(); diff --git a/packages/sqle/src/testUtils/mockApi/sqlManage/data.ts b/packages/sqle/src/testUtils/mockApi/sqlManage/data.ts index deaa98009..e9a61a9c2 100644 --- a/packages/sqle/src/testUtils/mockApi/sqlManage/data.ts +++ b/packages/sqle/src/testUtils/mockApi/sqlManage/data.ts @@ -22,7 +22,306 @@ export const ruleTipsData = [ ]; export const sqlManageListData = { - data: [{}], + data: [ + { + id: 249, + sql_fingerprint: + 'CREATE TABLE `members` (\n `uid` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL,\n `created_at` datetime(3) DEFAULT NULL,\n `updated_at` datetime(3) DEFAULT NULL,\n `user_uid` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL,\n `project_uid` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL,\n PRIMARY KEY (`uid`),\n UNIQUE KEY `project_user_id` (`user_uid`,`project_uid`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci', + sql: 'CREATE TABLE `members` (\n `uid` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL,\n `created_at` datetime(3) DEFAULT NULL,\n `updated_at` datetime(3) DEFAULT NULL,\n `user_uid` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL,\n `project_uid` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL,\n PRIMARY KEY (`uid`),\n UNIQUE KEY `project_user_id` (`user_uid`,`project_uid`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci', + source: { + type: 'audit_plan', + audit_plan_name: 'audit-plan-task1', + sql_audit_record_ids: null + }, + instance_name: 'mysql', + schema_name: 'dms', + audit_result: [ + { + level: 'error', + message: '新建表建议加入 IF NOT EXISTS,保证重复执行不报错', + rule_name: 'ddl_check_table_without_if_not_exists' + }, + { + level: 'error', + message: '主键建议使用自增', + rule_name: 'ddl_check_pk_without_auto_increment' + }, + { + level: 'error', + message: '主键建议使用 BIGINT 无符号类型,即 BIGINT UNSIGNED', + rule_name: 'ddl_check_pk_without_bigint_unsigned' + }, + { + level: 'error', + message: '除了自增列及大字段列之外,每个列都必须添加默认值', + rule_name: 'ddl_check_column_without_default' + }, + { + level: 'error', + message: '建议UNIQUE索引名使用 IDX_UK_表名_字段名', + rule_name: 'ddl_check_unique_index' + }, + { + level: 'error', + message: '建议UNIQUE索引要以"uniq_"为前缀', + rule_name: 'ddl_check_unique_index_prefix' + }, + { + level: 'warn', + message: '这些索引字段(user_uid,project_uid)需要有非空约束', + rule_name: 'ddl_check_index_not_null_constraint' + }, + { + level: 'warn', + message: '建议建表DDL包含CREATE_TIME字段且默认值为CURRENT_TIMESTAMP', + rule_name: 'ddl_check_create_time_column' + }, + { + level: 'warn', + message: '建议字段约束为NOT NULL时带默认值,以下字段不规范:uid', + rule_name: 'ddl_check_field_not_null_must_contain_default_value' + }, + { + level: 'warn', + message: + '建表DDL需要包含UPDATE_TIME字段且默认值为CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP', + rule_name: 'ddl_check_update_time_column' + }, + { + level: 'notice', + message: '建议使用规定的数据库排序规则为utf8mb4_0900_ai_ci', + rule_name: 'ddl_check_collation_database' + }, + { + level: 'notice', + message: + '建议字段created_at,updated_at,user_uid,project_uid设置NOT NULL约束', + rule_name: 'ddl_check_column_not_null' + }, + { + level: 'notice', + message: '列建议添加注释', + rule_name: 'ddl_check_column_without_comment' + }, + { + level: 'notice', + message: '建议主键命名为"PK_表名"', + rule_name: 'ddl_check_pk_name' + }, + { + level: 'notice', + message: '表建议添加注释', + rule_name: 'ddl_check_table_without_comment' + } + ], + first_appear_timestamp: '', + last_receive_timestamp: '', + fp_count: 0, + assignees: ['test'], + status: 'unhandled', + remark: '', + endpoints: [] + }, + { + id: 248, + sql_fingerprint: + 'CREATE TABLE `plugins` (\n `name` varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL,\n `add_db_service_pre_check_url` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,\n `del_db_service_pre_check_url` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,\n `del_user_pre_check_url` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,\n `del_user_group_pre_check_url` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,\n `operate_data_resource_handle_url` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,\n PRIMARY KEY (`name`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci', + sql: 'CREATE TABLE `plugins` (\n `name` varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL,\n `add_db_service_pre_check_url` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,\n `del_db_service_pre_check_url` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,\n `del_user_pre_check_url` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,\n `del_user_group_pre_check_url` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,\n `operate_data_resource_handle_url` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,\n PRIMARY KEY (`name`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci', + source: { + type: 'audit_plan', + audit_plan_name: 'audit-plan-task1', + sql_audit_record_ids: null + }, + instance_name: 'mysql', + schema_name: 'dms', + audit_result: [ + { + level: 'error', + message: '主键建议使用自增', + rule_name: 'ddl_check_pk_without_auto_increment' + }, + { + level: 'error', + message: '主键建议使用 BIGINT 无符号类型,即 BIGINT UNSIGNED', + rule_name: 'ddl_check_pk_without_bigint_unsigned' + }, + { + level: 'error', + message: '新建表建议加入 IF NOT EXISTS,保证重复执行不报错', + rule_name: 'ddl_check_table_without_if_not_exists' + }, + { + level: 'error', + message: '除了自增列及大字段列之外,每个列都必须添加默认值', + rule_name: 'ddl_check_column_without_default' + }, + { + level: 'warn', + message: + '建表DDL需要包含UPDATE_TIME字段且默认值为CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP', + rule_name: 'ddl_check_update_time_column' + }, + { + level: 'warn', + message: '建议建表DDL包含CREATE_TIME字段且默认值为CURRENT_TIMESTAMP', + rule_name: 'ddl_check_create_time_column' + }, + { + level: 'warn', + message: '建议字段约束为NOT NULL时带默认值,以下字段不规范:name', + rule_name: 'ddl_check_field_not_null_must_contain_default_value' + }, + { + level: 'notice', + message: '建议使用规定的数据库排序规则为utf8mb4_0900_ai_ci', + rule_name: 'ddl_check_collation_database' + }, + { + level: 'notice', + message: + '建议字段add_db_service_pre_check_url,del_db_service_pre_check_url,del_user_pre_check_url,del_user_group_pre_check_url,operate_data_resource_handle_url设置NOT NULL约束', + rule_name: 'ddl_check_column_not_null' + }, + { + level: 'notice', + message: '列建议添加注释', + rule_name: 'ddl_check_column_without_comment' + }, + { + level: 'notice', + message: '建议主键命名为"PK_表名"', + rule_name: 'ddl_check_pk_name' + }, + { + level: 'notice', + message: '表建议添加注释', + rule_name: 'ddl_check_table_without_comment' + } + ], + first_appear_timestamp: '', + last_receive_timestamp: '', + fp_count: 0, + assignees: ['test', 'admin'], + status: 'unhandled', + remark: '', + endpoints: [] + }, + { + id: 247, + sql_fingerprint: + "CREATE TABLE `projects` (\n `uid` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL,\n `created_at` datetime(3) DEFAULT NULL,\n `updated_at` datetime(3) DEFAULT NULL,\n `name` varchar(200) COLLATE utf8mb4_unicode_ci DEFAULT NULL,\n `desc` longtext COLLATE utf8mb4_unicode_ci,\n `create_user_uid` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL,\n `status` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT 'active',\n PRIMARY KEY (`uid`),\n UNIQUE KEY `name` (`name`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci", + sql: "CREATE TABLE `projects` (\n `uid` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL,\n `created_at` datetime(3) DEFAULT NULL,\n `updated_at` datetime(3) DEFAULT NULL,\n `name` varchar(200) COLLATE utf8mb4_unicode_ci DEFAULT NULL,\n `desc` longtext COLLATE utf8mb4_unicode_ci,\n `create_user_uid` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL,\n `status` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT 'active',\n PRIMARY KEY (`uid`),\n UNIQUE KEY `name` (`name`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci", + source: { + type: 'audit_plan', + audit_plan_name: 'audit-plan-task1', + sql_audit_record_ids: null + }, + instance_name: 'mysql', + schema_name: 'dms', + audit_result: [ + { + level: 'error', + message: '建议UNIQUE索引名使用 IDX_UK_表名_字段名', + rule_name: 'ddl_check_unique_index' + }, + { + level: 'error', + message: '数据库对象命名禁止使用保留字 desc', + rule_name: 'ddl_check_object_name_using_keyword' + }, + { + level: 'error', + message: '主键建议使用自增', + rule_name: 'ddl_check_pk_without_auto_increment' + }, + { + level: 'error', + message: '除了自增列及大字段列之外,每个列都必须添加默认值', + rule_name: 'ddl_check_column_without_default' + }, + { + level: 'error', + message: '新建表建议加入 IF NOT EXISTS,保证重复执行不报错', + rule_name: 'ddl_check_table_without_if_not_exists' + }, + { + level: 'error', + message: '主键建议使用 BIGINT 无符号类型,即 BIGINT UNSIGNED', + rule_name: 'ddl_check_pk_without_bigint_unsigned' + }, + { + level: 'error', + message: '建议UNIQUE索引要以"uniq_"为前缀', + rule_name: 'ddl_check_unique_index_prefix' + }, + { + level: 'warn', + message: '建议字段约束为NOT NULL时带默认值,以下字段不规范:uid', + rule_name: 'ddl_check_field_not_null_must_contain_default_value' + }, + { + level: 'warn', + message: '这些索引字段(name)需要有非空约束', + rule_name: 'ddl_check_index_not_null_constraint' + }, + { + level: 'warn', + message: '建议建表DDL包含CREATE_TIME字段且默认值为CURRENT_TIMESTAMP', + rule_name: 'ddl_check_create_time_column' + }, + { + level: 'warn', + message: + '建表DDL需要包含UPDATE_TIME字段且默认值为CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP', + rule_name: 'ddl_check_update_time_column' + }, + { + level: 'notice', + message: '不建议使用 BLOB 或 TEXT 类型', + rule_name: 'ddl_check_column_blob_notice' + }, + { + level: 'notice', + message: '列建议添加注释', + rule_name: 'ddl_check_column_without_comment' + }, + { + level: 'notice', + message: '建议主键命名为"PK_表名"', + rule_name: 'ddl_check_pk_name' + }, + { + level: 'notice', + message: + '字段:desc为TEXT类型,建议和原表进行分拆,与原表主键单独组成另外一个表进行存放', + rule_name: 'ddl_avoid_text' + }, + { + level: 'notice', + message: '建议使用规定的数据库排序规则为utf8mb4_0900_ai_ci', + rule_name: 'ddl_check_collation_database' + }, + { + level: 'notice', + message: '表建议添加注释', + rule_name: 'ddl_check_table_without_comment' + }, + { + level: 'notice', + message: + '建议字段created_at,updated_at,name,desc,create_user_uid,status设置NOT NULL约束', + rule_name: 'ddl_check_column_not_null' + } + ], + first_appear_timestamp: '', + last_receive_timestamp: '', + fp_count: 0, + assignees: null, + status: 'unhandled', + remark: '', + endpoints: [] + } + ], sql_manage_bad_num: 1, sql_manage_optimized_num: 1, sql_manage_total_num: 2 diff --git a/packages/sqle/src/testUtils/mockApi/sqlManage/index.ts b/packages/sqle/src/testUtils/mockApi/sqlManage/index.ts index cb81a6ab3..dd274bc95 100644 --- a/packages/sqle/src/testUtils/mockApi/sqlManage/index.ts +++ b/packages/sqle/src/testUtils/mockApi/sqlManage/index.ts @@ -25,7 +25,11 @@ class MockSqlManageApi implements MockSpyApy { public batchUpdateSqlManage() { const spy = jest.spyOn(SqlManage, 'BatchUpdateSqlManage'); - spy.mockImplementation(() => createSpySuccessResponse({})); + spy.mockImplementation(() => + createSpySuccessResponse({ + code: 0 + }) + ); return spy; } diff --git a/packages/sqle/src/testUtils/mockApi/user/data.ts b/packages/sqle/src/testUtils/mockApi/user/data.ts new file mode 100644 index 000000000..c6bc03d2c --- /dev/null +++ b/packages/sqle/src/testUtils/mockApi/user/data.ts @@ -0,0 +1,9 @@ +export const userTipListData = [ + { + user_id: '1739544663515205632', + user_name: 'test' + }, + { user_id: '700200', user_name: 'admin' }, + { user_id: '700201', user_name: 'one' }, + { user_id: '700202', user_name: 'two' } +]; diff --git a/packages/sqle/src/testUtils/mockApi/user/index.ts b/packages/sqle/src/testUtils/mockApi/user/index.ts new file mode 100644 index 000000000..72eef522c --- /dev/null +++ b/packages/sqle/src/testUtils/mockApi/user/index.ts @@ -0,0 +1,24 @@ +import { + MockSpyApy, + createSpySuccessResponse +} from '@actiontech/shared/lib/testUtil/mockApi'; +import { userTipListData } from './data'; +import user from '@actiontech/shared/lib/api/sqle/service/user'; + +class MockUserApi implements MockSpyApy { + public mockAllApi(): void { + this.getUserTip(); + } + + public getUserTip() { + const spy = jest.spyOn(user, 'getUserTipListV1'); + spy.mockImplementation(() => + createSpySuccessResponse({ + data: userTipListData + }) + ); + return spy; + } +} + +export default new MockUserApi(); diff --git a/packages/sqle/src/testUtils/mockApi/workflowTemplate/data.ts b/packages/sqle/src/testUtils/mockApi/workflowTemplate/data.ts index fc642d8df..ccc9a8fbc 100644 --- a/packages/sqle/src/testUtils/mockApi/workflowTemplate/data.ts +++ b/packages/sqle/src/testUtils/mockApi/workflowTemplate/data.ts @@ -31,13 +31,3 @@ export const workflowTemplateData = { ], workflow_template_name: '700300-WorkflowTemplate' }; - -export const userTipListData = [ - { - user_id: '1739544663515205632', - user_name: 'test' - }, - { user_id: '700200', user_name: 'admin' }, - { user_id: '700201', user_name: 'one' }, - { user_id: '700202', user_name: 'two' } -]; diff --git a/packages/sqle/src/testUtils/mockApi/workflowTemplate/index.ts b/packages/sqle/src/testUtils/mockApi/workflowTemplate/index.ts index 034cc4c54..32431c798 100644 --- a/packages/sqle/src/testUtils/mockApi/workflowTemplate/index.ts +++ b/packages/sqle/src/testUtils/mockApi/workflowTemplate/index.ts @@ -3,7 +3,7 @@ import { MockSpyApy, createSpySuccessResponse } from '@actiontech/shared/lib/testUtil/mockApi'; -import { userTipListData, workflowTemplateData } from './data'; +import { workflowTemplateData } from './data'; import user from '@actiontech/shared/lib/api/sqle/service/user'; import { cloneDeep } from 'lodash'; @@ -11,7 +11,6 @@ class MockWorkflowTemplateApi implements MockSpyApy { public mockAllApi(): void { this.updateWorkflowTemplate(); this.getWorkflowTemplate(); - this.getUserTip(); } public updateWorkflowTemplate() { @@ -29,16 +28,6 @@ class MockWorkflowTemplateApi implements MockSpyApy { }); return spy; } - - public getUserTip() { - const spy = jest.spyOn(user, 'getUserTipListV1'); - spy.mockImplementation(() => - createSpySuccessResponse({ - data: userTipListData - }) - ); - return spy; - } } export default new MockWorkflowTemplateApi(); diff --git a/packages/sqle/src/testUtils/mockRedux.tsx b/packages/sqle/src/testUtils/mockRedux.tsx index 5741caf04..fe9da0ff4 100644 --- a/packages/sqle/src/testUtils/mockRedux.tsx +++ b/packages/sqle/src/testUtils/mockRedux.tsx @@ -3,9 +3,11 @@ import React from 'react'; import { Provider } from 'react-redux'; import { combineReducers, configureStore } from '@reduxjs/toolkit'; import { Dictionary } from '@actiontech/shared/lib/types/common.type'; +import sqleManagement from '../store/sqleManagement'; const reducers = combineReducers({ - whitelist + whitelist, + sqleManagement }); export const storeFactory = (initStore: Dictionary = {}) => { From 1fccb30af4d7033f8115c219f4e157bdd7c82528 Mon Sep 17 00:00:00 2001 From: sunjinkang <2060037942@qq.com> Date: Tue, 16 Jan 2024 10:40:50 +0800 Subject: [PATCH 03/17] [test]: add test for sql manage status operation --- .../__snapshots__/index.test.tsx.snap | 6 +- .../Modal/AssignmentForm/index.test.tsx | 4 +- .../__snapshots__/index.test.tsx.snap | 6 +- .../Modal/AssignmentSingle/index.test.tsx | 6 +- .../__snapshots__/index.test.tsx.snap | 419 +++++ .../Modal/ChangeStatus/index.test.tsx | 113 ++ .../__snapshots__/index.test.tsx.snap | 1403 +++++++++++++++++ .../Modal/StatusDrawer/index.test.tsx | 102 ++ .../WorkflowTemplateDetail/index.test.tsx | 1 + .../src/testUtils/mockApi/sqlManage/data.ts | 67 +- 10 files changed, 2049 insertions(+), 78 deletions(-) create mode 100644 packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/ChangeStatus/__snapshots__/index.test.tsx.snap create mode 100644 packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/ChangeStatus/index.test.tsx create mode 100644 packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/StatusDrawer/__snapshots__/index.test.tsx.snap create mode 100644 packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/StatusDrawer/index.test.tsx diff --git a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentForm/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentForm/__snapshots__/index.test.tsx.snap index b436e6dd0..2601af0f2 100644 --- a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentForm/__snapshots__/index.test.tsx.snap +++ b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentForm/__snapshots__/index.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`page/SqlManagement/AssignmentBatch disable select 1`] = ` +exports[`page/SqlManagement/AssignmentForm disable select 1`] = `
@@ -111,7 +111,7 @@ exports[`page/SqlManagement/AssignmentBatch disable select 1`] = ` `; -exports[`page/SqlManagement/AssignmentBatch render form when init 1`] = ` +exports[`page/SqlManagement/AssignmentForm render form when init 1`] = `
@@ -221,7 +221,7 @@ exports[`page/SqlManagement/AssignmentBatch render form when init 1`] = ` `; -exports[`page/SqlManagement/AssignmentBatch render form when not init 1`] = ` +exports[`page/SqlManagement/AssignmentForm render form when not init 1`] = `
diff --git a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentForm/index.test.tsx b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentForm/index.test.tsx index 18bc783dc..f58b64f58 100644 --- a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentForm/index.test.tsx +++ b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentForm/index.test.tsx @@ -14,9 +14,7 @@ import { } from '@actiontech/shared/lib/testUtil/customQuery'; import { userTipListData } from '../../../../../../testUtils/mockApi/user/data'; -describe('page/SqlManagement/AssignmentBatch', () => { - const dispatchSpy = jest.fn(); - +describe('page/SqlManagement/AssignmentForm', () => { beforeEach(() => { mockUseCurrentProject(); user.mockAllApi(); diff --git a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentSingle/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentSingle/__snapshots__/index.test.tsx.snap index d66f1cac2..1f055cee8 100644 --- a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentSingle/__snapshots__/index.test.tsx.snap +++ b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentSingle/__snapshots__/index.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`page/SqlManagement/AssignmentBatch close modal by click button 1`] = ` +exports[`page/SqlManagement/AssignmentSingle close modal by click button 1`] = `
@@ -191,13 +191,13 @@ exports[`page/SqlManagement/AssignmentBatch close modal by click button 1`] = ` `; -exports[`page/SqlManagement/AssignmentBatch render modal when not open 1`] = ` +exports[`page/SqlManagement/AssignmentSingle render modal when not open 1`] = `
`; -exports[`page/SqlManagement/AssignmentBatch update single assign and submit change 1`] = ` +exports[`page/SqlManagement/AssignmentSingle update single assign and submit change 1`] = `
diff --git a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentSingle/index.test.tsx b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentSingle/index.test.tsx index 63554fc43..cf559ecbd 100644 --- a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentSingle/index.test.tsx +++ b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentSingle/index.test.tsx @@ -1,5 +1,5 @@ import { act, cleanup, fireEvent, screen } from '@testing-library/react'; -import AssignmentBatch from '.'; +import AssignmentSingle from '.'; import { superRender } from '../../../../../../testUtils/customRender'; import user from '../../../../../../testUtils/mockApi/user'; import { mockUseCurrentProject } from '@actiontech/shared/lib/testUtil/mockHook/mockUseCurrentProject'; @@ -21,7 +21,7 @@ jest.mock('react-redux', () => ({ useDispatch: jest.fn() })); -describe('page/SqlManagement/AssignmentBatch', () => { +describe('page/SqlManagement/AssignmentSingle', () => { const dispatchSpy = jest.fn(); beforeEach(() => { @@ -39,7 +39,7 @@ describe('page/SqlManagement/AssignmentBatch', () => { }); const customRender = (data?: boolean) => { - return superRender(, undefined, { + return superRender(, undefined, { initStore: { sqleManagement: { modalStatus: { diff --git a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/ChangeStatus/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/ChangeStatus/__snapshots__/index.test.tsx.snap new file mode 100644 index 000000000..630353b46 --- /dev/null +++ b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/ChangeStatus/__snapshots__/index.test.tsx.snap @@ -0,0 +1,419 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`page/SqlManagement/ChangeStatus change status and submit data 1`] = ` + +
+
+
+
+
+ +
+ +`; + +exports[`page/SqlManagement/ChangeStatus close modal by click button 1`] = ` + +
+
+
+
+
+ +
+ +`; + +exports[`page/SqlManagement/ChangeStatus render modal when not open 1`] = ` + +
+ +`; diff --git a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/ChangeStatus/index.test.tsx b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/ChangeStatus/index.test.tsx new file mode 100644 index 000000000..b8629504d --- /dev/null +++ b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/ChangeStatus/index.test.tsx @@ -0,0 +1,113 @@ +import { act, cleanup, fireEvent, screen } from '@testing-library/react'; +import ChangeStatus from '.'; +import { superRender } from '../../../../../../testUtils/customRender'; +import { mockUseCurrentProject } from '@actiontech/shared/lib/testUtil/mockHook/mockUseCurrentProject'; +import { ModalName } from '../../../../../../data/ModalName'; +import { sqlManageListData } from '../../../../../../testUtils/mockApi/sqlManage/data'; +import sqlManage from '../../../../../../testUtils/mockApi/sqlManage'; +import { mockProjectInfo } from '@actiontech/shared/lib/testUtil/mockHook/data'; +import { getAllBySelector } from '@actiontech/shared/lib/testUtil/customQuery'; +import EventEmitter from '../../../../../../utils/EventEmitter'; +import { useDispatch } from 'react-redux'; +import EmitterKey from '../../../../../../data/EmitterKey'; +import { BatchUpdateSqlManageReqStatusEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; + +jest.mock('react-redux', () => ({ + ...jest.requireActual('react-redux'), + useDispatch: jest.fn() +})); + +describe('page/SqlManagement/ChangeStatus', () => { + const dispatchSpy = jest.fn(); + + beforeEach(() => { + (useDispatch as jest.Mock).mockImplementation(() => dispatchSpy); + mockUseCurrentProject(); + sqlManage.mockAllApi(); + jest.useFakeTimers(); + }); + + afterEach(() => { + jest.useRealTimers(); + jest.clearAllMocks(); + cleanup(); + }); + + const customRender = (data?: boolean) => { + return superRender(, undefined, { + initStore: { + sqleManagement: { + modalStatus: { + [ModalName.Change_Status_Single]: data ?? true + }, + selectSqleManagement: sqlManageListData.data[0] + } + } + }); + }; + + it('render modal when not open', () => { + const { baseElement } = customRender(false); + expect(baseElement).toMatchSnapshot(); + }); + + it('change status and submit data', async () => { + const eventEmitSpy = jest.spyOn(EventEmitter, 'emit'); + const submitRequest = sqlManage.batchUpdateSqlManage(); + const { baseElement } = customRender(); + await act(async () => jest.advanceTimersByTime(3000)); + expect(baseElement).toMatchSnapshot(); + expect(screen.getByText('变更状态')).toBeInTheDocument(); + expect(screen.getByText('当前SQL状态')).toBeInTheDocument(); + expect(screen.getByText('忽略')).toBeInTheDocument(); + const radioOptions = getAllBySelector('.ant-radio-input'); + expect(radioOptions.length).toBe(3); + fireEvent.click(radioOptions?.[1]); + await act(async () => jest.advanceTimersByTime(300)); + fireEvent.click(screen.getByText('确 认')); + await act(async () => jest.advanceTimersByTime(300)); + expect(submitRequest).toBeCalledWith({ + project_name: mockProjectInfo.projectName, + sql_manage_id_list: [sqlManageListData.data[0].id], + status: BatchUpdateSqlManageReqStatusEnum.ignored + }); + await act(async () => jest.advanceTimersByTime(3000)); + expect(screen.getByText('更新SQL状态成功')).toBeInTheDocument(); + await act(async () => jest.advanceTimersByTime(3300)); + expect(dispatchSpy).toBeCalledTimes(2); + expect(dispatchSpy).toBeCalledWith({ + type: 'sqleManagement/updateModalStatus', + payload: { + modalName: ModalName.Change_Status_Single, + status: false + } + }); + expect(dispatchSpy).toBeCalledWith({ + type: 'sqleManagement/updateSqleManagement', + payload: null + }); + expect(eventEmitSpy).toBeCalledTimes(1); + expect(eventEmitSpy).toBeCalledWith(EmitterKey.Refresh_SQL_Management); + }); + + it('close modal by click button', async () => { + const { baseElement } = customRender(); + await act(async () => jest.advanceTimersByTime(3000)); + expect(baseElement).toMatchSnapshot(); + expect(screen.getByText('变更状态')).toBeInTheDocument(); + fireEvent.click(screen.getByText('取 消')); + await act(async () => jest.advanceTimersByTime(300)); + expect(dispatchSpy).toBeCalledTimes(2); + expect(dispatchSpy).toBeCalledWith({ + type: 'sqleManagement/updateModalStatus', + payload: { + modalName: ModalName.Change_Status_Single, + status: false + } + }); + expect(dispatchSpy).toBeCalledWith({ + type: 'sqleManagement/updateSqleManagement', + payload: null + }); + }); +}); diff --git a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/StatusDrawer/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/StatusDrawer/__snapshots__/index.test.tsx.snap new file mode 100644 index 000000000..ffc20e5eb --- /dev/null +++ b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/StatusDrawer/__snapshots__/index.test.tsx.snap @@ -0,0 +1,1403 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`page/SqlManagement/StatusDrawer close modal by click close button 1`] = ` + +
+
+
+
+ + +`; + +exports[`page/SqlManagement/StatusDrawer render empty status drawer info 1`] = ` + +
+
+
+
+ + +`; + +exports[`page/SqlManagement/StatusDrawer render modal when not open 1`] = ` + +
+ +`; + +exports[`page/SqlManagement/StatusDrawer render status drawer info 1`] = ` + +
+
+
+
+ + +`; diff --git a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/StatusDrawer/index.test.tsx b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/StatusDrawer/index.test.tsx new file mode 100644 index 000000000..9a8cabc06 --- /dev/null +++ b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/StatusDrawer/index.test.tsx @@ -0,0 +1,102 @@ +import { act, cleanup, fireEvent, screen } from '@testing-library/react'; +import StatusDrawer from '.'; +import { superRender } from '../../../../../../testUtils/customRender'; +import { mockUseCurrentProject } from '@actiontech/shared/lib/testUtil/mockHook/mockUseCurrentProject'; +import { ModalName } from '../../../../../../data/ModalName'; +import { sqlManageListData } from '../../../../../../testUtils/mockApi/sqlManage/data'; +import sqlManage from '../../../../../../testUtils/mockApi/sqlManage'; +import { mockProjectInfo } from '@actiontech/shared/lib/testUtil/mockHook/data'; +import { + getAllBySelector, + getBySelector +} from '@actiontech/shared/lib/testUtil/customQuery'; +import EventEmitter from '../../../../../../utils/EventEmitter'; +import { useDispatch } from 'react-redux'; +import EmitterKey from '../../../../../../data/EmitterKey'; +import { BatchUpdateSqlManageReqStatusEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; +import rule_template from '../../../../../../testUtils/mockApi/rule_template'; +import { ISqlManage } from '@actiontech/shared/lib/api/sqle/service/common'; + +jest.mock('react-redux', () => ({ + ...jest.requireActual('react-redux'), + useDispatch: jest.fn() +})); + +describe('page/SqlManagement/StatusDrawer', () => { + const dispatchSpy = jest.fn(); + + beforeEach(() => { + (useDispatch as jest.Mock).mockImplementation(() => dispatchSpy); + rule_template.mockAllApi(); + jest.useFakeTimers(); + }); + + afterEach(() => { + jest.useRealTimers(); + jest.clearAllMocks(); + cleanup(); + }); + + const customRender = (open?: boolean, selectData?: ISqlManage) => { + return superRender(, undefined, { + initStore: { + sqleManagement: { + modalStatus: { + [ModalName.View_Audit_Result_Drawer]: open ?? true + }, + selectSqleManagement: selectData ?? sqlManageListData.data[0] + } + } + }); + }; + + it('render modal when not open', () => { + const { baseElement } = customRender(false); + expect(baseElement).toMatchSnapshot(); + }); + + it('render empty status drawer info', async () => { + const { baseElement } = customRender( + true, + sqlManageListData.data[1] as ISqlManage + ); + await act(async () => jest.advanceTimersByTime(3000)); + expect(baseElement).toMatchSnapshot(); + }); + + it('render status drawer info', async () => { + const request = rule_template.getRuleList(); + const { baseElement } = customRender(); + await act(async () => jest.advanceTimersByTime(3000)); + const ruleNames = (sqlManageListData.data[0].audit_result ?? []) + .map((v) => v.rule_name ?? '') + .filter((v) => !!v); + expect(request).toBeCalledWith({ + filter_rule_names: ruleNames.join(',') + }); + expect(baseElement).toMatchSnapshot(); + expect(screen.getByText('SQL审核结果')).toBeInTheDocument(); + expect(screen.getByText('审核结果')).toBeInTheDocument(); + expect(screen.getByText('SQL语句')).toBeInTheDocument(); + }); + + it('close modal by click close button', async () => { + const { baseElement } = customRender(); + await act(async () => jest.advanceTimersByTime(3000)); + expect(baseElement).toMatchSnapshot(); + fireEvent.click(getBySelector('.closed-icon-custom')); + await act(async () => jest.advanceTimersByTime(300)); + expect(dispatchSpy).toBeCalledTimes(2); + expect(dispatchSpy).toBeCalledWith({ + type: 'sqleManagement/updateModalStatus', + payload: { + modalName: ModalName.View_Audit_Result_Drawer, + status: false + } + }); + expect(dispatchSpy).toBeCalledWith({ + type: 'sqleManagement/updateSqleManagement', + payload: null + }); + }); +}); diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx index e554c2ac1..f533de2c1 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx @@ -13,6 +13,7 @@ import user from '../../../testUtils/mockApi/user'; describe('page/WorkflowTemplate/WorkflowTemplateDetail', () => { beforeEach(() => { workflowTemplate.mockAllApi(); + user.mockAllApi(); mockUseCurrentProject(); mockUseCurrentUser(); jest.useFakeTimers(); diff --git a/packages/sqle/src/testUtils/mockApi/sqlManage/data.ts b/packages/sqle/src/testUtils/mockApi/sqlManage/data.ts index e9a61a9c2..8c7054f91 100644 --- a/packages/sqle/src/testUtils/mockApi/sqlManage/data.ts +++ b/packages/sqle/src/testUtils/mockApi/sqlManage/data.ts @@ -31,7 +31,7 @@ export const sqlManageListData = { source: { type: 'audit_plan', audit_plan_name: 'audit-plan-task1', - sql_audit_record_ids: null + sql_audit_record_ids: [] }, instance_name: 'mysql', schema_name: 'dms', @@ -126,7 +126,6 @@ export const sqlManageListData = { id: 248, sql_fingerprint: 'CREATE TABLE `plugins` (\n `name` varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL,\n `add_db_service_pre_check_url` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,\n `del_db_service_pre_check_url` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,\n `del_user_pre_check_url` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,\n `del_user_group_pre_check_url` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,\n `operate_data_resource_handle_url` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,\n PRIMARY KEY (`name`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci', - sql: 'CREATE TABLE `plugins` (\n `name` varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL,\n `add_db_service_pre_check_url` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,\n `del_db_service_pre_check_url` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,\n `del_user_pre_check_url` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,\n `del_user_group_pre_check_url` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,\n `operate_data_resource_handle_url` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,\n PRIMARY KEY (`name`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci', source: { type: 'audit_plan', audit_plan_name: 'audit-plan-task1', @@ -134,70 +133,6 @@ export const sqlManageListData = { }, instance_name: 'mysql', schema_name: 'dms', - audit_result: [ - { - level: 'error', - message: '主键建议使用自增', - rule_name: 'ddl_check_pk_without_auto_increment' - }, - { - level: 'error', - message: '主键建议使用 BIGINT 无符号类型,即 BIGINT UNSIGNED', - rule_name: 'ddl_check_pk_without_bigint_unsigned' - }, - { - level: 'error', - message: '新建表建议加入 IF NOT EXISTS,保证重复执行不报错', - rule_name: 'ddl_check_table_without_if_not_exists' - }, - { - level: 'error', - message: '除了自增列及大字段列之外,每个列都必须添加默认值', - rule_name: 'ddl_check_column_without_default' - }, - { - level: 'warn', - message: - '建表DDL需要包含UPDATE_TIME字段且默认值为CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP', - rule_name: 'ddl_check_update_time_column' - }, - { - level: 'warn', - message: '建议建表DDL包含CREATE_TIME字段且默认值为CURRENT_TIMESTAMP', - rule_name: 'ddl_check_create_time_column' - }, - { - level: 'warn', - message: '建议字段约束为NOT NULL时带默认值,以下字段不规范:name', - rule_name: 'ddl_check_field_not_null_must_contain_default_value' - }, - { - level: 'notice', - message: '建议使用规定的数据库排序规则为utf8mb4_0900_ai_ci', - rule_name: 'ddl_check_collation_database' - }, - { - level: 'notice', - message: - '建议字段add_db_service_pre_check_url,del_db_service_pre_check_url,del_user_pre_check_url,del_user_group_pre_check_url,operate_data_resource_handle_url设置NOT NULL约束', - rule_name: 'ddl_check_column_not_null' - }, - { - level: 'notice', - message: '列建议添加注释', - rule_name: 'ddl_check_column_without_comment' - }, - { - level: 'notice', - message: '建议主键命名为"PK_表名"', - rule_name: 'ddl_check_pk_name' - }, - { - level: 'notice', - message: '表建议添加注释', - rule_name: 'ddl_check_table_without_comment' - } - ], first_appear_timestamp: '', last_receive_timestamp: '', fp_count: 0, From 83c0e2b0a68033f01492e9823e52a533a9b8be86 Mon Sep 17 00:00:00 2001 From: sunjinkang <2060037942@qq.com> Date: Tue, 23 Jan 2024 19:25:54 +0800 Subject: [PATCH 04/17] [test]: add test for sql manage table --- .../Modal/AssignmentBatch/index.test.tsx | 2 +- .../Modal/AssignmentBatch/index.tsx | 33 +- .../Modal/AssignmentForm/index.test.tsx | 4 +- .../Modal/AssignmentSingle/index.test.tsx | 2 +- .../Modal/AssignmentSingle/index.tsx | 33 +- .../SQLEEIndex/Modal/ChangeStatus/index.tsx | 33 +- .../__snapshots__/index.test.tsx.snap | 1426 +--- .../SQLEEIndex/Modal/StatusDrawer/index.tsx | 34 +- .../component/SQLEEIndex/Modal/index.test.tsx | 57 + .../component/SQLEEIndex/Modal/index.tsx | 15 + .../__snapshots__/index.test.tsx.snap | 50 + .../SQLEEIndex/StatusTag/index.test.tsx | 44 + .../component/SQLEEIndex/StatusTag/index.tsx | 16 +- .../__snapshots__/index.test.tsx.snap | 6674 +++++++++++++++++ .../component/SQLEEIndex/column.tsx | 2 +- .../SQLEEIndex/hooks/useBatchAction.test.ts | 90 + .../SQLEEIndex/hooks/useBatchAction.ts | 77 + .../hooks/useGetTableFilterInfo.test.ts | 100 + .../SQLEEIndex/hooks/useGetTableFilterInfo.ts | 74 + .../SQLEEIndex/hooks/useTableRedux.test.ts | 106 + .../SQLEEIndex/hooks/useTableRedux.ts | 49 + .../component/SQLEEIndex/index.data.ts | 67 + .../component/SQLEEIndex/index.test.tsx | 230 + .../component/SQLEEIndex/index.tsx | 269 +- .../__snapshots__/index.test.tsx.snap | 238 + .../component/SQLStatistics/index.test.tsx | 51 + .../UpdateWorkflowTemplate/index.test.tsx | 10 +- .../WorkflowTemplateDetail/index.test.tsx | 6 +- .../src/testUtils/mockApi/sqlManage/data.ts | 206 +- .../sqle/src/testUtils/mockApi/user/data.ts | 6 +- .../sqle/src/testUtils/mockApi/user/index.ts | 4 +- 31 files changed, 8360 insertions(+), 1648 deletions(-) create mode 100644 packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/index.test.tsx create mode 100644 packages/sqle/src/page/SqlManagement/component/SQLEEIndex/StatusTag/__snapshots__/index.test.tsx.snap create mode 100644 packages/sqle/src/page/SqlManagement/component/SQLEEIndex/StatusTag/index.test.tsx create mode 100644 packages/sqle/src/page/SqlManagement/component/SQLEEIndex/__snapshots__/index.test.tsx.snap create mode 100644 packages/sqle/src/page/SqlManagement/component/SQLEEIndex/hooks/useBatchAction.test.ts create mode 100644 packages/sqle/src/page/SqlManagement/component/SQLEEIndex/hooks/useBatchAction.ts create mode 100644 packages/sqle/src/page/SqlManagement/component/SQLEEIndex/hooks/useGetTableFilterInfo.test.ts create mode 100644 packages/sqle/src/page/SqlManagement/component/SQLEEIndex/hooks/useGetTableFilterInfo.ts create mode 100644 packages/sqle/src/page/SqlManagement/component/SQLEEIndex/hooks/useTableRedux.test.ts create mode 100644 packages/sqle/src/page/SqlManagement/component/SQLEEIndex/hooks/useTableRedux.ts create mode 100644 packages/sqle/src/page/SqlManagement/component/SQLEEIndex/index.test.tsx create mode 100644 packages/sqle/src/page/SqlManagement/component/SQLStatistics/__snapshots__/index.test.tsx.snap create mode 100644 packages/sqle/src/page/SqlManagement/component/SQLStatistics/index.test.tsx diff --git a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentBatch/index.test.tsx b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentBatch/index.test.tsx index 72bde2195..c573c7013 100644 --- a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentBatch/index.test.tsx +++ b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentBatch/index.test.tsx @@ -58,7 +58,7 @@ describe('page/SqlManagement/AssignmentBatch', () => { it('update batch assign and submit change', async () => { const eventEmitSpy = jest.spyOn(EventEmitter, 'emit'); - const optionRequest = user.getUserTip(); + const optionRequest = user.getUserTipList(); const submitRequest = sqlManage.batchUpdateSqlManage(); const { baseElement } = customRender(); await act(async () => jest.advanceTimersByTime(3000)); diff --git a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentBatch/index.tsx b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentBatch/index.tsx index a9c2b4787..63451a8d9 100644 --- a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentBatch/index.tsx +++ b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentBatch/index.tsx @@ -1,4 +1,3 @@ -import { useDispatch } from 'react-redux'; import { useTranslation } from 'react-i18next'; import { ModalName } from '../../../../../../data/ModalName'; @@ -6,12 +5,6 @@ import { Space, message } from 'antd'; import AssignmentForm from '../AssignmentForm'; import { useBoolean } from 'ahooks'; -import { useSelector } from 'react-redux'; -import { IReduxState } from '../../../../../../../../base/src/store'; -import { - updateSqleManagementModalStatus, - updateSqlIdList -} from '../../../../../../store/sqleManagement'; import { useForm } from 'antd/es/form/Form'; import { BasicButton, BasicModal } from '@actiontech/shared'; import { useCurrentProject } from '@actiontech/shared/lib/global'; @@ -21,21 +14,20 @@ import { ResponseCode } from '@actiontech/shared/lib/enum'; import EmitterKey from '../../../../../../data/EmitterKey'; import EventEmitter from '../../../../../../utils/EventEmitter'; import { AssignmentFormField } from '../AssignmentForm/index.type'; -import { ISqlManage } from '@actiontech/shared/lib/api/sqle/service/common'; +import useTableRedux from '../../hooks/useTableRedux'; const AssignmentBatch = () => { const { t } = useTranslation(); - const dispatch = useDispatch(); + const { + open, + selectedSqlIdList: currentSelected, + updateIdList, + updateModalStatus + } = useTableRedux(ModalName.Assignment_Member_Batch); const [messageApi, contextMessageHolder] = message.useMessage(); - const open = useSelector( - (state) => - state.sqleManagement.modalStatus[ModalName.Assignment_Member_Batch] - ); - const currentSelected = useSelector( - (state) => state.sqleManagement.selectSqlIdList - ); + const { projectName } = useCurrentProject(); const [submitLoading, { setTrue: startSubmit, setFalse: submitFinish }] = useBoolean(); @@ -47,13 +39,8 @@ const AssignmentBatch = () => { }; const onCloseModal = () => { - dispatch( - updateSqleManagementModalStatus({ - modalName: ModalName.Assignment_Member_Batch, - status: false - }) - ); - dispatch(updateSqlIdList(null)); + updateModalStatus(ModalName.Assignment_Member_Batch, false); + updateIdList(null); }; const onSubmit = async () => { diff --git a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentForm/index.test.tsx b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentForm/index.test.tsx index f58b64f58..a4c26592b 100644 --- a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentForm/index.test.tsx +++ b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentForm/index.test.tsx @@ -50,7 +50,7 @@ describe('page/SqlManagement/AssignmentForm', () => { }); it('render form when init', async () => { - const request = user.getUserTip(); + const request = user.getUserTipList(); const { baseElement } = customRender(); expect(request).toBeCalled(); await act(async () => jest.advanceTimersByTime(3000)); @@ -68,7 +68,7 @@ describe('page/SqlManagement/AssignmentForm', () => { }); it('disable select', async () => { - const request = user.getUserTip(); + const request = user.getUserTipList(); const { baseElement } = customRender({ submitLoading: true }); expect(request).toBeCalled(); await act(async () => jest.advanceTimersByTime(3000)); diff --git a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentSingle/index.test.tsx b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentSingle/index.test.tsx index cf559ecbd..13d271115 100644 --- a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentSingle/index.test.tsx +++ b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentSingle/index.test.tsx @@ -58,7 +58,7 @@ describe('page/SqlManagement/AssignmentSingle', () => { it('update single assign and submit change', async () => { const eventEmitSpy = jest.spyOn(EventEmitter, 'emit'); - const optionRequest = user.getUserTip(); + const optionRequest = user.getUserTipList(); const submitRequest = sqlManage.batchUpdateSqlManage(); const { baseElement } = customRender(); await act(async () => jest.advanceTimersByTime(3000)); diff --git a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentSingle/index.tsx b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentSingle/index.tsx index 4586267b8..4d8b96d63 100644 --- a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentSingle/index.tsx +++ b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/AssignmentSingle/index.tsx @@ -1,4 +1,3 @@ -import { useDispatch } from 'react-redux'; import { useTranslation } from 'react-i18next'; import { ModalName } from '../../../../../../data/ModalName'; @@ -6,12 +5,6 @@ import { Space, message } from 'antd'; import AssignmentForm from '../AssignmentForm'; import { useBoolean } from 'ahooks'; -import { useSelector } from 'react-redux'; -import { IReduxState } from '../../../../../../../../base/src/store'; -import { - updateSqleManagementModalStatus, - updateSqleManagement -} from '../../../../../../store/sqleManagement'; import { useForm } from 'antd/es/form/Form'; import { BasicButton, BasicModal } from '@actiontech/shared'; import { useCurrentProject } from '@actiontech/shared/lib/global'; @@ -21,21 +14,20 @@ import { ResponseCode } from '@actiontech/shared/lib/enum'; import EmitterKey from '../../../../../../data/EmitterKey'; import EventEmitter from '../../../../../../utils/EventEmitter'; import { AssignmentFormField } from '../AssignmentForm/index.type'; -import { ISqlManage } from '@actiontech/shared/lib/api/sqle/service/common'; +import useTableRedux from '../../hooks/useTableRedux'; const AssignmentSingle = () => { const { t } = useTranslation(); - const dispatch = useDispatch(); + const { + open, + selectedSqleManagement: currentSelected, + setSelectData, + updateModalStatus + } = useTableRedux(ModalName.Assignment_Member_Single); const [messageApi, contextMessageHolder] = message.useMessage(); - const open = useSelector( - (state) => - state.sqleManagement.modalStatus[ModalName.Assignment_Member_Single] - ); - const currentSelected = useSelector( - (state) => state.sqleManagement.selectSqleManagement - ); + const { projectName } = useCurrentProject(); const [submitLoading, { setTrue: startSubmit, setFalse: submitFinish }] = useBoolean(); @@ -47,13 +39,8 @@ const AssignmentSingle = () => { }; const onCloseModal = () => { - dispatch( - updateSqleManagementModalStatus({ - modalName: ModalName.Assignment_Member_Single, - status: false - }) - ); - dispatch(updateSqleManagement(null)); + updateModalStatus(ModalName.Assignment_Member_Single, false); + setSelectData(null); }; const onSubmit = async () => { diff --git a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/ChangeStatus/index.tsx b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/ChangeStatus/index.tsx index 86a8cbf40..5bd9a44e7 100644 --- a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/ChangeStatus/index.tsx +++ b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/ChangeStatus/index.tsx @@ -1,17 +1,10 @@ import { useTranslation } from 'react-i18next'; import { Space, message, Form, Radio } from 'antd'; -import { useDispatch } from 'react-redux'; import { useBoolean } from 'ahooks'; -import { useSelector } from 'react-redux'; -import { IReduxState } from '../../../../../../../../base/src/store'; import { useForm } from 'antd/es/form/Form'; import { BasicButton, BasicModal } from '@actiontech/shared'; import { ModalName } from '../../../../../../data/ModalName'; -import { - updateSqleManagementModalStatus, - updateSqleManagement -} from '../../../../../../store/sqleManagement'; import { FormItemLabelStyleWrapper } from '@actiontech/shared/lib/components/FormCom/FormItemCom/style'; import { IBatchUpdateSqlManageParams } from '@actiontech/shared/lib/api/sqle/service/SqlManage/index.d'; import { useCurrentProject } from '@actiontech/shared/lib/global'; @@ -20,6 +13,7 @@ import SqlManage from '@actiontech/shared/lib/api/sqle/service/SqlManage'; import { ResponseCode } from '@actiontech/shared/lib/enum'; import EmitterKey from '../../../../../../data/EmitterKey'; import EventEmitter from '../../../../../../utils/EventEmitter'; +import useTableRedux from '../../hooks/useTableRedux'; export type ChangeStatusFields = { status: BatchUpdateSqlManageReqStatusEnum; @@ -28,14 +22,14 @@ export type ChangeStatusFields = { const ChangeStatus = () => { const { t } = useTranslation(); const [messageApi, contextMessageHolder] = message.useMessage(); - const dispatch = useDispatch(); - const open = useSelector( - (state) => state.sqleManagement.modalStatus[ModalName.Change_Status_Single] - ); - const currentSelected = useSelector( - (state) => state.sqleManagement.selectSqleManagement - ); + const { + open, + selectedSqleManagement: currentSelected, + setSelectData, + updateModalStatus + } = useTableRedux(ModalName.Change_Status_Single); + const [submitLoading, { setTrue: startSubmit, setFalse: submitFinish }] = useBoolean(false); const [form] = useForm(); @@ -47,13 +41,8 @@ const ChangeStatus = () => { }; const onCloseModal = () => { - dispatch( - updateSqleManagementModalStatus({ - modalName: ModalName.Change_Status_Single, - status: false - }) - ); - dispatch(updateSqleManagement(null)); + updateModalStatus(ModalName.Change_Status_Single, false); + setSelectData(null); handleReset(); }; @@ -62,7 +51,7 @@ const ChangeStatus = () => { startSubmit(); const params: IBatchUpdateSqlManageParams = { project_name: projectName, - sql_manage_id_list: [currentSelected?.id], + sql_manage_id_list: [currentSelected?.id as number], status: values.status }; SqlManage.BatchUpdateSqlManage(params) diff --git a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/StatusDrawer/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/StatusDrawer/__snapshots__/index.test.tsx.snap index ffc20e5eb..dcfce2f6c 100644 --- a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/StatusDrawer/__snapshots__/index.test.tsx.snap +++ b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/Modal/StatusDrawer/__snapshots__/index.test.tsx.snap @@ -69,7 +69,7 @@ exports[`page/SqlManagement/StatusDrawer close modal by click close button 1`] =
-
-
- - - - - - - - - 主键建议使用 BIGINT 无符号类型,即 BIGINT UNSIGNED - -
-
-
-
- - - - - - - - - 除了自增列及大字段列之外,每个列都必须添加默认值 - -
-
-
-
- - - - - - - - - 建议UNIQUE索引名使用 IDX_UK_表名_字段名 - -
-
-
-
- - - - - - - - - 建议UNIQUE索引要以"uniq_"为前缀 - -
-
-
-
- - - - - - - 这些索引字段(user_uid,project_uid)需要有非空约束 - -
-
-
-
- - - - - - - 建议建表DDL包含CREATE_TIME字段且默认值为CURRENT_TIMESTAMP - -
-
-
-
- - - - - - - 建议字段约束为NOT NULL时带默认值,以下字段不规范:uid - -
-
-
-
- - - - - - - 建表DDL需要包含UPDATE_TIME字段且默认值为CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP - -
-
-
-
- - - - - - - - - 建议使用规定的数据库排序规则为utf8mb4_0900_ai_ci - -
-
-
-
- - - - - - - - - 建议字段created_at,updated_at,user_uid,project_uid设置NOT NULL约束 - -
-
-
-
- - - - - - - - - 列建议添加注释 - -
-
-
-
- - - - - - - - - 建议主键命名为"PK_表名" - -
-
-
-
- - - - - - - - - 表建议添加注释 - -
-
-
- -
-
-

- SQL语句 -

-
-
- -
-
-
-
-
-
-
- -
- -`; - -exports[`page/SqlManagement/StatusDrawer render empty status drawer info 1`] = ` - -
-
-
-
- - -`; - -exports[`page/SqlManagement/StatusDrawer render modal when not open 1`] = ` - -
- -`; - -exports[`page/SqlManagement/StatusDrawer render status drawer info 1`] = ` - -
-
-
-
- + +
+ +`; + +exports[`page/SqlManagement/StatusDrawer render empty status drawer info 1`] = ` + +
+
+
+
+ + +
+ +`; + +exports[`page/SqlManagement/StatusDrawer render modal when not open 1`] = ` + +
+ +`; + +exports[`page/SqlManagement/StatusDrawer render status drawer info 1`] = ` + +
+
+
+
+ +
+ +`; + +exports[`page/SqlManagement/SQLEEIndex batch ignore operation for sql 1`] = ` + +
+
+
+ SQL管控 +
+
+ +
+
+
+
+
+
+
+
+ + 2 + + + SQL总数 + +
+
+
+ + 1 + + + 问题SQL数 + +
+
+
+ + 1 + + + 已优化SQL数 + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - +
+
+
+ class="ant-checkbox-inner" + /> + + - -
+ + SQL指纹 + + SQL + - - - - + - - - - + + 数据源 + + Schema + - - - + +
-
-
+ +
-
- -
- +
+
+ + 出现数量 + + +
- + + + + + + + - +
+ 负责人 + + 端点信息 + + 状态 + + 备注 + + 操作 +
+ + + + + - + +
+
- - - - - - - - - 建议UNIQUE索引名使用 IDX_UK_表名_字段名 - + + +
@@ -2310,12 +2362,12 @@ exports[`page/SqlManagement/SQLEEIndex batch operation for sql 1`] = `
- - + 2024-01-02 11:28:34 - - + 2024-01-03 11:28:34 - - +
+
+ + + T + + +
+
- - + + 12 + - +
-
+
+
+
+
    +
  • + + 共 2 条数据 + +
  • +
  • + +
  • +
  • + + 1 + +
  • +
  • + +
  • +
  • + +
  • +
+
+
+
+
+ +`; + +exports[`page/SqlManagement/SQLEEIndex batch solve operation for sql 1`] = ` + +
+
+
+ SQL管控 +
+
+ +
+
+
+
+
+
+
+
+ + 2 + + + SQL总数 + +
+
+
+ + 1 + + + 问题SQL数 + +
+
+
+ + 1 + + + 已优化SQL数 + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + +
+
+
+
+ + + + + + + + + + +
+
+ +
+
+
+
+
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+ SQL指纹 + + SQL + + 来源 + + 审核结果 + + 数据源 + + Schema + +
+ + 初次出现时间 + + + + +
+
+
+ + 最后一次出现时间 + + + + +
+
+
+ + 出现数量 + + + + +
+
+ 负责人 + + 端点信息 + + 状态 + + 备注 + + 操作 +
+ + + + + - + +
+
+
+ + + + + +
+
+
+
+ mysql + + dms + + 2024-01-02 11:28:34 + + 2024-01-03 11:28:34 + + 0 + +
+
+ + + T + + +
+
+
+ + 12 + + + + 未处理 + + +
+ this is remark text +
+ + + + + +
+ + +
+
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+
    +
  • + + 共 2 条数据 + +
  • +
  • + +
  • +
  • + + 1 + +
  • +
  • + +
  • +
  • + +
  • +
+
+
+
+
+ +`; + +exports[`page/SqlManagement/SQLEEIndex filter data about myself 1`] = ` + +
+
+
+ SQL管控 +
+
+ +
+
+
+
+
+
+ + + + + + +
+
+
+
+
+
+ + 0 + + + SQL总数 + +
+
+
+ + 0 + + + 问题SQL数 + +
+
+
+ + 0 + + + 已优化SQL数 + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + +
+
+
+
+ + + + + + + + + + +
+
+ +
+
+
+
+
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+ + + + + + +
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+ SQL指纹 + + SQL + + 来源 + + 审核结果 + + 数据源 + + Schema + +
+ + 初次出现时间 + + + + +
+
+
+ + 最后一次出现时间 + + + + +
+
+
+ + 出现数量 + + + + +
+
+ 负责人 + + 端点信息 + + 状态 + + 备注 + + 操作 +
+
+
+
+
+
+
+
+
+
+ +`; + +exports[`page/SqlManagement/SQLEEIndex filter data with rule name 1`] = ` + +
+
+
+ SQL管控 +
+
+ +
+
+
+
+
+
+ + + + + + +
+
+
+
+
+
+ + 0 + + + SQL总数 + +
+
+
+ + 0 + + + 问题SQL数 + +
+
+
+ + 0 + + + 已优化SQL数 + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + +
+
+
+
+ + + + + + + + + + +
+
+ +
+
+
+
+
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+ + + + + + +
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+ SQL指纹 + + SQL + + 来源 + + 审核结果 + + 数据源 + + Schema + +
+ + 初次出现时间 + + + + +
+
+
+ + 最后一次出现时间 + + + + +
+
+
+ + 出现数量 + + + + +
+
+ 负责人 + + 端点信息 + + 状态 + + 备注 + + 操作 +
+
+
+
+
+
+
+
+
+
+ +`; + +exports[`page/SqlManagement/SQLEEIndex filter data with rule name 2`] = ` + +
+
+
+ SQL管控 +
+
+ +
+
+
+
+
+
+
+
+ + 2 + + + SQL总数 + +
+
+
+ + 1 + + + 问题SQL数 + +
+
+
+ + 1 + + + 已优化SQL数 + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + +
+
+
+
+ + + + + + + + + + +
+
+ +
+
+
+
+
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+ + + + + + + 来源 + + + 请选择{{name}} + + + +
+
+
+
+
+
+ + + + + + + 数据源 + + + 请选择{{name}} + + + +
+
+
+
+
+
+ + + + + + + 最低审核等级 + + + 请选择{{name}} + + + +
+
+
+
+
+
+
+ +
+
+ + + + + +
+
+ +
+
+ + + 时间范围 + + +
+
+
+
+
+
+ + + + + + + 审核规则 + + + 请选择{{name}} + + + +
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+ SQL指纹 + + SQL + + 来源 + + 审核结果 + + 数据源 + + Schema + +
+ + 初次出现时间 + + + + +
+
+
+ + 最后一次出现时间 + + + + +
+
+
+ + 出现数量 + + + + +
+
+ 负责人 + + 端点信息 + + 状态 + + 备注 + + 操作 +
+ + + + + - + +
+
+
+ + + + + +
+
+
+
+ mysql + + dms + + 2024-01-02 11:28:34 + + 2024-01-03 11:28:34 + + 0 + +
+
+ + + T + + +
+
+
+ + 12 + + + + 未处理 + + +
+ this is remark text +
+ + + + + +
+ + +
+
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+
    +
  • + + 共 2 条数据 + +
  • +
  • + +
  • +
  • + + 1 + +
  • +
  • + +
  • +
  • + +
  • +
+
+
+
+
+
+
+
+ + + + + + + + + + + + +
+
+ +
+
+ +`; + +exports[`page/SqlManagement/SQLEEIndex filter data with status, sort and export data 1`] = ` + +
+
+
+ SQL管控 +
+
+ +
+
+
+
+
+
+ + + + + + +
+
+
+
+
+
+ + 0 + + + SQL总数 + +
+
+
+ + 0 + + + 问题SQL数 + +
+
+
+ + 0 + + + 已优化SQL数 + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + +
+
+
+
+ + + + + + + + + + +
+
+ +
+
+
+
+
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+ + + + + + +
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+ SQL指纹 + + SQL + + 来源 + + 审核结果 + + 数据源 + + Schema + +
+ + 初次出现时间 + + + + +
+
+
+ + 最后一次出现时间 + + + + +
+
+
+ + 出现数量 + + + + +
+
+ 负责人 + + 端点信息 + + 状态 + + 备注 + + 操作 +
+
+
+
+
+
+
+
+
+
+ +`; + +exports[`page/SqlManagement/SQLEEIndex jump to analyze and open modal when click row button 1`] = ` + +